[cfe-dev] [MinGW] Clang issues with static libstdc++
Mateusz Mikuła via cfe-dev
cfe-dev at lists.llvm.org
Sun Sep 17 04:40:27 PDT 2017
Sorry Saleem, looks like this topic got lost on my TODO.
Adding `-flto-visibility-public-std` to CC1 helps with undefined
reference to `_imp___cxa*` errors.
Is it safe enough to make it default flag for MSYS2?
If so I'll patch clang to use it by default.
------ Original Message ------
Subject: Re: [cfe-dev] [MinGW] Clang issues with static libstdc++
Date: Mon, 26 Jun 2017 21:51:19 -0700
To: Mateusz Mikuła, Reid Kleckner, Cfe-dev
From: Saleem Abdulrasool
> Building with `-flto-visibility-public-std` should allow the static
> build to work. I think that having support for a static c++ library
> makes sense, but need to expose it through a flag to have it behave
> like `/MT` vs `/MD`.
>
> There is a small performance cost for the thunks, plus binary size
> benefits for very large binaries (especially with the BFD linker).
> IIRC, some versions of lldb also had trouble with the import thunks
> when generated by the BFD linker. I would rather have this be the
> default and have an opt-out mechanism rather than the inverse (a la
> `-fno-plt`).
>
> On Sun, Jun 25, 2017 at 1:20 PM, Mateusz Mikuła <mati865 at gmail.com
> <mailto:mati865 at gmail.com>> wrote:
>
> I've been quite busy lately and lost track on recent fixes.
> Is there any progress on this or should I apply for bugzilla
> account and forward it there?
>
> On Mon, 2017-04-17 at 11∶56 -0700, Reid Kleckner wrote:
>> The __imp___cxa_begin_catch error seems related to this code
>> in CodeGenModule::CreateRuntimeFunction:
>> if (!Local && getTriple().isOSBinFormatCOFF() &&
>> !getCodeGenOpts().LTOVisibilityPublicStd) {
>> const FunctionDecl *FD = GetRuntimeFunctionDecl(Context,
>> Name);
>> if (!FD || FD->hasAttr<DLLImportAttr>()) {
>>
>> F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
>> F->setLinkage(llvm::GlobalValue::ExternalLinkage);
>> }
>> }
>>
>> This code assumes that all compiler-referenced runtime functions
>> on COFF are dllimport, unless we happen to see a prototype for
>> them during compilation that says otherwise. Saleem felt we
>> shouldn't rely on the import thunks that the linker generates
>> when you reference an imported function but forget to declare it
>> as dllimport during compilation. It has some performance
>> benefits, but it never really bothered me. Most users don't
>> complain about the extra absolute branch imposed by the PLT on
>> ELF, and those that do are getting -fno-plt soon.
>>
>> Anyway, you can see the code difference easily here:
>>
>> $ cat t.cpp
>> void g();
>> void f() {
>> try {
>> g();
>> } catch (...) {
>> }
>> }
>>
>> $ clang -O1 -S t.cpp --target=x86_64-windows-gnu -o - | grep __cxa
>> callq *__imp___cxa_begin_catch(%rip)
>> rex64 jmpq *__imp___cxa_end_catch(%rip) # TAILCALL
>>
>> $ gcc -O1 -S t.cpp -o - | grep __cxa
>> call __cxa_begin_catch
>> call __cxa_end_catch
>> .def __cxa_begin_catch; .scl 2; .type
>> 32; .endef
>> .def __cxa_end_catch; .scl 2; .type
>> 32; .endef
>>
>> The other error looks like some kind of COMDAT disagreement
>> between GCC and Clang that will require further investigation. It
>> might relate to our choice to stop using ".text$function_name"
>> for the section.
>>
>> On Mon, Apr 17, 2017 at 11:06 AM, Mateusz Mikuła via cfe-dev
>> <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>>>
>>> Clang doesn't work very well with static libstdc++ build for
>>> MinGW resulting in "multiple definition ..." or "undefined
>>> reference" to the symbols.
>>>
>>> Let's consider following code (removed includes and main for
>>> readability):
>>>
>>> 1. multiple definition:
>>>
>>> std::string a = "a";
>>> std::string b = '@'+ a;
>>>
>>> This simple code build with `-static` flag will cause this
>>> error:
>>>
>>> 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&)'
>>> D:\msys64\tmp\string-e39e30.o:(.text[_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_]+0x0):
>>> first defined here
>>> clang++.exe: error: linker command failed with exit code 1
>>> (use -v to see invocation)
>>>
>>> 2. undefined reference
>>>
>>> std::u16string b;
>>>
>>> This time adding `-static` to clang arguments will cause
>>> this error (note: `__imp___cxa_call_unexpected` exists only
>>> in dynamic libstdc++):
>>>
>>> D:\msys64\tmp\string-7062fd.o:(.text[_ZNSt7__cxx1112basic_stringIDsSt11char_traitsIDsESaIDsEED2Ev]+0x4a):
>>> undefined reference to `__imp___cxa_call_unexpected'
>>> D:\msys64\tmp\string-7062fd.o:(.text[__clang_call_terminate]+0x7):
>>> undefined reference to `__imp___cxa_begin_catch'
>>> D:\msys64\tmp\string-7062fd.o:(.text[_ZNSt7__cxx1112basic_stringIDsSt11char_traitsIDsESaIDsEE10_M_destroyEy]+0x72):
>>> undefined reference to `__imp___cxa_call_unexpected'
>>> clang++.exe: error: linker command failed with exit code 1
>>> (use -v to see invocation)
>>>
>>> It is probably related to the way the symbols are build into
>>> static libstdc++ for MinGW.
>>> Let's take a look at weak symbol from different test cases:
>>>
>>> 1. MinGW, dynamic libstdc++:
>>> 0000000000000000 I
>>> __imp__ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag
>>> 0000000000000000 T
>>> _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag
>>>
>>> 2. MinGW, static libstdc++:
>>> 0000000000000000 p
>>> .pdata$_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag
>>> 0000000000000000 t
>>> .text$_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag
>>> 0000000000000000 r
>>> .xdata$_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag
>>> 0000000000000000 T
>>> _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag
>>>
>>> 3. Linux, static libstdc++:
>>> 0000000000000000 W
>>> _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag
>>>
>>> This greatly reduces Clang usefulness on Windows with MinGW.
>>> All responses are welcome.
>>>
>>> Best Regards,
>>> Mateusz
>>>
>>>
>>> _______________________________________________
>>> cfe-dev mailing list
>>> cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>> <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev>
>>>
>>
>
>
>
> --
> Saleem Abdulrasool
> compnerd (at) compnerd (dot) org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170917/cdee20d2/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170917/cdee20d2/attachment.sig>
More information about the cfe-dev
mailing list