python: add type hints
This commit is contained in:
parent
dd89ea4505
commit
3f2016e552
|
@ -1,15 +1,17 @@
|
||||||
import os.path, subprocess, sys
|
import os.path, subprocess, sys
|
||||||
|
from typing import Collection, Iterable, Optional
|
||||||
|
|
||||||
from build.makeproject import MakeProject
|
from build.makeproject import MakeProject
|
||||||
|
|
||||||
class AutotoolsProject(MakeProject):
|
class AutotoolsProject(MakeProject):
|
||||||
def __init__(self, url, md5, installed, configure_args=[],
|
def __init__(self, url: str, md5: str, installed: str,
|
||||||
autogen=False,
|
configure_args: Iterable[str]=[],
|
||||||
autoreconf=False,
|
autogen: bool=False,
|
||||||
cppflags='',
|
autoreconf: bool=False,
|
||||||
ldflags='',
|
cppflags: str='',
|
||||||
libs='',
|
ldflags: str='',
|
||||||
subdirs=None,
|
libs: str='',
|
||||||
|
subdirs: Optional[Collection[str]]=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
MakeProject.__init__(self, url, md5, installed, **kwargs)
|
MakeProject.__init__(self, url, md5, installed, **kwargs)
|
||||||
self.configure_args = configure_args
|
self.configure_args = configure_args
|
||||||
|
@ -20,7 +22,7 @@ class AutotoolsProject(MakeProject):
|
||||||
self.libs = libs
|
self.libs = libs
|
||||||
self.subdirs = subdirs
|
self.subdirs = subdirs
|
||||||
|
|
||||||
def configure(self, toolchain):
|
def configure(self, toolchain) -> str:
|
||||||
src = self.unpack(toolchain)
|
src = self.unpack(toolchain)
|
||||||
if self.autogen:
|
if self.autogen:
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
|
@ -68,7 +70,7 @@ class AutotoolsProject(MakeProject):
|
||||||
|
|
||||||
return build
|
return build
|
||||||
|
|
||||||
def _build(self, toolchain):
|
def _build(self, toolchain) -> None:
|
||||||
build = self.configure(toolchain)
|
build = self.configure(toolchain)
|
||||||
if self.subdirs is not None:
|
if self.subdirs is not None:
|
||||||
for subdir in self.subdirs:
|
for subdir in self.subdirs:
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from typing import Optional, TextIO
|
||||||
|
from collections.abc import Mapping
|
||||||
|
|
||||||
from build.project import Project
|
from build.project import Project
|
||||||
|
|
||||||
def __write_cmake_compiler(f, language, compiler):
|
def __write_cmake_compiler(f: TextIO, language: str, compiler: str) -> None:
|
||||||
s = compiler.split(' ', 1)
|
s = compiler.split(' ', 1)
|
||||||
if len(s) == 2:
|
if len(s) == 2:
|
||||||
print(f'set(CMAKE_{language}_COMPILER_LAUNCHER {s[0]})', file=f)
|
print(f'set(CMAKE_{language}_COMPILER_LAUNCHER {s[0]})', file=f)
|
||||||
compiler = s[1]
|
compiler = s[1]
|
||||||
print(f'set(CMAKE_{language}_COMPILER {compiler})', file=f)
|
print(f'set(CMAKE_{language}_COMPILER {compiler})', file=f)
|
||||||
|
|
||||||
def __write_cmake_toolchain_file(f, toolchain):
|
def __write_cmake_toolchain_file(f: TextIO, toolchain) -> None:
|
||||||
if '-darwin' in toolchain.actual_arch:
|
if '-darwin' in toolchain.actual_arch:
|
||||||
cmake_system_name = 'Darwin'
|
cmake_system_name = 'Darwin'
|
||||||
elif toolchain.is_windows:
|
elif toolchain.is_windows:
|
||||||
|
@ -52,7 +54,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def configure(toolchain, src, build, args=(), env=None):
|
def configure(toolchain, src: str, build: str, args: list[str]=[], env: Optional[Mapping[str, str]]=None) -> None:
|
||||||
cross_args = []
|
cross_args = []
|
||||||
|
|
||||||
if toolchain.is_windows:
|
if toolchain.is_windows:
|
||||||
|
@ -91,16 +93,17 @@ def configure(toolchain, src, build, args=(), env=None):
|
||||||
subprocess.check_call(configure, env=env, cwd=build)
|
subprocess.check_call(configure, env=env, cwd=build)
|
||||||
|
|
||||||
class CmakeProject(Project):
|
class CmakeProject(Project):
|
||||||
def __init__(self, url, md5, installed, configure_args=[],
|
def __init__(self, url: str, md5: str, installed: str,
|
||||||
windows_configure_args=[],
|
configure_args: list[str]=[],
|
||||||
env=None,
|
windows_configure_args: list[str]=[],
|
||||||
|
env: Optional[Mapping[str, str]]=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
Project.__init__(self, url, md5, installed, **kwargs)
|
Project.__init__(self, url, md5, installed, **kwargs)
|
||||||
self.configure_args = configure_args
|
self.configure_args = configure_args
|
||||||
self.windows_configure_args = windows_configure_args
|
self.windows_configure_args = windows_configure_args
|
||||||
self.env = env
|
self.env = env
|
||||||
|
|
||||||
def configure(self, toolchain):
|
def configure(self, toolchain) -> str:
|
||||||
src = self.unpack(toolchain)
|
src = self.unpack(toolchain)
|
||||||
build = self.make_build_path(toolchain)
|
build = self.make_build_path(toolchain)
|
||||||
configure_args = self.configure_args
|
configure_args = self.configure_args
|
||||||
|
@ -109,7 +112,7 @@ class CmakeProject(Project):
|
||||||
configure(toolchain, src, build, configure_args, self.env)
|
configure(toolchain, src, build, configure_args, self.env)
|
||||||
return build
|
return build
|
||||||
|
|
||||||
def _build(self, toolchain):
|
def _build(self, toolchain) -> None:
|
||||||
build = self.configure(toolchain)
|
build = self.configure(toolchain)
|
||||||
subprocess.check_call(['ninja', '-v', 'install'],
|
subprocess.check_call(['ninja', '-v', 'install'],
|
||||||
cwd=build, env=toolchain.env)
|
cwd=build, env=toolchain.env)
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import subprocess, multiprocessing
|
import subprocess, multiprocessing
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from build.project import Project
|
from build.project import Project
|
||||||
|
|
||||||
class MakeProject(Project):
|
class MakeProject(Project):
|
||||||
def __init__(self, url, md5, installed,
|
def __init__(self, url: str, md5: str, installed: str,
|
||||||
install_target='install',
|
install_target: str='install',
|
||||||
**kwargs):
|
**kwargs):
|
||||||
Project.__init__(self, url, md5, installed, **kwargs)
|
Project.__init__(self, url, md5, installed, **kwargs)
|
||||||
self.install_target = install_target
|
self.install_target = install_target
|
||||||
|
|
||||||
def get_simultaneous_jobs(self):
|
def get_simultaneous_jobs(self) -> int:
|
||||||
try:
|
try:
|
||||||
# use twice as many simultaneous jobs as we have CPU cores
|
# use twice as many simultaneous jobs as we have CPU cores
|
||||||
return multiprocessing.cpu_count() * 2
|
return multiprocessing.cpu_count() * 2
|
||||||
|
@ -17,17 +18,17 @@ class MakeProject(Project):
|
||||||
# default to 12, if multiprocessing.cpu_count() is not implemented
|
# default to 12, if multiprocessing.cpu_count() is not implemented
|
||||||
return 12
|
return 12
|
||||||
|
|
||||||
def get_make_args(self, toolchain):
|
def get_make_args(self, toolchain) -> list[str]:
|
||||||
return ['--quiet', '-j' + str(self.get_simultaneous_jobs())]
|
return ['--quiet', '-j' + str(self.get_simultaneous_jobs())]
|
||||||
|
|
||||||
def get_make_install_args(self, toolchain):
|
def get_make_install_args(self, toolchain) -> list[str]:
|
||||||
return ['--quiet', self.install_target]
|
return ['--quiet', self.install_target]
|
||||||
|
|
||||||
def make(self, toolchain, wd, args):
|
def make(self, toolchain, wd: str, args: list[str]) -> None:
|
||||||
subprocess.check_call(['make'] + args,
|
subprocess.check_call(['make'] + args,
|
||||||
cwd=wd, env=toolchain.env)
|
cwd=wd, env=toolchain.env)
|
||||||
|
|
||||||
def build_make(self, toolchain, wd, install=True):
|
def build_make(self, toolchain, wd: str, install: bool=True) -> None:
|
||||||
self.make(toolchain, wd, self.get_make_args(toolchain))
|
self.make(toolchain, wd, self.get_make_args(toolchain))
|
||||||
if install:
|
if install:
|
||||||
self.make(toolchain, wd, self.get_make_install_args(toolchain))
|
self.make(toolchain, wd, self.get_make_install_args(toolchain))
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import platform
|
import platform
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from build.project import Project
|
from build.project import Project
|
||||||
|
|
||||||
def make_cross_file(toolchain):
|
def make_cross_file(toolchain) -> str:
|
||||||
if toolchain.is_windows:
|
if toolchain.is_windows:
|
||||||
system = 'windows'
|
system = 'windows'
|
||||||
windres = "windres = '%s'" % toolchain.windres
|
windres = "windres = '%s'" % toolchain.windres
|
||||||
|
@ -80,7 +81,7 @@ endian = '{endian}'
|
||||||
""")
|
""")
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def configure(toolchain, src, build, args=()):
|
def configure(toolchain, src: str, build: str, args: list[str]=[]) -> None:
|
||||||
cross_file = make_cross_file(toolchain)
|
cross_file = make_cross_file(toolchain)
|
||||||
configure = [
|
configure = [
|
||||||
'meson', 'setup',
|
'meson', 'setup',
|
||||||
|
@ -103,18 +104,19 @@ def configure(toolchain, src, build, args=()):
|
||||||
subprocess.check_call(configure, env=env)
|
subprocess.check_call(configure, env=env)
|
||||||
|
|
||||||
class MesonProject(Project):
|
class MesonProject(Project):
|
||||||
def __init__(self, url, md5, installed, configure_args=[],
|
def __init__(self, url: str, md5: str, installed: str,
|
||||||
|
configure_args: list[str]=[],
|
||||||
**kwargs):
|
**kwargs):
|
||||||
Project.__init__(self, url, md5, installed, **kwargs)
|
Project.__init__(self, url, md5, installed, **kwargs)
|
||||||
self.configure_args = configure_args
|
self.configure_args = configure_args
|
||||||
|
|
||||||
def configure(self, toolchain):
|
def configure(self, toolchain) -> str:
|
||||||
src = self.unpack(toolchain)
|
src = self.unpack(toolchain)
|
||||||
build = self.make_build_path(toolchain)
|
build = self.make_build_path(toolchain)
|
||||||
configure(toolchain, src, build, self.configure_args)
|
configure(toolchain, src, build, self.configure_args)
|
||||||
return build
|
return build
|
||||||
|
|
||||||
def _build(self, toolchain):
|
def _build(self, toolchain) -> None:
|
||||||
build = self.configure(toolchain)
|
build = self.configure(toolchain)
|
||||||
subprocess.check_call(['ninja', '-v', 'install'],
|
subprocess.check_call(['ninja', '-v', 'install'],
|
||||||
cwd=build, env=toolchain.env)
|
cwd=build, env=toolchain.env)
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from build.makeproject import MakeProject
|
from build.makeproject import MakeProject
|
||||||
|
|
||||||
class OpenSSLProject(MakeProject):
|
class OpenSSLProject(MakeProject):
|
||||||
def __init__(self, url, md5, installed,
|
def __init__(self, url: str, md5: str, installed: str,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
MakeProject.__init__(self, url, md5, installed, install_target='install_dev', **kwargs)
|
MakeProject.__init__(self, url, md5, installed, install_target='install_dev', **kwargs)
|
||||||
|
|
||||||
def get_make_args(self, toolchain):
|
def get_make_args(self, toolchain) -> list[str]:
|
||||||
return MakeProject.get_make_args(self, toolchain) + [
|
return MakeProject.get_make_args(self, toolchain) + [
|
||||||
'CC=' + toolchain.cc,
|
'CC=' + toolchain.cc,
|
||||||
'CFLAGS=' + toolchain.cflags,
|
'CFLAGS=' + toolchain.cflags,
|
||||||
|
@ -17,13 +18,13 @@ class OpenSSLProject(MakeProject):
|
||||||
'build_libs',
|
'build_libs',
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_make_install_args(self, toolchain):
|
def get_make_install_args(self, toolchain) -> list[str]:
|
||||||
# OpenSSL's Makefile runs "ranlib" during installation
|
# OpenSSL's Makefile runs "ranlib" during installation
|
||||||
return MakeProject.get_make_install_args(self, toolchain) + [
|
return MakeProject.get_make_install_args(self, toolchain) + [
|
||||||
'RANLIB=' + toolchain.ranlib,
|
'RANLIB=' + toolchain.ranlib,
|
||||||
]
|
]
|
||||||
|
|
||||||
def _build(self, toolchain):
|
def _build(self, toolchain) -> None:
|
||||||
src = self.unpack(toolchain, out_of_tree=False)
|
src = self.unpack(toolchain, out_of_tree=False)
|
||||||
|
|
||||||
# OpenSSL has a weird target architecture scheme with lots of
|
# OpenSSL has a weird target architecture scheme with lots of
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
import os, shutil
|
import os, shutil
|
||||||
import re
|
import re
|
||||||
|
from typing import cast, BinaryIO, Optional
|
||||||
|
|
||||||
from build.download import download_and_verify
|
from build.download import download_and_verify
|
||||||
from build.tar import untar
|
from build.tar import untar
|
||||||
from build.quilt import push_all
|
from build.quilt import push_all
|
||||||
|
|
||||||
class Project:
|
class Project:
|
||||||
def __init__(self, url, md5, installed, name=None, version=None,
|
def __init__(self, url: str, md5: str, installed: str,
|
||||||
base=None,
|
name: Optional[str]=None, version: Optional[str]=None,
|
||||||
patches=None,
|
base: Optional[str]=None,
|
||||||
|
patches: Optional[str]=None,
|
||||||
edits=None,
|
edits=None,
|
||||||
use_cxx=False):
|
use_cxx: bool=False):
|
||||||
if base is None:
|
if base is None:
|
||||||
basename = os.path.basename(url)
|
basename = os.path.basename(url)
|
||||||
m = re.match(r'^(.+)\.(tar(\.(gz|bz2|xz|lzma))?|zip)$', basename)
|
m = re.match(r'^(.+)\.(tar(\.(gz|bz2|xz|lzma))?|zip)$', basename)
|
||||||
|
@ -39,10 +41,10 @@ class Project:
|
||||||
self.edits = edits
|
self.edits = edits
|
||||||
self.use_cxx = use_cxx
|
self.use_cxx = use_cxx
|
||||||
|
|
||||||
def download(self, toolchain):
|
def download(self, toolchain) -> str:
|
||||||
return download_and_verify(self.url, self.md5, toolchain.tarball_path)
|
return download_and_verify(self.url, self.md5, toolchain.tarball_path)
|
||||||
|
|
||||||
def is_installed(self, toolchain):
|
def is_installed(self, toolchain) -> bool:
|
||||||
tarball = self.download(toolchain)
|
tarball = self.download(toolchain)
|
||||||
installed = os.path.join(toolchain.install_prefix, self.installed)
|
installed = os.path.join(toolchain.install_prefix, self.installed)
|
||||||
tarball_mtime = os.path.getmtime(tarball)
|
tarball_mtime = os.path.getmtime(tarball)
|
||||||
|
@ -51,7 +53,7 @@ class Project:
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def unpack(self, toolchain, out_of_tree=True):
|
def unpack(self, toolchain, out_of_tree: bool=True) -> str:
|
||||||
if out_of_tree:
|
if out_of_tree:
|
||||||
parent_path = toolchain.src_path
|
parent_path = toolchain.src_path
|
||||||
else:
|
else:
|
||||||
|
@ -72,7 +74,7 @@ class Project:
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def make_build_path(self, toolchain, lazy=False):
|
def make_build_path(self, toolchain, lazy: bool=False) -> str:
|
||||||
path = os.path.join(toolchain.build_path, self.base)
|
path = os.path.join(toolchain.build_path, self.base)
|
||||||
if lazy and os.path.isdir(path):
|
if lazy and os.path.isdir(path):
|
||||||
return path
|
return path
|
||||||
|
@ -83,5 +85,5 @@ class Project:
|
||||||
os.makedirs(path, exist_ok=True)
|
os.makedirs(path, exist_ok=True)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def build(self, toolchain):
|
def build(self, toolchain) -> None:
|
||||||
self._build(toolchain)
|
self._build(toolchain)
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
def run_quilt(toolchain, cwd, patches_path, *args):
|
def run_quilt(toolchain, cwd: str, patches_path: str, *args: str) -> None:
|
||||||
env = dict(toolchain.env)
|
env = dict(toolchain.env)
|
||||||
env['QUILT_PATCHES'] = patches_path
|
env['QUILT_PATCHES'] = patches_path
|
||||||
subprocess.check_call(['quilt'] + list(args), cwd=cwd, env=env)
|
subprocess.check_call(['quilt'] + list(args), cwd=cwd, env=env)
|
||||||
|
|
||||||
def push_all(toolchain, src_path, patches_path):
|
def push_all(toolchain, src_path: str, patches_path: str) -> None:
|
||||||
run_quilt(toolchain, src_path, patches_path, 'push', '-a')
|
run_quilt(toolchain, src_path, patches_path, 'push', '-a')
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import hashlib
|
import hashlib
|
||||||
|
from typing import cast, Any, BinaryIO
|
||||||
|
|
||||||
def feed_file(h, f):
|
def feed_file(h: Any, f: BinaryIO) -> None:
|
||||||
"""Feed data read from an open file into the hashlib instance."""
|
"""Feed data read from an open file into the hashlib instance."""
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
@ -10,20 +11,20 @@ def feed_file(h, f):
|
||||||
break
|
break
|
||||||
h.update(data)
|
h.update(data)
|
||||||
|
|
||||||
def feed_file_path(h, path):
|
def feed_file_path(h: Any, path: str) -> None:
|
||||||
"""Feed data read from a file (to be opened by this function) into the hashlib instance."""
|
"""Feed data read from a file (to be opened by this function) into the hashlib instance."""
|
||||||
|
|
||||||
with open(path, 'rb') as f:
|
with open(path, 'rb') as f:
|
||||||
feed_file(h, f)
|
feed_file(h, f)
|
||||||
|
|
||||||
def file_digest(algorithm, path):
|
def file_digest(algorithm: Any, path: str) -> str:
|
||||||
"""Calculate the digest of a file and return it in hexadecimal notation."""
|
"""Calculate the digest of a file and return it in hexadecimal notation."""
|
||||||
|
|
||||||
h = algorithm()
|
h = algorithm()
|
||||||
feed_file_path(h, path)
|
feed_file_path(h, path)
|
||||||
return h.hexdigest()
|
return cast(str, h.hexdigest())
|
||||||
|
|
||||||
def guess_digest_algorithm(digest):
|
def guess_digest_algorithm(digest: str) -> Any:
|
||||||
l = len(digest)
|
l = len(digest)
|
||||||
if l == 32:
|
if l == 32:
|
||||||
return hashlib.md5
|
return hashlib.md5
|
||||||
|
@ -36,7 +37,7 @@ def guess_digest_algorithm(digest):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def verify_file_digest(path, expected_digest):
|
def verify_file_digest(path: str, expected_digest: str) -> bool:
|
||||||
"""Verify the digest of a file, and return True if the digest matches with the given expected digest."""
|
"""Verify the digest of a file, and return True if the digest matches with the given expected digest."""
|
||||||
|
|
||||||
algorithm = guess_digest_algorithm(expected_digest)
|
algorithm = guess_digest_algorithm(expected_digest)
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from build.makeproject import MakeProject
|
from build.makeproject import MakeProject
|
||||||
|
|
||||||
class ZlibProject(MakeProject):
|
class ZlibProject(MakeProject):
|
||||||
def __init__(self, url, md5, installed,
|
def __init__(self, url: str, md5: str, installed: str,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
MakeProject.__init__(self, url, md5, installed, **kwargs)
|
MakeProject.__init__(self, url, md5, installed, **kwargs)
|
||||||
|
|
||||||
def get_make_args(self, toolchain):
|
def get_make_args(self, toolchain) -> list[str]:
|
||||||
return MakeProject.get_make_args(self, toolchain) + [
|
return MakeProject.get_make_args(self, toolchain) + [
|
||||||
'CC=' + toolchain.cc + ' ' + toolchain.cppflags + ' ' + toolchain.cflags,
|
'CC=' + toolchain.cc + ' ' + toolchain.cppflags + ' ' + toolchain.cflags,
|
||||||
'CPP=' + toolchain.cc + ' -E ' + toolchain.cppflags,
|
'CPP=' + toolchain.cc + ' -E ' + toolchain.cppflags,
|
||||||
|
@ -18,13 +19,13 @@ class ZlibProject(MakeProject):
|
||||||
'libz.a'
|
'libz.a'
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_make_install_args(self, toolchain):
|
def get_make_install_args(self, toolchain) -> list[str]:
|
||||||
return [
|
return [
|
||||||
'RANLIB=' + toolchain.ranlib,
|
'RANLIB=' + toolchain.ranlib,
|
||||||
self.install_target
|
self.install_target
|
||||||
]
|
]
|
||||||
|
|
||||||
def _build(self, toolchain):
|
def _build(self, toolchain) -> None:
|
||||||
src = self.unpack(toolchain, out_of_tree=False)
|
src = self.unpack(toolchain, out_of_tree=False)
|
||||||
|
|
||||||
subprocess.check_call(['./configure', '--prefix=' + toolchain.install_prefix, '--static'],
|
subprocess.check_call(['./configure', '--prefix=' + toolchain.install_prefix, '--static'],
|
||||||
|
|
Loading…
Reference in New Issue