pmb.build package

Submodules

pmb.build.autodetect module

pmb.build.autodetect.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”)

pmb.build.autodetect.chroot(apkbuild: dict[str, Any], arch: Arch) Chroot
pmb.build.autodetect.crosscompile(apkbuild: dict[str, Any], arch: Arch) Literal['native', 'crossdirect'] | None

Decide the type of compilation necessary to build a given APKBUILD.

pmb.build.backend module

class pmb.build.backend.BootstrapStage(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: IntEnum

Pass a BOOTSTRAP= environment variable with the given value to abuild. See bootstrap_1 etc. at https://postmarketos.org/pmaports.cfg for details.

NONE = 0
pmb.build.backend.handle_csum_failure(apkbuild: dict[str, Any], chroot: Chroot) None

Make /home/pmos/build/.git point to the .git dir from pmaports.git, with a symlink so abuild does not fail (#1841).

abuild expects the current working directory to be a subdirectory of a cloned git repository (e.g. main/openrc from aports.git). If git is installed, it will try to get the last git commit from that repository, and place it in the resulting apk (.PKGINFO) as well as use the date from that commit as SOURCE_DATE_EPOCH (for reproducible builds).

With that symlink, we actually make it use the last git commit from pmaports.git for SOURCE_DATE_EPOCH and have that in the resulting apk’s .PKGINFO.

pmb.build.backend.mount_pmaports(chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>) dict[str, Path]

Mount pmaports.git in chroot.

Parameters:

chroot – chroot to target

Returns:

dictionary mapping pkgrepo name to dest path

pmb.build.backend.override_source(apkbuild: dict[str, ~typing.Any], pkgver: str, src: str | None, chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>) None

Mount local source inside chroot and append new functions (prepare() etc.) to the APKBUILD to make it use the local source.

pmb.build.backend.run_abuild(context: ~pmb.core.context.Context, apkbuild: dict[str, ~typing.Any], pkgver: str, channel: str, arch: ~pmb.core.arch.Arch, strict: bool = False, force: bool = False, cross: ~typing.Literal['native', 'crossdirect'] | None = None, suffix: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>, src: str | None = None, bootstrap_stage: int = BootstrapStage.NONE) None

Set up all environment variables and construct the abuild command (all depending on the cross-compiler method and target architecture), copy the aport to the chroot and execute abuild.

Parameters:
  • cross – None, “native”, or “crossdirect”

  • src – override source used to build the package with a local folder

  • bootstrap_stage – pass a BOOTSTRAP= env var with the value to abuild

Returns:

(output, cmd, env), output is the destination apk path relative to the package folder (“x86_64/hello-1-r2.apk”). cmd and env are used by the test case, and they are the full abuild command and the environment variables dict generated in this function.

pmb.build.checksum module

pmb.build.checksum.update(pkgname)

Fetch all sources and update the checksums in the APKBUILD.

pmb.build.checksum.verify(pkgname)

Fetch all sources and verify their checksums.

pmb.build.envkernel module

pmb.build.envkernel.find_kbuild_output_dir(function_body)

Guess what the kernel build output directory is.

Parses each line of the function word by word, looking for paths which contain the kbuild output directory.

Parameters:

function_body – contents of a function from the kernel APKBUILD

Returns:

kbuild output dir None, when output dir is not found

pmb.build.envkernel.match_kbuild_out(word)
Look for paths in the following formats:

“<prefix>/<kbuild_out>/arch/<arch>/boot” “<prefix>/<kbuild_out>/include/config/kernel.release”

Parameters:

word – space separated string cut out from a line from an APKBUILD function body that might be the kbuild output path

Returns:

kernel build output directory. empty string when a separate build output directory isn’t used. None, when no output directory is found.

pmb.build.envkernel.modify_apkbuild(pkgname: str, aport: Path) None

Modify kernel APKBUILD to package build output from envkernel.sh.

pmb.build.envkernel.package_kernel(args: PmbArgs) None

Frontend for ‘pmbootstrap build –envkernel’: creates a package from envkernel output.

pmb.build.envkernel.run_abuild(context: Context, pkgname: str, arch: Arch, apkbuild_path: Path, kbuild_out: str) None

Prepare build environment and run abuild.

Parameters:
  • pkgname – package name of a linux kernel aport

  • arch – architecture for the kernel

  • apkbuild_path – path to APKBUILD of the kernel aport

  • kbuild_out – kernel build system output sub-directory

pmb.build.init module

pmb.build.init.init(chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>) bool

Initialize a chroot for building packages with abuild.

pmb.build.init.init_abuild_minimal(chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>, build_pkgs: list[str] = []) None

Initialize a minimal chroot with abuild where one can do ‘abuild checksum’.

pmb.build.init.init_compiler(context: Context, depends: list[str], cross: Literal['native', 'crossdirect'] | None, arch: Arch) None

pmb.build.kconfig module

class pmb.build.kconfig.KConfigUI(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

MENUCONFIG = 'menuconfig'
NCONFIG = 'nconfig'
XCONFIG = 'xconfig'
depends() list[str]
is_graphical() bool
pmb.build.kconfig.edit_config(pkgname: str, arch: Arch | None, config_ui: KConfigUI) None
pmb.build.kconfig.extract_and_patch_sources(pkgname: str, arch: Arch) None
pmb.build.kconfig.get_arch(apkbuild: dict[str, Any]) Arch

Take the architecture from the APKBUILD or complain if it’s ambiguous.

This function only gets called if –arch is not set.

Parameters:

apkbuild – looks like: {“pkgname”: “linux-…”, “arch”: [“x86_64”, “armhf”, “aarch64”]}

or: {“pkgname”: “linux-…”, “arch”: [“armhf”]}

pmb.build.kconfig.get_outputdir(pkgname: str, apkbuild: dict[str, Any]) Path

Get the folder for the kernel compilation output.

For most APKBUILDs, this is $builddir. But some older ones still use $srcdir/build (see the discussion in #1551).

pmb.build.kconfig.migrate_config(pkgname: str, arch: Arch | None) None

pmb.build.newapkbuild module

pmb.build.newapkbuild.newapkbuild(folder, args_passed, force=False)

pmb.build.other module

class pmb.build.other.BuildStatus(value, names=<not given>, *values, module=None, qualname=None, type=None, start=1, boundary=None)

Bases: Enum

CANT_BUILD = 'cant_build'
NEW = 'new'
OUTDATED = 'outdated'
UNNECESSARY = 'unnecessary'
necessary() bool
pmb.build.other.abuild_overrides(apkbuild: Path) None

Override some abuild functions by patching the APKBUILD file.

pmb.build.other.configure_abuild(chroot: Chroot, verify: bool = False) None

Set the correct JOBS count in abuild.conf.

Parameters:

verify – internally used to test if changing the config has worked.

pmb.build.other.configure_ccache(chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>, verify: bool = False) None

Set the maximum ccache size.

Parameters:

verify – internally used to test if changing the config has worked.

pmb.build.other.copy_to_buildpath(package: str, chroot: ~pmb.core.chroot.Chroot = <pmb.core.chroot.Chroot object>, no_override: bool = False) None
pmb.build.other.get_status(arch: Arch | None, apkbuild: dict[str, Any]) BuildStatus

Check if the package has already been built.

Compared to abuild’s check, this check also works for different architectures.

Parameters:
  • arch – package target architecture

  • apkbuild – from pmb.parse.apkbuild()

  • indexes – list of APKINDEX.tar.gz paths

Returns:

boolean

pmb.build.other.index_repo(arch: Arch | None = None) None

Recreate the APKINDEX.tar.gz for a specific repo, and clear the parsing cache for that file for the current pmbootstrap session (to prevent rebuilding packages twice, in case the rebuild takes less than a second).

Parameters:

arch – when not defined, re-index all repos

pmb.build._package module

class pmb.build._package.BuildQueueItem

Bases: TypedDict

apkbuild: dict[str, Any]
aports: str
arch: Arch
channel: str
chroot: Chroot
cross: Literal['native', 'crossdirect'] | None
depends: list[str]
has_binary: bool
name: str
output_path: Path
pkgver: str
pmb.build._package.check_build_for_arch(pkgname: str, arch: Arch) bool

Check if pmaport can be built or exists as binary for a specific arch.

Returns:

  • True when it can be built

  • False when it can’t be built, but exists in a binary repo (e.g. temp/mesa can’t be built for x86_64, but Alpine has it)

Raises:

RuntimeError if the package can’t be built for the given arch and does not exist as binary package.

pmb.build._package.finish(apkbuild: dict[str, Any], channel: str, arch: Arch, output: Path, chroot: Chroot, strict: bool = False) None

Various finishing tasks that need to be done after a build.

pmb.build._package.get_apkbuild(pkgname)

Parse the APKBUILD path for pkgname.

When there is none, try to find it in the binary package APKINDEX files or raise an exception.

Parameters:

pkgname – package name to be built, as specified in the APKBUILD

Returns:

None or parsed APKBUILD

pmb.build._package.get_depends(context: Context, apkbuild: dict[str, Any]) list[str]

Alpine’s abuild always builds/installs the “depends” and “makedepends” of a package before building it.

We used to only care about “makedepends” and it’s still possible to ignore the depends with –ignore-depends.

Returns:

list of dependency pkgnames (eg. [“sdl2”, “sdl2_net”])

pmb.build._package.get_pkgver(original_pkgver: str, original_source: bool = False) str

Get the original pkgver when using the original source.

Otherwise, get the pkgver with an appended suffix of current date and time. For example: _p20180218550502 When appending the suffix, an existing suffix (e.g. _git20171231) gets replaced.

Parameters:
  • original_pkgver – unmodified pkgver from the package’s APKBUILD.

  • original_source – the original source is used instead of overriding it with –src.

pmb.build._package.has_cyclical_dependency(unmet_deps: dict[str, list[str]], item: BuildQueueItem, dep: str) bool
pmb.build._package.is_cached_or_cache(arch: Arch, pkgname: str) bool

Check if a package is in the visited packages cache, if not then mark it as visited. We must mark as visited before building to break cyclical dependency loops.

pmb.build._package.output_path(arch: Arch, pkgname: str, pkgver: str, pkgrel: str) Path
pmb.build._package.packages(context: Context, pkgnames: list[str], arch: Arch | None = None, force: bool = False, strict: bool = False, src: str | None = None, bootstrap_stage: int = BootstrapStage.NONE, log_callback: Callable | None = None) list[str]

Build a package and its dependencies with Alpine Linux’ abuild.

Parameters:
  • pkgname – package name to be built, as specified in the APKBUILD

  • arch – architecture we’re building for (default: native)

  • force – always build, even if not necessary

  • strict – avoid building with irrelevant dependencies installed by letting abuild install and uninstall all dependencies.

  • src – override source used to build the package with a local folder

  • bootstrap_stage – pass a BOOTSTRAP= env var with the value to abuild

  • log_callback – function to call before building each package instead of logging. It should accept a single BuildQueueItem parameter.

Returns:

None if the build was not necessary output path relative to the packages folder (“armhf/ab-1-r2.apk”)

pmb.build._package.prioritise_build_queue(disarray: list[BuildQueueItem]) list[BuildQueueItem]

Figure out The Correct Order to build packages in, or bail.

pmb.build._package.process_package(context: Context, queue_build: Callable, pkgname: str, arch: Arch | None, fallback_arch: Arch, force: bool, from_src: bool) list[str]
Parameters:

arch – Set if we should build for a specific arch.

Module contents