[cfe-dev] [MinGW] Clang issues with static libstdc++

Mateusz Mikuła via cfe-dev cfe-dev at lists.llvm.org
Tue Sep 19 05:35:23 PDT 2017


This is what I've got for MSYS2 [0] and looks like there are no
regressions but I couldn't get `make check` to run (multiple definition
errors in LLVM).
I haven't tested this patch on Ubuntu but adding `-flto-visibility-
public-std` to CC1 solves this issue [1] so I belive  will help there.
Instead of reverting dllimport changes final solution could be similar
to this patch but probably it would require writing some tests but I
doubt I'll have time to learn how to do it with clang soon.

[0] https://github.com/mati865/MINGW-packages/blob/954fa97c5349029b75b6
3c58ae81c62a39fa9658/mingw-w64-clang/0106-MinGW-use-flto-visibility-
public-std-CC1-arg-to-get-.patch[1] https://bugs.llvm.org/show_bug.cgi?
id=34122
W dniu nie, 17.09.2017 o godzinie 09∶49 -0700, użytkownik Saleem
Abdulrasool napisał:
> I think that making it conditional to Windows and not the MSVC ABI
> and a static link to the C++ runtime sounds reasonable.
> 
> On Sun, Sep 17, 2017 at 4:40 AM, Mateusz Mikuła <mati865 at gmail.com>
> wrote:
> >   
> >     
> >   
> >   
> >     
> >       
> >         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>
> > >             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>
> > > > >                           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):
> > > > > >                               
> > > > > >                                 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__cxx111
> > > > > > 2basic_stringIT_T0_T1_EES5_RKS8_[_ZStplIcSt11char_traitsIcE
> > > > > > SaIcEENSt7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_]+0x0):
> > > > > >                                   multiple definition of
> > > > > >                                   `std::__cxx11::basic_stri
> > > > > > ng<char,
> > > > > >                                   std::char_traits<char>,
> > > > > >                                   std::allocator<char> >
> > > > > >                                   std::operator+<char,
> > > > > >                                   std::char_traits<char>,
> > > > > >                                   std::allocator<char>
> > > > > > >(char,
> > > > > >                                   std::__cxx11::basic_strin
> > > > > > g<char,
> > > > > >                                   std::char_traits<char>,
> > > > > >                                   std::allocator<char> >
> > > > > >                                   const&)'
> > > > > > 
> > > > > >                                   D:\msys64\tmp\string-
> > > > > > e39e30.o:(.text[_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx11
> > > > > > 12basic_stringIT_T0_T1_EES5_RKS8_]+0x0):
> > > > > >                                   first defined here
> > > > > > 
> > > > > >                                   clang++.exe: error:
> > > > > > linker command
> > > > > >                                   failed with exit code 1
> > > > > > (use -v to see
> > > > > >                                   invocation)
> > > > > > 
> > > > > >                                   
> > > > > > 
> > > > > >                                 
> > > > > >                                 undefined reference
> > > > > > 
> > > > > >                                   
> > > > > > 
> > > > > >                                       std::u16string b;
> > > > > >                                   
> > > > > > 
> > > > > >                                   This time adding `-
> > > > > > static` to clang
> > > > > >                                   arguments will cause this
> > > > > > error (note:
> > > > > >                                   `__imp___cxa_call_unexpec
> > > > > > ted` exists
> > > > > >                                   only in dynamic
> > > > > > libstdc++):
> > > > > > 
> > > > > >                                   
> > > > > > 
> > > > > >                                   D:\msys64\tmp\string-
> > > > > > 7062fd.o:(.text[_ZNSt7__cxx1112basic_stringIDsSt11char_trai
> > > > > > tsIDsESaIDsEED2Ev]+0x4a):
> > > > > >                                   undefined reference to
> > > > > >                                   `__imp___cxa_call_unexpec
> > > > > > ted'
> > > > > > 
> > > > > >                                   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_trai
> > > > > > tsIDsESaIDsEE10_M_destroyEy]+0x72):
> > > > > >                                   undefined reference to
> > > > > >                                   `__imp___cxa_call_unexpec
> > > > > > ted'
> > > > > > 
> > > > > >                                   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:
> > > > > >                               
> > > > > >                                 MinGW, dynamic libstdc++:
> > > > > > 
> > > > > >                                   0000000000000000 I
> > > > > >                                   __imp__ZNSt7__cxx1112basi
> > > > > > c_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8
> > > > > > _St20forward_iterator_tag
> > > > > > 
> > > > > >                                   0000000000000000 T
> > > > > >                                   _ZNSt7__cxx1112basic_stri
> > > > > > ngIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20f
> > > > > > orward_iterator_tag
> > > > > > 
> > > > > >                                   
> > > > > > 
> > > > > >                                 
> > > > > >                                 MinGW, static libstdc++:
> > > > > > 
> > > > > >                                   0000000000000000 p
> > > > > >                                   .pdata$_ZNSt7__cxx1112bas
> > > > > > ic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S
> > > > > > 8_St20forward_iterator_tag
> > > > > > 
> > > > > >                                   0000000000000000 t
> > > > > >                                   .text$_ZNSt7__cxx1112basi
> > > > > > c_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8
> > > > > > _St20forward_iterator_tag
> > > > > > 
> > > > > >                                   0000000000000000 r
> > > > > >                                   .xdata$_ZNSt7__cxx1112bas
> > > > > > ic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S
> > > > > > 8_St20forward_iterator_tag
> > > > > > 
> > > > > >                                   0000000000000000 T
> > > > > >                                   _ZNSt7__cxx1112basic_stri
> > > > > > ngIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20f
> > > > > > orward_iterator_tag
> > > > > > 
> > > > > >                                   
> > > > > > 
> > > > > >                                 
> > > > > >                                 Linux, static libstdc++:
> > > > > > 
> > > > > >                                   0000000000000000 W
> > > > > >                                   _ZNSt7__cxx1112basic_stri
> > > > > > ngIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20f
> > > > > > orward_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
> > > > > > 
> > > > > >                             http://lists.llvm.org/cgi-bin/m
> > > > > > ailman/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/20170919/758b6b87/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: This is a digitally signed message part
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170919/758b6b87/attachment.sig>


More information about the cfe-dev mailing list