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.
This commit is contained in:
Oliver Smith 2017-09-08 23:50:59 +00:00 committed by GitHub
parent 9f5607d4c3
commit bed1eacbb5
4 changed files with 34 additions and 10 deletions

View File

@ -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"):

View File

@ -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

View File

@ -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):

View File

@ -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="+")