aboutsummaryrefslogtreecommitdiff
path: root/build2/cc/guess.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2018-01-04 15:35:57 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2018-01-05 15:10:01 +0200
commit76de594667b370094f5da5c0871c155d788d135e (patch)
tree610d67fc2350a4fdeaa2de7b6583f5da9067bc24 /build2/cc/guess.cxx
parentd6427addaf7de41d401dd2a871b4789022e5f7cf (diff)
Initial support for c/cxx runtime/stdlib detection
Diffstat (limited to 'build2/cc/guess.cxx')
-rw-r--r--build2/cc/guess.cxx141
1 files changed, 122 insertions, 19 deletions
diff --git a/build2/cc/guess.cxx b/build2/cc/guess.cxx
index c39c02e..e3eeb82 100644
--- a/build2/cc/guess.cxx
+++ b/build2/cc/guess.cxx
@@ -502,6 +502,8 @@ namespace build2
fail << "unable to extract target architecture from " << xc
<< " -print-multiarch or -dumpmachine output";
+ string ot (t);
+
// Derive the toolchain pattern. Try cc/c++ as a fallback.
//
string pat (pattern (xc, xl == lang::c ? "gcc" : "g++"));
@@ -509,6 +511,12 @@ namespace build2
if (pat.empty ())
pat = pattern (xc, xl == lang::c ? "cc" : "c++");
+
+ // GCC always uses libgcc (even on MinGW). Even with -nostdlib GCC's
+ // documentation says that you should usually specify -lgcc.
+ //
+ string rt ("libgcc");
+
return compiler_info {
move (gr.path),
move (gr.id),
@@ -517,8 +525,12 @@ namespace build2
move (gr.signature),
move (gr.checksum), // Calculated on whole -v output.
move (t),
+ move (ot),
move (pat),
- string ()};
+ "",
+ move (rt),
+ "",
+ ""};
}
static compiler_info
@@ -615,6 +627,32 @@ namespace build2
fail << "unable to extract target architecture from " << xc
<< " -dumpmachine output";
+ string ot (t);
+
+ // Parse the target into triplet (for further tests) ignoring any
+ // failures.
+ //
+ target_triplet tt;
+ try {tt = target_triplet (t);} catch (const invalid_argument&) {}
+
+ // For Clang on Windows targeting MSVC we remap the target to match
+ // MSVC's.
+ //
+ if (tt.system == "windows-msvc")
+ {
+ // Keep the CPU and replace the rest.
+ //
+ // @@ Note that currently there is no straightforward way to determine
+ // the VC version Clang is using. See:
+ //
+ // http://lists.llvm.org/pipermail/cfe-dev/2017-December/056240.html
+ //
+ tt.vendor = "microsoft";
+ tt.system = "win32-msvc";
+ tt.version = "14.1";
+ t = tt.string ();
+ }
+
// Derive the toolchain pattern. Try clang/clang++, the gcc/g++ alias,
// as well as cc/c++.
//
@@ -626,6 +664,38 @@ namespace build2
if (pat.empty ())
pat = pattern (xc, xl == lang::c ? "cc" : "c++");
+ // Clang can use libgcc, its own compiler-rt, or, on Windows targeting
+ // MSVC, the VC's runtime. As usual, there is no straightforward way
+ // to query this and silence on the mailing list. See:
+ //
+ // http://lists.llvm.org/pipermail/cfe-dev/2018-January/056494.html
+ //
+ // So for now we will just look for --rtlib and if none specified,
+ // assume some platform-specific defaults.
+ //
+ string rt;
+ {
+ auto find_rtlib = [] (const strings* ops) -> const string*
+ {
+ return ops != nullptr
+ ? find_option_prefix ("--rtlib=", *ops, false)
+ : nullptr;
+ };
+
+ const string* o;
+ if ((o = find_rtlib (x_coptions)) != nullptr ||
+ (o = find_rtlib (c_coptions)) != nullptr)
+ {
+ rt = string (*o, 8);
+ }
+ // Defaults.
+ //
+ else if (tt.system == "win32-msvc") rt = "msvc";
+ else if (tt.system == "linux-gnu" ||
+ tt.system == "freebsd") rt = "libgcc";
+ else /* Mac OS, etc. */ rt = "compiler-rt";
+ }
+
return compiler_info {
move (gr.path),
move (gr.id),
@@ -634,8 +704,12 @@ namespace build2
move (gr.signature),
move (gr.checksum), // Calculated on whole -v output.
move (t),
+ move (ot),
move (pat),
- string ()};
+ "",
+ move (rt),
+ "",
+ ""};
}
static compiler_info
@@ -836,7 +910,16 @@ namespace build2
if (p == string::npos)
fail << "unable to parse icc target architecture '" << t << "'";
- arch.append (t, p, string::npos);
+ t.swap (arch);
+ t.append (arch, p, string::npos);
+
+ string ot (t);
+
+ // Parse the target into triplet (for further tests) ignoring any
+ // failures.
+ //
+ target_triplet tt;
+ try {tt = target_triplet (t);} catch (const invalid_argument&) {}
// Derive the toolchain pattern.
//
@@ -846,6 +929,10 @@ namespace build2
//
sha256 cs (s);
+ // Runtime and standard library.
+ //
+ string rt (tt.system == "win32-msvc" ? "msvc" : "libgcc");
+
return compiler_info {
move (gr.path),
move (gr.id),
@@ -853,9 +940,13 @@ namespace build2
move (v),
move (gr.signature),
cs.string (),
- move (arch),
+ move (t),
+ move (ot),
move (pat),
- string ()};
+ "",
+ move (rt),
+ "",
+ ""};
}
static compiler_info
@@ -1016,14 +1107,16 @@ namespace build2
// x64 x86_64-microsoft-win32-msvc14.0
// ARM arm-microsoft-winup-???
//
+ string t;
+
if (arch == "ARM")
fail << "cl.exe ARM/WinRT/UWP target is not yet supported";
else
{
if (arch == "x64")
- arch = "x86_64-microsoft-win32-msvc";
+ t = "x86_64-microsoft-win32-msvc";
else if (arch == "x86" || arch == "80x86")
- arch = "i386-microsoft-win32-msvc";
+ t = "i386-microsoft-win32-msvc";
else
assert (false);
@@ -1045,20 +1138,22 @@ namespace build2
// 2005 8 14.00 8.0/80
// 2003 7.1 13.10 7.1/71
//
- /**/ if (v.major == 19 && v.minor == 12) arch += "14.1";
- else if (v.major == 19 && v.minor == 11) arch += "14.1";
- else if (v.major == 19 && v.minor == 10) arch += "14.1";
- else if (v.major == 19 && v.minor == 0) arch += "14.0";
- else if (v.major == 18 && v.minor == 0) arch += "12.0";
- else if (v.major == 17 && v.minor == 0) arch += "11.0";
- else if (v.major == 16 && v.minor == 0) arch += "10.0";
- else if (v.major == 15 && v.minor == 0) arch += "9.0";
- else if (v.major == 14 && v.minor == 0) arch += "8.0";
- else if (v.major == 13 && v.minor == 10) arch += "7.1";
+ /**/ if (v.major == 19 && v.minor == 12) t += "14.1";
+ else if (v.major == 19 && v.minor == 11) t += "14.1";
+ else if (v.major == 19 && v.minor == 10) t += "14.1";
+ else if (v.major == 19 && v.minor == 0) t += "14.0";
+ else if (v.major == 18 && v.minor == 0) t += "12.0";
+ else if (v.major == 17 && v.minor == 0) t += "11.0";
+ else if (v.major == 16 && v.minor == 0) t += "10.0";
+ else if (v.major == 15 && v.minor == 0) t += "9.0";
+ else if (v.major == 14 && v.minor == 0) t += "8.0";
+ else if (v.major == 13 && v.minor == 10) t += "7.1";
else fail << "unable to map msvc compiler version '" << v.string
<< "' to runtime version";
}
+ string ot (t);
+
// Derive the toolchain pattern.
//
// If the compiler name is/starts with 'cl' (e.g., cl.exe, cl-14),
@@ -1072,6 +1167,10 @@ namespace build2
//
sha256 cs (s);
+ // Runtime and standard library.
+ //
+ string rt ("msvc");
+
return compiler_info {
move (gr.path),
move (gr.id),
@@ -1079,9 +1178,13 @@ namespace build2
move (v),
move (gr.signature),
cs.string (),
- move (arch),
+ move (t),
+ move (ot),
move (cpat),
- move (bpat)};
+ move (bpat),
+ move (rt),
+ "",
+ ""};
}
compiler_info