aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/cc/compile-rule.cxx8
-rw-r--r--build2/cc/module.cxx50
-rw-r--r--build2/cxx/init.cxx6
3 files changed, 53 insertions, 11 deletions
diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx
index dd38945..794b64e 100644
--- a/build2/cc/compile-rule.cxx
+++ b/build2/cc/compile-rule.cxx
@@ -2005,7 +2005,13 @@ namespace build2
//
if (const strings* ih = import_hdr)
{
- auto i (lower_bound (ih->begin (), ih->end (), hp));
+ auto i (lower_bound (ih->begin (),
+ ih->end (),
+ hp,
+ [] (const string& x, const string& y)
+ {
+ return path::traits::compare (x, y) < 0;
+ }));
if (i != ih->end () && *i == hp)
{
diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx
index 20e39a8..1e3806a 100644
--- a/build2/cc/module.cxx
+++ b/build2/cc/module.cxx
@@ -290,8 +290,8 @@ namespace build2
//
tstd = translate_std (ci, rs, cast_null<string> (rs[x_std]));
- // Extract system library search paths from the compiler and determine
- // additional system include search paths.
+ // Extract system header/library search paths from the compiler and
+ // determine if we need any additional search paths.
//
dir_paths lib_dirs;
dir_paths inc_dirs;
@@ -506,17 +506,53 @@ namespace build2
// Process, sort, and cache (in this->import_hdr) importable headers.
// Keep the cache NULL if unused or empty.
//
- // @@ MODHDR TODO: translate <> to absolute paths.
// @@ MODHDR TODO: support exclusions entries (e.g., -<stdio.h>)?
//
if (modules && x_importable_headers != nullptr)
{
- strings* v (cast_null<strings> (rs.assign (x_importable_headers)));
+ strings* ih (cast_null<strings> (rs.assign (x_importable_headers)));
- if (v != nullptr && !v->empty ())
+ if (ih != nullptr && !ih->empty ())
{
- sort (v->begin (), v->end ());
- import_hdr = v;
+ // Translate <>-style header names to absolute paths using the
+ // compiler's include search paths.
+ //
+ for (string& h: *ih)
+ {
+ if (h.empty () || h.front () != '<' || h.back () != '>')
+ continue;
+
+ h.pop_back ();
+ h.erase (0, 1);
+
+ path f; // Reuse the buffer.
+ bool r (false);
+ for (const dir_path& d: sys_inc_dirs)
+ {
+ if ((r = file_exists ((f = d, f /= h),
+ true /* follow_symlinks */,
+ true /* ignore_errors */)))
+ {
+ h = move (f.normalize ()).string ();
+ break;
+ }
+ }
+
+ // What should we do if not found? While we can fail, this could
+ // be too drastic if, for example, the header is "optional" and
+ // may or may not be present/used. So for now let's restore the
+ // original form to aid debugging (it can't possibly match any
+ // absolute path).
+ //
+ if (!r)
+ {
+ h.insert (0, 1, '<');
+ h.push_back ('>');
+ }
+ }
+
+ sort (ih->begin (), ih->end ());
+ import_hdr = ih;
}
}
diff --git a/build2/cxx/init.cxx b/build2/cxx/init.cxx
index a04a30a..2491d90 100644
--- a/build2/cxx/init.cxx
+++ b/build2/cxx/init.cxx
@@ -399,9 +399,9 @@ namespace build2
//
// A header can be specified either as an absolute and normalized path
// or as a <>-style include name. The latter kind is automatically
- // translated to the absolute form based on the include search paths
- // extracted from the compiler. Note also that all entries must be
- // specified before loading the cxx module.
+ // translated to the absolute form based on the compiler's system
+ // header search paths (as opposed to -I). Note also that all entries
+ // must be specified before loading the cxx module.
//
&v.insert<strings> ("config.cxx.importable_headers", true),