aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-06-26 10:30:51 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-06-26 10:30:51 +0200
commit64429b9e46c988256a1d196aa0159ba71744b332 (patch)
treedfb68d968c34fceb74c9472cf440a605a2eaaa23
parent038e93a15109d006fe82121c6bb8848338ee4abe (diff)
Handle #import in MSVC /showIncludes output
-rw-r--r--libbuild2/cc/compile-rule.cxx35
-rw-r--r--libbuild2/cc/msvc.cxx22
2 files changed, 44 insertions, 13 deletions
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<size_t, size_t>
msvc_sense_diag (const string&, char); // msvc.cxx
+ static inline bool
+ msvc_header_c1083 (const string& l, const pair<size_t, size_t>& 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<size_t, size_t> 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<size_t, size_t> 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<size_t, size_t>
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;
}