Hello,
I am currently testing clang compilation and ran into several issues. Due to #1669 being unfixed at this moment I mostly relied on 3.8.0 win32 and 3.9.0 rc3 win32, however I tested mingw-w64-i686-clang (3.8) as well. Due to reports getting large I decided to split them.
2. A number of symbols present in libstdc++ headers are exported by libstdc++.a
The issue is pretty straight-forward. When performing optimised static linking to libstdc++.a one is likely to face multiple symbol definition issue.
Minimal sample (issue confirmed on any clang):
_clang++ -target i686-w64-mingw32 -static -std=c++11 -pthread -O1 example2.cpp_
#include <string>
int main () {
auto s = std::string("1234");
auto ws = std::u16string(u"1234");
auto s1 = "#" + s;
}
This will produce the following error message:
C:\msys64\mingw32\lib\gcc\i686-w64-mingw32\6.1.0\libstdc++.a(string-inst.o):(.text$_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_[__ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_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 const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
C:\msys64\tmp\example2-b21e71.o:(.text[__ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_]+0x0): first defined here
C:\msys64\mingw32\lib\gcc\i686-w64-mingw32\6.1.0\libstdc++.a(string-inst.o):(.text$_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag[__ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag]+0x0): multiple definition of `void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag)'
C:\msys64\tmp\example2-b21e71.o:(.text[__ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag]+0x0): first defined here
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
As it can be seen from the error the bug is caused by exported symbols in libstdc++.a. I do not expect it to export any _M_construct but it does this for char-instantiated one. I.e. u16string has no this bug. One is also required to enable optimisation (e.g. -O1) to get compilation failure.
I could imagine various ways to get this fixed, for example, SFINAE. I used a force_inline attribute.
Suggested changes:
_msys64\mingw32\include\c++\6.1.0\bits\basic_string.h_
// For forward_iterators up to random_access_iterators, used for
// string::iterator, _CharT*, etc.
template<typename _FwdIterator>
#ifdef __clang__
__attribute__((always_inline))
#endif
void
_M_construct(_FwdIterator __beg, _FwdIterator __end,
std::forward_iterator_tag);
and
/**
* @brief Concatenate C string and string.
* @param __lhs First string.
* @param __rhs Last string.
* @return New string with value of @a __lhs followed by @a __rhs.
*/
template<typename _CharT, typename _Traits, typename _Alloc>
#ifdef __clang__
__attribute__((always_inline))
#endif
basic_string<_CharT,_Traits,_Alloc>
operator+(const _CharT* __lhs,
const basic_string<_CharT,_Traits,_Alloc>& __rhs);
These methods may not be the only ones but are so far the only noticed ones by myself.
Also, I had to pass -pthread to get the sample compile without undefined pthread symbols. This feels undesired but I do not know any details about who is responsible here.
A bit more:
_msys64\mingw32\include\c++\6.1.0\bits\basic_string.h_:
/**
* @brief Construct string as copy of a range.
* @param __beg Start of range.
* @param __end End of range.
* @param __a Allocator to use (default is default allocator).
*/
#if __cplusplus >= 201103L
template<typename _InputIterator,
typename = std::_RequireInputIter<_InputIterator>>
#else
template<typename _InputIterator>
#endif
#ifdef __clang__
__attribute__((always_inline))
#endif
basic_string(_InputIterator __beg, _InputIterator __end,
const _Alloc& __a = _Alloc())
: _M_dataplus(_M_local_data(), __a)
{ _M_construct(__beg, __end); }
_msys64\mingw32\include\c++\6.1.0\bits\shared_ptr_base.h_:
#ifdef __clang__
__attribute__((always_inline))
#endif
_M_release() noexcept
{
// Be race-detector-friendly. For more info see bits/c++config.
and
// Called when _M_weak_count drops to zero.
virtual void
_M_destroy() noexcept
#ifdef __clang__
;
#else
{ delete this; }
#endif
_msys64\mingw32\include\c++\6.1.0typeinfo_:
#ifdef __clang__
__attribute__((always_inline))
#endif
bool operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT
I think the question is: "Why does it work on Linux but not here?".
@mati865 the question is: "Why did it dare to link the supposedly inline functions into a static library".
Issue persists as of 3.9.1
What is that status of this? This still occurs in clang 5.0.
I have reported it some time ago to upstream but looks like we need to take
care of it ourselves...
17.09.2017 01:05 "K. S. Ernest (iFire) Lee" notifications@github.com
napisał(a):
What is that status of this? This still occurs in clang 5.0.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Alexpux/MINGW-packages/issues/1677#issuecomment-330000109,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABHsdtOlhCjFyE8ohO_pjRMZ5OUUEatxks5sjFQdgaJpZM4JuvXC
.
LINKFLAGS='-Wl,--allow-multiple-definition' This is an ugly workaround.
@fire it causes segfaults in specific cases so it's an unsafe workaround.
It happened to me, when building with clang++ -std=c++17 -static -O <two files here>
B:\msys64\mingw64\lib\gcc\x86_64-w64-mingw32\7.3.0\libstdc++.a(string-inst.o):(.text$_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEyyPKcy[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEyyPKcy]+0x0): definiciones múltiples de `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_mutate(unsigned long long, unsigned long long, char const*, unsigned long long)'
B:\msys64\tmp\narc-5ea9c5.o:(.text[_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEyyPKcy]+0x0): primero se define aquÃ
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
By removing this line in my code
mNarcFiles[iFile].resize(fileSize);
the linkage error fixes.
This looks like it was probably caused by my change in r268331, which makes us emit functions into subsections called ".text" instead of subsections called ".text$_Z3foov" where _Z3foov is the symbol name. I think I didn't realize how incompatible the COFF port of ld.bfd is with the Visual C++ linker. I kind of assumed all that low-level object file stuff would be the same, since it's the most well-documented thing we have to work with. Now I'm really sad. :(
Here is a really small example of the inline function ABI incompatibility:
$ cat a.cpp
inline int foo(int a, int b) { return a + b; }
int bar(void);
int main() { return foo(1, 2) + bar(); }
$ cat b.cpp
inline int foo(int a, int b) { return a + b; }
int bar() { return foo(3, 4); }
$ gcc a.cpp -c -o a.o && clang --target=x86_64-w64-windows-gnu -c b.cpp -o b.o
$ gcc a.o b.o -o a.exe
b.o:(.text[_Z3fooii]+0x0): multiple definition of `foo(int, int)'
a.o:a.cpp:(.text$_Z3fooii[_Z3fooii]+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
Going back to the section name .text$_Z3fooii in clang makes the problem go away.
@rnk, that's quite unpleasant but at least the problem is more clear now. Will you submit a patch to clang upstream so that it could land in 7.0.0 release at least?
Most helpful comment
Here is a really small example of the inline function ABI incompatibility:
Going back to the section name
.text$_Z3fooiiin clang makes the problem go away.