From 1ada80642d06d8ef5144933178191eba262a1372 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 5 Sep 2016 14:54:27 +0200 Subject: Handle /usr/local brain-death --- build2/c/init.cxx | 2 ++ build2/cc/common | 6 +++++- build2/cc/compile.cxx | 23 +++++++++++++++++++++++ build2/cc/module.cxx | 40 +++++++++++++++++++++++++++++++--------- build2/cc/pkgconfig.cxx | 34 ++++++++++++++++++++++++++-------- build2/cxx/init.cxx | 2 ++ 6 files changed, 89 insertions(+), 18 deletions(-) diff --git a/build2/c/init.cxx b/build2/c/init.cxx index 503d942..750c729 100644 --- a/build2/c/init.cxx +++ b/build2/c/init.cxx @@ -135,6 +135,7 @@ namespace build2 v.insert ("c.path"), v.insert ("c.sys_lib_dirs"), + v.insert ("c.sys_inc_dirs"), v.insert ("c.poptions"), v.insert ("c.coptions"), @@ -243,6 +244,7 @@ namespace build2 cast_null (rs["pkgconfig.path"]), cast (rs[cm.x_sys_lib_dirs]), + cast (rs[cm.x_sys_inc_dirs]), c::static_type, hdr, diff --git a/build2/cc/common b/build2/cc/common index 6e042ee..49e6331 100644 --- a/build2/cc/common +++ b/build2/cc/common @@ -40,6 +40,7 @@ namespace build2 const variable& x_path; // Compiler process path. const variable& x_sys_lib_dirs; // System library search directories. + const variable& x_sys_inc_dirs; // Extra header search directories. const variable& x_poptions; const variable& x_coptions; @@ -105,6 +106,7 @@ namespace build2 const process_path* pkgconfig; // pkgconfig.path (can be NULL). const dir_paths& sys_lib_dirs; // x.sys_lib_dirs + const dir_paths& sys_inc_dirs; // x.sys_inc_dirs const target_type& x_src; // Source target type (c{}, cxx{}). @@ -144,6 +146,7 @@ namespace build2 const string& std, const process_path* pkgc, const dir_paths& sld, + const dir_paths& sid, const target_type& src, const target_type* const* hdr, const target_type* const* inc) @@ -153,7 +156,8 @@ namespace build2 x_install (install), x_uninstall (uninstall), cid (id), ctg (tg), tsys (ts), tclass (tc), - tstd (std), pkgconfig (pkgc), sys_lib_dirs (sld), + tstd (std), + pkgconfig (pkgc), sys_lib_dirs (sld), sys_inc_dirs (sid), x_src (src), x_hdr (hdr), x_inc (inc) {} }; diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx index fce5d21..a89555c 100644 --- a/build2/cc/compile.cxx +++ b/build2/cc/compile.cxx @@ -340,6 +340,12 @@ namespace build2 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) + cs.append (d.string ()); + hash_options (cs, t, c_coptions); hash_options (cs, t, x_coptions); hash_std (cs); @@ -731,6 +737,14 @@ namespace build2 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) + { + args.push_back ("-I"); + args.push_back (d.string ().c_str ()); + } + // Some compile options (e.g., -std, -m) affect the preprocessor. // append_options (args, t, c_coptions); @@ -1392,6 +1406,15 @@ namespace build2 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) + { + args.push_back ("-I"); + args.push_back (d.string ().c_str ()); + } + append_options (args, t, c_coptions); append_options (args, t, x_coptions); diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx index cb5650d..f619e5f 100644 --- a/build2/cc/module.cxx +++ b/build2/cc/module.cxx @@ -125,19 +125,33 @@ namespace build2 if (auto l = rs[x_std]) tstd = translate_std (ci, rs, cast (*l)); - // Extract system library search paths from the compiler. + // Extract system library search paths from the compiler and determine + // additional system include search paths. // - dir_paths lib_dirs (ci.id.type == "msvc" - ? msvc_library_search_paths (ci.path, rs) - : gcc_library_search_paths (ci.path, rs)); + dir_paths lib_dirs; + dir_paths inc_dirs; - // On FreeBSD /usr/local/lib is not one of the default search paths. - // Quoting its wiki: "FreeBSD can't even find libraries that it - // installed." So let's help it a bit. - // - if (tt.system == "freebsd") + if (ci.id.type == "msvc") + lib_dirs = msvc_library_search_paths (ci.path, rs); + else + { + lib_dirs = gcc_library_search_paths (ci.path, rs); + + // Many platforms don't search in /usr/local/lib by default (but do + // for headers in /usr/local/include). So add it as the last option. + // lib_dirs.push_back (dir_path ("/usr/local/lib")); + // FreeBSD is at least consistent: it searches in neither. Quoting its + // wiki: "FreeBSD can't even find libraries that it installed." So + // let's help it a bit. Note that we don't add it for all the + // platforms for good measure because this will actually appear as + // usually unnecessary noise on the command line. + // + if (tt.system == "freebsd") + inc_dirs.push_back (dir_path ("/usr/local/include")); + } + // If this is a new value (e.g., we are configuring), then print the // report at verbosity level 2 and up (-v). // @@ -180,6 +194,13 @@ namespace build2 dr << " pattern " << ci.cc_pattern << '\n'; } + if (verb >= 3 && !inc_dirs.empty ()) + { + dr << " inc dirs\n"; + for (const dir_path& d: inc_dirs) + dr << " " << d << '\n'; + } + if (verb >= 3 && !lib_dirs.empty ()) { dr << " lib dirs\n"; @@ -194,6 +215,7 @@ namespace build2 rs.assign (x_path) = move (ci.path); rs.assign (x_sys_lib_dirs) = move (lib_dirs); + rs.assign (x_sys_inc_dirs) = move (inc_dirs); rs.assign (x_id) = ci.id.string (); rs.assign (x_id_type) = move (ci.id.type); diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx index 8ab608a..23128e4 100644 --- a/build2/cc/pkgconfig.cxx +++ b/build2/cc/pkgconfig.cxx @@ -191,14 +191,27 @@ namespace build2 string cstr (extract ("--cflags", false)); strings pops; - bool arg (false); string o; + char arg ('\0'); for (size_t b (0), e (0); !(o = next (cstr, b, e)).empty (); ) { - if (arg) + // Filter out /usr/local/include since most platforms/compilers + // search in there (at the end, as in other system header + // directories) by default. And for those that don't (like FreeBSD) + // we should just fix it ourselves (see config_module::init ()). + // + // Failed that /usr/local/include may appear before "more specific" + // directories which can lead to the installed headers being picked + // up instead. + // + if (arg != '\0') { - pops.push_back (move (o)); - arg = false; + if (arg == 'I' && o == "/usr/local/include") + pops.pop_back (); + else + pops.push_back (move (o)); + + arg = '\0'; continue; } @@ -210,15 +223,20 @@ namespace build2 o[0] == '-' && (o[1] == 'I' || o[1] == 'D' || o[1] == 'U')) { - pops.push_back (move (o)); - arg = (n == 2); + if (!(n > 2 && + o[1] == 'I' && + o.compare (2, string::npos, "/usr/local/include") == 0)) + pops.push_back (move (o)); + + if (n == 2) + arg = o[1]; continue; } l4 ([&]{trace << "ignoring " << f << " --cflags option " << o;}); } - if (arg) + if (arg != '\0') fail << "argument expected after " << pops.back () << info << "while parsing pkg-config --cflags output of " << f; @@ -425,7 +443,7 @@ namespace build2 if (all && known) lops.clear (); - if (lops.empty ()) + if (!lops.empty ()) { if (cid == "msvc") { diff --git a/build2/cxx/init.cxx b/build2/cxx/init.cxx index de52b47..59d4cc6 100644 --- a/build2/cxx/init.cxx +++ b/build2/cxx/init.cxx @@ -135,6 +135,7 @@ namespace build2 v.insert ("cxx.path"), v.insert ("cxx.sys_lib_dirs"), + v.insert ("cxx.sys_inc_dirs"), v.insert ("cxx.poptions"), v.insert ("cxx.coptions"), @@ -250,6 +251,7 @@ namespace build2 cast_null (rs["pkgconfig.path"]), cast (rs[cm.x_sys_lib_dirs]), + cast (rs[cm.x_sys_inc_dirs]), cxx::static_type, hdr, -- cgit v1.1