aboutsummaryrefslogtreecommitdiff
path: root/bpkg/package-skeleton.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/package-skeleton.cxx')
-rw-r--r--bpkg/package-skeleton.cxx455
1 files changed, 321 insertions, 134 deletions
diff --git a/bpkg/package-skeleton.cxx b/bpkg/package-skeleton.cxx
index fee4bbc..78635e7 100644
--- a/bpkg/package-skeleton.cxx
+++ b/bpkg/package-skeleton.cxx
@@ -16,12 +16,14 @@
#include <libbuild2/context.hxx>
#include <libbuild2/variable.hxx>
#include <libbuild2/operation.hxx>
+#include <libbuild2/diagnostics.hxx>
#include <libbuild2/lexer.hxx>
#include <libbuild2/parser.hxx>
#include <libbuild2/config/utility.hxx>
+#include <bpkg/bpkg.hxx>
#include <bpkg/package.hxx>
#include <bpkg/database.hxx>
#include <bpkg/manifest-utility.hxx>
@@ -31,19 +33,6 @@ using namespace butl;
namespace bpkg
{
- // These are defined in bpkg.cxx and initialized in main().
- //
- extern strings build2_cmd_vars;
- extern build2::scheduler build2_sched;
- extern build2::global_mutexes build2_mutexes;
- extern build2::file_cache build2_fcache;
-
- void
- build2_init (const common_options&);
-}
-
-namespace bpkg
-{
// Check whether the specified configuration variable override has a project
// variable (i.e., its name starts with config.<project>). If the last
// argument is not NULL, then set it to the length of the variable portion.
@@ -152,7 +141,7 @@ namespace bpkg
// (build2 stuff is only forward-declared in the header).
//
static build2::scope_map::iterator
- bootstrap (package_skeleton&, const strings&);
+ bootstrap (package_skeleton&, const strings&, bool old = false);
package_skeleton::
~package_skeleton ()
@@ -160,18 +149,23 @@ namespace bpkg
}
package_skeleton::
- package_skeleton (package_skeleton&& v)
+ package_skeleton (package_skeleton&& v) noexcept
: package (move (v.package)),
system (v.system),
available (move (v.available)),
+ load_config_flags (v.load_config_flags),
co_ (v.co_),
db_ (v.db_),
var_prefix_ (move (v.var_prefix_)),
config_vars_ (move (v.config_vars_)),
+ config_var_srcs_ (move (v.config_var_srcs_)),
disfigure_ (v.disfigure_),
config_srcs_ (v.config_srcs_),
src_root_ (move (v.src_root_)),
out_root_ (move (v.out_root_)),
+ src_root_specified_ (v.src_root_specified_),
+ old_src_root_ (move (v.old_src_root_)),
+ old_out_root_ (move (v.old_out_root_)),
created_ (v.created_),
verified_ (v.verified_),
loaded_old_config_ (v.loaded_old_config_),
@@ -194,21 +188,26 @@ namespace bpkg
}
package_skeleton& package_skeleton::
- operator= (package_skeleton&& v)
+ operator= (package_skeleton&& v) noexcept
{
if (this != &v)
{
package = move (v.package);
system = v.system;
available = move (v.available);
+ load_config_flags = v.load_config_flags;
co_ = v.co_;
db_ = v.db_;
var_prefix_ = move (v.var_prefix_);
config_vars_ = move (v.config_vars_);
+ config_var_srcs_ = move (v.config_var_srcs_);
disfigure_ = v.disfigure_;
config_srcs_ = v.config_srcs_;
src_root_ = move (v.src_root_);
out_root_ = move (v.out_root_);
+ src_root_specified_ = v.src_root_specified_;
+ old_src_root_ = move (v.old_src_root_);
+ old_out_root_ = move (v.old_out_root_);
created_ = v.created_;
verified_ = v.verified_;
loaded_old_config_ = v.loaded_old_config_;
@@ -238,14 +237,19 @@ namespace bpkg
: package (v.package),
system (v.system),
available (v.available),
+ load_config_flags (v.load_config_flags),
co_ (v.co_),
db_ (v.db_),
var_prefix_ (v.var_prefix_),
config_vars_ (v.config_vars_),
+ config_var_srcs_ (v.config_var_srcs_),
disfigure_ (v.disfigure_),
config_srcs_ (v.config_srcs_),
src_root_ (v.src_root_),
out_root_ (v.out_root_),
+ src_root_specified_ (v.src_root_specified_),
+ old_src_root_ (v.old_src_root_),
+ old_out_root_ (v.old_out_root_),
created_ (v.created_),
verified_ (v.verified_),
loaded_old_config_ (v.loaded_old_config_),
@@ -307,10 +311,14 @@ namespace bpkg
bool df,
const vector<config_variable>* css,
optional<dir_path> src_root,
- optional<dir_path> out_root)
+ optional<dir_path> out_root,
+ optional<dir_path> old_src_root,
+ optional<dir_path> old_out_root,
+ uint16_t lcf)
: package (move (pk)),
system (sys),
available (move (ap)),
+ load_config_flags (lcf),
co_ (&co),
db_ (&package.db.get ()),
var_prefix_ ("config." + package.name.variable ()),
@@ -323,14 +331,21 @@ namespace bpkg
else
assert (system);
+ if (!config_vars_.empty ())
+ config_var_srcs_ = vector<config_source> (config_vars_.size (),
+ config_source::user);
+
// We are only interested in old user configuration variables.
//
if (config_srcs_ != nullptr)
{
if (find_if (config_srcs_->begin (), config_srcs_->end (),
- [] (const config_variable& v)
+ [this] (const config_variable& v)
{
- return v.source == config_source::user;
+ return ((load_config_flags & load_config_user) != 0 &&
+ v.source == config_source::user) ||
+ ((load_config_flags & load_config_dependent) != 0 &&
+ v.source == config_source::dependent);
}) == config_srcs_->end ())
config_srcs_ = nullptr;
}
@@ -352,8 +367,8 @@ namespace bpkg
{
// For now tighten it even further so that we can continue
// using repositories without package skeleton information
- // (bootstrap.build, root.build). See load_old_config() for
- // details.
+ // (bootstrap.build, root.build). See
+ // load_old_config_impl() for details.
//
#if 0
return project_override (v, var_prefix_);
@@ -369,11 +384,27 @@ namespace bpkg
{
src_root_ = move (*src_root);
+ assert (!src_root_.empty ()); // Must exist.
+
+ src_root_specified_ = true;
+
if (out_root)
out_root_ = move (*out_root);
}
else
assert (!out_root);
+
+ if (old_src_root)
+ {
+ old_src_root_ = move (*old_src_root);
+
+ assert (!old_src_root_.empty ()); // Must exist.
+
+ if (old_out_root)
+ old_out_root_ = move (*old_out_root);
+ }
+ else
+ assert (!old_out_root);
}
// Serialize a variable assignment for a command line override.
@@ -391,7 +422,7 @@ namespace bpkg
else
{
storage.clear ();
- names_view nv (reverse (val, storage));
+ names_view nv (reverse (val, storage, true /* reduce */));
if (!nv.empty ())
{
@@ -406,7 +437,8 @@ namespace bpkg
return r;
}
- // Reverse value to names.
+ // Reverse value to names reducing empty simple value to empty list of
+ // names.
//
static optional<build2::names>
reverse_value (const build2::value& val)
@@ -417,7 +449,7 @@ namespace bpkg
return nullopt;
names storage;
- names_view nv (reverse (val, storage));
+ names_view nv (reverse (val, storage, true /* reduce */));
return (nv.data () == storage.data ()
? move (storage)
@@ -462,11 +494,12 @@ namespace bpkg
ctx_ == nullptr);
if (!loaded_old_config_)
- load_old_config ();
+ load_old_config_impl ();
try
{
using namespace build2;
+ using build2::info;
// This is what needs to happen to the variables of different origins in
// the passed configuration:
@@ -486,13 +519,22 @@ namespace bpkg
// construction (in evaluate_{prefer_accept,require}()): we do not add
// as dependent variables that have the override origin.
//
- scope& rs (
- *bootstrap (
- *this, merge_cmd_vars (dependent_cmd_vars (cfg)))->second.front ());
+ scope* rs;
+ {
+ auto df = build2::make_diag_frame (
+ [this] (const build2::diag_record& dr)
+ {
+ dr << info << "while loading build system skeleton of package "
+ << package.name;
+ });
- // Load project's root.build.
- //
- load_root (rs);
+ rs = bootstrap (
+ *this, merge_cmd_vars (dependent_cmd_vars (cfg)))->second.front ();
+
+ // Load project's root.build.
+ //
+ load_root (*rs);
+ }
package_configuration old (move (cfg));
cfg.package = move (old.package);
@@ -515,14 +557,16 @@ namespace bpkg
// variable), then the saved variables map seem like the natural place
// to keep this information.
//
- for (const variable& var: rs.ctx.var_pool)
+ // Note: go straight for the public variable pool.
+ //
+ for (const variable& var: rs->ctx.var_pool)
{
if (!project_variable (var.name, var_prefix_))
continue;
using config::variable_origin;
- pair<variable_origin, lookup> ol (config::origin (rs, var));
+ pair<variable_origin, lookup> ol (config::origin (*rs, var));
switch (ol.first)
{
@@ -616,8 +660,10 @@ namespace bpkg
create_context (*this, strings {});
context& ctx (*ctx_);
+ // Note: go straight for the public variable pool.
+ //
scope& gs (ctx.global_scope.rw ());
- auto& vp (ctx.var_pool.rw ());
+ auto& vp (gs.var_pool (true /* public */));
for (const string& v: config_vars_)
{
@@ -690,11 +736,12 @@ namespace bpkg
ctx_ == nullptr);
if (!loaded_old_config_)
- load_old_config ();
+ load_old_config_impl ();
try
{
using namespace build2;
+ using build2::info;
// For now we treat any failure to load root.build as bad configuration,
// which is not very precise. One idea to make this more precise would
@@ -702,15 +749,23 @@ namespace bpkg
// (e.g., either via an attribute or via special config.assert directive
// or some such).
//
- // For now we rely on load_defaults() and load_old_config() to "flush"
- // out any unrelated errors (e.g., one of the modules configuration is
- // bad, etc). However, if that did not happen naturally, then we must do
- // it ourselves.
+ // For now we rely on load_defaults() and load_old_config_impl() to
+ // "flush" out any unrelated errors (e.g., one of the modules
+ // configuration is bad, etc). However, if that did not happen
+ // naturally, then we must do it ourselves.
//
if (!verified_)
{
+ auto df = build2::make_diag_frame (
+ [this] (const build2::diag_record& dr)
+ {
+ dr << info << "while loading build system skeleton of package "
+ << package.name;
+ });
+
scope& rs (
*bootstrap (*this, merge_cmd_vars (strings {}))->second.front ());
+
load_root (rs);
verified_ = true;
@@ -723,6 +778,8 @@ namespace bpkg
// Load project's root.build while redirecting the diagnostics stream.
//
+ // Note: no diag_frame unlike all the other places.
+ //
ostringstream ds;
auto dg (make_guard ([ods = diag_stream] () {diag_stream = ods;}));
diag_stream = &ds;
@@ -758,10 +815,12 @@ namespace bpkg
// Print the location of a depends value in the specified manifest file.
//
- // Note that currently we only use this function for the external packages.
- // We could also do something similar for normal packages by pointing to the
- // manifest we have serialized. In this case we would also need to make sure
- // the temp directory is not cleaned in case of an error. Maybe one day.
+ // Note that currently we only use this function for the being reconfigured
+ // and external packages (i.e. when the existing source directory is
+ // specified). We could also do something similar for the remaining cases by
+ // pointing to the manifest we have serialized. In this case we would also
+ // need to make sure the temp directory is not cleaned in case of an error.
+ // Maybe one day.
//
static void
depends_location (const build2::diag_record& dr,
@@ -834,20 +893,19 @@ namespace bpkg
uint64_t il (1);
auto df = build2::make_diag_frame (
- [this, &cond, &rs, depends_index] (const build2::diag_record& dr)
+ [this, &cond, depends_index] (const build2::diag_record& dr)
{
dr << info << "enable condition: (" << cond << ")";
- // For external packages we have the manifest so print the location
- // of the depends value in questions.
+ // If an existing source directory has been specified, then we have
+ // the manifest and so print the location of the depends value in
+ // questions.
//
- if (rs.out_eq_src ())
+ if (src_root_specified_)
+ depends_location (dr, src_root_ / manifest_file, depends_index);
+ else
dr << info << "in depends manifest value of package "
<< package.name;
- else
- depends_location (dr,
- rs.src_path () / manifest_file,
- depends_index);
});
lexer l (is, in, il /* start line */);
@@ -903,9 +961,9 @@ namespace bpkg
// values that are derived from them in root.build). It seems like we have
// two options here: either enter them as true overrides similar to
// config_vars_ or just evaluate them similar to loading config.build
- // (which, BTW, we might have, in case of an external package). The big
- // problem with the former approach is that it will then prevent any
- // further reflect clauses from modifying the same values.
+ // (which, BTW, we might have, in case of a being reconfigured or external
+ // package). The big problem with the former approach is that it will then
+ // prevent any further reflect clauses from modifying the same values.
//
// So overall it feels like we have iterative/compartmentalized
// configuration process. A feedback loop, in a sense. And it's the
@@ -1031,7 +1089,7 @@ namespace bpkg
// Note: keep it active until the end (see the override detection).
//
auto df = build2::make_diag_frame (
- [this, &refl, &rs, depends_index] (const build2::diag_record& dr)
+ [this, &refl, depends_index] (const build2::diag_record& dr)
{
// Probably safe to assume a one-line fragment contains a variable
// assignment.
@@ -1042,16 +1100,15 @@ namespace bpkg
dr << info << "reflect clause:\n"
<< trim_right (string (refl));
- // For external packages we have the manifest so print the
- // location of the depends value in questions.
+ // If an existing source directory has been specified, then we have
+ // the manifest and so print the location of the depends value in
+ // questions.
//
- if (rs.out_eq_src ())
+ if (src_root_specified_)
+ depends_location (dr, src_root_ / manifest_file, depends_index);
+ else
dr << info << "in depends manifest value of package "
<< package.name;
- else
- depends_location (dr,
- rs.src_path () / manifest_file,
- depends_index);
});
lexer l (is, in, il /* start line */);
@@ -1065,10 +1122,11 @@ namespace bpkg
// Add to the vars set the reflect variables collected previously.
//
- auto& vp (rs.var_pool ());
for (const reflect_variable_value& v: reflect_)
{
- const variable* var (vp.find (v.name));
+ // Note: go straight for the public variable pool.
+ //
+ const variable* var (rs.ctx.var_pool.find (v.name));
assert (var != nullptr); // Must be there (set by load()).
auto p (vars.insert (rvar {var, nullptr, 0}));
@@ -1248,21 +1306,20 @@ namespace bpkg
uint64_t il (1);
auto df = build2::make_diag_frame (
- [this, &prefer, &rs, depends_index] (const build2::diag_record& dr)
+ [this, &prefer, depends_index] (const build2::diag_record& dr)
{
dr << info << "prefer clause:\n"
<< trim_right (string (prefer));
- // For external packages we have the manifest so print the
- // location of the depends value in questions.
+ // If an existing source directory has been specified, then we
+ // have the manifest and so print the location of the depends
+ // value in questions.
//
- if (rs.out_eq_src ())
+ if (src_root_specified_)
+ depends_location (dr, src_root_ / manifest_file, depends_index);
+ else
dr << info << "in depends manifest value of package "
<< package.name;
- else
- depends_location (dr,
- rs.src_path () / manifest_file,
- depends_index);
});
lexer l (is, in, il /* start line */);
@@ -1310,20 +1367,19 @@ namespace bpkg
uint64_t il (1);
auto df = build2::make_diag_frame (
- [this, &accept, &rs, depends_index] (const build2::diag_record& dr)
+ [this, &accept, depends_index] (const build2::diag_record& dr)
{
dr << info << "accept condition: (" << accept << ")";
- // For external packages we have the manifest so print the
- // location of the depends value in questions.
+ // If an existing source directory has been specified, then we
+ // have the manifest and so print the location of the depends
+ // value in questions.
//
- if (rs.out_eq_src ())
+ if (src_root_specified_)
+ depends_location (dr, src_root_ / manifest_file, depends_index);
+ else
dr << info << "in depends manifest value of package "
<< package.name;
- else
- depends_location (dr,
- rs.src_path () / manifest_file,
- depends_index);
});
lexer l (is, in, il /* start line */);
@@ -1543,21 +1599,20 @@ namespace bpkg
uint64_t il (1);
auto df = build2::make_diag_frame (
- [this, &require, &rs, depends_index] (const build2::diag_record& dr)
+ [this, &require, depends_index] (const build2::diag_record& dr)
{
dr << info << "require clause:\n"
<< trim_right (string (require));
- // For external packages we have the manifest so print the
- // location of the depends value in questions.
+ // If an existing source directory has been specified, then we
+ // have the manifest and so print the location of the depends
+ // value in questions.
//
- if (rs.out_eq_src ())
+ if (src_root_specified_)
+ depends_location (dr, src_root_ / manifest_file, depends_index);
+ else
dr << info << "in depends manifest value of package "
<< package.name;
- else
- depends_location (dr,
- rs.src_path () / manifest_file,
- depends_index);
});
lexer l (is, in, il /* start line */);
@@ -1824,7 +1879,7 @@ namespace bpkg
empty_print ()
{
if (!loaded_old_config_)
- load_old_config ();
+ load_old_config_impl ();
return (dependent_vars_.empty () &&
reflect_.empty () &&
@@ -1855,7 +1910,7 @@ namespace bpkg
using build2::config::variable_origin;
if (!loaded_old_config_)
- load_old_config ();
+ load_old_config_impl ();
auto print = [&os,
indent,
@@ -1880,8 +1935,10 @@ namespace bpkg
// First comes the user configuration.
//
- for (const string& v: config_vars_)
+ for (size_t i (0); i != config_vars_.size (); ++i)
{
+ const string& v (config_vars_[i]);
+
size_t vn;
if (project_override (v, var_prefix_, &vn))
{
@@ -1895,8 +1952,17 @@ namespace bpkg
continue;
}
+ const char* s (nullptr);
+
+ switch (config_var_srcs_[i])
+ {
+ case config_source::user: s = "user"; break;
+ case config_source::dependent: s = "dependent"; break;
+ case config_source::reflect: assert (false); // Must never be loaded.
+ }
+
print (v) << " (" << (system ? "expected " : "")
- << "user configuration)";
+ << s << " configuration)";
}
}
@@ -1924,15 +1990,24 @@ namespace bpkg
}
}
+ void package_skeleton::
+ load_old_config ()
+ {
+ if (!loaded_old_config_)
+ load_old_config_impl ();
+ }
+
pair<strings, vector<config_variable>> package_skeleton::
collect_config () &&
{
+ // NOTE: remember to update config_checksum() if changing anything here.
+
assert (db_ != nullptr); // Must be called only once.
using build2::config::variable_origin;
if (!loaded_old_config_)
- load_old_config ();
+ load_old_config_impl ();
// Merge all the variables into a single list in the correct order
// and assign their sources while at it.
@@ -1969,11 +2044,19 @@ namespace bpkg
// variables which are project variables (i.e., names start with
// config.<project>).
//
+ size_t pn (var_prefix_.size ());
for (const string& v: config_vars_)
{
- if (project_override (v, var_prefix_))
+ size_t vn;
+ if (project_override (v, var_prefix_, &vn))
{
- string n (var_name (v));
+ // Skip config.<project>.develop (can potentially be passed by
+ // bdep-init) if the package doesn't use it.
+ //
+ if (!develop_ && v.compare (pn, vn - pn, ".develop") == 0)
+ continue;
+
+ string n (v, 0, vn);
// Check for a duplicate.
//
@@ -2039,13 +2122,61 @@ namespace bpkg
return make_pair (move (vars), move (srcs));
}
+ string package_skeleton::
+ config_checksum ()
+ {
+ // Note: this is parallel to collect_config() logic but is not destructive.
+
+ assert (db_ != nullptr); // Must be called before collect_config().
+
+ if (!loaded_old_config_)
+ load_old_config_impl ();
+
+ sha256 cs;
+
+ if (!config_vars_.empty ())
+ {
+ cstrings vs;
+ size_t pn (var_prefix_.size ());
+ for (const string& v: config_vars_)
+ {
+ size_t vn;
+ if (project_override (v, var_prefix_, &vn))
+ {
+ // Skip config.<project>.develop (can potentially be passed by
+ // bdep-init) if the package doesn't use it.
+ //
+ if (develop_ || v.compare (pn, vn - pn, ".develop") != 0)
+ cs.append (v);
+ }
+ }
+ }
+
+ if (!dependent_vars_.empty ())
+ {
+ for (const string& v: dependent_vars_)
+ cs.append (v);
+ }
+
+ if (!reflect_.empty ())
+ {
+ for (const reflect_variable_value& v: reflect_)
+ {
+ if (v.origin != build2::config::variable_origin::override_)
+ cs.append (serialize_cmdline (v.name, v.value));
+ }
+ }
+
+ return !cs.empty () ? cs.string () : string ();
+ }
+
const strings& package_skeleton::
merge_cmd_vars (const strings& dependent_vars,
const strings& dependency_vars,
bool cache)
{
// Merge variable overrides (note that the order is important). See also a
- // custom/optimized version in load_old_config().
+ // custom/optimized version in load_old_config_impl().
//
if (!cache || !cmd_vars_cache_)
{
@@ -2093,13 +2224,14 @@ namespace bpkg
}
void package_skeleton::
- load_old_config ()
+ load_old_config_impl ()
{
assert (!loaded_old_config_ && ctx_ == nullptr);
try
{
using namespace build2;
+ using build2::info;
// This load that must be done without config.config.disfigure. Also, it
// would be nice to optimize for the common case where the only load is
@@ -2136,13 +2268,25 @@ namespace bpkg
}
}
- scope& rs (*bootstrap (*this, *cmd_vars)->second.front ());
+ scope* rs;
+ {
+ auto df = build2::make_diag_frame (
+ [this] (const build2::diag_record& dr)
+ {
+ dr << info << "while loading build system skeleton of package "
+ << package.name;
+ });
- // Load project's root.build.
- //
- load_root (rs);
+ rs = bootstrap (*this, *cmd_vars, true /* old */)->second.front ();
- if (const variable* var = rs.var_pool ().find (var_prefix_ + ".develop"))
+ // Load project's root.build.
+ //
+ load_root (*rs);
+ }
+
+ // Note: go straight for the public variable pool.
+ //
+ if (const variable* var = rs->ctx.var_pool.find (var_prefix_ + ".develop"))
{
// Use the fact that the variable is typed as a proxy for it being
// defined with config directive (the more accurate way would be via
@@ -2156,27 +2300,32 @@ namespace bpkg
//
// Also, build2 warns about unused variables being dropped.
//
- // Note that currently load_old_config() is disabled unless there is
- // a config.*.develop variable; see package_skeleton ctor.
+ // Note that currently load_old_config_impl() is disabled unless
+ // there is a config.*.develop variable or we were asked to load
+ // dependent configuration; see package_skeleton ctor.
- // Extract and merge old user configuration variables from config.build
- // (or equivalent) into config_vars.
+ // Extract and merge old user and/or dependent configuration variables
+ // from config.build (or equivalent) into config_vars.
//
if (config_srcs_ != nullptr)
{
assert (!disfigure_);
- auto i (config_vars_.begin ()); // Insert position, see below.
+ auto i (config_vars_.begin ()); // Insert position, see below.
+ auto j (config_var_srcs_.begin ()); // Insert position, see below.
names storage;
for (const config_variable& v: *config_srcs_)
{
- if (v.source != config_source::user)
+ if (!(((load_config_flags & load_config_user) != 0 &&
+ v.source == config_source::user) ||
+ ((load_config_flags & load_config_dependent) != 0 &&
+ v.source == config_source::dependent)))
continue;
using config::variable_origin;
- pair<variable_origin, lookup> ol (config::origin (rs, v.name));
+ pair<variable_origin, lookup> ol (config::origin (*rs, v.name));
switch (ol.first)
{
@@ -2201,6 +2350,7 @@ namespace bpkg
i,
serialize_cmdline (v.name, *ol.second, storage)) + 1;
+ j = config_var_srcs_.insert (j, v.source) + 1;
break;
}
case variable_origin::undefined:
@@ -2219,7 +2369,10 @@ namespace bpkg
}
loaded_old_config_ = true;
- verified_ = true; // Managed to load without errors.
+
+ if (old_src_root_.empty ())
+ verified_ = true; // Managed to load without errors.
+
ctx_ = nullptr;
}
catch (const build2::failed&)
@@ -2242,11 +2395,12 @@ namespace bpkg
}
if (!loaded_old_config_)
- load_old_config ();
+ load_old_config_impl ();
try
{
using namespace build2;
+ using build2::info;
using build2::config::variable_origin;
// If we have any dependency configurations, then here we need to add
@@ -2283,6 +2437,13 @@ namespace bpkg
dependency_vars,
dependency_vars.empty () /* cache */));
+ auto df = build2::make_diag_frame (
+ [this] (const build2::diag_record& dr)
+ {
+ dr << info << "while loading build system skeleton of package "
+ << package.name;
+ });
+
auto rsi (bootstrap (*this, cmd_vars));
scope& rs (*rsi->second.front ());
@@ -2329,7 +2490,9 @@ namespace bpkg
assert (vt != nullptr);
}
- return rs.var_pool ().insert (name, vt);
+ // Note: go straight for the public variable pool.
+ //
+ return rs.var_pool (true /* public */).insert (name, vt);
};
for (const reflect_variable_value& v: reflect_)
@@ -2436,10 +2599,11 @@ namespace bpkg
new context (build2_sched,
build2_mutexes,
build2_fcache,
- false /* match_only */, // Shouldn't matter.
- false /* no_external_modules */,
- false /* dry_run */, // Shouldn't matter.
- false /* keep_going */, // Shouldnt' matter.
+ nullopt /* match_only */, // Shouldn't matter.
+ false /* no_external_modules */,
+ false /* dry_run */, // Shouldn't matter.
+ false /* no_diag_buffer */, // Shouldn't matter.
+ false /* keep_going */, // Shouldnt' matter.
cmd_vars));
}
catch (const build2::failed&)
@@ -2451,7 +2615,7 @@ namespace bpkg
// Bootstrap the package skeleton.
//
static build2::scope_map::iterator
- bootstrap (package_skeleton& skl, const strings& cmd_vars)
+ bootstrap (package_skeleton& skl, const strings& cmd_vars, bool old)
{
assert (skl.db_ != nullptr &&
skl.ctx_ == nullptr &&
@@ -2473,6 +2637,12 @@ namespace bpkg
// Create the skeleton filesystem state, if it doesn't exist yet.
//
+ if (old && skl.old_src_root_.empty ())
+ old = false;
+
+ dir_path& skl_src_root (old ? skl.old_src_root_ : skl.src_root_);
+ dir_path& skl_out_root (old ? skl.old_out_root_ : skl.out_root_);
+
if (!skl.created_)
{
const available_package& ap (*skl.available);
@@ -2482,14 +2652,28 @@ namespace bpkg
// they never clash with other temporary subdirectories (git
// repositories, etc).
//
- if (skl.src_root_.empty () || skl.out_root_.empty ())
+ // Note: for old src/out, everything should already exist.
+ //
+ if (!old && (skl_src_root.empty () || skl_out_root.empty ()))
{
// Cannot be specified if src_root_ is unspecified.
//
- assert (skl.out_root_.empty ());
+ assert (skl_out_root.empty ());
+
+ // Note that only configurations which can be used as repository
+ // information sources has the temporary directory facility
+ // pre-initialized (see pkg-build.cxx for details). Thus, we may need
+ // to initialize it ourselves.
+ //
+ const dir_path& c (skl.db_->config_orig);
+ auto i (tmp_dirs.find (c));
- auto i (tmp_dirs.find (skl.db_->config_orig));
- assert (i != tmp_dirs.end ());
+ if (i == tmp_dirs.end ())
+ {
+ init_tmp (c);
+
+ i = tmp_dirs.find (c);
+ }
// Make sure the source and out root directories, if set, are absolute
// and normalized.
@@ -2502,14 +2686,16 @@ namespace bpkg
d /= "skeletons";
d /= skl.package.name.string () + '-' + ap.version.string ();
- if (skl.src_root_.empty ())
- skl.src_root_ = move (d); // out_root_ is the same.
+ if (skl_src_root.empty ())
+ skl_src_root = move (d); // out_root_ is the same.
else
- skl.out_root_ = move (d); // Don't even need to create it.
+ skl_out_root = move (d); // Don't even need to create it.
}
- if (!exists (skl.src_root_))
+ if (!exists (skl_src_root))
{
+ assert (!old); // An old package version cannot not exist.
+
// Create the buildfiles.
//
// Note that it's probably doesn't matter which naming scheme to use
@@ -2519,7 +2705,7 @@ namespace bpkg
{
bool an (*ap.alt_naming);
- path bf (skl.src_root_ /
+ path bf (skl_src_root /
(an ? alt_bootstrap_file : std_bootstrap_file));
mk_p (bf.directory ());
@@ -2544,11 +2730,11 @@ namespace bpkg
if (ap.root_build)
save (*ap.root_build,
- skl.src_root_ / (an ? alt_root_file : std_root_file));
+ skl_src_root / (an ? alt_root_file : std_root_file));
for (const buildfile& f: ap.buildfiles)
{
- path p (skl.src_root_ /
+ path p (skl_src_root /
(an ? alt_build_dir : std_build_dir) /
f.path);
@@ -2589,7 +2775,7 @@ namespace bpkg
m.dependencies.push_back (das);
}
- path mf (skl.src_root_ / manifest_file);
+ path mf (skl_src_root / manifest_file);
try
{
@@ -2614,7 +2800,8 @@ namespace bpkg
}
}
- skl.created_ = true;
+ if (!old)
+ skl.created_ = true;
}
try
@@ -2647,10 +2834,10 @@ namespace bpkg
// Note that it's ok for out_root to not exist (external package).
//
- const dir_path& src_root (skl.src_root_);
- const dir_path& out_root (skl.out_root_.empty ()
- ? skl.src_root_
- : skl.out_root_);
+ const dir_path& src_root (skl_src_root);
+ const dir_path& out_root (skl_out_root.empty ()
+ ? skl_src_root
+ : skl_out_root);
auto rsi (create_root (ctx, out_root, src_root));
scope& rs (*rsi->second.front ());