aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-05-25 11:32:01 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-05-25 11:32:01 +0200
commit71d9aedda0919fb22e39d6e6ce60506ceb69812e (patch)
tree585afc25774555047ff41dc865c617732caf5ff2
parenta1f459f8446370704695919b3131653300866ee9 (diff)
Add compiler_id enum
-rw-r--r--build2/c/init.cxx3
-rw-r--r--build2/cc/common.cxx10
-rw-r--r--build2/cc/common.hxx21
-rw-r--r--build2/cc/compile.cxx136
-rw-r--r--build2/cc/guess.cxx12
-rw-r--r--build2/cc/guess.hxx15
-rw-r--r--build2/cc/link.cxx20
-rw-r--r--build2/cc/module.cxx1
-rw-r--r--build2/cc/module.hxx2
-rw-r--r--build2/cc/pkgconfig.cxx2
-rw-r--r--build2/cxx/init.cxx3
11 files changed, 142 insertions, 83 deletions
diff --git a/build2/c/init.cxx b/build2/c/init.cxx
index ebaa193..a80a4d0 100644
--- a/build2/c/init.cxx
+++ b/build2/c/init.cxx
@@ -238,7 +238,8 @@ namespace build2
"c.install",
"c.uninstall",
- cast<string> (rs[cm.x_id]),
+ cm.cid,
+ cast<string> (rs[cm.x_id_variant]),
cast<uint64_t> (rs[cm.x_version_major]),
cast<uint64_t> (rs[cm.x_version_minor]),
cast<target_triplet> (rs[cm.x_target]),
diff --git a/build2/cc/common.cxx b/build2/cc/common.cxx
index 59feb9b..1df84c9 100644
--- a/build2/cc/common.cxx
+++ b/build2/cc/common.cxx
@@ -515,7 +515,7 @@ namespace build2
//
const char* e ("");
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
an = path (name);
e = "lib";
@@ -543,7 +543,7 @@ namespace build2
{
const char* e ("");
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
sn = path (name);
e = "dll.lib";
@@ -661,7 +661,7 @@ namespace build2
//
// If we didn't find .dll.lib then we cannot assume .lib is static.
//
- if (!an.empty () && (s != nullptr || cid != "msvc"))
+ if (!an.empty () && (s != nullptr || cid != compiler_id::msvc))
{
f = d;
f /= an;
@@ -682,7 +682,7 @@ namespace build2
// Alternative search for VC.
//
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
const scope& rs (*p.scope->root_scope ());
const process_path& ld (cast<process_path> (rs["bin.ld.path"]));
@@ -879,7 +879,7 @@ namespace build2
dir_path d;
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
// /LIBPATH:<dir> (case-insensitive).
//
diff --git a/build2/cc/common.hxx b/build2/cc/common.hxx
index bc52311..c0289d1 100644
--- a/build2/cc/common.hxx
+++ b/build2/cc/common.hxx
@@ -13,6 +13,7 @@
#include <build2/bin/target.hxx>
#include <build2/cc/types.hxx>
+#include <build2/cc/guess.hxx> // compiler_id
namespace build2
{
@@ -99,15 +100,17 @@ namespace build2
// Cached values for some commonly-used variables/values.
//
- const string& cid; // x.id
- uint64_t cmaj; // x.version.major
- uint64_t cmin; // x.version.minor
- const target_triplet& ctg; // x.target
- const string& tsys; // x.target.system
- const string& tclass; // x.target.class
+ compiler_id::value_type cid; // x.id (no variant)
+ const string& cvar; // x.id.variant
+ uint64_t cmaj; // x.version.major
+ uint64_t cmin; // x.version.minor
- const string& tstd; // Translated x_std value (can be empty).
+ const target_triplet& ctg; // x.target
+ const string& tsys; // x.target.system
+ const string& tclass; // x.target.class
+
+ const string& tstd; // Translated x_std value (can be empty).
const process_path* pkgconfig; // pkgconfig.path (can be NULL).
const dir_paths& sys_lib_dirs; // x.sys_lib_dirs
@@ -144,7 +147,7 @@ namespace build2
const char* link,
const char* install,
const char* uninstall,
- const string& id,
+ compiler_id::value_type id, const string& var,
uint64_t mj, uint64_t mi,
const target_triplet& tg,
const string& std,
@@ -159,7 +162,7 @@ namespace build2
x_link (link),
x_install (install),
x_uninstall (uninstall),
- cid (id), cmaj (mj), cmin (mi),
+ cid (id), cvar (var), cmaj (mj), cmin (mi),
ctg (tg), tsys (ctg.system), tclass (ctg.class_),
tstd (std),
pkgconfig (pkgc), sys_lib_dirs (sld), sys_inc_dirs (sid),
diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx
index 21f7ecf..9982a91 100644
--- a/build2/cc/compile.cxx
+++ b/build2/cc/compile.cxx
@@ -954,29 +954,38 @@ namespace build2
//
const char* pp (nullptr);
- if (cid == "msvc") pp = "/C";
- else if (cid == "gcc")
+ switch (cid)
{
- // -fdirectives-only is available since GCC 4.3.0.
- //
- if (cmaj > 4 || (cmaj == 4 && cmin >= 3))
- pp = "-fdirectives-only";
- }
- else if (cid == "clang")
- {
- // -frewrite-includes is available since Clang 3.2.0.
- //
- if (cmaj > 3 || (cmaj == 3 && cmin >= 2))
- pp = "-frewrite-includes";
- }
- else if (cid == "clang-apple")
- {
- // Apple Clang 5.0 is based on LLVM 3.3svn so it should have this
- // option (4.2 is based on 3.2svc so it may or may not have it and,
- // no, we are not going to try to find out).
- //
- if (cmaj >= 5)
- pp = "-frewrite-includes";
+ case compiler_id::gcc:
+ {
+ // -fdirectives-only is available since GCC 4.3.0.
+ //
+ if (cmaj > 4 || (cmaj == 4 && cmin >= 3))
+ pp = "-fdirectives-only";
+
+ break;
+ }
+ case compiler_id::clang:
+ {
+ // -frewrite-includes is available since vanilla Clang 3.2.0.
+ //
+ // Apple Clang 5.0 is based on LLVM 3.3svn so it should have this
+ // option (4.2 is based on 3.2svc so it may or may not have it and,
+ // no, we are not going to try to find out).
+ //
+ if (cvar == "" ? (cmaj > 3 || (cmaj == 3 && cmin >= 2)) :
+ cvar == "apple" ? (cmaj >= 5) : false)
+ pp = "-frewrite-includes";
+
+ break;
+ }
+ case compiler_id::msvc:
+ {
+ pp = "/C";
+ break;
+ }
+ case compiler_id::icc:
+ break;
}
// Initialize lazily, only if required.
@@ -1138,7 +1147,7 @@ namespace build2
args.push_back ("-fPIC");
}
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
assert (pp != nullptr);
@@ -1186,7 +1195,7 @@ namespace build2
// Clang's -M does not imply -w (disable warnings). We also don't
// need them in the -MD case (see above) so disable for both.
//
- if (cid == "clang" || cid == "clang-apple")
+ if (cid == compiler_id::clang)
args.push_back ("-w");
// Previously we used '*' as a target name but it gets expanded to
@@ -1215,7 +1224,7 @@ namespace build2
// GCC is not capable of writing the dependency info to stdout.
// We also need to sense the diagnostics on the -E runs.
//
- if (cid == "gcc")
+ if (cid == compiler_id::gcc)
{
// Use the .t extension (for "temporary"; .d is taken).
//
@@ -1260,7 +1269,7 @@ namespace build2
args[i + 2] = rels.string ().c_str ();
args[i + 3] = nullptr;
- if (cid == "gcc")
+ if (cid == compiler_id::gcc)
{
sense_diag = false;
}
@@ -1274,7 +1283,7 @@ namespace build2
args[i + 2] = pp;
args[i + 3] = "-MF";
- if (cid == "gcc")
+ if (cid == compiler_id::gcc)
{
r = &drm.path ();
sense_diag = true;
@@ -1648,7 +1657,7 @@ namespace build2
args.data (),
0,
-1,
- cid == "msvc" ? 1 : gen ? 2 : -2);
+ cid == compiler_id::msvc ? 1 : gen ? 2 : -2);
}
else
{
@@ -1712,7 +1721,7 @@ namespace build2
// Parse different dependency output formats.
//
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
if (first)
{
@@ -1840,9 +1849,9 @@ namespace build2
// eof, this and all subsequent writes to cerr will fail (and
// you won't see a thing).
//
- if (is.peek () != ifdstream::traits_type::eof () &&
- cid == "msvc" &&
- bad_error)
+ if (bad_error &&
+ cid == compiler_id::msvc &&
+ is.peek () != ifdstream::traits_type::eof ())
cerr << is.rdbuf ();
is.close ();
@@ -1990,7 +1999,7 @@ namespace build2
append_std (args);
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
// The /F*: option variants with separate names only became available
// in VS2013/12.0. Why do we bother? Because the command line suddenly
@@ -2117,21 +2126,32 @@ namespace build2
// This should match with how we setup preprocessing.
//
- if (cid == "gcc")
+ switch (cid)
{
- // The -fpreprocessed in implied by .i/.ii.
- //
- args.push_back ("-fdirectives-only");
- }
- else if (cid == "clang" || cid == "clang-apple")
- {
- // Without this Clang will treat .i/.ii as fully preprocessed.
- //
- args.push_back ("-x");
- args.push_back (x_name);
- }
- else if (cid != "msvc") // Nothing to do (/TP or /TC already there).
+ case compiler_id::gcc:
+ {
+ // The -fpreprocessed in implied by .i/.ii.
+ //
+ args.push_back ("-fdirectives-only");
+ break;
+ }
+ case compiler_id::clang:
+ {
+ // Without this Clang will treat .i/.ii as fully preprocessed.
+ //
+ args.push_back ("-x");
+ args.push_back (x_name);
+ break;
+ }
+ case compiler_id::msvc:
+ {
+ // Nothing to do (/TP or /TC already there).
+ //
+ break;
+ }
+ case compiler_id::icc:
assert (false);
+ }
args.push_back (rels.string ().c_str ());
args.push_back (nullptr);
@@ -2157,7 +2177,7 @@ namespace build2
// tries to pull off something similar. For sane compilers this should
// be harmless.
//
- bool filter (cid == "msvc");
+ bool filter (cid == compiler_id::msvc);
process pr (xc, args.data (), 0, (filter ? -1 : 2));
@@ -2213,18 +2233,22 @@ namespace build2
}
target_state compile::
- perform_clean (action act, const target& xt) const
+ perform_clean (action a, const target& xt) const
{
const file& t (xt.as<file> ());
- if (cid == "msvc")
- return clean_extra (act, t, {".d", x_pext, ".idb", ".pdb"});
- else if (cid == "gcc")
- return clean_extra (act, t, {".d", x_pext, ".t"});
- else if (cid == "clang" || cid == "clang-apple")
- return clean_extra (act, t, {".d", x_pext});
- else
- return clean_extra (act, t, {".d"});
+ using id = compiler_id;
+
+ switch (cid)
+ {
+ case id::gcc: return clean_extra (a, t, {".d", x_pext, ".t"});
+ case id::clang: return clean_extra (a, t, {".d", x_pext});
+ case id::msvc: return clean_extra (a, t, {".d", x_pext, ".idb", ".pdb"});
+ case id::icc: return clean_extra (a, t, {".d"});
+ }
+
+ assert (false);
+ return target_state::unchanged;
}
}
}
diff --git a/build2/cc/guess.cxx b/build2/cc/guess.cxx
index 0569bdc..9f14661 100644
--- a/build2/cc/guess.cxx
+++ b/build2/cc/guess.cxx
@@ -14,6 +14,18 @@ namespace build2
{
namespace cc
{
+ auto compiler_id::
+ value () const -> value_type
+ {
+ if (type == "gcc") return gcc;
+ if (type == "clang") return clang;
+ if (type == "msvc") return msvc;
+ if (type == "icc") return icc;
+
+ assert (false);
+ return gcc;
+ }
+
// Pre-guess the compiler type based on the compiler executable name.
// Return empty string if can't make a guess (for example, because the
// compiler name is a generic 'c++'). Note that it only guesses the type,
diff --git a/build2/cc/guess.hxx b/build2/cc/guess.hxx
index dbd06e3..4d5d036 100644
--- a/build2/cc/guess.hxx
+++ b/build2/cc/guess.hxx
@@ -23,8 +23,8 @@ namespace build2
// gcc GCC gcc/g++
// clang Vanilla Clang clang/clang++
// clang-apple Apple Clang clang/clang++ and the gcc/g++ "alias"
- // icc Intel icc/icpc
// msvc Microsoft cl.exe
+ // icc Intel icc/icpc
//
struct compiler_id
{
@@ -36,6 +36,19 @@ namespace build2
std::string
string () const {return variant.empty () ? type : type + "-" + variant;}
+
+ // Note: does not include variant.
+ //
+ enum value_type
+ {
+ gcc,
+ clang,
+ msvc,
+ icc
+ };
+
+ value_type
+ value () const;
};
inline ostream&
diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx
index 1b2f306..e2b8275 100644
--- a/build2/cc/link.cxx
+++ b/build2/cc/link.cxx
@@ -355,7 +355,7 @@ namespace build2
}
case otype::a:
{
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
e = "lib";
else
{
@@ -388,8 +388,8 @@ namespace build2
// PDB
//
- if (lt != otype::a &&
- cid == "msvc" &&
+ if (lt != otype::a &&
+ cid == compiler_id::msvc &&
(find_option ("/DEBUG", t, c_loptions, true) ||
find_option ("/DEBUG", t, x_loptions, true)))
{
@@ -1140,7 +1140,9 @@ namespace build2
//
const string& cs (
cast<string> (
- rs[cid == "msvc" ? var_pool["bin.ld.checksum"] : x_checksum]));
+ rs[cid == compiler_id::msvc
+ ? var_pool["bin.ld.checksum"]
+ : x_checksum]));
if (dd.expect (cs) != nullptr)
l4 ([&]{trace << "linker mismatch forcing update of " << t;});
@@ -1169,7 +1171,7 @@ namespace build2
if (lt == otype::a)
{
- if (cid == "msvc") ;
+ if (cid == compiler_id::msvc) ;
else
{
// If the user asked for ranlib, don't try to do its function with
@@ -1181,7 +1183,7 @@ namespace build2
}
else
{
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
// We are using link.exe directly so don't pass the compiler
// options.
@@ -1362,7 +1364,7 @@ namespace build2
{
ld = &cast<process_path> (rs["bin.ar.path"]);
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
// lib.exe has /LIBPATH but it's not clear/documented what it's
// used for. Perhaps for link-time code generation (/LTCG)? If
@@ -1387,7 +1389,7 @@ namespace build2
case otype::e:
case otype::s:
{
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
// Using link.exe directly.
//
@@ -1616,7 +1618,7 @@ namespace build2
// something like this) we are going to redirect stdout to stderr. For
// sane compilers this should be harmless.
//
- bool filter (cid == "msvc" && lt != otype::a);
+ bool filter (cid == compiler_id::msvc && lt != otype::a);
process pr (*ld, args.data (), 0, (filter ? -1 : 2));
diff --git a/build2/cc/module.cxx b/build2/cc/module.cxx
index 6d8c799..885d6c7 100644
--- a/build2/cc/module.cxx
+++ b/build2/cc/module.cxx
@@ -219,6 +219,7 @@ namespace build2
rs.assign (x_sys_lib_dirs) = move (lib_dirs);
rs.assign (x_sys_inc_dirs) = move (inc_dirs);
+ cid = ci.id.value ();
rs.assign (x_id) = ci.id.string ();
rs.assign (x_id_type) = move (ci.id.type);
rs.assign (x_id_variant) = move (ci.id.variant);
diff --git a/build2/cc/module.hxx b/build2/cc/module.hxx
index 643cf89..eaa82eb 100644
--- a/build2/cc/module.hxx
+++ b/build2/cc/module.hxx
@@ -40,6 +40,8 @@ namespace build2
string tstd;
+ compiler_id::value_type cid;
+
private:
dir_paths
gcc_library_search_paths (process_path&, scope&) const; // gcc.cxx
diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx
index 1b67f5f..80f418c 100644
--- a/build2/cc/pkgconfig.cxx
+++ b/build2/cc/pkgconfig.cxx
@@ -446,7 +446,7 @@ namespace build2
if (!lops.empty ())
{
- if (cid == "msvc")
+ if (cid == compiler_id::msvc)
{
// Translate -L to /LIBPATH.
//
diff --git a/build2/cxx/init.cxx b/build2/cxx/init.cxx
index 578e617..d73f4cb 100644
--- a/build2/cxx/init.cxx
+++ b/build2/cxx/init.cxx
@@ -308,7 +308,8 @@ namespace build2
"cxx.install",
"cxx.uninstall",
- cast<string> (rs[cm.x_id]),
+ cm.cid,
+ cast<string> (rs[cm.x_id_variant]),
cast<uint64_t> (rs[cm.x_version_major]),
cast<uint64_t> (rs[cm.x_version_minor]),
cast<target_triplet> (rs[cm.x_target]),