From bed1eacbb5b0a668032fc13d32698d93bc5e8b84 Mon Sep 17 00:00:00 2001 From: Oliver Smith Date: Fri, 8 Sep 2017 23:50:59 +0000 Subject: [PATCH] Close #256: Implement strict package building mode (#532) Contrary to abuild, pmbootstrap only installs makedepends, and keeps the installed packages around - both hacks save lots of time. However, they may introduce missing makedepends in the APKBUILDs, that the authors of the APKBUILDs do not notice because it works for them. This PR adss a strict mode, which will always clean the chroots before building a package, and also remove all installed dependencies after the package was built. You can use the following syntax to only zap once, but build many packages at once: `pmbootstrap build --strict hello-world 0xffff heimdall` It also builds dependencies properly without leaving makedepends behind. --- pmb/build/autodetect.py | 8 +++++--- pmb/build/package.py | 23 +++++++++++++++++------ pmb/helpers/frontend.py | 4 +++- pmb/parse/arguments.py | 9 +++++++++ 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/pmb/build/autodetect.py b/pmb/build/autodetect.py index 5b0de9b2..26c7245a 100644 --- a/pmb/build/autodetect.py +++ b/pmb/build/autodetect.py @@ -22,8 +22,12 @@ import pmb.chroot.apk import pmb.parse.arch -def carch(args, apkbuild, carch): +def carch(args, apkbuild, carch, strict=False): if "noarch" in apkbuild["arch"]: + if "noarch_arch" in args and args.noarch_arch: + return args.noarch_arch + if strict: + return args.deviceinfo["arch"] return args.arch_native if carch: if "all" not in apkbuild["arch"] and carch not in apkbuild["arch"]: @@ -41,8 +45,6 @@ def carch(args, apkbuild, carch): def suffix(args, apkbuild, carch): if carch == args.arch_native: return "native" - if "noarch" in apkbuild["arch"]: - return "native" pkgname = apkbuild["pkgname"] if pkgname.endswith("-repack"): diff --git a/pmb/build/package.py b/pmb/build/package.py index 9c9477b8..1ec88053 100644 --- a/pmb/build/package.py +++ b/pmb/build/package.py @@ -29,7 +29,7 @@ import pmb.parse import pmb.parse.arch -def package(args, pkgname, carch, force=False, buildinfo=False): +def package(args, pkgname, carch, force=False, buildinfo=False, strict=False): """ Build a package with Alpine Linux' abuild. @@ -47,7 +47,7 @@ def package(args, pkgname, carch, force=False, buildinfo=False): # Autodetect the build environment apkbuild = pmb.parse.apkbuild(args, aport + "/APKBUILD") pkgname = apkbuild["pkgname"] - carch_buildenv = pmb.build.autodetect.carch(args, apkbuild, carch) + carch_buildenv = pmb.build.autodetect.carch(args, apkbuild, carch, strict) suffix = pmb.build.autodetect.suffix(args, apkbuild, carch_buildenv) cross = pmb.build.autodetect.crosscompile(args, apkbuild, carch_buildenv, suffix) @@ -59,7 +59,11 @@ def package(args, pkgname, carch, force=False, buildinfo=False): # Initialize build environment, install/build makedepends pmb.build.init(args, suffix) if len(apkbuild["makedepends"]): - pmb.chroot.apk.install(args, apkbuild["makedepends"], suffix) + if strict: + for makedepend in apkbuild["makedepends"]: + package(args, makedepend, carch_buildenv, strict=True) + else: + pmb.chroot.apk.install(args, apkbuild["makedepends"], suffix) if cross: pmb.chroot.apk.install(args, ["gcc-" + carch_buildenv, "g++-" + carch_buildenv, @@ -87,7 +91,7 @@ def package(args, pkgname, carch, force=False, buildinfo=False): " cross-compiling in the native chroot. This will probably" " fail!") - # Run abuild with ignored dependencies + # Run abuild pmb.build.copy_to_buildpath(args, pkgname, suffix) cmd = [] env = {"CARCH": carch_buildenv} @@ -100,7 +104,11 @@ def package(args, pkgname, carch, force=False, buildinfo=False): env["DISTCC_HOSTS"] = "127.0.0.1:" + args.port_distccd for key, value in env.items(): cmd += [key + "=" + value] - cmd += ["abuild", "-d"] + cmd += ["abuild"] + if strict: + cmd += ["-r"] # install depends with abuild + else: + cmd += ["-d"] # do not install depends with abuild if force: cmd += ["-f"] pmb.chroot.user(args, cmd, suffix, "/home/user/build") @@ -120,8 +128,11 @@ def package(args, pkgname, carch, force=False, buildinfo=False): if "noarch" in apkbuild["arch"]: pmb.build.symlink_noarch_package(args, output) - # Clear APKINDEX cache + # Clean up (APKINDEX cache, depends when strict) pmb.parse.apkindex.clear_cache(args, args.work + "/packages/" + carch_buildenv + "/APKINDEX.tar.gz") + if strict: + logging.info("(" + suffix + ") uninstall makedepends") + pmb.chroot.user(args, ["abuild", "undeps"], suffix, "/home/user/build") return output diff --git a/pmb/helpers/frontend.py b/pmb/helpers/frontend.py index 62bb80c8..ebd4628a 100644 --- a/pmb/helpers/frontend.py +++ b/pmb/helpers/frontend.py @@ -79,9 +79,11 @@ def aportgen(args): def build(args): + if args.strict: + pmb.chroot.zap(args, False) for package in args.packages: pmb.build.package(args, package, args.arch, args.force, - args.buildinfo) + args.buildinfo, args.strict) def build_init(args): diff --git a/pmb/parse/arguments.py b/pmb/parse/arguments.py index b4a3489c..eb4914f0 100644 --- a/pmb/parse/arguments.py +++ b/pmb/parse/arguments.py @@ -231,6 +231,15 @@ def arguments(): build.add_argument("--arch") build.add_argument("--force", action="store_true") build.add_argument("--buildinfo", action="store_true") + build.add_argument("--strict", action="store_true", help="(slower) zap and install only" + " required depends when building, to detect dependency errors") + build.add_argument("--noarch-arch", dest="noarch_arch", default=None, + help="which architecture to use to build 'noarch'" + " packages. Defaults to the native arch normally," + " and to the device arch when --strict is set." + " Override in case of strict mode failing on" + " dependencies, which only exist for a certain" + " arch.") for action in [checksum, build, aportgen]: action.add_argument("packages", nargs="+")