aboutsummaryrefslogtreecommitdiff
path: root/bpkg/pkg-configure.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/pkg-configure.cxx')
-rw-r--r--bpkg/pkg-configure.cxx134
1 files changed, 93 insertions, 41 deletions
diff --git a/bpkg/pkg-configure.cxx b/bpkg/pkg-configure.cxx
index cd55575..aaf9033 100644
--- a/bpkg/pkg-configure.cxx
+++ b/bpkg/pkg-configure.cxx
@@ -20,14 +20,14 @@ namespace bpkg
{
package_prerequisites
pkg_configure_prerequisites (const common_options& o,
- transaction& t,
+ database& db,
+ transaction&,
const dependencies& deps,
- const package_name& package)
+ const package_name& package,
+ const function<find_database_function>& fdb)
{
package_prerequisites r;
- database& db (t.database ());
-
for (const dependency_alternatives_ex& da: deps)
{
assert (!da.conditional); //@@ TODO
@@ -57,13 +57,16 @@ namespace bpkg
satisfied = true;
break;
}
- // else
- //
- // @@ TODO: in the future we would need to at least make sure the
- // build and target machines are the same. See also pkg-build.
}
- if (shared_ptr<selected_package> dp = db.find<selected_package> (n))
+ database* ddb (fdb ? fdb (db, n, da.buildtime) : nullptr);
+
+ pair<shared_ptr<selected_package>, database*> spd (
+ ddb != nullptr
+ ? make_pair (ddb->find<selected_package> (n), ddb)
+ : find_dependency (db, n, da.buildtime));
+
+ if (const shared_ptr<selected_package>& dp = spd.first)
{
if (dp->state != package_state::configured)
continue;
@@ -71,27 +74,32 @@ namespace bpkg
if (!satisfies (dp->version, d.constraint))
continue;
- auto p (r.emplace (dp, d.constraint));
-
- // Currently we can only capture a single constraint, so if we
- // already have a dependency on this package and one constraint is
- // not a subset of the other, complain.
+ // See the package_prerequisites definition for details on creating
+ // the map keys with the database passed.
//
- if (!p.second)
- {
- auto& c (p.first->second);
-
- bool s1 (satisfies (c, d.constraint));
- bool s2 (satisfies (d.constraint, c));
-
- if (!s1 && !s2)
- fail << "multiple dependencies on package " << n <<
- info << n << " " << *c <<
- info << n << " " << *d.constraint;
-
- if (s2 && !s1)
- c = d.constraint;
- }
+ auto p (
+ r.emplace (lazy_shared_ptr<selected_package> (*spd.second, dp),
+ d.constraint));
+
+ // Currently we can only capture a single constraint, so if we
+ // already have a dependency on this package and one constraint is
+ // not a subset of the other, complain.
+ //
+ if (!p.second)
+ {
+ auto& c (p.first->second);
+
+ bool s1 (satisfies (c, d.constraint));
+ bool s2 (satisfies (d.constraint, c));
+
+ if (!s1 && !s2)
+ fail << "multiple dependencies on package " << n <<
+ info << n << " " << *c <<
+ info << n << " " << *d.constraint;
+
+ if (s2 && !s1)
+ c = d.constraint;
+ }
satisfied = true;
break;
@@ -106,22 +114,23 @@ namespace bpkg
}
void
- pkg_configure (const dir_path& c,
- const common_options& o,
+ pkg_configure (const common_options& o,
+ database& db,
transaction& t,
const shared_ptr<selected_package>& p,
const dependencies& deps,
const strings& vars,
- bool simulate)
+ bool simulate,
+ const function<find_database_function>& fdb)
{
tracer trace ("pkg_configure");
assert (p->state == package_state::unpacked);
assert (p->src_root); // Must be set since unpacked.
- database& db (t.database ());
tracer_guard tg (db, trace);
+ const dir_path& c (db.config_orig);
dir_path src_root (p->effective_src_root (c));
// Calculate package's out_root.
@@ -139,10 +148,53 @@ namespace bpkg
//
assert (p->prerequisites.empty ());
- p->prerequisites = pkg_configure_prerequisites (o, t, deps, p->name);
+ p->prerequisites = pkg_configure_prerequisites (o,
+ db,
+ t,
+ deps,
+ p->name,
+ fdb);
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<selected_package> 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;
@@ -162,7 +214,7 @@ namespace bpkg
//
try
{
- run_b (o, verb_b::quiet, vars, bspec);
+ run_b (o, verb_b::quiet, imports, vars, bspec);
}
catch (const failed&)
{
@@ -180,7 +232,7 @@ namespace bpkg
// Commits the transaction.
//
- pkg_disfigure (c, o, t, p, true /* clean */, false /* simulate */);
+ pkg_disfigure (o, db, t, p, true /* clean */, false /* simulate */);
throw;
}
}
@@ -195,11 +247,11 @@ namespace bpkg
shared_ptr<selected_package>
pkg_configure_system (const package_name& n,
const version& v,
+ database& db,
transaction& t)
{
tracer trace ("pkg_configure_system");
- database& db (t.database ());
tracer_guard tg (db, trace);
shared_ptr<selected_package> p (
@@ -269,7 +321,7 @@ namespace bpkg
if (ps == package_scheme::sys && !vars.empty ())
fail << "configuration variables specified for a system package";
- database db (open (c, trace));
+ database db (c, trace, true /* pre_attach */);
transaction t (db);
session s;
@@ -297,7 +349,7 @@ namespace bpkg
if (filter_one (root, db.query<available_package> (q)).first == nullptr)
fail << "unknown package " << n;
- p = pkg_configure_system (n, v.empty () ? wildcard_version : v, t);
+ p = pkg_configure_system (n, v.empty () ? wildcard_version : v, db, t);
}
else
{
@@ -319,8 +371,8 @@ namespace bpkg
true /* ignore_unknown */,
[&p] (version& v) {v = p->version;}));
- pkg_configure (c,
- o,
+ pkg_configure (o,
+ db,
t,
p,
convert (move (m.dependencies)),