On Fri, 15 Feb 2019, Bruce Cartland via curl-library wrote:
I'm finding this a bit bizarre. I feel like I'm missing something obvious. I have a very simple test dll with function "int zzz_init(void)" that uses curl. Dynamically: ------------ /C/msys64/mingw32/bin/gcc.exe -O2 -Wl,--allow-multiple-definition -shared -o libzzz.dll -Wl,--out-implib,libzzz.dll.a -Wl,--major-image-version,3,--minor-image-version,0 -Wl,--whole-archive CMakeFiles/zzz.dir/objects.a -Wl,--no-whole-archive -lcurl -Wl,-Bstatic -lssl -lcrypto -lxml2 -ljansson -static-libgcc -lpsl -lidn2 -lnghttp2 -lcrypt32 -lunistring -lssh2 -lbrotlidec-static -lbrotlicommon-static -lz -llzma -lintl -liconv -lwldap32 -lwsock32 -lws2_32 -lgdi32 -lcomdlg32 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 zzz_init exists: $ nm _build/mingw32-Release/atoakm3/libzzz.dll.a | grep zzz_init 00000000 I __imp__zzz_init 00000000 T _zzz_init Statically: ----------- /C/msys64/mingw32/bin/gcc.exe -O2 -Wl,--allow-multiple-definition -shared -o libzzz.dll -Wl,--out-implib,libzzz.dll.a -Wl,--major-image-version,3,--minor-image-version,0 -Wl,--whole-archive CMakeFiles/zzz.dir/objects.a -Wl,--no-whole-archive -Wl,-Bstatic -lcurl -lssl -lcrypto -lxml2 -ljansson -static-libgcc -lpsl -lidn2 -lnghttp2 -lcrypt32 -lunistring -lssh2 -lbrotlidec-static -lbrotlicommon-static -lz -llzma -lintl -liconv -lwldap32 -lwsock32 -lws2_32 -lgdi32 -lcomdlg32 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 zzz_init does not exist: $ nm _build/mingw32-Release/atoakm3/libzzz.dll.a | grep zzz_init The only difference is that -lcurl is after -Wl,-Bstatic not before.
This sounds like a case where the static libcurl contains dllexport directives.
When linking a DLL, there are many different mechanisms for choosing what symbols to export. One way is to annotate individual functions with __declspec(dllexport). If there are no functions marked dllexport, the linker defaults to exporting all symbols.
When linking in dependencies statically, this has two consequences. If there are no dllexport markings, all the functions from the dependency library are exported, together with your own functions. That's probably unexpected but mostly harmless.
However if the static library contains dllexport markings, these functions will be exported, but the default mechanism for exporting all symbols won't be invoked.
If you explicitly pass -Wl,--export-all-symbols to the linker, you enforce exporting all symbols, regardless of dllexport directives.
I don't off-hand know of any common GNU binutils tool to list embedded directives in object files. If you happen to have llvm-readobj available though, you can do "llvm-readobj -coff-directives libcurl.a" and have it list all the object files that the static library contained, together with their embedded directives. That would look like this: "Directive(s): -export:func"
Ideally a static library shouldn't have dllexport attributes - I haven't checked if static builds of curl normally include them or not. (If using dllexport attributes for limiting what to export from a library, one has to do two separate builds to get both a dynamic library and a static library without the dllexport attributes.)
// Martin
------------------------------------------------------------------- Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library Etiquette: https://curl.haxx.se/mail/etiquette.html