diff options
-rw-r--r-- | libbuild2/c/init.cxx | 6 | ||||
-rw-r--r-- | libbuild2/cc/common.hxx | 6 | ||||
-rw-r--r-- | libbuild2/cc/compile-rule.cxx | 33 | ||||
-rw-r--r-- | libbuild2/cc/init.cxx | 1 | ||||
-rw-r--r-- | libbuild2/cxx/init.cxx | 38 |
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, |