python/build: add support for fallback download URLs
This commit is contained in:
parent
f6d73555a6
commit
eb23788fec
|
@ -1,11 +1,11 @@
|
||||||
import os.path, subprocess, sys
|
import os.path, subprocess, sys
|
||||||
from typing import Collection, Iterable, Optional
|
from typing import Collection, Iterable, Optional, Sequence, Union
|
||||||
|
|
||||||
from build.makeproject import MakeProject
|
from build.makeproject import MakeProject
|
||||||
from .toolchain import AnyToolchain
|
from .toolchain import AnyToolchain
|
||||||
|
|
||||||
class AutotoolsProject(MakeProject):
|
class AutotoolsProject(MakeProject):
|
||||||
def __init__(self, url: str, md5: str, installed: str,
|
def __init__(self, url: Union[str, Sequence[str]], md5: str, installed: str,
|
||||||
configure_args: Iterable[str]=[],
|
configure_args: Iterable[str]=[],
|
||||||
autogen: bool=False,
|
autogen: bool=False,
|
||||||
autoreconf: bool=False,
|
autoreconf: bool=False,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional, TextIO
|
from typing import Optional, Sequence, TextIO, Union
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
|
|
||||||
from build.project import Project
|
from build.project import Project
|
||||||
|
@ -94,7 +94,7 @@ def configure(toolchain: AnyToolchain, src: str, build: str, args: list[str]=[],
|
||||||
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: str, md5: str, installed: str,
|
def __init__(self, url: Union[str, Sequence[str]], md5: str, installed: str,
|
||||||
configure_args: list[str]=[],
|
configure_args: list[str]=[],
|
||||||
windows_configure_args: list[str]=[],
|
windows_configure_args: list[str]=[],
|
||||||
env: Optional[Mapping[str, str]]=None,
|
env: Optional[Mapping[str, str]]=None,
|
||||||
|
|
|
@ -1,13 +1,50 @@
|
||||||
|
from typing import Sequence, Union
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
|
||||||
from .verify import verify_file_digest
|
from .verify import verify_file_digest
|
||||||
|
|
||||||
def download_and_verify(url, md5, parent_path):
|
def __to_string_sequence(x: Union[str, Sequence[str]]) -> Sequence[str]:
|
||||||
|
if isinstance(x, str):
|
||||||
|
return (x,)
|
||||||
|
else:
|
||||||
|
return x
|
||||||
|
|
||||||
|
def __get_any(x: Union[str, Sequence[str]]) -> str:
|
||||||
|
if isinstance(x, str):
|
||||||
|
return x
|
||||||
|
else:
|
||||||
|
return x[0]
|
||||||
|
|
||||||
|
def __download_one(url: str, path: str) -> None:
|
||||||
|
print("download", url)
|
||||||
|
urllib.request.urlretrieve(url, path)
|
||||||
|
|
||||||
|
def __download(urls: Sequence[str], path: str) -> None:
|
||||||
|
for url in urls[:-1]:
|
||||||
|
try:
|
||||||
|
__download_one(url, path)
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
print("download error:", sys.exc_info()[0])
|
||||||
|
__download_one(urls[-1], path)
|
||||||
|
|
||||||
|
def __download_and_verify_to(urls: Sequence[str], md5: str, path: str) -> None:
|
||||||
|
__download(urls, path)
|
||||||
|
if not verify_file_digest(path, md5):
|
||||||
|
raise RuntimeError("Digest mismatch")
|
||||||
|
|
||||||
|
def download_basename(urls: Union[str, Sequence[str]]) -> str:
|
||||||
|
return os.path.basename(__get_any(urls))
|
||||||
|
|
||||||
|
def download_and_verify(urls: Union[str, Sequence[str]], md5: str, parent_path: str) -> str:
|
||||||
"""Download a file, verify its MD5 checksum and return the local path."""
|
"""Download a file, verify its MD5 checksum and return the local path."""
|
||||||
|
|
||||||
|
base = download_basename(urls)
|
||||||
|
|
||||||
os.makedirs(parent_path, exist_ok=True)
|
os.makedirs(parent_path, exist_ok=True)
|
||||||
path = os.path.join(parent_path, os.path.basename(url))
|
path = os.path.join(parent_path, base)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if verify_file_digest(path, md5): return path
|
if verify_file_digest(path, md5): return path
|
||||||
|
@ -17,11 +54,6 @@ def download_and_verify(url, md5, parent_path):
|
||||||
|
|
||||||
tmp_path = path + '.tmp'
|
tmp_path = path + '.tmp'
|
||||||
|
|
||||||
print("download", url)
|
__download_and_verify_to(__to_string_sequence(urls), md5, tmp_path)
|
||||||
urllib.request.urlretrieve(url, tmp_path)
|
|
||||||
if not verify_file_digest(tmp_path, md5):
|
|
||||||
os.unlink(tmp_path)
|
|
||||||
raise RuntimeError("Digest mismatch")
|
|
||||||
|
|
||||||
os.rename(tmp_path, path)
|
os.rename(tmp_path, path)
|
||||||
return path
|
return path
|
||||||
|
|
|
@ -57,7 +57,8 @@ flac = AutotoolsProject(
|
||||||
)
|
)
|
||||||
|
|
||||||
zlib = ZlibProject(
|
zlib = ZlibProject(
|
||||||
'http://zlib.net/zlib-1.3.tar.xz',
|
('http://zlib.net/zlib-1.3.tar.xz',
|
||||||
|
'https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.xz'),
|
||||||
'8a9ba2898e1d0d774eca6ba5b4627a11e5588ba85c8851336eb38de4683050a7',
|
'8a9ba2898e1d0d774eca6ba5b4627a11e5588ba85c8851336eb38de4683050a7',
|
||||||
'lib/libz.a',
|
'lib/libz.a',
|
||||||
)
|
)
|
||||||
|
@ -599,13 +600,15 @@ ffmpeg = FfmpegProject(
|
||||||
)
|
)
|
||||||
|
|
||||||
openssl = OpenSSLProject(
|
openssl = OpenSSLProject(
|
||||||
'https://www.openssl.org/source/openssl-3.1.3.tar.gz',
|
('https://www.openssl.org/source/openssl-3.1.3.tar.gz',
|
||||||
|
'https://artfiles.org/openssl.org/source/openssl-3.1.3.tar.gz'),
|
||||||
'f0316a2ebd89e7f2352976445458689f80302093788c466692fb2a188b2eacf6',
|
'f0316a2ebd89e7f2352976445458689f80302093788c466692fb2a188b2eacf6',
|
||||||
'include/openssl/ossl_typ.h',
|
'include/openssl/ossl_typ.h',
|
||||||
)
|
)
|
||||||
|
|
||||||
curl = CmakeProject(
|
curl = CmakeProject(
|
||||||
'https://curl.se/download/curl-8.2.1.tar.xz',
|
('https://curl.se/download/curl-8.2.1.tar.xz',
|
||||||
|
'https://github.com/curl/curl/releases/download/curl-8_2_1/curl-8.2.1.tar.xz'),
|
||||||
'dd322f6bd0a20e6cebdfd388f69e98c3d183bed792cf4713c8a7ef498cba4894',
|
'dd322f6bd0a20e6cebdfd388f69e98c3d183bed792cf4713c8a7ef498cba4894',
|
||||||
'lib/libcurl.a',
|
'lib/libcurl.a',
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import subprocess, multiprocessing
|
import subprocess, multiprocessing
|
||||||
from typing import Optional
|
from typing import Optional, Sequence, Union
|
||||||
|
|
||||||
from build.project import Project
|
from build.project import Project
|
||||||
from .toolchain import AnyToolchain
|
from .toolchain import AnyToolchain
|
||||||
|
|
||||||
class MakeProject(Project):
|
class MakeProject(Project):
|
||||||
def __init__(self, url: str, md5: str, installed: str,
|
def __init__(self, url: Union[str, Sequence[str]], md5: str, installed: str,
|
||||||
install_target: str='install',
|
install_target: str='install',
|
||||||
**kwargs):
|
**kwargs):
|
||||||
Project.__init__(self, url, md5, installed, **kwargs)
|
Project.__init__(self, url, md5, installed, **kwargs)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import platform
|
import platform
|
||||||
from typing import Optional
|
from typing import Optional, Sequence, Union
|
||||||
|
|
||||||
from build.project import Project
|
from build.project import Project
|
||||||
from .toolchain import AnyToolchain
|
from .toolchain import AnyToolchain
|
||||||
|
@ -105,7 +105,7 @@ def configure(toolchain: AnyToolchain, src: str, build: str, args: list[str]=[])
|
||||||
subprocess.check_call(configure, env=env)
|
subprocess.check_call(configure, env=env)
|
||||||
|
|
||||||
class MesonProject(Project):
|
class MesonProject(Project):
|
||||||
def __init__(self, url: str, md5: str, installed: str,
|
def __init__(self, url: Union[str, Sequence[str]], md5: str, installed: str,
|
||||||
configure_args: list[str]=[],
|
configure_args: list[str]=[],
|
||||||
**kwargs):
|
**kwargs):
|
||||||
Project.__init__(self, url, md5, installed, **kwargs)
|
Project.__init__(self, url, md5, installed, **kwargs)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional
|
from typing import Optional, Sequence, Union
|
||||||
|
|
||||||
from build.makeproject import MakeProject
|
from build.makeproject import MakeProject
|
||||||
from .toolchain import AnyToolchain
|
from .toolchain import AnyToolchain
|
||||||
|
|
||||||
class OpenSSLProject(MakeProject):
|
class OpenSSLProject(MakeProject):
|
||||||
def __init__(self, url: str, md5: str, installed: str,
|
def __init__(self, url: Union[str, Sequence[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)
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import os, shutil
|
import os, shutil
|
||||||
import re
|
import re
|
||||||
from typing import cast, BinaryIO, Optional
|
from typing import cast, BinaryIO, Optional, Sequence, Union
|
||||||
|
|
||||||
from build.download import download_and_verify
|
from build.download import download_basename, 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
|
||||||
from .toolchain import AnyToolchain
|
from .toolchain import AnyToolchain
|
||||||
|
|
||||||
class Project:
|
class Project:
|
||||||
def __init__(self, url: str, md5: str, installed: str,
|
def __init__(self, url: Union[str, Sequence[str]], md5: str, installed: str,
|
||||||
name: Optional[str]=None, version: Optional[str]=None,
|
name: Optional[str]=None, version: Optional[str]=None,
|
||||||
base: Optional[str]=None,
|
base: Optional[str]=None,
|
||||||
patches: Optional[str]=None,
|
patches: Optional[str]=None,
|
||||||
edits=None,
|
edits=None,
|
||||||
use_cxx: bool=False):
|
use_cxx: bool=False):
|
||||||
if base is None:
|
if base is None:
|
||||||
basename = os.path.basename(url)
|
basename = download_basename(url)
|
||||||
m = re.match(r'^(.+)\.(tar(\.(gz|bz2|xz|lzma))?|zip)$', basename)
|
m = re.match(r'^(.+)\.(tar(\.(gz|bz2|xz|lzma))?|zip)$', basename)
|
||||||
if not m: raise RuntimeError('Could not identify tarball name: ' + basename)
|
if not m: raise RuntimeError('Could not identify tarball name: ' + basename)
|
||||||
self.base = m.group(1)
|
self.base = m.group(1)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
from typing import Optional
|
from typing import Optional, Sequence, Union
|
||||||
|
|
||||||
from build.makeproject import MakeProject
|
from build.makeproject import MakeProject
|
||||||
from .toolchain import AnyToolchain
|
from .toolchain import AnyToolchain
|
||||||
|
|
||||||
class ZlibProject(MakeProject):
|
class ZlibProject(MakeProject):
|
||||||
def __init__(self, url: str, md5: str, installed: str,
|
def __init__(self, url: Union[str, Sequence[str]], md5: str, installed: str,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
MakeProject.__init__(self, url, md5, installed, **kwargs)
|
MakeProject.__init__(self, url, md5, installed, **kwargs)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue