Skip to content

Commit

Permalink
Merge pull request #7 from dwoz/relenvimport
Browse files Browse the repository at this point in the history
Refactor common module to avoid setuptools import
  • Loading branch information
dwoz authored Sep 28, 2024
2 parents ed11d22 + e141901 commit d776a97
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 86 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down
72 changes: 7 additions & 65 deletions src/ppbt/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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.
Expand Down Expand Up @@ -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"
Expand All @@ -237,15 +179,15 @@ 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"

print(f"toolchain: {toolchain}")

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():
Expand Down Expand Up @@ -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():
Expand Down
105 changes: 86 additions & 19 deletions src/ppbt/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand All @@ -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",
}

0 comments on commit d776a97

Please sign in to comment.