aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/cc
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-10-11 11:36:56 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-10-11 11:36:56 +0200
commit19e1b71a396e6b82c8e8a4602446ada0173579b9 (patch)
tree5a8c4cf56ba7afdc6041cf5e083fbb20f07361e6 /libbuild2/cc
parent2388953dffb456b6905d789fa85186810bccaae3 (diff)
Various fixes to make clang-cl work
Note that clang-cl's /showInclude output differs from cl's in the face of missing headers. In particular, it does not issue C1083 that we expect. As a result, this part of clang-cl's support is currently non-functional (the rest seems to work, however).
Diffstat (limited to 'libbuild2/cc')
-rw-r--r--libbuild2/cc/compile-rule.cxx74
-rw-r--r--libbuild2/cc/guess.cxx2
2 files changed, 45 insertions, 31 deletions
diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx
index c46355c..d4ea390 100644
--- a/libbuild2/cc/compile-rule.cxx
+++ b/libbuild2/cc/compile-rule.cxx
@@ -1507,8 +1507,9 @@ namespace build2
}
// VC /showIncludes output. The first line is the file being compiled
- // (handled by our caller). Then we have the list of headers, one per
- // line, in this form (text can presumably be translated):
+ // (unless clang-cl; handled by our caller). Then we have the list of
+ // headers, one per line, in this form (text can presumably be
+ // translated):
//
// Note: including file: C:\Program Files (x86)\[...]\iostream
//
@@ -1518,6 +1519,9 @@ namespace build2
// x.cpp(3): fatal error C1083: Cannot open include file: 'd/h.hpp':
// No such file or directory
//
+ // @@ TODO: this is not the case for clang-cl: it issues completely
+ // different diagnostics and before any /showIncludes lines.
+ //
// Distinguishing between the include note and the include error is
// easy: we can just check for C1083. Distinguising between the note and
// other errors/warnings is harder: an error could very well end with
@@ -2994,6 +2998,10 @@ namespace build2
{
case compiler_class::msvc:
{
+ // /F*: style option availability (see perform_update()).
+ //
+ bool fc (cmaj >= 18 && cvariant != "clang");
+
args.push_back ("/nologo");
// See perform_update() for details on overriding the default
@@ -3015,7 +3023,7 @@ namespace build2
psrc = auto_rmfile (t.path () + x_pext);
- if (cast<uint64_t> (rs[x_version_major]) >= 18)
+ if (fc)
{
args.push_back ("/Fi:");
args.push_back (psrc.path.string ().c_str ());
@@ -3673,33 +3681,38 @@ namespace build2
{
case compiler_class::msvc:
{
+ // The first line should be the file we are compiling,
+ // unless this is clang-cl. If it is not, then something
+ // went wrong even before we could compile anything
+ // (e.g., file does not exist). In this case the first
+ // line (and everything after it) is presumably
+ // diagnostics.
+ //
+ // It can, however, be a command line warning, for
+ // example:
+ //
+ // cl : Command line warning D9025 : overriding '/W3' with '/W4'
+ //
+ // So we try to detect and skip them assuming they will
+ // also show up during the compilation proper.
+ //
if (first)
{
- // The first line should be the file we are compiling.
- // If it is not, then something went wrong even before
- // we could compile anything (e.g., file does not
- // exist). In this case the first line (and everything
- // after it) is presumably diagnostics.
- //
- // It can, however, be a command line warning, for
- // example:
- //
- // cl : Command line warning D9025 : overriding '/W3' with '/W4'
- //
- // So we try to detect and skip them assuming they
- // will also show up during the compilation proper.
- //
- if (l != src.path ().leaf ().string ())
+ if (cvariant != "clang")
{
- // D8XXX are errors while D9XXX are warnings.
- //
- size_t p (msvc_sense_diag (l, 'D'));
- if (p != string::npos && l[p] == '9')
- continue;
+ if (l != src.path ().leaf ().string ())
+ {
+ // D8XXX are errors while D9XXX are warnings.
+ //
+ size_t p (msvc_sense_diag (l, 'D'));
+ if (p != string::npos && l[p] == '9')
+ continue;
- text << l;
- bad_error = true;
- break;
+ text << l;
+ bad_error = true;
+ break;
+ }
+ // Fall through.
}
first = false;
@@ -5649,7 +5662,6 @@ namespace build2
touch (ctx, md.dd, false, verb_never);
const scope& bs (t.base_scope ());
- const scope& rs (*bs.root_scope ());
otype ot (compile_type (t, ut));
linfo li (link_info (bs, ot));
@@ -5708,7 +5720,9 @@ namespace build2
// in VS2013/12.0. Why do we bother? Because the command line suddenly
// becomes readable.
//
- uint64_t ver (cast<uint64_t> (rs[x_version_major]));
+ // Also, clang-cl does not yet support them, at least not in 8 or 9.
+ //
+ bool fc (cmaj >= 18 && cvariant != "clang");
args.push_back ("/nologo");
@@ -5768,7 +5782,7 @@ namespace build2
//
if (find_options ({"/Zi", "/ZI"}, args))
{
- if (ver >= 18)
+ if (fc)
args.push_back ("/Fd:");
else
out1 = "/Fd";
@@ -5779,7 +5793,7 @@ namespace build2
args.push_back (out1.c_str ());
}
- if (ver >= 18)
+ if (fc)
{
args.push_back ("/Fo:");
args.push_back (relo.string ().c_str ());
diff --git a/libbuild2/cc/guess.cxx b/libbuild2/cc/guess.cxx
index cf78774..7b993f0 100644
--- a/libbuild2/cc/guess.cxx
+++ b/libbuild2/cc/guess.cxx
@@ -1822,7 +1822,7 @@ namespace build2
return compiler_info {
move (gr.path),
move (gr.id),
- compiler_class::gcc,
+ cl ? compiler_class::msvc : compiler_class::gcc,
move (ver),
move (var_ver),
move (gr.signature),