[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