mirror of
https://gitlab.postmarketos.org/postmarketOS/pmbootstrap.git
synced 2025-07-13 11:29:46 +03:00
Set things up so that we can run abuild on the native chroot and use it's cross compilation features rather than running it and the build system through QEMU. This massively speeds up building when it works. cross-native used to be quite limited in functionality and didn't integrate into abuild itself, this commit fixes that. Packages can opt-in to this by adding pmb:cross-native2 to their options and configuring makedepends_host and makedepends_build. This also speeds up building packages like postmarketos-initramfs since it entirely avoids running commands through QEMU (usually abuild itself would be run through QEMU). Lastly, we preserve the old pmb:cross-kernel options, this can be used to enable the old cross compiler behaviour which is used for cross compiling kernels in pmaports. This allows them to keep being supporting while we adapt them to the new cross-native2. Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
108 lines
3.4 KiB
Python
108 lines
3.4 KiB
Python
# Copyright 2023 Oliver Smith
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
from pathlib import Path
|
|
from pmb.core.arch import Arch
|
|
from pmb.helpers import logging
|
|
|
|
import pmb.config
|
|
import pmb.chroot.apk
|
|
import pmb.helpers.pmaports
|
|
from pmb.core import Chroot
|
|
from pmb.core.context import get_context
|
|
from pmb.meta import Cache
|
|
from pmb.types import Apkbuild, CrossCompileType
|
|
|
|
|
|
def arch_from_deviceinfo(pkgname: str, aport: Path) -> Arch | None:
|
|
"""
|
|
The device- packages are noarch packages. But it only makes sense to build
|
|
them for the device's architecture, which is specified in the deviceinfo
|
|
file.
|
|
|
|
:returns: None (no deviceinfo file)
|
|
arch from the deviceinfo (e.g. "armhf")
|
|
"""
|
|
# Require a deviceinfo file in the aport
|
|
if not pkgname.startswith("device-"):
|
|
return None
|
|
deviceinfo = aport / "deviceinfo"
|
|
if not deviceinfo.exists():
|
|
return None
|
|
|
|
# Return its arch
|
|
device = pkgname.split("-", 1)[1]
|
|
arch = pmb.parse.deviceinfo(device).arch
|
|
logging.verbose(f"{pkgname}: arch from deviceinfo: {arch}")
|
|
return arch
|
|
|
|
|
|
@Cache("package")
|
|
def arch(package: str | Apkbuild) -> Arch:
|
|
"""
|
|
Find a good default in case the user did not specify for which architecture
|
|
a package should be built.
|
|
|
|
:param package: The name of the package or parsed APKBUILD
|
|
|
|
:returns: Arch object. Preferred order, depending
|
|
on what is supported by the APKBUILD:
|
|
* native arch
|
|
* device arch (this will be preferred instead if build_default_device_arch is true)
|
|
* first arch in the APKBUILD
|
|
"""
|
|
pkgname = package["pkgname"] if isinstance(package, dict) else package
|
|
aport = pmb.helpers.pmaports.find(pkgname)
|
|
if not aport:
|
|
raise FileNotFoundError(f"APKBUILD not found for {pkgname}")
|
|
ret = arch_from_deviceinfo(pkgname, aport)
|
|
if ret:
|
|
return ret
|
|
|
|
apkbuild = pmb.parse.apkbuild(aport) if isinstance(package, str) else package
|
|
arches = apkbuild["arch"]
|
|
deviceinfo = pmb.parse.deviceinfo()
|
|
|
|
if get_context().config.build_default_device_arch:
|
|
preferred_arch = deviceinfo.arch
|
|
preferred_arch_2nd = Arch.native()
|
|
else:
|
|
preferred_arch = Arch.native()
|
|
preferred_arch_2nd = deviceinfo.arch
|
|
|
|
if "noarch" in arches or "all" in arches or preferred_arch in arches:
|
|
return preferred_arch
|
|
|
|
if preferred_arch_2nd in arches:
|
|
return preferred_arch_2nd
|
|
|
|
try:
|
|
arch_str = apkbuild["arch"][0]
|
|
return Arch.from_str(arch_str) if arch_str else Arch.native()
|
|
except IndexError:
|
|
return Arch.native()
|
|
|
|
|
|
def chroot(apkbuild: Apkbuild, arch: Arch) -> Chroot:
|
|
if arch == Arch.native():
|
|
return Chroot.native()
|
|
|
|
if "pmb:cross-native" in apkbuild["options"]:
|
|
return Chroot.native()
|
|
|
|
return Chroot.buildroot(arch)
|
|
|
|
|
|
def crosscompile(apkbuild: Apkbuild, arch: Arch) -> CrossCompileType:
|
|
"""Decide the type of compilation necessary to build a given APKBUILD."""
|
|
if not get_context().cross:
|
|
return None
|
|
if not arch.cpu_emulation_required():
|
|
return None
|
|
# deprecated cross-native environment for building kernels
|
|
if "pmb:cross-native" in apkbuild["options"]:
|
|
return "kernel"
|
|
if arch.is_native() or "pmb:cross-native2" in apkbuild["options"]:
|
|
return "native"
|
|
if "!pmb:crossdirect" in apkbuild["options"]:
|
|
return None
|
|
return "crossdirect"
|