aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-06-30 13:46:37 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-07-01 08:19:20 +0200
commit2a80e9c100651ee8595959b6df37090f808eef87 (patch)
tree4cf9c5b3759817140b6e82a930fefb5824c851cf /libbuild2
parent83fc9f4287d24826abc8ea61e1524edf23dcd449 (diff)
Add *.export.imp_libs to get rid of dual *.export.libs semantics
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/c/init.cxx2
-rw-r--r--libbuild2/cc/common.cxx71
-rw-r--r--libbuild2/cc/common.hxx2
-rw-r--r--libbuild2/cc/init.cxx1
-rw-r--r--libbuild2/cxx/init.cxx2
5 files changed, 42 insertions, 36 deletions
diff --git a/libbuild2/c/init.cxx b/libbuild2/c/init.cxx
index 5a70b54..7760808 100644
--- a/libbuild2/c/init.cxx
+++ b/libbuild2/c/init.cxx
@@ -202,11 +202,13 @@ namespace build2
vp.insert<strings> ("c.export.coptions"),
vp.insert<strings> ("c.export.loptions"),
vp.insert<vector<name>> ("c.export.libs"),
+ vp.insert<vector<name>> ("c.export.imp_libs"),
vp["cc.export.poptions"],
vp["cc.export.coptions"],
vp["cc.export.loptions"],
vp["cc.export.libs"],
+ vp["cc.export.imp_libs"],
vp.insert_alias (vp["cc.stdlib"], "c.stdlib"), // Same as cc.stdlib.
diff --git a/libbuild2/cc/common.cxx b/libbuild2/cc/common.cxx
index 6b8bd96..bf592cd 100644
--- a/libbuild2/cc/common.cxx
+++ b/libbuild2/cc/common.cxx
@@ -21,13 +21,14 @@ namespace build2
{
using namespace bin;
- // Recursively process prerequisite libraries. If proc_impl returns false,
- // then only process interface (*.export.libs), otherwise -- interface and
- // implementation (prerequisite and from *.libs, unless overriden).
+ // Recursively process prerequisite libraries of the specified library. If
+ // proc_impl returns false, then only process interface (*.export.libs),
+ // otherwise -- interface and implementation (prerequisite and from
+ // *.libs, unless overriden with *.export.imp_libs).
//
- // Note that here we assume that an interface library is also an
- // implementation (since we don't use *.export.libs in static link). We
- // currently have this restriction to make sure the target in
+ // Note that here we assume that an interface library is also always an
+ // implementation (since we don't use *.export.libs for static linking).
+ // We currently have this restriction to make sure the target in
// *.export.libs is up-to-date (which will happen automatically if it is
// listed as a prerequisite of this library).
//
@@ -44,7 +45,7 @@ namespace build2
//
// The first argument to proc_lib is a pointer to the last element of an
// array that contains the current library dependency chain all the way to
- // the library passes to process_libraries(). The first element of this
+ // the library passed to process_libraries(). The first element of this
// array is NULL.
//
void common::
@@ -92,31 +93,26 @@ namespace build2
if (t != nullptr)
{
- cc = *t == "cc";
- same = !cc && *t == x;
-
- // The explicit export override should be set on the liba/libs{}
- // target itself. Note also that we only check for *.libs. If one
- // doesn't have any libraries but needs to set, say, *.loptions, then
- // *.libs should be set to NULL or empty (this is why we check for
- // the result being defined).
+ cc = (*t == "cc");
+ same = (!cc && *t == x);
+
+ // Note that we used to treat *.export.libs set on the liba/libs{}
+ // members as *.libs overrides rather than as member-specific
+ // interface dependencies. This difference in semantics proved to be
+ // surprising so now we have separate *.export.imp_libs for that.
+ // Note that in this case options come from *.export.* variables.
//
- if (impl)
- c_e_libs = l.vars[c_export_libs]; // Override.
- else if (l.group != nullptr) // lib{} group.
- c_e_libs = l.group->vars[c_export_libs];
+ // Note also that we only check for *.*libs. If one doesn't have any
+ // libraries but needs to set, say, *.loptions, then *.*libs should be
+ // set to NULL or empty (this is why we check for the result being
+ // defined).
+ //
+ c_e_libs = l[impl ? c_export_imp_libs : c_export_libs];
if (!cc)
- {
- const variable& var (same
- ? x_export_libs
- : vp[*t + ".export.libs"]);
-
- if (impl)
- x_e_libs = l.vars[var]; // Override.
- else if (l.group != nullptr) // lib{} group.
- x_e_libs = l.group->vars[var];
- }
+ x_e_libs = l[same
+ ? (impl ? x_export_imp_libs : x_export_libs)
+ : vp[*t + (impl ? ".export.imp_libs" : ".export.libs")]];
// Process options first.
//
@@ -140,9 +136,10 @@ namespace build2
// perhaps we can assume non-common values will be set on
// libs{}/liba{}.
//
+ // Note: options come from *.export.* variables.
+ //
proc_opt (l, *t, false, true);
proc_opt (l, *t, true, true);
-
}
else
{
@@ -233,7 +230,7 @@ namespace build2
// Only go into prerequisites (implementation) if instructed and we are
// not using explicit export. Otherwise, interface dependencies come
- // from the lib{}:*.export.libs below.
+ // from the lib{}:*.export.imp_libs below.
//
if (impl && !c_e_libs.defined () && !x_e_libs.defined ())
{
@@ -262,7 +259,7 @@ namespace build2
}
}
- // Process libraries (recursively) from *.export.libs (of type names)
+ // Process libraries (recursively) from *.export.*libs (of type names)
// handling import, etc.
//
// If it is not a C-common library, then it probably doesn't have any of
@@ -292,7 +289,7 @@ namespace build2
&proc_impl, &proc_lib, &proc_opt, chain,
&sysd, &usrd,
&find_sysd, &find_linfo, &sys_simple,
- &bs, a, &li, this] (const lookup& lu)
+ &bs, a, &li, impl, this] (const lookup& lu)
{
const vector<name>* ns (cast_null<vector<name>> (lu));
if (ns == nullptr || ns->empty ())
@@ -339,8 +336,10 @@ namespace build2
// paths.
//
if (t.mtime () == timestamp_unknown)
- fail << "interface dependency " << t << " is out of date" <<
- info << "mentioned in *.export.libs of target " << l <<
+ fail << (impl ? "implementation" : "interface")
+ << " dependency " << t << " is out of date" <<
+ info << "mentioned in *.export." << (impl ? "imp_" : "")
+ << "libs of target " << l <<
info << "is it a prerequisite of " << l << "?";
}
@@ -377,7 +376,7 @@ namespace build2
// Note: the same structure as when processing options above.
//
// If all we know is it's a C-common library, then in both cases we
- // only look for cc.export.libs.
+ // only look for cc.export.*libs.
//
if (cc)
{
diff --git a/libbuild2/cc/common.hxx b/libbuild2/cc/common.hxx
index 0b04990..6df1ab0 100644
--- a/libbuild2/cc/common.hxx
+++ b/libbuild2/cc/common.hxx
@@ -77,11 +77,13 @@ namespace build2
const variable& x_export_coptions;
const variable& x_export_loptions;
const variable& x_export_libs;
+ const variable& x_export_imp_libs;
const variable& c_export_poptions; // cc.export.*
const variable& c_export_coptions;
const variable& c_export_loptions;
const variable& c_export_libs;
+ const variable& c_export_imp_libs;
const variable& x_stdlib; // x.stdlib
diff --git a/libbuild2/cc/init.cxx b/libbuild2/cc/init.cxx
index 1470a21..040df7f 100644
--- a/libbuild2/cc/init.cxx
+++ b/libbuild2/cc/init.cxx
@@ -108,6 +108,7 @@ namespace build2
vp.insert<strings> ("cc.export.coptions");
vp.insert<strings> ("cc.export.loptions");
vp.insert<vector<name>> ("cc.export.libs");
+ vp.insert<vector<name>> ("cc.export.imp_libs");
// Hint variables (not overridable).
//
diff --git a/libbuild2/cxx/init.cxx b/libbuild2/cxx/init.cxx
index 49ed076..bb6653d 100644
--- a/libbuild2/cxx/init.cxx
+++ b/libbuild2/cxx/init.cxx
@@ -455,11 +455,13 @@ namespace build2
vp.insert<strings> ("cxx.export.coptions"),
vp.insert<strings> ("cxx.export.loptions"),
vp.insert<vector<name>> ("cxx.export.libs"),
+ vp.insert<vector<name>> ("cxx.export.imp_libs"),
vp["cc.export.poptions"],
vp["cc.export.coptions"],
vp["cc.export.loptions"],
vp["cc.export.libs"],
+ vp["cc.export.imp_libs"],
vp.insert<string> ("cxx.stdlib"),