diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2018-11-05 09:01:53 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2018-11-05 09:01:53 +0200 |
commit | fa05a1a11dc42b393c99059cd0705912b48b050d (patch) | |
tree | 9d1a0660d4b75f0e7ef0b5e03d5a3b22638b9274 | |
parent | bebadb5220d7387ebbc0f916f35ce9f460f36a66 (diff) |
Handle MSVC command line warnings
-rw-r--r-- | build2/cc/compile-rule.cxx | 49 | ||||
-rw-r--r-- | build2/cc/msvc.cxx | 53 |
2 files changed, 66 insertions, 36 deletions
diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx index 1866e13..720b9d0 100644 --- a/build2/cc/compile-rule.cxx +++ b/build2/cc/compile-rule.cxx @@ -1337,40 +1337,14 @@ namespace build2 // translation, etc. // // It turns out C1083 is also used when we are unable to open the main - // source file and the error line looks like this: + // source file and the error line (which is printed after the first line + // containing the file name) looks like this: // // c1xx: fatal error C1083: Cannot open source file: 's.cpp': No such // file or directory - // Sense whether this is an include note (return npos) or a diagnostics - // line (return postion of the NNNN code in CNNNN). - // - static inline size_t - next_show_sense (const string& l) - { - size_t p (l.find (':')); - - for (size_t n (l.size ()); - p != string::npos; - p = ++p != n ? l.find (':', p) : string::npos) - { - auto isnum = [](char c) {return c >= '0' && c <= '9';}; - - if (p > 5 && - l[p - 6] == ' ' && - l[p - 5] == 'C' && - isnum (l[p - 4]) && - isnum (l[p - 3]) && - isnum (l[p - 2]) && - isnum (l[p - 1])) - { - p -= 4; // Start of the error code. - break; - } - } - - return p; - } + size_t + msvc_sense_diag (const string&, char); // msvc.cxx // Extract the include path from the VC /showIncludes output line. Return // empty string if the line is not an include note or include error. Set @@ -1384,7 +1358,7 @@ namespace build2 // assert (!good_error); - size_t p (next_show_sense (l)); + size_t p (msvc_sense_diag (l, 'C')); if (p == string::npos) { // Include note. @@ -2596,8 +2570,19 @@ namespace build2 // 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 (msvc_sense_diag (l, 'D') != string::npos) + continue; + text << l; bad_error = true; break; @@ -2746,7 +2731,7 @@ namespace build2 // for (; !eof (getline (is, l)); ) { - size_t p (next_show_sense (l)); + size_t p (msvc_sense_diag (l, 'C')); if (p != string::npos && l.compare (p, 4, "1083") != 0) diag_stream_lock () << l << endl; } diff --git a/build2/cc/msvc.cxx b/build2/cc/msvc.cxx index 9eb3de0..272b48c 100644 --- a/build2/cc/msvc.cxx +++ b/build2/cc/msvc.cxx @@ -42,17 +42,62 @@ namespace build2 return m; } + // Sense whether this is a diagnostics line returning the postion of the + // NNNN code in XNNNN and npos otherwise. + // + size_t + msvc_sense_diag (const string& l, char f) + { + size_t p (l.find (':')); + + // Note that while the C-numbers seems to all be in the ' CNNNN:' form, + // the D ones can be ' DNNNN :', for example: + // + // cl : Command line warning D9025 : overriding '/W3' with '/W4' + // + for (size_t n (l.size ()); + p != string::npos; + p = ++p != n ? l.find_first_of (": ", p) : string::npos) + { + auto isnum = [](char c) {return c >= '0' && c <= '9';}; + + if (p > 5 && + l[p - 6] == ' ' && + l[p - 5] == f && + isnum (l[p - 4]) && + isnum (l[p - 3]) && + isnum (l[p - 2]) && + isnum (l[p - 1])) + { + p -= 4; // Start of the error code. + break; + } + } + + return p; + } + // Filter cl.exe and link.exe noise. // void msvc_filter_cl (ifdstream& is, const path& src) { // While it appears VC always prints the source name (event if the - // file does not exist), let's do a sanity check. + // file does not exist), let's do a sanity check. Also handle the + // command line warnings which come before the file name. // - string l; - if (getline (is, l) && l != src.leaf ().string ()) - diag_stream_lock () << l << endl; + for (string l; !eof (getline (is, l)); ) + { + if (l != src.leaf ().string ()) + { + diag_stream_lock () << l << endl; + + if (msvc_sense_diag (l, 'D') != string::npos) + continue; + } + + break; + } } void |