aboutsummaryrefslogtreecommitdiff
path: root/build2/bin
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-05-20 23:25:45 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-06-11 19:06:40 +0200
commit4218bfe7668d55e36814d6bdcec2da40454025c1 (patch)
tree1abe3f38109ba83755adf7307414dbbd1e1a9eb8 /build2/bin
parent9f56941794837ec63b8732d8d0cae4659528e714 (diff)
Initial VC++ support (static libraries only)
Diffstat (limited to 'build2/bin')
-rw-r--r--build2/bin/guess10
-rw-r--r--build2/bin/guess.cxx174
-rw-r--r--build2/bin/module.cxx4
3 files changed, 111 insertions, 77 deletions
diff --git a/build2/bin/guess b/build2/bin/guess
index 005235d..a80539e 100644
--- a/build2/bin/guess
+++ b/build2/bin/guess
@@ -14,6 +14,14 @@ namespace build2
{
// ar/ranlib information.
//
+ // Currently recognized ar/ranlib and their ids:
+ //
+ // gnu GNU binutils
+ // llvm LLVM
+ // bsd FreeBSD (and maybe other BSDs)
+ // msvc Microsoft's lib.exe
+ // generic Generic/unrecognized
+ //
// The signature is normally the --version/-V line.
//
// The checksum is used to detect ar/ranlib changes. It is calculated in
@@ -22,9 +30,11 @@ namespace build2
//
struct bin_info
{
+ string ar_id;
string ar_signature;
string ar_checksum;
+ string ranlib_id;
string ranlib_signature;
string ranlib_checksum;
};
diff --git a/build2/bin/guess.cxx b/build2/bin/guess.cxx
index 1cdb40d..d036f81 100644
--- a/build2/bin/guess.cxx
+++ b/build2/bin/guess.cxx
@@ -12,48 +12,67 @@ namespace build2
{
namespace bin
{
+ struct guess_result
+ {
+ string id;
+ string signature;
+ string checksum;
+
+ bool
+ empty () const {return id.empty ();}
+ };
+
bin_info
- guess (const path& ar, const path& ranlib)
+ guess (const path& ar, const path& rl)
{
tracer trace ("bin::guess");
- bin_info r;
- string& as (r.ar_signature);
+ guess_result arr, rlr;
// Binutils, LLVM, and FreeBSD ar/ranlib all recognize the --version
- // option, so start with that.
+ // option. While Microsoft's lib.exe doesn't support --version, it only
+ // issues a warning and exits with zero status, printing its usual
+ // banner before that (running lib.exe without any options result in
+ // non-zero exit status -- go figure). So we are going to start with
+ // that.
//
{
- auto f = [] (string& l) -> string
+ auto f = [] (string& l) -> guess_result
{
// Binutils ar --version output has a line that starts with
// "GNU ar ".
//
if (l.compare (0, 7, "GNU ar ") == 0)
- return 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 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 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 string ();
+ return guess_result ();
};
// Suppress all the errors because we may be trying an unsupported
- // option.
+ // option. Note that in case of lib.exe we will hash the warning
+ // (yes, it goes to stdout) but that seems harmless.
//
sha256 cs;
- as = run<string> (ar, "--version", f, false, false, &cs);
+ arr = run<guess_result> (ar, "--version", f, false, false, &cs);
- if (!as.empty ())
- r.ar_checksum = cs.string ();
+ if (!arr.empty ())
+ arr.checksum = cs.string ();
}
// On Mac OS X (and probably also older BSDs) ar/ranlib doesn't have an
@@ -61,94 +80,95 @@ namespace build2
// it dumps usage and exist with an error status. So we will have to use
// that.
//
- if (as.empty ())
+ if (arr.empty ())
{
- auto f = [] (string& l) -> string
+ auto f = [] (string& l) -> guess_result
{
- return l.find (" ar ") == string::npos ? string () : move (l);
+ return l.find (" ar ") != string::npos
+ ? guess_result {"generic", move (l), ""}
+ : guess_result ();
};
// Redirect STDERR to STDOUT and ignore exit status.
//
sha256 cs;
- as = run<string> (ar, f, false, true, &cs);
+ arr = run<guess_result> (ar, f, false, true, &cs);
- if (!as.empty ())
+ if (!arr.empty ())
{
- l4 ([&]{trace << "generic ar signature '" << as << "'";});
-
- r.ar_signature = "Generic ar";
- r.ar_checksum = cs.string ();
+ l4 ([&]{trace << "generic ar '" << arr.signature << "'";});
+ arr.checksum = cs.string ();
}
}
- if (as.empty ())
+ if (arr.empty ())
fail << "unable to guess " << ar << " signature";
// Now repeat pretty much the same steps for ranlib if requested.
//
- if (ranlib.empty ())
- return r;
-
- string& rs (r.ranlib_signature);
-
- // Binutils, LLVM, and FreeBSD.
- //
+ if (!rl.empty ())
{
- auto f = [] (string& l) -> string
- {
- // "GNU ranlib ".
- //
- if (l.compare (0, 11, "GNU ranlib ") == 0)
- return move (l);
-
- // "LLVM version ".
- //
- if (l.compare (0, 13, "LLVM version ") == 0)
- return move (l);
-
- // "ranlib " (note: not "BSD ranlib " for some reason).
- //
- if (l.compare (0, 7, "ranlib ") == 0)
- return move (l);
-
- return string ();
- };
-
- sha256 cs;
- rs = run<string> (ranlib, "--version", f, false, false, &cs);
-
- if (!rs.empty ())
- r.ranlib_checksum = cs.string ();
- }
-
- // Mac OS X (and probably also older BSDs).
- //
- if (rs.empty ())
- {
- auto f = [] (string& l) -> string
+ // Binutils, LLVM, and FreeBSD.
+ //
{
- return l.find ("ranlib") == string::npos ? string () : move (l);
- };
+ auto f = [] (string& l) -> guess_result
+ {
+ // "GNU ranlib ".
+ //
+ if (l.compare (0, 11, "GNU ranlib ") == 0)
+ return guess_result {"gnu", move (l), ""};
+
+ // "LLVM version ".
+ //
+ if (l.compare (0, 13, "LLVM version ") == 0)
+ 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 ();
+ };
+
+ sha256 cs;
+ rlr = run<guess_result> (rl, "--version", f, false, false, &cs);
+
+ if (!rlr.empty ())
+ rlr.checksum = cs.string ();
+ }
- // Redirect STDERR to STDOUT and ignore exit status.
+ // Mac OS X (and probably also older BSDs).
//
- sha256 cs;
- rs = run<string> (ranlib, f, false, true, &cs);
-
- if (!rs.empty ())
+ if (rlr.empty ())
{
- l4 ([&]{trace << "generic ranlib signature '" << rs << "'";});
-
- r.ranlib_signature = "Generic ranlib";
- r.ranlib_checksum = cs.string ();
+ auto f = [] (string& l) -> guess_result
+ {
+ return l.find ("ranlib") != string::npos
+ ? 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);
+
+ if (!rlr.empty ())
+ {
+ l4 ([&]{trace << "generic ranlib '" << rlr.signature << "'";});
+ rlr.checksum = cs.string ();
+ }
}
- }
- if (rs.empty ())
- fail << "unable to guess " << ranlib << " signature";
+ if (rlr.empty ())
+ fail << "unable to guess " << rl << " signature";
+ }
- return r;
+ return bin_info {
+ move (arr.id), move (arr.signature), move (arr.checksum),
+ move (rlr.id), move (rlr.signature), move (rlr.checksum)};
}
}
}
diff --git a/build2/bin/module.cxx b/build2/bin/module.cxx
index 866bab2..edb3c53 100644
--- a/build2/bin/module.cxx
+++ b/build2/bin/module.cxx
@@ -185,22 +185,26 @@ namespace build2
//@@ Print project out root or name? See cxx.
text << ar << ":\n"
+ << " id " << bi.ar_id << "\n"
<< " signature " << bi.ar_signature << "\n"
<< " checksum " << bi.ar_checksum;
if (!ranlib.empty ())
{
text << ranlib << ":\n"
+ << " id " << bi.ranlib_id << "\n"
<< " signature " << bi.ranlib_signature << "\n"
<< " checksum " << bi.ranlib_checksum;
}
}
+ r.assign<string> ("bin.ar.id") = move (bi.ar_id);
r.assign<string> ("bin.ar.signature") = move (bi.ar_signature);
r.assign<string> ("bin.ar.checksum") = move (bi.ar_checksum);
if (!ranlib.empty ())
{
+ r.assign<string> ("bin.ranlib.id") = move (bi.ranlib_id);
r.assign<string> ("bin.ranlib.signature") =
move (bi.ranlib_signature);
r.assign<string> ("bin.ranlib.checksum") = move (bi.ranlib_checksum);