aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-10-04 10:27:55 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-10-04 10:27:55 +0200
commite1a1d978d364c723935acfc7b56fae8b8253d054 (patch)
tree02b9bdac94800c7d29b40584f7a135f220cd22df
parentdb8336a686a85f0e458acb2d5f1ad442585bfc9a (diff)
Add support for treating specific libraries as always internal
-rw-r--r--libbuild2/c/init.cxx6
-rw-r--r--libbuild2/cc/common.hxx6
-rw-r--r--libbuild2/cc/compile-rule.cxx33
-rw-r--r--libbuild2/cc/init.cxx1
-rw-r--r--libbuild2/cxx/init.cxx38
5 files changed, 76 insertions, 8 deletions
diff --git a/libbuild2/c/init.cxx b/libbuild2/c/init.cxx
index 9a62a5e..01b9ae7 100644
--- a/libbuild2/c/init.cxx
+++ b/libbuild2/c/init.cxx
@@ -202,7 +202,8 @@ namespace build2
vp.insert<strings> ("c.aoptions"),
vp.insert<strings> ("c.libs"),
- vp.insert<string> ("c.internal.scope"),
+ vp.insert<string> ("c.internal.scope"),
+ vp.insert<strings> ("c.internal.libs"),
nullptr /* c.translate_include */,
@@ -365,6 +366,9 @@ namespace build2
cm.internal_scope,
cm.internal_scope_current,
+ cast_null<strings> (rs["cc.internal.libs"]),
+ cast_null<strings> (rs[cm.x_internal_libs]),
+
cast<dir_paths> (rs[cm.x_sys_lib_dirs]),
cast<dir_paths> (rs[cm.x_sys_hdr_dirs]),
cm.x_info->sys_mod_dirs ? &cm.x_info->sys_mod_dirs->first : nullptr,
diff --git a/libbuild2/cc/common.hxx b/libbuild2/cc/common.hxx
index a3cd6b6..6e36f8e 100644
--- a/libbuild2/cc/common.hxx
+++ b/libbuild2/cc/common.hxx
@@ -81,6 +81,7 @@ namespace build2
const variable& x_aoptions;
const variable& x_libs;
const variable& x_internal_scope;
+ const variable& x_internal_libs;
const variable* x_translate_include;
const variable& c_poptions; // cc.*
@@ -182,6 +183,9 @@ namespace build2
const string* internal_scope; // x.internal.scope
const scope* internal_scope_current;
+ const strings* c_internal_libs; // cc.internal.libs
+ const strings* x_internal_libs; // x.internal.libs
+
const scope*
effective_internal_scope (const scope& bs) const;
@@ -247,6 +251,7 @@ namespace build2
bool fm,
bool fs,
const string* ints, const scope* intsc,
+ const strings* cils, const strings* xils,
const dir_paths& sld,
const dir_paths& shd,
const dir_paths* smd,
@@ -270,6 +275,7 @@ namespace build2
modules (fm),
symexport (fs),
internal_scope (ints), internal_scope_current (intsc),
+ c_internal_libs (cils), x_internal_libs (xils),
importable_headers (nullptr),
sys_lib_dirs (sld), sys_hdr_dirs (shd), sys_mod_dirs (smd),
sys_lib_dirs_mode (slm), sys_hdr_dirs_mode (shm),
diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx
index 7636722..9149f0c 100644
--- a/libbuild2/cc/compile-rule.cxx
+++ b/libbuild2/cc/compile-rule.cxx
@@ -6,6 +6,8 @@
#include <cstdlib> // exit()
#include <cstring> // strlen(), strchr(), strncmp()
+#include <libbutl/path-pattern.hxx>
+
#include <libbuild2/file.hxx>
#include <libbuild2/depdb.hxx>
#include <libbuild2/scope.hxx>
@@ -503,14 +505,33 @@ namespace build2
if (const strings* ops = cast_null<strings> (l[var]))
{
+ // If enabled, remap -I to -isystem or /external:I for paths that
+ // are outside of the internal scope provided the library is not
+ // whitelisted.
+ //
+ auto whitelist = [&l] (const strings* pats)
+ {
+ return (pats != nullptr &&
+ find_if (pats->begin (), pats->end (),
+ [&l] (const string& pat)
+ {
+ return path_match (l.name, pat);
+ }) != pats->end ());
+ };
+
+ const scope* is (d.is);
+
+ if (is != nullptr && whitelist (c_internal_libs))
+ is = nullptr;
+
+ if (is != nullptr && whitelist (x_internal_libs))
+ is = nullptr;
+
for (auto i (ops->begin ()), e (ops->end ()); i != e; ++i)
{
const string& o (*i);
- // If enabled, remap -I to -isystem or /external:I for paths that
- // are outside of the internal scope.
- //
- if (d.is != nullptr)
+ if (is != nullptr)
{
// See if this is -I<dir> or -I <dir> (or /I... for MSVC).
//
@@ -587,8 +608,8 @@ namespace build2
// Translate if it's neither in src nor in out of the
// internal scope.
//
- if (!sub (d.is->src_path ()) &&
- (d.is->out_eq_src () || !sub (d.is->out_path ())))
+ if (!sub (is->src_path ()) &&
+ (is->out_eq_src () || !sub (is->out_path ())))
{
// Note: must use original value (path is temporary).
//
diff --git a/libbuild2/cc/init.cxx b/libbuild2/cc/init.cxx
index 769f6bb..affc4ab 100644
--- a/libbuild2/cc/init.cxx
+++ b/libbuild2/cc/init.cxx
@@ -105,6 +105,7 @@ namespace build2
vp.insert<strings> ("cc.aoptions");
vp.insert<strings> ("cc.libs");
vp.insert<string> ("cc.internal.scope");
+ vp.insert<strings> ("cc.internal.libs");
vp.insert<strings> ("cc.export.poptions");
vp.insert<strings> ("cc.export.coptions");
diff --git a/libbuild2/cxx/init.cxx b/libbuild2/cxx/init.cxx
index a10fc5c..0f99c3a 100644
--- a/libbuild2/cxx/init.cxx
+++ b/libbuild2/cxx/init.cxx
@@ -560,6 +560,38 @@ namespace build2
// project (which acts as a bundle amalgamation), unless it is being
// built out of source (for example, to test an installed library).
//
+ // A project can also whitelist specific libraries using the
+ // cxx.internal.libs variable. If a library target name (that is, the
+ // name inside lib{}) matches any of the wildcard patterns listed in
+ // this variable, then the library is considered internal regardless
+ // of its location. For example (notice that the pattern is quoted):
+ //
+ // # root.build
+ //
+ // cxx.internal.scope = current
+ // cxx.internal.libs = foo 'bar-*'
+ //
+ // using cxx
+ //
+ // Note that this variable should also be set before loading the
+ // cxx module and there is the common cc.internal.libs equivalent.
+ // However, there are no config.* versions nor the override by the
+ // bundle amalgamation semantics.
+ //
+ // Typically you would want to whitelist libraries that are developed
+ // together but reside in separate build system projects. In
+ // particular, a separate *-tests project for a library should
+ // whitelist the library being tested if the internal scope
+ // functionality is in use. Another reason to whitelist is to catch
+ // warnings in instantiations of templates that belong to a library
+ // that is otherwise warning-free (see the MSVC /external:templates-
+ // option for details).
+ //
+ // Note also that if multiple libraries are installed into the same
+ // location (or otherwise share the same header search paths, for
+ // example, as a family of libraries), then the whitelist may not
+ // be effective.
+ //
vp.insert<string> ("config.cxx.internal.scope"),
// Headers and header groups whose inclusion should or should not be
@@ -614,7 +646,8 @@ namespace build2
vp.insert<strings> ("cxx.aoptions"),
vp.insert<strings> ("cxx.libs"),
- vp.insert<string> ("cxx.internal.scope"),
+ vp.insert<string> ("cxx.internal.scope"),
+ vp.insert<strings> ("cxx.internal.libs"),
&vp.insert<cc::translatable_headers> ("cxx.translate_include"),
@@ -811,6 +844,9 @@ namespace build2
cm.internal_scope,
cm.internal_scope_current,
+ cast_null<strings> (rs["cc.internal.libs"]),
+ cast_null<strings> (rs[cm.x_internal_libs]),
+
cast<dir_paths> (rs[cm.x_sys_lib_dirs]),
cast<dir_paths> (rs[cm.x_sys_hdr_dirs]),
cm.x_info->sys_mod_dirs ? &cm.x_info->sys_mod_dirs->first : nullptr,