aboutsummaryrefslogtreecommitdiff
path: root/build2/bin
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/bin
parent3b6f882ce0dae1d80a330b36a63fbe65026a3278 (diff)
Cache process_path, use fallback search directory for binutils
Diffstat (limited to 'build2/bin')
-rw-r--r--build2/bin/guess10
-rw-r--r--build2/bin/guess.cxx81
-rw-r--r--build2/bin/init.cxx83
3 files changed, 111 insertions, 63 deletions
diff --git a/build2/bin/guess b/build2/bin/guess
index 540e644..bcf9732 100644
--- a/build2/bin/guess
+++ b/build2/bin/guess
@@ -30,10 +30,12 @@ namespace build2
//
struct ar_info
{
+ process_path ar_path;
string ar_id;
string ar_signature;
string ar_checksum;
+ process_path ranlib_path;
string ranlib_id;
string ranlib_signature;
string ranlib_checksum;
@@ -43,7 +45,7 @@ namespace build2
// attemplated and the returned ranlib_* members will be left empty.
//
ar_info
- guess_ar (const path& ar, const path* ranlib);
+ guess_ar (const path& ar, const path* ranlib, const dir_path& fallback);
// ld information.
//
@@ -67,13 +69,14 @@ namespace build2
//
struct ld_info
{
+ process_path path;
string id;
string signature;
string checksum;
};
ld_info
- guess_ld (const path& ld);
+ guess_ld (const path& ld, const dir_path& fallback);
// rc information.
//
@@ -90,13 +93,14 @@ namespace build2
//
struct rc_info
{
+ process_path path;
string id;
string signature;
string checksum;
};
rc_info
- guess_rc (const path& rc);
+ guess_rc (const path& rc, const dir_path& fallback);
}
}
diff --git a/build2/bin/guess.cxx b/build2/bin/guess.cxx
index de91db3..13f3933 100644
--- a/build2/bin/guess.cxx
+++ b/build2/bin/guess.cxx
@@ -18,17 +18,26 @@ namespace build2
string signature;
string checksum;
+ guess_result () = default;
+ guess_result (string&& i, string&& s)
+ : id (move (i)), signature (move (s)) {}
+
bool
empty () const {return id.empty ();}
};
ar_info
- guess_ar (const path& ar, const path* rl)
+ guess_ar (const path& ar, const path* rl, const dir_path& fallback)
{
tracer trace ("bin::guess_ar");
guess_result arr, rlr;
+ process_path arp (run_search (ar, true, fallback));
+ process_path rlp (rl != nullptr
+ ? run_search (*rl, true, fallback)
+ : process_path ());
+
// Binutils, LLVM, and FreeBSD ar/ranlib all recognize the --version
// option. While Microsoft's lib.exe doesn't support --version, it only
// issues a warning and exits with zero status, printing its usual
@@ -43,23 +52,23 @@ namespace build2
// "GNU ar ".
//
if (l.compare (0, 7, "GNU ar ") == 0)
- return guess_result {"gnu", move (l), ""};
+ return guess_result ("gnu", move (l));
// LLVM ar --version output has a line that starts with
// "LLVM version ".
//
if (l.compare (0, 13, "LLVM version ") == 0)
- return guess_result {"llvm", move (l), ""};
+ return guess_result ("llvm", move (l));
// FreeBSD ar --verison output starts with "BSD ar ".
//
if (l.compare (0, 7, "BSD ar ") == 0)
- return guess_result {"bsd", move (l), ""};
+ return guess_result ("bsd", move (l));
// Microsoft lib.exe output starts with "Microsoft (R) ".
//
if (l.compare (0, 14, "Microsoft (R) ") == 0)
- return guess_result {"msvc", move (l), ""};
+ return guess_result ("msvc", move (l));
return guess_result ();
};
@@ -69,7 +78,7 @@ namespace build2
// (yes, it goes to stdout) but that seems harmless.
//
sha256 cs;
- arr = run<guess_result> (ar, "--version", f, false, false, &cs);
+ arr = run<guess_result> (arp, "--version", f, false, false, &cs);
if (!arr.empty ())
arr.checksum = cs.string ();
@@ -85,14 +94,14 @@ namespace build2
auto f = [] (string& l) -> guess_result
{
return l.find (" ar ") != string::npos
- ? guess_result {"generic", move (l), ""}
+ ? guess_result ("generic", move (l))
: guess_result ();
};
// Redirect STDERR to STDOUT and ignore exit status.
//
sha256 cs;
- arr = run<guess_result> (ar, f, false, true, &cs);
+ arr = run<guess_result> (arp, f, false, true, &cs);
if (!arr.empty ())
{
@@ -116,24 +125,24 @@ namespace build2
// "GNU ranlib ".
//
if (l.compare (0, 11, "GNU ranlib ") == 0)
- return guess_result {"gnu", move (l), ""};
+ return guess_result ("gnu", move (l));
// "LLVM version ".
//
if (l.compare (0, 13, "LLVM version ") == 0)
- return guess_result {"llvm", move (l), ""};
+ return guess_result ("llvm", move (l));
// On FreeBSD we get "ranlib" rather than "BSD ranlib" for some
// reason. Which means we can't really call it 'bsd' for sure.
//
//if (l.compare (0, 7, "ranlib ") == 0)
- // return guess_result {"bsd", move (l), ""};
+ // return guess_result ("bsd", move (l));
return guess_result ();
};
sha256 cs;
- rlr = run<guess_result> (*rl, "--version", f, false, false, &cs);
+ rlr = run<guess_result> (rlp, "--version", f, false, false, &cs);
if (!rlr.empty ())
rlr.checksum = cs.string ();
@@ -146,14 +155,14 @@ namespace build2
auto f = [] (string& l) -> guess_result
{
return l.find ("ranlib") != string::npos
- ? guess_result {"generic", move (l), ""}
+ ? guess_result ("generic", move (l))
: guess_result ();
};
// Redirect STDERR to STDOUT and ignore exit status.
//
sha256 cs;
- rlr = run<guess_result> (*rl, f, false, true, &cs);
+ rlr = run<guess_result> (rlp, f, false, true, &cs);
if (!rlr.empty ())
{
@@ -167,17 +176,19 @@ namespace build2
}
return ar_info {
- move (arr.id), move (arr.signature), move (arr.checksum),
- move (rlr.id), move (rlr.signature), move (rlr.checksum)};
+ move (arp), move (arr.id), move (arr.signature), move (arr.checksum),
+ move (rlp), move (rlr.id), move (rlr.signature), move (rlr.checksum)};
}
ld_info
- guess_ld (const path& ld)
+ guess_ld (const path& ld, const dir_path& fallback)
{
tracer trace ("bin::guess_ld");
guess_result r;
+ process_path pp (run_search (ld, true, fallback));
+
// Binutils ld recognizes the --version option. Microsoft's link.exe
// doesn't support --version (nor any other way to get the version
// without the error exist status) but it will still print its banner.
@@ -194,16 +205,16 @@ namespace build2
// Microsoft link.exe output starts with "Microsoft (R) ".
//
if (l.compare (0, 14, "Microsoft (R) ") == 0)
- return guess_result {"msvc", move (l), ""};
+ return guess_result ("msvc", move (l));
// Binutils ld.bfd --version output has a line that starts with
// "GNU ld " while ld.gold -- "GNU gold".
//
if (l.compare (0, 7, "GNU ld ") == 0)
- return guess_result {"gnu", move (l), ""};
+ return guess_result ("gnu", move (l));
if (l.compare (0, 9, "GNU gold ") == 0)
- return guess_result {"gold", move (l), ""};
+ return guess_result ("gold", move (l));
return guess_result ();
};
@@ -213,7 +224,7 @@ namespace build2
// but that seems harmless.
//
sha256 cs;
- r = run<guess_result> (ld, "--version", f, false, true, &cs);
+ r = run<guess_result> (pp, "--version", f, false, true, &cs);
if (!r.empty ())
r.checksum = cs.string ();
@@ -231,20 +242,20 @@ namespace build2
// @(#)PROGRAM:ld PROJECT:ld64-242.2
//
if (l.find ("PROJECT:ld64") != string::npos)
- return guess_result {"ld64", move (l), ""};
+ return guess_result ("ld64", move (l));
// Old ld has "cctools" in the first line, for example:
//
// Apple Computer, Inc. version cctools-622.9~2
//
if (l.find ("cctools") != string::npos)
- return guess_result {"cctools", move (l), ""};
+ return guess_result ("cctools", move (l));
return guess_result ();
};
sha256 cs;
- r = run<guess_result> (ld, "-v", f, false, false, &cs);
+ r = run<guess_result> (pp, "-v", f, false, false, &cs);
if (!r.empty ())
r.checksum = cs.string ();
@@ -262,7 +273,7 @@ namespace build2
// LLVM Linker Version: 3.7
//
if (l.compare (0, 19, "LLVM Linker Version") == 0)
- return guess_result {"llvm", move (l), ""};
+ return guess_result ("llvm", move (l));
return guess_result ();
};
@@ -271,7 +282,7 @@ namespace build2
// option.
//
sha256 cs;
- r = run<guess_result> (ld, "-version", f, false, false, &cs);
+ r = run<guess_result> (pp, "-version", f, false, false, &cs);
if (!r.empty ())
r.checksum = cs.string ();
@@ -280,16 +291,19 @@ namespace build2
if (r.empty ())
fail << "unable to guess " << ld << " signature";
- return ld_info {move (r.id), move (r.signature), move (r.checksum)};
+ return ld_info {
+ move (pp), move (r.id), move (r.signature), move (r.checksum)};
}
rc_info
- guess_rc (const path& rc)
+ guess_rc (const path& rc, const dir_path& fallback)
{
tracer trace ("bin::guess_rc");
guess_result r;
+ process_path pp (run_search (rc, true, fallback));
+
// Binutils windres recognizes the --version option.
//
{
@@ -299,7 +313,7 @@ namespace build2
// "GNU windres ".
//
if (l.compare (0, 12, "GNU windres ") == 0)
- return guess_result {"gnu", move (l), ""};
+ return guess_result ("gnu", move (l));
return guess_result ();
};
@@ -308,7 +322,7 @@ namespace build2
// option.
//
sha256 cs;
- r = run<guess_result> (rc, "--version", f, false, false, &cs);
+ r = run<guess_result> (pp, "--version", f, false, false, &cs);
if (!r.empty ())
r.checksum = cs.string ();
@@ -322,13 +336,13 @@ namespace build2
auto f = [] (string& l) -> guess_result
{
if (l.compare (0, 14, "Microsoft (R) ") == 0)
- return guess_result {"msvc", move (l), ""};
+ return guess_result ("msvc", move (l));
return guess_result ();
};
sha256 cs;
- r = run<guess_result> (rc, "/?", f, false, false, &cs);
+ r = run<guess_result> (pp, "/?", f, false, false, &cs);
if (!r.empty ())
r.checksum = cs.string ();
@@ -337,7 +351,8 @@ namespace build2
if (r.empty ())
fail << "unable to guess " << rc << " signature";
- return rc_info {move (r.id), move (r.signature), move (r.checksum)};
+ return rc_info {
+ move (pp), move (r.id), move (r.signature), move (r.checksum)};
}
}
}
diff --git a/build2/bin/init.cxx b/build2/bin/init.cxx
index 424a729..125bc7d 100644
--- a/build2/bin/init.cxx
+++ b/build2/bin/init.cxx
@@ -273,8 +273,12 @@ namespace build2
{
const string& s (cast<string> (*v));
- if (s.find ('*') == string::npos)
+ if (s.empty () ||
+ (!path::traits::is_separator (s.back ()) &&
+ s.find ('*') == string::npos))
+ {
fail << "missing '*' in binutils pattern '" << s << "'";
+ }
r.assign<string> ("bin.pattern") = s;
new_val = new_val || p.second; // False for a hinted value.
@@ -428,8 +432,11 @@ namespace build2
{
auto& v (var_pool);
- v.insert<path> ("config.bin.ar", true);
- v.insert<path> ("config.bin.ranlib", true);
+ v.insert<process_path> ("bin.rc.path");
+ v.insert<process_path> ("bin.ranlib.path");
+
+ v.insert<path> ("config.bin.ar", true);
+ v.insert<path> ("config.bin.ranlib", true);
}
// Configure.
@@ -456,6 +463,11 @@ namespace build2
const string& tsys (cast<string> (r["bin.target.system"]));
const char* ar_d (tsys == "win32-msvc" ? "lib" : "ar");
+ // This can be either a pattern or a fallback search directory.
+ //
+ const string* pat (cast_null<string> (r["bin.pattern"]));
+ bool fb (pat != nullptr && path::traits::is_separator (pat->back ()));
+
// Don't save the default value to config.build so that if the user
// changes, say, the C++ compiler (which hinted the pattern), then
// ar will automatically change as well.
@@ -464,7 +476,7 @@ namespace build2
config::required (
r,
"config.bin.ar",
- path (apply_pattern (ar_d, cast_null<string> (r["bin.pattern"]))),
+ path (apply_pattern (ar_d, fb ? nullptr : pat)),
false,
config::save_commented));
@@ -482,7 +494,8 @@ namespace build2
if (ranlib != nullptr && ranlib->empty ()) // @@ BC LT [null].
ranlib = nullptr;
- ar_info ari (guess_ar (ar, ranlib));
+ ar_info ari (
+ guess_ar (ar, ranlib, fb ? dir_path (*pat) : dir_path ()));
// If this is a new value (e.g., we are configuring), then print the
// report at verbosity level 2 and up (-v).
@@ -492,7 +505,7 @@ namespace build2
diag_record dr (text);
dr << "bin.ar " << project (r) << '@' << r.out_path () << '\n'
- << " ar " << ar << '\n'
+ << " ar " << ari.ar_path << '\n'
<< " id " << ari.ar_id << '\n'
<< " signature " << ari.ar_signature << '\n'
<< " checksum " << ari.ar_checksum;
@@ -500,23 +513,25 @@ namespace build2
if (ranlib != nullptr)
{
dr << '\n'
- << " ranlib " << *ranlib << '\n'
+ << " ranlib " << ari.ranlib_path << '\n'
<< " id " << ari.ranlib_id << '\n'
<< " signature " << ari.ranlib_signature << '\n'
<< " checksum " << ari.ranlib_checksum;
}
}
- r.assign<string> ("bin.ar.id") = move (ari.ar_id);
- r.assign<string> ("bin.ar.signature") = move (ari.ar_signature);
- r.assign<string> ("bin.ar.checksum") = move (ari.ar_checksum);
+ r.assign<process_path> ("bin.ar.path") = move (ari.ar_path);
+ r.assign<string> ("bin.ar.id") = move (ari.ar_id);
+ r.assign<string> ("bin.ar.signature") = move (ari.ar_signature);
+ r.assign<string> ("bin.ar.checksum") = move (ari.ar_checksum);
if (ranlib != nullptr)
{
- r.assign<string> ("bin.ranlib.id") = move (ari.ranlib_id);
- r.assign<string> ("bin.ranlib.signature") =
+ r.assign<process_path> ("bin.ranlib.path") = move (ari.ranlib_path);
+ r.assign<string> ("bin.ranlib.id") = move (ari.ranlib_id);
+ r.assign<string> ("bin.ranlib.signature") =
move (ari.ranlib_signature);
- r.assign<string> ("bin.ranlib.checksum") =
+ r.assign<string> ("bin.ranlib.checksum") =
move (ari.ranlib_checksum);
}
}
@@ -570,7 +585,8 @@ namespace build2
{
auto& v (var_pool);
- v.insert<path> ("config.bin.ld", true);
+ v.insert<process_path> ("bin.ld.path");
+ v.insert<path> ("config.bin.ld", true);
}
// Configure.
@@ -584,16 +600,21 @@ namespace build2
const string& tsys (cast<string> (r["bin.target.system"]));
const char* ld_d (tsys == "win32-msvc" ? "link" : "ld");
+ // This can be either a pattern or a fallback search directory.
+ //
+ const string* pat (cast_null<string> (r["bin.pattern"]));
+ bool fb (pat != nullptr && path::traits::is_separator (pat->back ()));
+
auto p (
config::required (
r,
"config.bin.ld",
- path (apply_pattern (ld_d, cast_null<string> (r["bin.pattern"]))),
+ path (apply_pattern (ld_d, fb ? nullptr : pat)),
false,
config::save_commented));
const path& ld (cast<path> (p.first));
- ld_info ldi (guess_ld (ld));
+ ld_info ldi (guess_ld (ld, fb ? dir_path (*pat) : dir_path ()));
// If this is a new value (e.g., we are configuring), then print the
// report at verbosity level 2 and up (-v).
@@ -601,15 +622,16 @@ namespace build2
if (verb >= (p.second ? 2 : 3))
{
text << "bin.ld " << project (r) << '@' << r.out_path () << '\n'
- << " ld " << ld << '\n'
+ << " ld " << ldi.path << '\n'
<< " id " << ldi.id << '\n'
<< " signature " << ldi.signature << '\n'
<< " checksum " << ldi.checksum;
}
- r.assign<string> ("bin.ld.id") = move (ldi.id);
- r.assign<string> ("bin.ld.signature") = move (ldi.signature);
- r.assign<string> ("bin.ld.checksum") = move (ldi.checksum);
+ r.assign<process_path> ("bin.ld.path") = move (ldi.path);
+ r.assign<string> ("bin.ld.id") = move (ldi.id);
+ r.assign<string> ("bin.ld.signature") = move (ldi.signature);
+ r.assign<string> ("bin.ld.checksum") = move (ldi.checksum);
}
return true;
@@ -674,7 +696,8 @@ namespace build2
{
auto& v (var_pool);
- v.insert<path> ("config.bin.rc", true);
+ v.insert<process_path> ("bin.rc.path");
+ v.insert<path> ("config.bin.rc", true);
}
// Configure.
@@ -688,16 +711,21 @@ namespace build2
const string& tsys (cast<string> (r["bin.target.system"]));
const char* rc_d (tsys == "win32-msvc" ? "rc" : "windres");
+ // This can be either a pattern or a fallback search directory.
+ //
+ const string* pat (cast_null<string> (r["bin.pattern"]));
+ bool fb (pat != nullptr && path::traits::is_separator (pat->back ()));
+
auto p (
config::required (
r,
"config.bin.rc",
- path (apply_pattern (rc_d, cast_null<string> (r["bin.pattern"]))),
+ path (apply_pattern (rc_d, fb ? nullptr : pat)),
false,
config::save_commented));
const path& rc (cast<path> (p.first));
- rc_info rci (guess_rc (rc));
+ rc_info rci (guess_rc (rc, fb ? dir_path (*pat) : dir_path ()));
// If this is a new value (e.g., we are configuring), then print the
// report at verbosity level 2 and up (-v).
@@ -705,15 +733,16 @@ namespace build2
if (verb >= (p.second ? 2 : 3))
{
text << "bin.rc " << project (r) << '@' << r.out_path () << '\n'
- << " rc " << rc << '\n'
+ << " rc " << rci.path << '\n'
<< " id " << rci.id << '\n'
<< " signature " << rci.signature << '\n'
<< " checksum " << rci.checksum;
}
- r.assign<string> ("bin.rc.id") = move (rci.id);
- r.assign<string> ("bin.rc.signature") = move (rci.signature);
- r.assign<string> ("bin.rc.checksum") = move (rci.checksum);
+ r.assign<process_path> ("bin.rc.path") = move (rci.path);
+ r.assign<string> ("bin.rc.id") = move (rci.id);
+ r.assign<string> ("bin.rc.signature") = move (rci.signature);
+ r.assign<string> ("bin.rc.checksum") = move (rci.checksum);
}
return true;