Alexey Pavlov alexpux@gmail.com writes:
2013/11/29 Niels Möller nisse@lysator.liu.se:
What failed? Can I repost your message to the list?
I do it already. I receive subscribing message now.
Ok. I'm now cc:ing the list. Context: Link error when building a dynamic libnettle.dll and libhogweed.dll, and statically linking to libgmp.a.
i686-w64-mingw32-gcc -march=i686 -mtune=generic -O2 -pipe -I/mingw32/include -ggdb3 -Wno-pointer-sign -Wall -W -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes -Wpointer-arith -Wbad-function-cast -Wnested-externs -L.. -pipe -L/mingw32/lib ecc-mod-test.o testutils.o ../nettle-internal.o -lhogweed -lnettle -lgmp -o ecc-mod-test.exe
C:/msys64/mingw32/lib/libgmp.a(sub_n.o):(.text+0x0): multiple definition of `__gmpn_sub_n'
../libhogweed.dll.a(d000131.o):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
So you're building shared libraries for nettle, but you have a static gmp library? The way I understand the error, the used gmp functions gets copied into libhogweed.dll. Not sure if that is the best behavior.
Yes I have static GMP because we build toolchains with static prerequisites and don't want to has dynamic dependencies from them (gmp, mpc, mpfr, clog, isl). I prefer to use static versions of them.
But I'm not sure I understand the link error. There's some function depending on __gmpn_sub_n ("mpn_sub_n" to user code), but if that function is included in libhogweed.dll, why isn't that function just skipped when the linker processes libgmp.a?
A program in C can have only one definition (declaration which assigns a value) for each object (storage space for a variable).
But when doing linking with static libraries, multiple definitions are generally ok. The linker copies only the object files which are needed, and when it needs a symbol, it includes only the first object file in any of the libraries, which define the symbol.
One may still get clashes if each object file includes multiple symbols, since in the set of object files selected by the linker in the end, multiple definitions of the same symbol are not allowed.
As I understand, somewhere header file contains definitions for several functions __gmpn_sub_n which when included in several different translation units results in the linker throwing this error.
I don't think so. My understanding is that
1. The symbol __gmp_sub_n is defined in some object file included in libgmp.a, and nowhere in the nettle source or object code (and mini-gmp.c doesn't count, it's not involved in the link, and it uses different linker symbol names than the real gmp).
2. This object file gets copied from libgmp.a into libhogweed.dll by the linker. Not sure if this is right; -lgmp was added to the libhogweed link command primarily to get dependencies between *shared* libraries right.
3. You then link the executable ecc-mod-test.exe with -lhogweed and -lgmp. The linked sees two definitions of the symbol __gmpn_sub_n, one in libgmp.a, and one in libhogweed.dll, and it considers this an error.
What I don't understand, is why, in (3) above, the linker doesn't just ignore the object in libgmp.a which defines the symbol.
Regards, /Niels
From: nisse@lysator.liu.se (Niels Möller) Date: Fri, 29 Nov 2013 14:02:05 +0100 Cc: Nettle Crypto Library nettle-bugs@lists.lysator.liu.se
Alexey Pavlov alexpux@gmail.com writes:
2013/11/29 Niels Möller nisse@lysator.liu.se:
What failed? Can I repost your message to the list?
I do it already. I receive subscribing message now.
Ok. I'm now cc:ing the list. Context: Link error when building a dynamic libnettle.dll and libhogweed.dll, and statically linking to libgmp.a.
AFAIK, this cannot possibly work on Windows. A DLL cannot depend on a static library. And if the linker is clever enough to copy the entire libgmp into the DLL, you will have trouble while linking programs against such a DLL, like the trouble we see here.
So you're building shared libraries for nettle, but you have a static gmp library? The way I understand the error, the used gmp functions gets copied into libhogweed.dll. Not sure if that is the best behavior.
No, the symbols from libgmp are copied into the libhogweed _import_ library libhogweed.dll.a. The import library is a static library.
The symbol __gmp_sub_n is defined in some object file included in libgmp.a, and nowhere in the nettle source or object code (and mini-gmp.c doesn't count, it's not involved in the link, and it uses different linker symbol names than the real gmp).
This object file gets copied from libgmp.a into libhogweed.dll by the linker. Not sure if this is right; -lgmp was added to the libhogweed link command primarily to get dependencies between *shared* libraries right.
You then link the executable ecc-mod-test.exe with -lhogweed and -lgmp. The linked sees two definitions of the symbol __gmpn_sub_n, one in libgmp.a, and one in libhogweed.dll, and it considers this an error.
What I don't understand, is why, in (3) above, the linker doesn't just ignore the object in libgmp.a which defines the symbol.
It could be because the module sub_n.o, which is taken from libgmp.a, is needed to satisfy other externals, and that module brings with it a second definition of __gmpn_sub_n.
But anyway, I think this is unworkable on Windows. If Alexey doesn't want dependencies on shared libraries, he needs to build static libraries from libhogweed and libnettle (I think --disable-shared at configure time will achieve that effect).
Eli Zaretskii eliz@gnu.org writes:
Ok. I'm now cc:ing the list. Context: Link error when building a dynamic libnettle.dll and libhogweed.dll, and statically linking to libgmp.a.
AFAIK, this cannot possibly work on Windows. A DLL cannot depend on a static library. And if the linker is clever enough to copy the entire libgmp into the DLL, you will have trouble while linking programs against such a DLL, like the trouble we see here.
Thanks. I wasn't entirely sure if this problem was windows-specific or not.
And it's equally impossible to omit -lgmp when linking libhogweed.dll, and only add -lgmp when linking the executable?
For ELF systems, if libhogweed is dynamic and libgmp is static, is it still the right thing to do to link libhogweed with -lgmp, which will copy needed gmp objects into libhogweed.so?
No, the symbols from libgmp are copied into the libhogweed _import_ library libhogweed.dll.a. The import library is a static library.
I admit I don't understand all the fine details here. But that sounds undesirable, the import library is intended to only contain thin glue to the dll?
But anyway, I think this is unworkable on Windows. If Alexey doesn't want dependencies on shared libraries, he needs to build static libraries from libhogweed and libnettle (I think --disable-shared at configure time will achieve that effect).
Right, --disable-shared should do that.
Regards, /Niels
From: nisse@lysator.liu.se (Niels Möller) Cc: alexpux@gmail.com, nettle-bugs@lists.lysator.liu.se Date: Fri, 29 Nov 2013 16:53:11 +0100
And it's equally impossible to omit -lgmp when linking libhogweed.dll, and only add -lgmp when linking the executable?
Not if libhogweed calls functions from libgmp.
For ELF systems, if libhogweed is dynamic and libgmp is static, is it still the right thing to do to link libhogweed with -lgmp, which will copy needed gmp objects into libhogweed.so?
I'm not an expert, but I think it is. Unix allows a shared library to be generated with unresolved references, which are then resolved at run time. By contrast, on Windows all the references must be visible at link time, and are hard-coded into the DLL. This is why Windows will refuse to run an executable that references a DLL which is missing.
No, the symbols from libgmp are copied into the libhogweed _import_ library libhogweed.dll.a. The import library is a static library.
I admit I don't understand all the fine details here. But that sounds undesirable, the import library is intended to only contain thin glue to the dll?
The import library contains short functions each of which has a single instruction: an indirect jump to the address of the real function in its DLL. The import library itself is a static library, so that these indirect jumps are statically linked into the program.
nettle-bugs@lists.lysator.liu.se