aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-04-13 10:41:00 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-04-13 10:41:00 +0200
commit863dc3baae48909d843cf826446c67ab5767224e (patch)
treed7fd64e13bcc71e47dfbec2bb4df9876d4352151
parent4d0df41f94bec13a9af5c76b0176596f1ca3ab7b (diff)
Beat into more or less working
-rw-r--r--bpkg/bpkg.cxx2
-rw-r--r--bpkg/buildfile3
-rw-r--r--bpkg/pkg-build.cxx35
-rw-r--r--bpkg/pkg-configure.cxx122
-rw-r--r--bpkg/pkg-configure.hxx13
-rw-r--r--bpkg/utility.txx2
6 files changed, 149 insertions, 28 deletions
diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx
index 417127e..fa294c5 100644
--- a/bpkg/bpkg.cxx
+++ b/bpkg/bpkg.cxx
@@ -222,7 +222,7 @@ namespace bpkg
}
catch (const build2::failed&)
{
- throw failed (); // Assume the diagnostics has already been issued.
+ throw bpkg::failed (); // Assume the diagnostics has already been issued.
}
}
diff --git a/bpkg/buildfile b/bpkg/buildfile
index 6bddbb8..e64e413 100644
--- a/bpkg/buildfile
+++ b/bpkg/buildfile
@@ -98,7 +98,8 @@ for t: cxx{**.test...}
# Build options.
#
-cxx.poptions += -DBPKG_OUTPROC_CONFIGURE
+
+#cxx.poptions += -DBPKG_OUTPROC_CONFIGURE
obj{utility}: cxx.poptions += \
"-DBPKG_EXE_PREFIX=\"$bin.exe.prefix\"" \
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index 5d73eb7..54f5a37 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -5634,10 +5634,39 @@ namespace bpkg
unique_ptr<build2::context> configure_ctx;
#ifndef BPKG_OUTPROC_CONFIGURE
- // @@ TODO: create context. Unless simulating.
+ if (!simulate)
+ {
+ using build2::context;
+ using build2::variable_override;
+
+ function<context::var_override_function> vof (
+ [&configure_packages] (context& ctx, size_t& i)
+ {
+ for (configure_package& cp: configure_packages)
+ {
+ for (const string& v: cp.res.config_variables)
+ {
+ pair<char, variable_override> p (
+ ctx.parse_variable_override (v, i++, false /* buildspec */));
+
+ variable_override& vo (p.second);
+
+ // @@ TODO: put absolute scope overrides into global_vars.
+ //
+ assert (!(p.first == '!' || (vo.dir && vo.dir->absolute ())));
+
+ cp.ovrs.push_back (move (vo));
+ }
+ }
+ });
- // @@ TODO
- //assert (ctx->var_overrides.empty ()); // Global only.
+ configure_ctx = pkg_configure_context (
+ o, move (configure_global_vars), vof);
+
+ // Only global in configure_global_vars.
+ //
+ assert (configure_ctx->var_overrides.empty ());
+ }
#endif
if (progress)
diff --git a/bpkg/pkg-configure.cxx b/bpkg/pkg-configure.cxx
index ded567d..ccf2f54 100644
--- a/bpkg/pkg-configure.cxx
+++ b/bpkg/pkg-configure.cxx
@@ -286,8 +286,25 @@ namespace bpkg
else
od = sp->effective_out_root (pdb.config);
+#ifndef BPKG_OUTPROC_CONFIGURE
+ // Use global overrides to recreate the original behavior of
+ // not warning about unused config.import.* variables
+ // (achived via the config.config.persist value in
+ // amalgamation). Even though it's probably misguided (we
+ // don't actually save the unused values anywhere, just
+ // don't warn about them).
+ //
+ // @@ Can we somehow cause a clash, say if the same package
+ // comes from different configurations? Yeah, we probably
+ // can. Maybe detect a clash somehow and "fallforward" to
+ // the correct behavior?
+ //
+ vars.push_back ("!config.import." + sp->name.variable () +
+ "='" + od.representation () + '\'');
+#else
vars.push_back ("config.import." + sp->name.variable () +
"='" + od.representation () + '\'');
+#endif
}
}
}
@@ -377,7 +394,7 @@ namespace bpkg
// Re-tune the scheduler for parallel execution (see build2_init()
// for details).
//
- if (!build2_sched.serial ())
+ if (build2_sched.tuned ())
build2_sched.tune (0);
auto merge_cmd_vars = [&cmd_vars] () -> const strings&
@@ -414,11 +431,12 @@ namespace bpkg
nullptr /* inherited_mudules_lock */,
var_ovr_func));
- scope& gs (ctx->global_scope.rw ());
-
- ctx->current_mname = "configure";
+ // Set the current meta-operation once per context so that we don't reset
+ // ctx->current_on. Note that this function also sets ctx->current_mname
+ // and var_build_meta_operation on global scope.
+ //
+ ctx->current_meta_operation (config::mo_configure);
ctx->current_oname = string (); // default
- gs.assign (ctx->var_build_meta_operation) = "configure";
return ctx;
}
@@ -445,15 +463,22 @@ namespace bpkg
tracer_guard tg (db, trace);
- const dir_path& c (db.config_orig);
+#ifndef BPKG_OUTPROC_CONFIGURE
+ const dir_path& c (db.config); // Absolute.
+#else
+ const dir_path& c (db.config_orig); // Relative.
+#endif
+
dir_path src_root (p->effective_src_root (c));
// Calculate package's out_root.
//
// Note: see a version of this in pkg_configure_prerequisites().
//
+ bool external (p->external ());
+
dir_path out_root (
- p->external ()
+ external
? c / dir_path (p->name.string ())
: c / dir_path (p->name.string () + '-' + p->version.string ()));
@@ -470,9 +495,13 @@ namespace bpkg
// Original implementation that runs the standard build system driver.
//
// Note that the semantics doesn't match 100%. In particular, in the
- // in-process implementation we enter unqualified variable in each
- // project instead of the amalgamation (which is probably more accurate,
- // since we don't re-configure the amalgamation or some dependencies).
+ // in-process implementation we enter overrides with global visibility
+ // in each project instead of the amalgamation (which is probably more
+ // accurate, since we don't re-configure the amalgamation nor some
+ // dependencies which could be affected by such overrides). In a sense,
+ // we enter them as if they were specified with the special .../ scope
+ // (but not with the % project visibility -- they must still be visible
+ // in subprojects).
//
#ifdef BPKG_OUTPROC_CONFIGURE
// Form the buildspec.
@@ -508,15 +537,22 @@ namespace bpkg
//
try
{
+ // Note: no bpkg::failed should be thrown from this block.
+ //
using namespace build2;
using build2::fail;
using build2::info;
using build2::endf;
using build2::location;
- // @@ Uses verb_b::normal, we need verb_b::quiet. Temporarily
- // adjust build2::verb then restore?
+ // The build2_init() function initializes the build system verbosity
+ // as if running with verb_b::normal while we need verb_b::quiet. So
+ // we temporarily adjust the build2 verbosity (see map_verb_b() for
+ // details).
//
+ auto verbg (make_guard ([ov = build2::verb] () {build2::verb = ov;}));
+ if (bpkg::verb == 1)
+ build2::verb = 0;
context& ctx (*pctx);
@@ -549,7 +585,7 @@ namespace bpkg
if (src_root != p)
{
- // @@ fuzzy if need this or can do as package skeleto (seeing
+ // @@ fuzzy if need this or can do as package skeleton (seeing
// that we know we are re-configuring).
ctx.new_src_root = src_root;
@@ -577,8 +613,6 @@ namespace bpkg
// Skip configure_pre() and configure_operation_pre() calls since we
// don't pass any parameteres and pass default operation. We also know
// that op_default has no pre/post operations, naturally.
- //
- ctx.current_meta_operation (mif);
// Find the root buildfile. Note that the implied buildfile logic does
// not apply (our target is the project root directory).
@@ -590,7 +624,14 @@ namespace bpkg
// Enter project-wide overrides.
//
- ctx.enter_project_overrides (rs, out_root, ovrs);
+ // Note that the use of the root scope as amalgamation makes sure
+ // scenarious like below work correctly (see above for background).
+ //
+ // bpkg create -d cfg cc config.cc.coptions=-Wall
+ // bpkg build { config.cc.coptions+=-g }+ libfoo
+ // { config.cc.coptions+=-O }+ libbar
+ //
+ ctx.enter_project_overrides (rs, out_root, ovrs, &rs);
// The goal here is to be more or less semantically equivalent to
// configuring several projects at once. Except that here we have
@@ -626,6 +667,35 @@ namespace bpkg
mif.execute (mparams, a, tgs, 2 /* diag */, true /* progress */);
// Note: no operation_post/meta_operation_post for configure.
+
+ // Here is a tricky part: if this is a normal package, then it will be
+ // discovered as a subproject of the bpkg configuration when we load
+ // it for the first time (because they are all unpacked). However, if
+ // this is an external package, there could be no out_root directory
+ // for it in the bpkg configuration yet. As a result, we need to
+ // manually add it as a newly discovered subproject.
+ //
+ if (external)
+ {
+ scope* as (rs.parent_scope ()->root_scope ());
+ assert (as != nullptr); // No bpkg configuration?
+
+ // Kept NULL if there are no subprojects, so we may need to
+ // initialize it (see build2::bootstrap_src() for details).
+ //
+ subprojects* sp (*as->root_extra->subprojects);
+ if (sp == nullptr)
+ {
+ value& v (as->vars.assign (*ctx.var_subprojects));
+ v = subprojects {};
+ sp = *(as->root_extra->subprojects = &cast<subprojects> (v));
+ }
+
+ const project_name& n (**rs.root_extra->project);
+
+ if (sp->find (n) == sp->end ())
+ sp->emplace (n, out_root.leaf ());
+ }
}
catch (const build2::failed&)
{
@@ -651,7 +721,7 @@ namespace bpkg
false /* simulate */);
- throw failed ();
+ throw bpkg::failed ();
}
#endif
@@ -714,16 +784,22 @@ namespace bpkg
}
unique_ptr<build2::context> ctx;
- build2::variable_overrides ovrs;
#ifndef BPKG_OUTPROC_CONFIGURE
-
- // @@ TODO: create context unless simulating, populate ovrs from
- // cpr via callback.
- //
+ if (!simulate)
+ ctx = pkg_configure_context (o, move (cpr.config_variables));
#endif
- pkg_configure (o, db, t, p, move (cpr), ctx, ovrs, simulate);
+ pkg_configure (o,
+ db,
+ t,
+ p,
+ move (cpr),
+ ctx,
+ (ctx != nullptr
+ ? ctx->var_overrides
+ : build2::variable_overrides {}),
+ simulate);
}
shared_ptr<selected_package>
diff --git a/bpkg/pkg-configure.hxx b/bpkg/pkg-configure.hxx
index 255371c..c4c2758 100644
--- a/bpkg/pkg-configure.hxx
+++ b/bpkg/pkg-configure.hxx
@@ -112,6 +112,9 @@ namespace bpkg
// Note: variable_overrides must include config.config.disfigure, if
// required.
//
+ // Note: expects all the non-external packages to be configured to be
+ // already unpackged (for subproject discovery).
+ //
void
pkg_configure (const common_options&,
database&,
@@ -122,6 +125,16 @@ namespace bpkg
const build2::variable_overrides&,
bool simulate);
+ // Create a build context suitable for configuring packages.
+ //
+ unique_ptr<build2::context>
+ pkg_configure_context (
+ const common_options&,
+ strings&& cmd_vars,
+ const function<build2::context::var_override_function>& = nullptr);
+
+ // This is a higher-level version meant for configuring a single package.
+ //
// Note: loads selected packages.
//
void
diff --git a/bpkg/utility.txx b/bpkg/utility.txx
index a21325c..8bdd7ec 100644
--- a/bpkg/utility.txx
+++ b/bpkg/utility.txx
@@ -25,6 +25,8 @@ namespace bpkg
}
else if (verb == 1)
{
+ // NOTE: search for verb_b usage if changing anything here.
+ //
if (v != verb_b::normal)
{
ops.push_back ("-q");