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