From aac298fcef914b99cf28d9cf1f4f58cc6714fb92 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 9 Aug 2021 21:46:16 +0300 Subject: Don't create private configurations in private configurations --- bpkg/database.cxx | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++- bpkg/database.hxx | 36 +++++++++++++++++++++++++++ bpkg/pkg-build.cxx | 36 +++++++++++++-------------- 3 files changed, 124 insertions(+), 20 deletions(-) (limited to 'bpkg') 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 `[]` 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 (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 lc (cfg_link (*ddb, - ddb->config / cd, + shared_ptr 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. -- cgit v1.1