diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2016-08-22 12:55:21 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2016-08-22 12:55:21 +0200 |
commit | 48e2e4140b8e5aacdfd107a1215f21c9632c81c8 (patch) | |
tree | 7897b62300a433533318be5de14f9ba0745da4d8 /build2/cc | |
parent | 3b6f882ce0dae1d80a330b36a63fbe65026a3278 (diff) |
Cache process_path, use fallback search directory for binutils
Diffstat (limited to 'build2/cc')
-rw-r--r-- | build2/cc/common | 1 | ||||
-rw-r--r-- | build2/cc/compile.cxx | 14 | ||||
-rw-r--r-- | build2/cc/guess | 6 | ||||
-rw-r--r-- | build2/cc/guess.cxx | 49 | ||||
-rw-r--r-- | build2/cc/link | 8 | ||||
-rw-r--r-- | build2/cc/link.cxx | 27 | ||||
-rw-r--r-- | build2/cc/module.cxx | 3 | ||||
-rw-r--r-- | build2/cc/msvc.cxx | 16 |
8 files changed, 86 insertions, 38 deletions
diff --git a/build2/cc/common b/build2/cc/common index 2be290a..987fe7b 100644 --- a/build2/cc/common +++ b/build2/cc/common @@ -36,6 +36,7 @@ namespace build2 const variable& config_x_loptions; const variable& config_x_libs; + const variable& x_path; const variable& x_poptions; const variable& x_coptions; const variable& x_loptions; diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx index 92ddf3b..33be687 100644 --- a/build2/cc/compile.cxx +++ b/build2/cc/compile.cxx @@ -644,12 +644,14 @@ namespace build2 // Initialize lazily, only if required. // + const process_path* xc (nullptr); cstrings args; string std; // Storage. - auto init_args = [&t, lo, &src, &rs, &args, &std, this] () + auto init_args = [&t, lo, &src, &rs, &xc, &args, &std, this] () { - args.push_back (cast<path> (rs[config_x]).string ().c_str ()); + xc = &cast<process_path> (rs[x_path]); + args.push_back (xc->recall_string ()); // Add *.export.poptions from prerequisite libraries. Note that here // we don't need to see group members (see apply()). @@ -1034,7 +1036,8 @@ namespace build2 // For VC with /EP we need a pipe to stderr and stdout should go // to /dev/null. // - process pr (args.data (), + process pr (*xc, + args.data (), 0, cid == "msvc" ? -2 : -1, cid == "msvc" ? -1 : 2); @@ -1261,7 +1264,8 @@ namespace build2 scope& rs (*bs.root_scope ()); otype ct (compile_type (t)); - cstrings args {cast<path> (rs[config_x]).string ().c_str ()}; + const process_path& xc (cast<process_path> (rs[x_path])); + cstrings args {xc.recall_string ()}; // Translate paths to relative (to working directory) ones. This // results in easier to read diagnostics. @@ -1418,7 +1422,7 @@ namespace build2 // bool filter (cid == "msvc"); - process pr (args.data (), 0, (filter ? -1 : 2)); + process pr (xc, args.data (), 0, (filter ? -1 : 2)); if (filter) { diff --git a/build2/cc/guess b/build2/cc/guess index d852a5c..c49fb4f 100644 --- a/build2/cc/guess +++ b/build2/cc/guess @@ -100,10 +100,14 @@ namespace build2 // derived for some toolchains. For example, i686-w64-mingw32-*-4.9. // // The bin_pattern is the binutils program pattern that could sometimes be - // derived for some toolchains. For example, i686-w64-mingw32-*. + // derived for some toolchains. For example, i686-w64-mingw32-*. If the + // pattern could not be derived, then it could contain a fallback search + // directory, in which case it will end with a directory separator but + // will not contain '*'. // struct compiler_info { + process_path path; compiler_id id; compiler_version version; string signature; diff --git a/build2/cc/guess.cxx b/build2/cc/guess.cxx index 5001879..c2b552a 100644 --- a/build2/cc/guess.cxx +++ b/build2/cc/guess.cxx @@ -105,6 +105,11 @@ namespace build2 compiler_id id; string signature; string checksum; + process_path path; + + guess_result () = default; + guess_result (compiler_id&& i, string&& s) + : id (move (i)), signature (move (s)) {} bool empty () const {return id.empty ();} @@ -117,6 +122,8 @@ namespace build2 guess_result r; + process_path pp (run_search (xc, true)); + // Start with -v. This will cover gcc and clang. // // While icc also writes what may seem like something we can use to @@ -152,7 +159,7 @@ namespace build2 // gcc version 6.0.0 20160131 (experimental) (GCC) // if (l.compare (0, 4, "gcc ") == 0) - return guess_result {{"gcc", ""}, move (l), ""}; + return guess_result (compiler_id {"gcc", ""}, move (l)); // The Apple clang/clang++ -v output will have a line (currently // first) in the form: @@ -182,7 +189,7 @@ namespace build2 if (l.compare (0, 6, "Apple ") == 0 && (l.compare (6, 5, "LLVM ") == 0 || l.compare (6, 6, "clang ") == 0)) - return guess_result {{"clang", "apple"}, move (l), ""}; + return guess_result (compiler_id {"clang", "apple"}, move (l)); // The vanilla clang/clang++ -v output will have a line (currently // first) in the form: @@ -197,7 +204,7 @@ namespace build2 // clang version 3.7.0 (tags/RELEASE_370/final) // if (l.find ("clang ") != string::npos) - return guess_result {{"clang", ""}, move (l), ""}; + return guess_result (compiler_id {"clang", ""}, move (l)); return guess_result (); }; @@ -216,7 +223,7 @@ namespace build2 // Suppress all the compiler errors because we may be trying an // unsupported option. // - r = run<guess_result> (xc, "-v", f, false, false, &cs); + r = run<guess_result> (pp, "-v", f, false, false, &cs); if (!r.empty ()) r.checksum = cs.string (); @@ -239,12 +246,12 @@ namespace build2 // icc (ICC) 16.0.2 20160204 // if (l.find (" (ICC) ") != string::npos) - return guess_result {{"icc", ""}, move (l), ""}; + return guess_result (compiler_id {"icc", ""}, move (l)); return guess_result (); }; - r = run<guess_result> (xc, "--version", f, false); + r = run<guess_result> (pp, "--version", f, false); } // Finally try to run it without any options to detect msvc. @@ -271,12 +278,12 @@ namespace build2 // if (l.find ("Microsoft (R)") != string::npos && l.find ("C/C++") != string::npos) - return guess_result {{"msvc", ""}, move (l), ""}; + return guess_result (compiler_id {"msvc", ""}, move (l)); return guess_result (); }; - r = run<guess_result> (xc, f, false); + r = run<guess_result> (pp, f, false); } if (!r.empty ()) @@ -290,8 +297,12 @@ namespace build2 r = guess_result (); } else + { l5 ([&]{trace << xc << " is " << r.id << ": '" << r.signature << "'";}); + + r.path = move (pp); + } } else l4 ([&]{trace << "unable to determine compiler type of " << xc;}); @@ -463,6 +474,7 @@ namespace build2 pat = pattern (xc, xl == lang::c ? "cc" : "c++"); return compiler_info { + move (gr.path), move (gr.id), move (v), move (gr.signature), @@ -579,6 +591,7 @@ namespace build2 pat = pattern (xc, xl == lang::c ? "cc" : "c++"); return compiler_info { + move (gr.path), move (gr.id), move (v), move (gr.signature), @@ -798,6 +811,7 @@ namespace build2 sha256 cs (s); return compiler_info { + move (gr.path), move (gr.id), move (v), move (gr.signature), @@ -1011,6 +1025,7 @@ namespace build2 sha256 cs (s); return compiler_info { + move (gr.path), move (gr.id), move (v), move (gr.signature), @@ -1075,11 +1090,12 @@ namespace build2 // Derive binutils pattern unless this has already been done by the // compiler-specific code. // + + // When cross-compiling the whole toolchain is normally prefixed with + // the target triplet, e.g., x86_64-w64-mingw32-{gcc,g++,ar,ld}. + // if (r.bin_pattern.empty ()) { - // When cross-compiling the whole toolchain is normally prefixed with - // the target triplet, e.g., x86_64-w64-mingw32-{gcc,g++,ar,ld}. - // // BTW, for GCC we also get gcc-{ar,ranlib} which add support for the // LTO plugin though it seems more recent GNU binutils (2.25) are able // to load the plugin when needed automatically. So it doesn't seem we @@ -1103,6 +1119,17 @@ namespace build2 } } + // If we could not derive the pattern, then see if we can come up with a + // fallback search directory. + // + if (r.bin_pattern.empty ()) + { + const path& p (r.path.recall.empty () ? xc : r.path.recall); + + if (!p.simple ()) + r.bin_pattern = p.directory ().representation (); // Trailing slash. + } + return r; } diff --git a/build2/cc/link b/build2/cc/link index 8be386f..f6a16c0 100644 --- a/build2/cc/link +++ b/build2/cc/link @@ -56,10 +56,14 @@ namespace build2 // Alternative search logic for VC (msvc.cxx). // bin::liba* - msvc_search_static (const path&, const dir_path&, prerequisite&) const; + msvc_search_static (const process_path&, + const dir_path&, + prerequisite&) const; bin::libs* - msvc_search_shared (const path&, const dir_path&, prerequisite&) const; + msvc_search_shared (const process_path&, + const dir_path&, + prerequisite&) const; target* search_library (optional<dir_paths>&, prerequisite&) const; diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx index 61dd0ad..7a6b059 100644 --- a/build2/cc/link.cxx +++ b/build2/cc/link.cxx @@ -420,7 +420,7 @@ namespace build2 if (cid == "msvc") { scope& rs (*p.scope.root_scope ()); - const path& ld (cast<path> (rs["config.bin.ld"])); + const process_path& ld (cast<process_path> (rs["bin.ld.path"])); if (s == nullptr && !sn.empty ()) s = msvc_search_shared (ld, d, p); @@ -1135,10 +1135,12 @@ namespace build2 { path of (relative (manifest)); + const process_path& rc (cast<process_path> (rs["bin.rc.path"])); + // @@ Would be good to add this to depdb (e.g,, rc changes). // const char* args[] = { - cast<path> (rs["config.bin.rc"]).string ().c_str (), + rc.recall_string (), "--input-format=rc", "--output-format=coff", "-o", of.string ().c_str (), @@ -1149,7 +1151,7 @@ namespace build2 try { - process pr (args, -1); + process pr (rc, args, -1); try { @@ -1224,7 +1226,7 @@ namespace build2 // if (lt == otype::a) { - ranlib = rs["config.bin.ranlib"]; + ranlib = rs["bin.ranlib.path"]; if (ranlib && ranlib->empty ()) // @@ BC LT [null]. ranlib = lookup (); @@ -1481,11 +1483,12 @@ namespace build2 // path relt (relative (t.path ())); + const process_path* ld (nullptr); switch (lt) { case otype::a: { - args[0] = cast<path> (rs["config.bin.ar"]).string ().c_str (); + ld = &cast<process_path> (rs["bin.ar.path"]); if (cid == "msvc") { @@ -1516,7 +1519,7 @@ namespace build2 { // Using link.exe directly. // - args[0] = cast<path> (rs["config.bin.ld"]).string ().c_str (); + ld = &cast<process_path> (rs["bin.ld.path"]); args.push_back ("/NOLOGO"); if (lt == otype::s) @@ -1608,7 +1611,7 @@ namespace build2 } else { - args[0] = cast<path> (rs[config_x]).string ().c_str (); + ld = &cast<process_path> (rs[x_path]); // Add the option that triggers building a shared library and take // care of any extras (e.g., import library). @@ -1639,6 +1642,8 @@ namespace build2 } } + args[0] = ld->recall_string (); + for (target* pt: t.prerequisite_targets) { file* f; @@ -1709,7 +1714,7 @@ namespace build2 // bool filter (cid == "msvc" && lt != otype::a); - process pr (args.data (), 0, (filter ? -1 : 2)); + process pr (*ld, args.data (), 0, (filter ? -1 : 2)); if (filter) { @@ -1756,8 +1761,10 @@ namespace build2 if (ranlib) { + const process_path& rl (cast<process_path> (ranlib)); + const char* args[] = { - cast<path> (ranlib).string ().c_str (), + rl.recall_string (), relt.string ().c_str (), nullptr}; @@ -1766,7 +1773,7 @@ namespace build2 try { - process pr (args); + process pr (rl, args); if (!pr.wait ()) throw failed (); diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx index d3849e1..4926fac 100644 --- a/build2/cc/module.cxx +++ b/build2/cc/module.cxx @@ -105,7 +105,7 @@ namespace build2 { dr << x << ' ' << project (r) << '@' << r.out_path () << '\n' - << " " << left << setw (11) << x << xc << '\n' + << " " << left << setw (11) << x << ci.path << '\n' << " id " << ci.id << '\n' << " version " << ci.version.string << '\n' << " major " << ci.version.major << '\n' @@ -129,6 +129,7 @@ namespace build2 } } + r.assign (x_path) = move (ci.path); r.assign (x_id) = ci.id.string (); r.assign (x_id_type) = move (ci.id.type); r.assign (x_id_variant) = move (ci.id.variant); diff --git a/build2/cc/msvc.cxx b/build2/cc/msvc.cxx index 84020d0..84f5853 100644 --- a/build2/cc/msvc.cxx +++ b/build2/cc/msvc.cxx @@ -105,7 +105,7 @@ namespace build2 // Return otype::e if it is neither (which we quietly ignore). // static otype - library_type (const path& ld, const path& l) + library_type (const process_path& ld, const path& l) { // The are several reasonably reliable methods to tell whether it is a // static or import library. One is lib.exe /LIST -- if there aren't any @@ -125,7 +125,7 @@ namespace build2 // for libraries then we have bin.ld. So we will use the link.exe /DUMP // /ARCHIVEMEMBERS. // - const char* args[] = {ld.string ().c_str (), + const char* args[] = {ld.recall_string (), "/DUMP", // Must come first. "/NOLOGO", "/ARCHIVEMEMBERS", @@ -135,7 +135,7 @@ namespace build2 // Link.exe seem to always dump everything to stdout but just in case // redirect stderr to stdout. // - process pr (start_run (args, false)); + process pr (run_start (ld, args, false)); bool obj (false), dll (false); string s; @@ -192,11 +192,11 @@ namespace build2 } catch (const ifdstream::failure&) { - // Presumably the child process failed. Let finish_run() deal with + // Presumably the child process failed. Let run_finish() deal with // that. } - if (!finish_run (args, false, pr, s)) + if (!run_finish (args, false, pr, s)) return otype::e; if (obj && dll) @@ -217,7 +217,7 @@ namespace build2 template <typename T> static T* msvc_search_library (const char* mod, - const path& ld, + const process_path& ld, const dir_path& d, prerequisite& p, otype lt, @@ -275,7 +275,7 @@ namespace build2 } liba* link:: - msvc_search_static (const path& ld, + msvc_search_static (const process_path& ld, const dir_path& d, prerequisite& p) const { @@ -302,7 +302,7 @@ namespace build2 } libs* link:: - msvc_search_shared (const path& ld, + msvc_search_shared (const process_path& ld, const dir_path& d, prerequisite& p) const { |