From 97527ad5720cd64e1168e88f7d74e21975bfda8d Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sat, 25 Dec 2021 18:26:48 +0300 Subject: Add initial support for dependency alternative reflect clause --- bpkg/pkg-configure.cxx | 115 ++++++++++++--------- bpkg/pkg-configure.hxx | 23 +---- .../dependency-alternatives/t8a/fox-1.0.0.tar.gz | Bin 0 -> 452 bytes tests/pkg-build.testscript | 1 + tests/pkg-configure.testscript | 24 +++++ 5 files changed, 95 insertions(+), 68 deletions(-) create mode 100644 tests/common/dependency-alternatives/t8a/fox-1.0.0.tar.gz diff --git a/bpkg/pkg-configure.cxx b/bpkg/pkg-configure.cxx index ebd6545..136bf50 100644 --- a/bpkg/pkg-configure.cxx +++ b/bpkg/pkg-configure.cxx @@ -18,15 +18,26 @@ using namespace butl; namespace bpkg { - package_prerequisites + // Given dependencies of a package, return its prerequisite packages and + // configuration variables that resulted from selection of these + // prerequisites (import, reflection, etc). Fail if for some of the + // dependency alternative lists there is no satisfactory alternative (all + // its dependencies are configured and satisfy the respective constraints, + // etc). Note that the package argument is used for diagnostics only. + // + // Note: loads selected packages. + // + static pair> pkg_configure_prerequisites (const common_options& o, database& db, transaction&, const dependencies& deps, const package_name& package, + bool simulate, const function& fdb) { - package_prerequisites r; + package_prerequisites pps; + small_vector cvs; for (const dependency_alternatives_ex& das: deps) { @@ -120,7 +131,7 @@ namespace bpkg const package_name& pn (pr.first.object_id ()); const optional& pc (pr.second); - auto p (r.emplace (pr.first, pc)); + auto p (pps.emplace (pr.first, pc)); // Currently we can only capture a single constraint, so if we // already have a dependency on this package and one constraint is @@ -141,8 +152,54 @@ namespace bpkg if (s2 && !s1) c = pc; } + + // If the prerequisite is configured in the linked configuration, + // then add the respective config.import.* variable. + // + if (!simulate) + { + database& pdb (pr.first.database ()); + + if (pdb != db) + { + shared_ptr sp (pr.first.load ()); + + if (!sp->system ()) + { + // @@ Note that this doesn't work for build2 modules that + // require bootstrap. For their dependents we need to + // specify the import variable as a global override, + // whenever required (configure, update, etc). + // + // This, in particular, means that if we build a package + // that doesn't have direct build2 module dependencies but + // some of its (potentially indirect) dependencies do, then + // we still need to specify the !config.import.* global + // overrides for all of the involved build2 + // modules. Implementation of that feels too hairy at the + // moment, so let's handle all the build2 modules uniformly + // for now. + // + // Also note that such modules are marked with `requires: + // bootstrap` in their manifest. + // + dir_path od (sp->effective_out_root (pdb.config)); + cvs.push_back ("config.import." + sp->name.variable () + + "='" + od.representation () + "'"); + } + } + } } + // Add the dependency alternative reflection configuration variable, + // if present. + // + // @@ DEP For now we assume that the reflection, if present, contains + // a single configuration variable that assigns a literal value. + // + if (!simulate && da.reflect) + cvs.push_back (*da.reflect); + satisfied = true; break; } @@ -151,7 +208,7 @@ namespace bpkg fail << "unable to satisfy dependency on " << das; } - return r; + return make_pair (move (pps), move (cvs)); } void @@ -189,53 +246,13 @@ namespace bpkg // assert (p->prerequisites.empty ()); - p->prerequisites = pkg_configure_prerequisites (o, - db, - t, - deps, - p->name, - fdb); + pair> cpr ( + pkg_configure_prerequisites (o, db, t, deps, p->name, simulate, fdb)); + + p->prerequisites = move (cpr.first); if (!simulate) { - // Add the config.import.* variables for prerequisites from the linked - // configurations. - // - strings imports; - - for (const auto& pp: p->prerequisites) - { - database& pdb (pp.first.database ()); - - if (pdb != db) - { - shared_ptr sp (pp.first.load ()); - - if (!sp->system ()) - { - // @@ Note that this doesn't work for build2 modules that require - // bootstrap. For their dependents we need to specify the - // import variable as a global override, whenever required - // (configure, update, etc). - // - // This, in particular, means that if we build a package that - // doesn't have direct build2 module dependencies but some of - // its (potentially indirect) dependencies do, then we still - // need to specify the !config.import.* global overrides for - // all of the involved build2 modules. Implementation of that - // feels too hairy at the moment, so let's handle all the - // build2 modules uniformly for now. - // - // Also note that such modules are marked with `requires: - // bootstrap` in their manifest. - // - dir_path od (sp->effective_out_root (pdb.config)); - imports.push_back ("config.import." + sp->name.variable () + - "='" + od.representation () + "'"); - } - } - } - // Form the buildspec. // string bspec; @@ -255,7 +272,7 @@ namespace bpkg // try { - run_b (o, verb_b::quiet, imports, vars, bspec); + run_b (o, verb_b::quiet, cpr.second, vars, bspec); } catch (const failed&) { diff --git a/bpkg/pkg-configure.hxx b/bpkg/pkg-configure.hxx index 6d3a7c9..f049f81 100644 --- a/bpkg/pkg-configure.hxx +++ b/bpkg/pkg-configure.hxx @@ -21,10 +21,10 @@ namespace bpkg pkg_configure (const pkg_configure_options&, cli::scanner& args); // The custom search function. If specified, it is called by pkg_configure() - // and pkg_configure_prerequisites() to obtain the database to search for - // the prerequisite in, instead of searching for it in the linked databases, - // recursively. If the function returns NULL, then fallback to the recursive - // search through the linked databases. + // to obtain the database to search for the prerequisite in, instead of + // searching for it in the linked databases, recursively. If the function + // returns NULL, then fallback to the recursive search through the linked + // databases. // using find_database_function = database* (database&, const package_name&, @@ -52,21 +52,6 @@ namespace bpkg const version&, database&, transaction&); - - // Return package prerequisites given its dependencies. Fail if some of the - // prerequisites are not configured or don't satisfy the package's - // dependency constraints. Note that the package argument is used for - // diagnostics only. - // - // Note: loads selected packages. - // - package_prerequisites - pkg_configure_prerequisites (const common_options&, - database&, - transaction&, - const dependencies&, - const package_name&, - const function& = {}); } #endif // BPKG_PKG_CONFIGURE_HXX diff --git a/tests/common/dependency-alternatives/t8a/fox-1.0.0.tar.gz b/tests/common/dependency-alternatives/t8a/fox-1.0.0.tar.gz new file mode 100644 index 0000000..baf1068 Binary files /dev/null and b/tests/common/dependency-alternatives/t8a/fox-1.0.0.tar.gz differ diff --git a/tests/pkg-build.testscript b/tests/pkg-build.testscript index 213290d..a67eca3 100644 --- a/tests/pkg-build.testscript +++ b/tests/pkg-build.testscript @@ -138,6 +138,7 @@ # | # |-- t8a # | |-- foo-1.0.0.tar.gz -> {libbar libbaz} ^1.0.0 +# | |-- fox-1.0.0.tar.gz -> libbar ^1.0.0 | libbaz ^1.0.0 # | |-- libbar-1.0.0.tar.gz # | |-- libbaz-1.0.0.tar.gz # | `-- repositories.manifest diff --git a/tests/pkg-configure.testscript b/tests/pkg-configure.testscript index eff0a2e..1c049b6 100644 --- a/tests/pkg-configure.testscript +++ b/tests/pkg-configure.testscript @@ -451,4 +451,28 @@ if ($posix && "$uid" != '0') $pkg_disfigure libbar 2>!; $pkg_purge libbar 2>! } + + : reflect + : + { + $clone_cfg; + + $pkg_fetch fox/1.0.0 && $pkg_unpack fox; + $pkg_fetch libbaz/1.0.0 && $pkg_unpack libbaz; + + $* libbaz 2>!; + + $* fox 2>'configured fox/1.0.0'; + + cat cfg/fox-1.0.0/build/config.build >>~%EOO%; + %.* + config.fox.backend = libbaz + %.* + EOO + + $pkg_disfigure fox 2>!; + $pkg_purge fox 2>!; + $pkg_disfigure libbaz 2>!; + $pkg_purge libbaz 2>! + } } -- cgit v1.1