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

Mateusz Mikuła via cfe-dev cfe-dev at lists.llvm.org
Fri Nov 3 08:15:28 PDT 2017


The same thing apply to static libc++ on Windows and when cross compiling
to Windows.

Martell told me about his patch for this bug [0] and while it works the
same as passing mentioned flag to CC1 it looks better.
Any chances for accepting it soon?

[0] https://reviews.llvm.org/D33620

2017-09-19 14:35 GMT+02:00 Mateusz Mikuła <mati865 at gmail.com>:

> 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/
> 954fa97c5349029b75b63c58ae81c62a39fa9658/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):
>
>    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_traitsIcESaIcEENSt
>    7__cxx1112basic_stringIT_T0_T1_EES5_RKS8_[_ZStplIcSt11char_t
>    raitsIcESaIcEENSt7__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_traits
>    IcESaIcEENSt7__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_st
>    ringIDsSt11char_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_st
>    ringIDsSt11char_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_str
>    ingIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20f
>    orward_iterator_tag
>    0000000000000000 T _ZNSt7__cxx1112basic_stringIcS
>    t11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward
>    _iterator_tag
>
>    2. MinGW, static libstdc++:
>    0000000000000000 p .pdata$_ZNSt7__cxx1112basic_st
>    ringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20
>    forward_iterator_tag
>    0000000000000000 t .text$_ZNSt7__cxx1112basic_str
>    ingIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20f
>    orward_iterator_tag
>    0000000000000000 r .xdata$_ZNSt7__cxx1112basic_st
>    ringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20
>    forward_iterator_tag
>    0000000000000000 T _ZNSt7__cxx1112basic_stringIcS
>    t11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward
>    _iterator_tag
>
>    3. Linux, static libstdc++:
>    0000000000000000 W _ZNSt7__cxx1112basic_stringIcS
>    t11char_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
> 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/20171103/93beaca2/attachment.html>


More information about the cfe-dev mailing list