From 64429b9e46c988256a1d196aa0159ba71744b332 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 26 Jun 2020 10:30:51 +0200 Subject: Handle #import in MSVC /showIncludes output --- libbuild2/cc/compile-rule.cxx | 35 ++++++++++++++++++++++++++++------- libbuild2/cc/msvc.cxx | 22 ++++++++++++++++------ 2 files changed, 44 insertions(+), 13 deletions(-) (limited to 'libbuild2/cc') diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx index 2af5012..8fe5e98 100644 --- a/libbuild2/cc/compile-rule.cxx +++ b/libbuild2/cc/compile-rule.cxx @@ -1568,10 +1568,26 @@ namespace build2 // // c1xx: fatal error C1083: Cannot open source file: 's.cpp': No such // file or directory + // + // And it turns out C1083 is also used when we are unable to open a type + // library specified with #import. In this case the error looks like this + // (at least in VC 14, 15, and 16): + // + // ...\comdef.h: fatal error C1083: Cannot open type library file: + // 'l.tlb': Error loading type library/DLL. + // - size_t + pair msvc_sense_diag (const string&, char); // msvc.cxx + static inline bool + msvc_header_c1083 (const string& l, const pair& pr) + { + return + l.compare (pr.second, 5, "c1xx:") != 0 && /* Not source file. */ + l.compare (pr.second, 9, "comdef.h:") != 0; /* Not type library. */ + } + // 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 // the good_error flag if it is an include error (which means the process @@ -1584,7 +1600,9 @@ namespace build2 // assert (!good_error); - size_t p (msvc_sense_diag (l, 'C')); + pair pr (msvc_sense_diag (l, 'C')); + size_t p (pr.first); + if (p == string::npos) { // Include note. @@ -1623,8 +1641,7 @@ namespace build2 return string (l, p); } - else if (l.compare (p, 4, "1083") == 0 && - l.compare (0, 5, "c1xx:") != 0 /* Not the main source file. */ ) + else if (l.compare (p, 4, "1083") == 0 && msvc_header_c1083 (l, pr)) { // Include error. // @@ -3816,7 +3833,7 @@ namespace build2 { // D8XXX are errors while D9XXX are warnings. // - size_t p (msvc_sense_diag (l, 'D')); + size_t p (msvc_sense_diag (l, 'D').first); if (p != string::npos && l[p] == '9') continue; @@ -4015,9 +4032,13 @@ namespace build2 // for (; !eof (getline (is, l)); ) { - size_t p (msvc_sense_diag (l, 'C')); - if (p != string::npos && l.compare (p, 4, "1083") != 0) + pair p (msvc_sense_diag (l, 'C')); + if (p.first != string::npos && + l.compare (p.first, 4, "1083") != 0 && + msvc_header_c1083 (l, p)) + { diag_stream_lock () << l << endl; + } } } diff --git a/libbuild2/cc/msvc.cxx b/libbuild2/cc/msvc.cxx index 8887555..20239c7 100644 --- a/libbuild2/cc/msvc.cxx +++ b/libbuild2/cc/msvc.cxx @@ -119,13 +119,17 @@ namespace build2 } } - // Sense whether this is a diagnostics line returning the postion of the - // NNNN code in XNNNN and npos otherwise. + // Sense whether this is a diagnostics line returning in the first half of + // pair the position of the NNNN code in XNNNN and npos otherwise. If the + // first half is not npos then the second half is the start of the last + // path component before first `:`. // - size_t + // foo\bar.h: fatal error C1083: ... + // + pair msvc_sense_diag (const string& l, char f) { - size_t p (l.find (':')); + size_t c (l.find (": ")), p (c); // Note that while the C-numbers seems to all be in the ' CNNNN:' form, // the D ones can be ' DNNNN :', for example: @@ -149,7 +153,13 @@ namespace build2 } } - return p; + if (p != string::npos) + { + c = path::traits_type::rfind_separator (l, c); + c = c != string::npos ? c + 1 : 0; + } + + return make_pair (p, c); } // Filter cl.exe and link.exe noise. @@ -167,7 +177,7 @@ namespace build2 { diag_stream_lock () << l << endl; - if (msvc_sense_diag (l, 'D') != string::npos) + if (msvc_sense_diag (l, 'D').first != string::npos) continue; } -- cgit v1.1