diff --git a/CHANGELOG.md b/CHANGELOG.md index 4592e1b..f713019 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +0.1.8 +===== +- Refactor to support early import of ppbt.common at relenv runtime. + + 0.1.7 ===== - Use tar instead of tarfile to create toolchain tarballs diff --git a/pyproject.toml b/pyproject.toml index 5e77e5b..a79534e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,8 +4,8 @@ requires = [ "wheel>=0.31.0", "twine>=1.11.0" ] -build-backend = "build" -backend-path = ["src/ppbt"] +build-backend = "ppbt.build" +backend-path = ["src"] [tool.pytest.ini_options] pythonpath = [ diff --git a/src/ppbt/build.py b/src/ppbt/build.py index abfe83f..8e05098 100644 --- a/src/ppbt/build.py +++ b/src/ppbt/build.py @@ -14,13 +14,14 @@ import shutil import subprocess import sys -import tarfile import time import urllib.error import urllib.request from setuptools.build_meta import build_sdist, build_wheel +import ppbt.common + CT_NG_VER = "1.26.0" CT_URL = "http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-{version}.tar.bz2" CT_GIT_REPO = "https://github.com/crosstool-ng/crosstool-ng.git" @@ -35,69 +36,10 @@ _build_sdist = build_sdist -class BuildError(RuntimeError): +class BuildError(ppbt.common.PPBTException, RuntimeError): """Generic build error.""" -def build_arch(): - """ - Return the current machine. - """ - machine = platform.machine() - return machine.lower() - - -def get_triplet(machine=None, plat=None): - """ - Get the target triplet for the specified machine and platform. - - If any of the args are None, it will try to deduce what they should be. - - :param machine: The machine for the triplet - :type machine: str - :param plat: The platform for the triplet - :type plat: str - - :raises BuildError: If the platform is unknown - - :return: The target triplet - :rtype: str - """ - if not plat: - plat = sys.platform - if not machine: - machine = build_arch() - if plat == "darwin": - return f"{machine}-macos" - elif plat == "win32": - return f"{machine}-win" - elif plat == "linux": - return f"{machine}-linux-gnu" - else: - raise BuildError(f"Unknown platform {plat}") - - -def extract_archive(to_dir, archive): - """ - Extract an archive to a specific location. - - :param to_dir: The directory to extract to - :type to_dir: str - :param archive: The archive to extract - :type archive: str - """ - if archive.endswith("tgz"): - read_type = "r:gz" - elif archive.endswith("xz"): - read_type = "r:xz" - elif archive.endswith("bz2"): - read_type = "r:bz2" - else: - read_type = "r" - with tarfile.open(archive, read_type) as t: - t.extractall(to_dir) - - def get_download_location(url, dest): """ Get the full path to where the url will be downloaded to. @@ -224,7 +166,7 @@ def build_ppbt(branch=None, use_tempdir=True): if not ctngdir.exists(): url = CT_URL.format(version=CT_NG_VER) archive = download_url(url, build) - extract_archive(build, archive) + ppbt.common.extract_archive(build, archive) os.chdir(ctngdir) ctng = ctngdir / "ct-ng" @@ -237,7 +179,7 @@ def build_ppbt(branch=None, use_tempdir=True): runcmd(["make"]) print(f"Using compiled ct-ng: {ctng}") - arch = build_arch() + arch = ppbt.common.build_arch() machine = platform.machine() toolchain = cwd / "src" / "ppbt" / "_toolchain" @@ -245,7 +187,7 @@ def build_ppbt(branch=None, use_tempdir=True): toolchain.mkdir(exist_ok=True) - triplet = get_triplet(arch) + triplet = ppbt.common.get_triplet(arch) archdir = build / triplet print(f"Arch dir is {archdir}") if archdir.exists(): @@ -296,7 +238,7 @@ def build_ppbt(branch=None, use_tempdir=True): else: print(f"Fetchin patchelf source: {PATCHELF_SOURCE}") archive = download_url(PATCHELF_SOURCE, build) - extract_archive(build, archive) + ppbt.common.extract_archive(build, archive) os.chdir(source) if patchelf.exists(): diff --git a/src/ppbt/common.py b/src/ppbt/common.py index b377ef2..661d5d4 100644 --- a/src/ppbt/common.py +++ b/src/ppbt/common.py @@ -8,42 +8,109 @@ import csv import logging import pathlib +import platform +import sys +import tarfile -from .build import build_arch, extract_archive, get_triplet +__version__ = "0.1.8" + +log = logging.getLogger(__name__) -__version__ = "0.1.7" -triplet = get_triplet(build_arch()) +class PPBTException(Exception): + """ + Base class for all ppbt exceptions. -archive = pathlib.Path(__file__).parent / "_toolchain" / f"{triplet}.tar.xz" -toolchain = pathlib.Path(__file__).parent / "_toolchain" / triplet -toolchain_root = pathlib.Path(__file__).parent / "_toolchain" + """ + + +def get_triplet(machine=None, plat=None): + """ + Get the target triplet for the specified machine and platform. + + If any of the args are None, it will try to deduce what they should be. + + :param machine: The machine for the triplet + :type machine: str + :param plat: The platform for the triplet + :type plat: str + + :raises BuildError: If the platform is unknown + + :return: The target triplet + :rtype: str + """ + if not plat: + plat = sys.platform + if not machine: + machine = build_arch() + if plat == "darwin": + return f"{machine}-macos" + elif plat == "win32": + return f"{machine}-win" + elif plat == "linux": + return f"{machine}-linux-gnu" + else: + raise PPBTException(f"Unknown platform {plat}") + + +def build_arch(): + """ + Return the current machine. + """ + machine = platform.machine() + return machine.lower() + + +TRIPLET = get_triplet(build_arch()) +ARCHIVE = pathlib.Path(__file__).parent / "_toolchain" / f"{TRIPLET}.tar.xz" +TOOLCHAIN_ROOT = pathlib.Path(__file__).parent / "_toolchain" +TOOLCHAIN = TOOLCHAIN_ROOT / TRIPLET # This is not reliable, the version can be modified by setuptools at build time. -distinfo = ( +DISTINFO = ( pathlib.Path(__file__).resolve().parent.parent / f"ppbt-{__version__}.dist-info" ) -log = logging.getLogger(__name__) + +def extract_archive(to_dir, archive): + """ + Extract an archive to a specific location. + + :param to_dir: The directory to extract to + :type to_dir: str + :param archive: The archive to extract + :type archive: str + """ + if archive.endswith("tgz"): + read_type = "r:gz" + elif archive.endswith("xz"): + read_type = "r:xz" + elif archive.endswith("bz2"): + read_type = "r:bz2" + else: + read_type = "r" + with tarfile.open(archive, read_type) as t: + t.extractall(to_dir) def extract(overwrite=False): """ Extract the toolchain tarball. """ - if toolchain.exists() and not overwrite: + if TOOLCHAIN.exists() and not overwrite: log.debug("Toolchain directory exists") else: log.info("Extract archive") - extract_archive(toolchain_root, str(archive)) - record = distinfo / "RECORD" + extract_archive(TOOLCHAIN_ROOT, str(ARCHIVE)) + record = DISTINFO / "RECORD" if record.exists(): records = [] log.info("Update pkg metadata") with open(record, "r") as fp: for row in csv.reader(fp): records.append(row) - with open(str(archive) + ".record", "r") as fp: + with open(str(ARCHIVE) + ".record", "r") as fp: for row in csv.reader(fp): records.append(row) records = sorted(records, key=lambda _: _[0]) @@ -57,18 +124,18 @@ def environ(auto_extract=False): """ Toolchain build environment. """ - if not toolchain.exists(): + if not TOOLCHAIN.exists(): if auto_extract: extract() else: raise RuntimeError("Toolchain not extracted") - basebin = toolchain / "bin" / triplet + basebin = TOOLCHAIN / "bin" / TRIPLET return { - "TOOLCHAIN_PATH": f"{toolchain}", + "TOOLCHAIN_PATH": f"{TOOLCHAIN}", "CC": f"{basebin}-gcc", "CXX": f"{basebin}-g++", - "CFLAGS": f"-I{toolchain}/{triplet}/sysroot/usr/include", - "CPPFLAGS": f"-I{toolchain}/{triplet}/sysroot/usr/include", - "CMAKE_FLAGS": f"-I{toolchain}/{triplet}/sysroot/usr/include", - "LDFLAGS": f"-L{toolchain}/{triplet}/sysroot/lib", + "CFLAGS": f"-I{TOOLCHAIN}/{TRIPLET}/sysroot/usr/include", + "CPPFLAGS": f"-I{TOOLCHAIN}/{TRIPLET}/sysroot/usr/include", + "CMAKE_FLAGS": f"-I{TOOLCHAIN}/{TRIPLET}/sysroot/usr/include", + "LDFLAGS": f"-L{TOOLCHAIN}/{TRIPLET}/sysroot/lib", }