<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body smarttemplateinserted="true" text="#000000" bgcolor="#FFFFFF">
<p>Clang doesn't work very well with static libstdc++ build for
MinGW resulting in "multiple definition ..." or "undefined
reference" to the symbols.<br>
</p>
<p>Let's consider following code (removed includes and main for
readability):</p>
<ol>
<li>multiple definition:<br>
<br>
<div style="color: #d4d4d4;background-color: #1e1e1e;font-family: Consolas, 'Courier New', monospace;font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;"><div><span style="color: #d4d4d4;"> std::string a = </span><span style="color: #ce9178;">"a"</span><span style="color: #d4d4d4;">;</span></div><div><span style="color: #d4d4d4;"> std::string b = </span><span style="color: #ce9178;">'@'</span><span style="color: #d4d4d4;"> + a;</span></div></div>
<br>
This simple code build with `-static` flag will cause this
error:<br>
<br>
D:\msys64\mingw64\lib\gcc\x86_64-w64-mingw32\6.3.0\libstdc++.a(string-inst.o):(.text$_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_[_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_]+0x0):
multiple definition of `std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >
std::operator+<char, std::char_traits<char>,
std::allocator<char> >(char,
std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >
const&)'<br>
D:\msys64\tmp\string-e39e30.o:(.text[_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_]+0x0):
first defined here<br>
clang++.exe: error: linker command failed with exit code 1 (use
-v to see invocation)<br>
<br>
</li>
<li>undefined reference<br>
<br>
<div style="color: #d4d4d4;background-color: #1e1e1e;font-family: Consolas, 'Courier New', monospace;font-weight: normal;font-size: 14px;line-height: 19px;white-space: pre;"><div><span style="color: #d4d4d4;"> std::u16string b;</span></div></div>
<br>
This time adding `-static` to clang arguments will cause this
error (note: `__imp___cxa_call_unexpected` exists only in
dynamic libstdc++):<br>
<br>
D:\msys64\tmp\string-7062fd.o:(.text[_ZNSt7__cxx1112basic_stringIDsSt11char_traitsIDsESaIDsEED2Ev]+0x4a):
undefined reference to `__imp___cxa_call_unexpected'<br>
D:\msys64\tmp\string-7062fd.o:(.text[__clang_call_terminate]+0x7):
undefined reference to `__imp___cxa_begin_catch'<br>
D:\msys64\tmp\string-7062fd.o:(.text[_ZNSt7__cxx1112basic_stringIDsSt11char_traitsIDsESaIDsEE10_M_destroyEy]+0x72):
undefined reference to `__imp___cxa_call_unexpected'<br>
clang++.exe: error: linker command failed with exit code 1 (use
-v to see invocation)<br>
<br>
</li>
</ol>
<p>It is probably related to the way the symbols are build into
static libstdc++ for MinGW.<br>
Let's take a look at weak symbol from different test cases:</p>
<ol>
<li>MinGW, dynamic libstdc++:<br>
0000000000000000 I
__imp__ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag<br>
0000000000000000 T
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag<br>
<br>
</li>
<li>MinGW, static libstdc++:<br>
0000000000000000 p
.pdata$_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag<br>
0000000000000000 t
.text$_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag<br>
0000000000000000 r
.xdata$_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag<br>
0000000000000000 T
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag<br>
<br>
</li>
<li>Linux, static libstdc++:<br>
0000000000000000 W
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag</li>
</ol>
<p>This greatly reduces Clang usefulness on Windows with MinGW.<br>
All responses are welcome.</p>
<p>Best Regards,<br>
Mateusz<br>
</p>
</body>
</html>