From 09d32eb787d3f2826b56dbc8c2c00a7d02ab0b5d Mon Sep 17 00:00:00 2001 From: "Daniel A. Wozniak" Date: Fri, 27 Sep 2024 15:49:54 -0700 Subject: [PATCH 1/2] Refactor common module to avoid setuptools import We do not need the setuptools import used while building packages in ppbt.common. Having that import around breaks relenv runtime when trying to setup the toolchain. --- CHANGELOG.md | 5 +++ src/ppbt/build.py | 72 +++---------------------------- src/ppbt/common.py | 105 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 98 insertions(+), 84 deletions(-) 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/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", } From e14190127209d4720fa8a8249b92a6d5c67261b2 Mon Sep 17 00:00:00 2001 From: "Daniel A. Wozniak" Date: Fri, 27 Sep 2024 15:57:21 -0700 Subject: [PATCH 2/2] Use full module name for build backend --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 = [