aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-09-05 16:11:12 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-09-05 16:11:12 +0200
commitfae229bbcbc4f69fe8af58ad3e5f3305cca12a02 (patch)
tree141e3a4335d6449364636717135810edaf996abb
parent1ada80642d06d8ef5144933178191eba262a1372 (diff)
Change order in which library options are processed
The idea is that we want more "specialized" -I/-L options before more "generic" in order to make sure we don't pick up installed headers or libraries. This is still not bullet-proof though.
-rw-r--r--build2/cc/common.cxx141
-rw-r--r--build2/cc/compile.cxx22
2 files changed, 104 insertions, 59 deletions
diff --git a/build2/cc/common.cxx b/build2/cc/common.cxx
index c9b9108..911fbfa 100644
--- a/build2/cc/common.cxx
+++ b/build2/cc/common.cxx
@@ -37,6 +37,13 @@ namespace build2
// either from the target's path or from one of the *.libs variables
// neither of which should change on this run).
//
+ // Note that the order of processing is:
+ //
+ // 1. options
+ // 2. lib itself (if self is true)
+ // 3. dependency libs (prerequisite_targets)
+ // 4. dependency libs (*.libs variables).
+ //
void common::
process_libraries (
scope& top_bs,
@@ -55,45 +62,12 @@ namespace build2
bool exp)>& proc_opt, // *.export.
bool self /*= false*/) const // Call proc_lib on l?
{
- // Determine if an absolute path is to a system library. Note that
- // we assume both paths to be normalized.
- //
- auto sys = [] (const dir_paths& sysd, const string& p) -> bool
- {
- size_t pn (p.size ());
-
- for (const dir_path& d: sysd)
- {
- const string& ds (d.string ()); // Can be "/", otherwise no slash.
- size_t dn (ds.size ());
-
- if (pn > dn &&
- p.compare (0, dn, ds) == 0 &&
- (path::traits::is_separator (ds[dn - 1]) ||
- path::traits::is_separator (p[dn])))
- return true;
- }
-
- return false;
- };
-
// See what type of library this is (C, C++, etc). Use it do decide
// which x.libs variable name to use. If it's unknown, then we only
// look into prerequisites.
//
const string* t (cast_null<string> (l.vars[c_type]));
- if (self && proc_lib)
- {
- const string& p (l.path ().string ());
-
- bool s (t != nullptr // If cc library (matched or imported).
- ? cast_false<bool> (l.vars[c_system])
- : sys (top_sysd, p));
-
- proc_lib (&l, p, s);
- }
-
bool impl (proc_impl && proc_impl (l, la));
bool cc (false), same (false);
@@ -128,6 +102,85 @@ namespace build2
else if (l.group != nullptr) // lib{} group.
x_e_libs = l.group->vars[var];
}
+
+ // Process options first.
+ //
+ if (proc_opt)
+ {
+ // If all we know is it's a C-common library, then in both cases we
+ // only look for cc.export.*.
+ //
+ if (cc)
+ proc_opt (l, *t, true, true);
+ else
+ {
+ if (impl)
+ {
+ // Interface and implementation: as discussed above, we can have
+ // two situations: overriden export or default export.
+ //
+ if (c_e_libs.defined () || x_e_libs.defined ())
+ {
+ // NOTE: should this not be from l.vars rather than l? Or
+ // perhaps we can assume non-common values will be set on
+ // libs{}/liba{}.
+ //
+ proc_opt (l, *t, true, true);
+ proc_opt (l, *t, false, true);
+ }
+ else
+ {
+ // For default export we use the same options as were used to
+ // build the library.
+ //
+ proc_opt (l, *t, true, false);
+ proc_opt (l, *t, false, false);
+ }
+ }
+ else
+ {
+ // Interface: only add *.export.* (interface dependencies).
+ //
+ proc_opt (l, *t, true, true);
+ proc_opt (l, *t, false, true);
+ }
+ }
+ }
+ }
+
+ // Determine if an absolute path is to a system library. Note that
+ // we assume both paths to be normalized.
+ //
+ auto sys = [] (const dir_paths& sysd, const string& p) -> bool
+ {
+ size_t pn (p.size ());
+
+ for (const dir_path& d: sysd)
+ {
+ const string& ds (d.string ()); // Can be "/", otherwise no slash.
+ size_t dn (ds.size ());
+
+ if (pn > dn &&
+ p.compare (0, dn, ds) == 0 &&
+ (path::traits::is_separator (ds[dn - 1]) ||
+ path::traits::is_separator (p[dn])))
+ return true;
+ }
+
+ return false;
+ };
+
+ // Next process the library itself if requested.
+ //
+ if (self && proc_lib)
+ {
+ const string& p (l.path ().string ());
+
+ bool s (t != nullptr // If cc library (matched or imported).
+ ? cast_false<bool> (l.vars[c_system])
+ : sys (top_sysd, p));
+
+ proc_lib (&l, p, s);
}
scope& bs (t == nullptr || cc ? top_bs : l.base_scope ());
@@ -279,12 +332,13 @@ 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.
//
if (cc)
{
- if (proc_opt) proc_opt (l, *t, true, true);
if (c_e_libs) proc_int (c_e_libs);
}
else
@@ -296,13 +350,7 @@ namespace build2
//
if (c_e_libs.defined () || x_e_libs.defined ())
{
- // NOTE: should this not be from l.vars rather than l? Or perhaps
- // we can assume non-common values will be set on libs{}/liba{}.
- //
- if (proc_opt) proc_opt (l, *t, true, true);
if (c_e_libs) proc_int (c_e_libs);
-
- if (proc_opt) proc_opt (l, *t, false, true);
if (x_e_libs) proc_int (x_e_libs);
}
else
@@ -311,21 +359,18 @@ namespace build2
// build the library. Since libraries in (non-export) *.libs are
// not targets, we don't need to recurse.
//
- if (proc_opt) proc_opt (l, *t, true, false);
- if (proc_lib) proc_imp (l[c_libs]);
-
- if (proc_opt) proc_opt (l, *t, false, false);
- if (proc_lib) proc_imp (l[same ? x_libs : vp[*t + ".libs"]]);
+ if (proc_lib)
+ {
+ proc_imp (l[c_libs]);
+ proc_imp (l[same ? x_libs : vp[*t + ".libs"]]);
+ }
}
}
else
{
// Interface: only add *.export.* (interface dependencies).
//
- if (proc_opt) proc_opt (l, *t, true, true);
if (c_e_libs) proc_int (c_e_libs);
-
- if (proc_opt) proc_opt (l, *t, false, true);
if (x_e_libs) proc_int (x_e_libs);
}
}
diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx
index a89555c..6fd6f16 100644
--- a/build2/cc/compile.cxx
+++ b/build2/cc/compile.cxx
@@ -334,13 +334,13 @@ namespace build2
//
sha256 cs;
+ hash_options (cs, t, c_poptions);
+ hash_options (cs, t, x_poptions);
+
// Hash *.export.poptions from prerequisite libraries.
//
hash_lib_options (cs, t, bs, lo);
- hash_options (cs, t, c_poptions);
- hash_options (cs, t, x_poptions);
-
// Extra system header dirs (last).
//
for (const dir_path& d: sys_inc_dirs)
@@ -514,15 +514,15 @@ namespace build2
{
prefix_map m;
- // First process the include directories from prerequisite libraries.
- //
- append_lib_prefixes (m, t, bs, lo);
-
- // Then process our own.
+ // First process our own.
//
append_prefixes (m, t, c_poptions);
append_prefixes (m, t, x_poptions);
+ // Then process the include directories from prerequisite libraries.
+ //
+ append_lib_prefixes (m, t, bs, lo);
+
return m;
}
@@ -1400,13 +1400,13 @@ namespace build2
path relo (relative (t.path ()));
path rels (relative (s->path ()));
+ append_options (args, t, c_poptions);
+ append_options (args, t, x_poptions);
+
// Add *.export.poptions from prerequisite libraries.
//
append_lib_options (args, t, bs, lo);
- append_options (args, t, c_poptions);
- append_options (args, t, x_poptions);
-
// Extra system header dirs (last).
//
for (const dir_path& d: sys_inc_dirs)