Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor common module to avoid setuptools import #7

Merged
merged 2 commits into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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",
}
Loading