aboutsummaryrefslogtreecommitdiff
path: root/bpkg
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg')
-rw-r--r--bpkg/database.cxx72
-rw-r--r--bpkg/database.hxx36
-rw-r--r--bpkg/pkg-build.cxx36
3 files changed, 124 insertions, 20 deletions
diff --git a/bpkg/database.cxx b/bpkg/database.cxx
index 6724582..22cd61a 100644
--- a/bpkg/database.cxx
+++ b/bpkg/database.cxx
@@ -653,10 +653,27 @@ namespace bpkg
const linked_databases& lds (db.implicit_links (true /* attach */,
sys_rep));
+ // New boundary type.
+ //
+ const std::string& nbt (db.type == bt ? bt : empty_string);
+
// Skip the self-link.
//
for (auto i (lds.begin () + 1); i != lds.end (); ++i)
- add (*i, db.type, db.type == bt ? bt : empty_string, add);
+ {
+ database& ldb (*i);
+ add (ldb, db.type, nbt, add);
+
+ // If this configuration is of the build2 type, then also add the
+ // private host configurations of its implicitly linked
+ // configurations.
+ //
+ if (db.type == build2_config_type)
+ {
+ if (database* hdb = ldb.private_config (host_config_type))
+ add (*hdb, db.type, nbt, add);
+ }
+ }
};
add (*this,
@@ -750,6 +767,21 @@ namespace bpkg
//
for (auto i (lcs.begin () + 1); i != lcs.end (); ++i)
add (i->db, db.type, add);
+
+ // If this is a private host configuration, then also add the parent's
+ // explicitly linked configurations of the build2 type.
+ //
+ if (db.private_ () && db.type == host_config_type)
+ {
+ const linked_configs& lcs (db.parent_config ().explicit_links ());
+
+ for (auto i (lcs.begin () + 1); i != lcs.end (); ++i)
+ {
+ database& ldb (i->db);
+ if (ldb.type == build2_config_type)
+ add (ldb, db.type, add);
+ }
+ }
};
add (*this, type, add);
@@ -824,6 +856,44 @@ namespace bpkg
<< config_orig << endf;
}
+ database& database::
+ parent_config (bool sys_rep)
+ {
+ assert (private_ ());
+
+ dir_path pd (config.directory ().directory ()); // Parent configuration.
+ const linked_databases& lds (implicit_links (true /* attach */, sys_rep));
+
+ // Skip the self-link.
+ //
+ for (auto i (lds.begin () + 1); i != lds.end (); ++i)
+ {
+ if (i->get ().config == pd)
+ return *i;
+ }
+
+ // This should not happen normally and is likely to be the result of some
+ // bpkg misuse.
+ //
+ fail << "configuration " << pd << " is not linked to its private "
+ << "configuration " << config << endf;
+ }
+
+ database* database::
+ private_config (const std::string& type)
+ {
+ assert (!explicit_links_.empty ());
+
+ auto r (find_if (explicit_links_.begin () + 1, explicit_links_.end (),
+ [&type] (const linked_config& lc)
+ {
+ database& db (lc.db);
+ return db.private_ () && db.type == type;
+ }));
+
+ return r != explicit_links_.end () ? &r->db.get () : nullptr;
+ }
+
bool database::
main ()
{
diff --git a/bpkg/database.hxx b/bpkg/database.hxx
index bf52ecb..32169bb 100644
--- a/bpkg/database.hxx
+++ b/bpkg/database.hxx
@@ -198,6 +198,13 @@ namespace bpkg
// So for the above link chain only cfg2 configuration is included for a
// build-time dependency foo and none for libbuild2-foo.
//
+ // - While traversing through a private configuration of the host type
+ // consider the parent's explicitly linked configurations of the build2
+ // type as also being explicitly linked to this private
+ // configuration. Note that build system module dependencies of packages
+ // in private host configurations are resolved from the parent's
+ // explicitly linked configurations of the build2 type.
+ //
linked_databases
dependency_configs ();
@@ -215,6 +222,13 @@ namespace bpkg
// configurations for dependents of a build-time dependency in host
// configuration).
//
+ // While traversing through a configuration of the build2 type consider
+ // private host configurations of its implicitly linked configurations as
+ // also being implicitly linked to this build2 configuration. Note that
+ // build system module dependencies of packages in private host
+ // configurations are resolved from the parent's explicitly linked
+ // configurations of the build2 type.
+ //
linked_databases
dependent_configs (bool sys_rep = false);
@@ -243,6 +257,28 @@ namespace bpkg
database&
find_dependency_config (const uuid_type&);
+ // Return true if this configuration is private (i.e. its parent directory
+ // name is `.bpkg`).
+ //
+ bool
+ private_ ()
+ {
+ return config.directory ().leaf () == bpkg_dir;
+ }
+
+ // Return the implicitly linked configuration containing this
+ // configuration and issue diagnostics and fail if not found. Assume that
+ // this configuration is private.
+ //
+ database&
+ parent_config (bool sys_rep = false);
+
+ // Return a private configuration of the specified type, if present, and
+ // NULL otherwise.
+ //
+ database*
+ private_config (const string& type);
+
// Return an empty string for the main database and the original
// configuration directory path in the `[<dir>]` form otherwise.
//
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index 3ce9f43..e20909b 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -1154,33 +1154,31 @@ namespace bpkg
// only one of them has the suitable type, then we use that. If there
// are multiple of them, then we fail advising the user to pick one
// explicitly. If there are none, then we create the private
- // configuration and use that.
+ // configuration and use that. If the current configuration is
+ // private, then search/create in the parent configuration instead.
//
// Note that if the user has explicitly specified the configuration
// for this dependency on the command line (using --config-*), then
// this configuration is used as the starting point for this search.
//
- if (da.buildtime && dsp == nullptr)
+ if (da.buildtime &&
+ dsp == nullptr &&
+ ddb->type != buildtime_dependency_type (dn))
{
- database* db (nullptr);
+ database* db (nullptr);
+ database& sdb (ddb->private_ () ? ddb->parent_config () : *ddb);
+
const string& type (buildtime_dependency_type (dn));
- // Note that the first returned link is for ddb itself.
+ // Skip the self-link.
//
- for (const linked_config& lc: ddb->explicit_links ())
+ const linked_configs& lcs (sdb.explicit_links ());
+ for (auto i (lcs.begin () + 1); i != lcs.end (); ++i)
{
- database& ldb (lc.db);
+ database& ldb (i->db);
if (ldb.type == type)
{
- // We are done if the self-link is of the suitable type.
- //
- if (lc.id == 0)
- {
- db = &ldb;
- break;
- }
-
if (db == nullptr)
db = &ldb;
else
@@ -1250,7 +1248,7 @@ namespace bpkg
// outdated database schema version, etc.
//
cfg_create (options,
- ddb->config_orig / cd,
+ sdb.config_orig / cd,
optional<string> (type) /* name */,
type /* type */,
mods,
@@ -1261,8 +1259,8 @@ namespace bpkg
// Note that we will copy the name from the configuration unless
// it clashes with one of the existing links.
//
- shared_ptr<configuration> lc (cfg_link (*ddb,
- ddb->config / cd,
+ shared_ptr<configuration> lc (cfg_link (sdb,
+ sdb.config / cd,
true /* relative */,
nullopt /* name */,
true /* sys_rep */));
@@ -1271,9 +1269,9 @@ namespace bpkg
// containing configuration database, for their subsequent re-
// link.
//
- priv_cfgs.emplace_back (*ddb, move (cd));
+ priv_cfgs.emplace_back (sdb, move (cd));
- db = &ddb->find_attached (*lc->id);
+ db = &sdb.find_attached (*lc->id);
}
ddb = db; // Switch to the dependency configuration.