aboutsummaryrefslogtreecommitdiff
path: root/bpkg/pkg-build.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-04-12 07:34:39 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-04-15 09:57:58 +0200
commit5267c62f8c1f483c5348d4a2e498088a41c2e945 (patch)
tree9592af2b2a374e9d5924dd7c859e4069ec75c4fb /bpkg/pkg-build.cxx
parent306ad185e8d8f50923316bdd1b68ef9a3b1e50e6 (diff)
Implement in-process package configuration
Diffstat (limited to 'bpkg/pkg-build.cxx')
-rw-r--r--bpkg/pkg-build.cxx124
1 files changed, 118 insertions, 6 deletions
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index 2484880..4f5b423 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -1245,7 +1245,13 @@ namespace bpkg
if (a.find ('=') == string::npos)
fail << "unexpected group argument '" << a << "'";
- cvs.push_back (move (trim (a)));
+ trim (a);
+
+ if (a[0] == '!')
+ fail << "global override in package-specific configuration "
+ << "variable '" << a << "'";
+
+ cvs.push_back (move (a));
}
}
@@ -5356,12 +5362,26 @@ namespace bpkg
struct configure_package
{
reference_wrapper<build_package> pkg;
- configure_prerequisites_result res; // Unused for system package.
+
+ // These are unused for system packages.
+ //
+ configure_prerequisites_result res;
+ build2::variable_overrides ovrs;
};
vector<configure_package> configure_packages;
-
configure_packages.reserve (build_pkgs.size ());
+ // While at it also collect global configuration variable overrides from
+ // each configure_prerequisites_result::config_variables and merge them
+ // into configure_global_vars.
+ //
+ // @@ TODO: Note that the current global override semantics is quite
+ // broken in that we don't force reconfiguration of all the packages.
+ //
+#ifndef BPKG_OUTPROC_CONFIGURE
+ strings configure_global_vars;
+#endif
+
// Return the "would be" state of packages that would be configured
// by this stage.
//
@@ -5557,11 +5577,97 @@ namespace bpkg
}
t.commit ();
+
+ if (verb >= 5 && !simulate && !cpr.config_variables.empty ())
+ {
+ diag_record dr (trace);
+
+ dr << sp->name << pdb << " configuration variables:";
+
+ for (const string& cv: cpr.config_variables)
+ dr << "\n " << cv;
+ }
+
+ if (!simulate)
+ {
+#ifndef BPKG_OUTPROC_CONFIGURE
+ auto& gvs (configure_global_vars);
+
+ // Note that we keep global overrides in cpr.config_variables for
+ // diagnostics and skip them in var_override_function below.
+ //
+ for (const string& v: cpr.config_variables)
+ {
+ // Each package should have exactly the same set of global
+ // overrides by construction since we don't allow package-
+ // specific global overrides.
+ //
+ if (v[0] == '!')
+ {
+ if (find (gvs.begin (), gvs.end (), v) == gvs.end ())
+ gvs.push_back (v);
+ }
+ }
+#endif
+ // Add config.config.disfigure unless already disfigured (see the
+ // high-level pkg_configure() version for background).
+ //
+ if (ap == nullptr || !p.disfigure)
+ {
+ cpr.config_variables.push_back (
+ "config.config.disfigure='config." + sp->name.variable () + "**'");
+ }
+ }
}
- configure_packages.push_back (configure_package {p, move (cpr)});
+ configure_packages.push_back (configure_package {p, move (cpr), {}});
}
+ // Reuse the build state to avoid reloading the dependencies over and over
+ // again. This is a valid optimization since we are configuring in the
+ // dependency-dependent order.
+ //
+ unique_ptr<build2::context> configure_ctx;
+
+#ifndef BPKG_OUTPROC_CONFIGURE
+ 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)
+ {
+ if (v[0] == '!') // Skip global overrides (see above).
+ continue;
+
+ 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));
+ }
+ }
+ });
+
+ 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)
{
prog_i = 0;
@@ -5606,7 +5712,8 @@ namespace bpkg
t,
sp,
move (cp.res),
- p.disfigure,
+ configure_ctx,
+ cp.ovrs,
simulate);
}
else // Dependent.
@@ -5616,7 +5723,8 @@ namespace bpkg
t,
sp,
move (cp.res),
- false /* disfigured */,
+ configure_ctx,
+ cp.ovrs,
simulate);
}
}
@@ -5643,6 +5751,10 @@ namespace bpkg
}
}
+#ifndef BPKG_OUTPROC_CONFIGURE
+ configure_ctx.reset (); // Free.
+#endif
+
// Clear the progress if shown.
//
if (progress)