[libcxx-dev] build issue on mingw gcc, need some help

Martin Storsjö via libcxx-dev libcxx-dev at lists.llvm.org
Tue Jan 8 13:27:31 PST 2019


On Tue, 8 Jan 2019, Maarten Verhage via libcxx-dev wrote:

> Hi Martin and others,
>
>>> Somehow the file libc++abi.dll is build but it is just about 50 kB and 
>>> llvm-readobj -coff-exports shows nothing.
>>>
>>> My question is what kind of define or flag might have caused this to 
>>> happen?
>>> And how can I correct it?
>>
>
> To answer my own question: The low libc++abi.dll size was due a missing 
> linker option:
> -Wl,--whole-archive cxx_objects.a -Wl,--no-whole-archive

I presume you mean cxxabi_objects.a, for building libc++abi.dll? You don't 
want to do that with cxx_objects.a, otherwise you'd end up including all 
of libc++ in libc++abi.

The whole concept of -Wl,--whole-archive and a static archive when linking 
a dynamic library is a rather cmake specific roundabout way of doing 
things - if you are building your own makefiles, you could just as well 
pass the object files directly to the linker, especially as there 
shouldn't be any issue with command line length with the relatively low 
number of object files in libc++/libc++abi.

>> First off, I haven't been able to build libc++abi standalone as a DLL, as 
>> there are some amount of circular dependencies between libc++abi and 
>> libc++. (If linking doesn't end up including everything, you might not 
>> notice this.)
>
> As libc++ and libc++abi sources are quite large. I first setup a little 
> example with two dlls that use functions of each. In that makefile I first 
> build two import libraries for each dll with dlltool and later linking the 
> object code against the import library of the other dll. No problems.
>
> Regarding the circular dependencies I believe a link commands such as:
> -Wl,--start-group <multiple circular dependency libs> -Wl,--end-group
> is the proper way to ask gcc to figure this out.
>
> Something on SO about this:
> https://stackoverflow.com/questions/9380363/resolving-circular-dependencies-by-linking-the-same-library-twice

This is unrelated. Resolving circular dependencies between two static 
libraris can indeed be done this way (with ld.bfd; with lld it's not 
necessary).

Resolving circular dependencies between two dynamic libraries does instead 
need you do to bootstrapping tricks with import libraries, which it seems 
you are trying to do.

>> Due to this, when building libc++ as a DLL, I build libc++abi as a static 
>> library, but manually override defines to get the same effect as if I had 
>> built libc++abi dynamically, and making the libc++ includes behave as if 
>> building libc++ itself, as the object files will be included within 
>> libc++.dll. Likewise, for libc++, I add defines to make libc++abi headers 
>> behave as if building libc++abi itself:
>>
>> https://github.com/mstorsjo/llvm-mingw/blob/b9eb66bc/build-libcxx.sh#L143
>> https://github.com/mstorsjo/llvm-mingw/blob/b9eb66bc/build-libcxx.sh#L181
>>
>> In the end, I top it off by linking the DLL with -Wl,--export-all-symbols. 
>> Without that, for me, a number of symbols aren't exported even if they are 
>> expected to. I believe that's a Clang-specific issue though, but I haven't 
>> analyzed it further yet, as this hack/workaround seems to work well enough 
>> for now.
>>
>> // Martin
>
> I hope to get it a little better than -Wl,--export-all-symbols.

Don't comment on that until you actually have gotten it all done - that 
part is not related to how they're built and linked, but whether the 
compiler emits dllexport for all the necessary symbols.

I've looked a bit closer on that matter now, and it's related to how 
libcxx does explicit template instantiation with visibility attributes 
(dllexport). Neither g++ nor clang in mingw mode will create dllexports 
for symbols from an explicit template instantiation with a dllexport 
attribute, while msvc and clang in msvc mode does. I can open a bug report 
with full details later.

> Ok, please read with me, I try to be as clear as I could:
> What I'm facing right now. The shared library build of libc++abi needs to 
> process the import library: libc++.dll.a. But the linker gives undefined 
> references to things like __imp__ZNSt8bad_castC1Ev.

Do the undefined referenes come from libc++.dll.a or the libc++abi object 
files themselves? The former should be a plain import library which 
shouldn't give any undefined references to that. And the libc++abi object 
files should define the symbol _ZNSt8bad_castC1Ev, shouldn't produce any 
references to the __imp_ prefixed symbol (since it's declared dllexport 
while building libc++abi).

> When I run the nm tool on the archive libary cxx_objects.a I see symbols 
> like these are all available.

What? cxx_objects.a, I presume, is an archive of the object files from 
libcxx. That should have undefined references to _ZNSt8bad_castC1Ev (or 
with an __imp_ prefix), but shouldn't provide a definition of it.

> But I believe when I run the dlltool to make the import libary from 
> cxx_objects.a I loose the visibility of the symbols (exported stuff).

Sorry but you have to be much much more precise than this, it's impossible 
to know exactly what you're implying here. Without even knowing what 
dlltool command you're running, on what files, it's pretty much impossible 
to say anything about this.

> In the libcxx source folder in the subdirectory lib there are exp files 
> that contain symbols for exports which needs to be applied somehow to 
> the build of libc++. The file libc++abi2.exp contain the exports which I 
> believe I would need. The symbol names match. In the build of libc++ in 
> the cmake style they seem to do it on the final linking stage with 
> options like -Wl,-reexported_symbols_list,<.exp file>.

> I my situation it seems to make more sense to apply these symbols to the 
> creation of the import library. But I cannot figure out with GNU binutil 
> tool I should use for this and what options to use. I know I can do an 
> --input-def option on the call to dlltool. But that libc++abi2.exp is 
> not a Windows def file. So, I do need a little help with this.

You should be able to create a def file from it just by adding two lines 
at the top, "LIBRARY libc++abi.dll" and "EXPORTS" at the top of it, and 
create an import library with "dlltool -m <machine> -d libc++abi.def -l 
libc++abi.dll.a".

// Martin



More information about the libcxx-dev mailing list