[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