aboutsummaryrefslogtreecommitdiff
path: root/build2/cc
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-08-22 12:55:21 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-08-22 12:55:21 +0200
commit48e2e4140b8e5aacdfd107a1215f21c9632c81c8 (patch)
tree7897b62300a433533318be5de14f9ba0745da4d8 /build2/cc
parent3b6f882ce0dae1d80a330b36a63fbe65026a3278 (diff)
Cache process_path, use fallback search directory for binutils
Diffstat (limited to 'build2/cc')
-rw-r--r--build2/cc/common1
-rw-r--r--build2/cc/compile.cxx14
-rw-r--r--build2/cc/guess6
-rw-r--r--build2/cc/guess.cxx49
-rw-r--r--build2/cc/link8
-rw-r--r--build2/cc/link.cxx27
-rw-r--r--build2/cc/module.cxx3
-rw-r--r--build2/cc/msvc.cxx16
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
{