From c323f21ca56f18fac9b3617f8b4b52b9af27604b Mon Sep 17 00:00:00 2001 From: Oliver Smith Date: Sat, 19 Aug 2017 12:52:11 +0000 Subject: [PATCH] (binary repo reated) Don't specify pkgnames from "provides" as dependencies (#416) * Don't specify pkgnames from "provides" as dependencies Always use the regular pkgname. That way, we avoid listing all kinds of so: files as dependencies (because Alpine automatically adds them as depends= to the package database). This fixes building weston, and reproducing the build with `pmbootstrap challenge`. Additional changes. * Clear the parsed APKINDEX cache for the current pmbootstrap session after building a package * Avoid rebuilding a package, in case it was already built due to circular dependencies --- pmb/build/other.py | 6 +++++ pmb/build/package.py | 8 ++++++ pmb/parse/apkindex.py | 9 +++++++ pmb/parse/depends.py | 59 +++++++++++++++++++++++++------------------ 4 files changed, 57 insertions(+), 25 deletions(-) diff --git a/pmb/build/other.py b/pmb/build/other.py index b482aa7b..46bea04c 100644 --- a/pmb/build/other.py +++ b/pmb/build/other.py @@ -232,6 +232,10 @@ def is_necessary(args, arch, apkbuild, apkindex_path=None): def index_repo(args, arch=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). + :param arch: when not defined, re-index all repos """ pmb.build.init(args) @@ -253,6 +257,8 @@ def index_repo(args, arch=None): ] for command in commands: pmb.chroot.user(args, command, working_dir=path_repo_chroot) + pmb.parse.apkindex.clear_cache(args, args.work + path + + "/APKINDEX.tar.gz") def symlink_noarch_package(args, arch_apk): diff --git a/pmb/build/package.py b/pmb/build/package.py index 2220992f..9c9477b8 100644 --- a/pmb/build/package.py +++ b/pmb/build/package.py @@ -69,6 +69,10 @@ def package(args, pkgname, carch, force=False, buildinfo=False): build=False) pmb.chroot.distccd.start(args, carch_buildenv) + # Avoid re-building for circular dependencies + if not force and not pmb.build.is_necessary(args, carch, apkbuild): + return + # Configure abuild.conf pmb.build.other.configure_abuild(args, suffix) @@ -116,4 +120,8 @@ def package(args, pkgname, carch, force=False, buildinfo=False): if "noarch" in apkbuild["arch"]: pmb.build.symlink_noarch_package(args, output) + # Clear APKINDEX cache + pmb.parse.apkindex.clear_cache(args, args.work + "/packages/" + + carch_buildenv + "/APKINDEX.tar.gz") + return output diff --git a/pmb/parse/apkindex.py b/pmb/parse/apkindex.py index 92eb9762..a9691be4 100644 --- a/pmb/parse/apkindex.py +++ b/pmb/parse/apkindex.py @@ -198,6 +198,15 @@ def parse(args, path, strict=False): return ret +def clear_cache(args, path): + logging.verbose("Clear APKINDEX cache for: " + path) + if path in args.cache["apkindex"]: + del args.cache["apkindex"][path] + else: + logging.verbose("Nothing to do, path was not in cache:" + + str(args.cache["apkindex"].keys())) + + def read(args, package, path, must_exist=True): """ Get information about a single package from an APKINDEX.tar.gz file. diff --git a/pmb/parse/depends.py b/pmb/parse/depends.py index 6bc921a8..87124e00 100644 --- a/pmb/parse/depends.py +++ b/pmb/parse/depends.py @@ -22,17 +22,6 @@ import pmb.chroot.apk import pmb.parse.apkindex -def apkindex(args, pkgname, arch): - """ - Non-recursively get the dependencies of one package in any APKINDEX. - """ - index_data = pmb.parse.apkindex.read_any_index(args, pkgname, arch) - if index_data: - return index_data["depends"] - else: - return None - - def recurse_error_message(pkgname, in_aports, in_apkindexes): ret = "Could not find package '" + pkgname + "'" if in_aports: @@ -59,40 +48,60 @@ def recurse(args, pkgnames, arch=None, in_apkindexes=True, in_aports=True, str(in_apkindexes)) # Sanity check - if not apkindex and not in_aports: - raise RuntimeError("Set at least one of apkindex or aports to True.") + if not in_apkindexes and not in_aports: + raise RuntimeError("Set at least one of in_apkindexes or in_aports to" + " True.") + # Iterate over todo-list until is is empty todo = list(pkgnames) ret = [] while len(todo): # Skip already passed entries - pkgname = todo.pop(0) - if pkgname in ret: + pkgname_depend = todo.pop(0) + if pkgname_depend in ret: continue - # Get depends - logging.verbose("Getting depends of single package: " + pkgname) + # Get depends and pkgname from aports + logging.verbose("Get dependencies of: " + pkgname_depend) depends = None if in_aports: - aport = pmb.build.find_aport(args, pkgname, False) + aport = pmb.build.find_aport(args, pkgname_depend, False) if aport: logging.verbose("-> Found aport: " + aport) apkbuild = pmb.parse.apkbuild(args, aport + "/APKBUILD") depends = apkbuild["depends"] + if pkgname_depend in apkbuild["subpackages"]: + pkgname = pkgname_depend + else: + pkgname = apkbuild["pkgname"] + + # Get depends and pkgname from APKINDEX if depends is None and in_apkindexes: logging.verbose("-> Search through APKINDEX files") - depends = apkindex(args, pkgname, arch) - if depends is None and strict: + index_data = pmb.parse.apkindex.read_any_index(args, pkgname_depend, + arch) + if index_data: + depends = index_data["depends"] + pkgname = index_data["pkgname"] + + # Nothing found + if pkgname is None and strict: raise RuntimeError( recurse_error_message( pkgname, in_aports, in_apkindexes)) - # Append to todo/ret - logging.verbose("-> Depends: " + str(depends)) - if depends: - todo += depends - ret.append(pkgname) + # Append to todo/ret (unless it is a duplicate) + if pkgname != pkgname_depend: + logging.verbose("-> '" + pkgname_depend + "' is provided by '" + + pkgname + "'") + if pkgname in ret: + logging.verbose("-> '" + pkgname + "' already found") + else: + logging.verbose("-> '" + pkgname + "' depends on: " + str(depends)) + if depends: + todo += depends + ret.append(pkgname) return ret