curl / Mailing Lists / curl-library / Single Mail

curl-library

Re: msys2/mingw32 linking dll to libcurl.a suppresses DLL exports

From: Bruce Cartland via curl-library <curl-library_at_cool.haxx.se>
Date: Fri, 15 Feb 2019 20:41:46 +1100

THANK YOU.

That explains it. I link against other static libs with no problem. And
of course everything is fine on Linux and MacOS.

It works if I add __declspec(dllexport) to the method(s).
-Wl,--export-all-symbols also works and would be my preferred approach.

It's possible it's an issue with the msys2 port of curl. I've had some
other issues with it.

And thanks for the reference.

Cheers
Bruce

On 15/2/19 7:21 pm, Martin Storsjö via curl-library wrote:
> On Fri, 15 Feb 2019, Martin Storsjö via curl-library wrote:
>
>> 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.)
>
> I forgot to add the reference to the GNU ld manual that describes this
> behaviour: https://sourceware.org/binutils/docs/ld/WIN32.html
>
> // Martin
>
> -------------------------------------------------------------------
> Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
> Etiquette: https://curl.haxx.se/mail/etiquette.html

-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html
Received on 2019-02-15