diff options
-rw-r--r-- | build2/cc/compile-rule.cxx | 8 | ||||
-rw-r--r-- | build2/cc/module.cxx | 50 | ||||
-rw-r--r-- | build2/cxx/init.cxx | 6 |
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), |