bug#34219: libtool cannot statically link dependencies into shared C++ library

Ulya Trofimovich <[email protected]>
Newsgroups gmane.comp.gnu.libtool.bugs
Message-ID <[email protected]>
Hello!


I'm trying to build a portable DLL for windows with libtool. To do that,
I need to eliminate dynamic dependencies on libstdc++ and libgcc. With
GCC it is normally done by passing -static-libstdc++ -statlic-libgcc to
the linker.

I would want these commands to result in a shared library that has no
dynamic dependencies on libstdc++ and libgcc:

$ libtool --tag=CXX --mode=compile g++ -c foo.cc
$ libtool --tag=CXX --mode=link g++ \
    -static-libstdc++ -static-libgcc \
    -o libfoo.la foo.lo -rpath /usr/lib

First problem is that libtool doesn't recognize these options, and as a
result it does not pass them to linker. This can be worked around by
wrapping them in -Wc,-static-libstdc++ -Wc,-static-libgcc.

Second problem is that libtool adds hard-coded link option -nostdlib and
some predefined startup object files. Because of that, -static-libstdc++
-statlic-libgcc have no effect and the resulting shared library still
has dynamic dependencies on libstdc++ and libgcc.

Let me show what I mean on a simple example (I will build native
library, not DLL, because it's simpler and shows the same problem).
Let's say, source code of our library is in a file foo.cc:

$ cat foo.cc
#include <iostream>
void foo(void)
{
    std::cout << "foo" << std::endl;
}

Without libtool, I can build shared library like this:

$ g++ -shared -fPIC foo.cc -o libfoo.so
$ objdump -x libfoo.so | grep NEEDED
  NEEDED               libstdc++.so.6
  NEEDED               libm.so.6
  NEEDED               libgcc_s.so.1
  NEEDED               libc.so.6

Note the dependency on libstdc++. I can get rid of it like this:

$ g++ -shared -fPIC foo.cc -o libfoo.so -static-libstdc++ -static-libgcc
$ objdump -x libfoo.so | grep NEEDED
  NEEDED               libm.so.6
  NEEDED               libc.so.6
  NEEDED               ld-linux-x86-64.so.2

With libtool, however, I'm stuck:

$ libtool --tag=CXX --mode=compile g++ -c foo.cc
libtool: compile:  g++ -c foo.cc  -fPIC -DPIC -o .libs/foo.o
libtool: compile:  g++ -c foo.cc -o foo.o >/dev/null 2>&1

$ libtool --tag=CXX --mode=link g++ \
    -Wc,-static-libstdc++ -Wc,-static-libgcc \
    -o libfoo.la foo.lo -rpath /usr/lib
libtool: link: rm -fr  .libs/libfoo.a .libs/libfoo.la .libs/libfoo.lai
.libs/libfoo.so .libs/libfoo.so.0 .libs/libfoo.so.0.0.0
libtool: link: x86_64-pc-linux-gnu-g++  -fPIC -DPIC -shared -nostdlib
/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/crtbeginS.o  .libs/foo.o
-L/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0
-L/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../lib64
-L/lib/../lib64 -L/usr/lib/../lib64
-L/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../x86_64-pc-linux-gnu/lib
-L/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../.. -lstdc++ -lm -lc
-lgcc_s /usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/crtendS.o
/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../lib64/crtn.o
-static-libstdc++ -static-libgcc   -Wl,-soname -Wl,libfoo.so.0 -o
.libs/libfoo.so.0.0.0
libtool: link: (cd ".libs" && rm -f "libfoo.so.0" && ln -s
"libfoo.so.0.0.0" "libfoo.so.0")
libtool: link: (cd ".libs" && rm -f "libfoo.so" && ln -s
"libfoo.so.0.0.0" "libfoo.so")
libtool: link: x86_64-pc-linux-gnu-ar cru .libs/libfoo.a  foo.o
libtool: link: x86_64-pc-linux-gnu-ranlib .libs/libfoo.a
libtool: link: ( cd ".libs" && rm -f "libfoo.la" && ln -s "../libfoo.la"
"libfoo.la" )

$ objdump -x .libs/libfoo.so | grep NEEDED
  NEEDED               libstdc++.so.6
  NEEDED               libm.so.6
  NEEDED               libc.so.6
  NEEDED               libgcc_s.so.1

Even though options -static-libstdc++ -static-libgcc are passed to the
linker, hard-coded -nostdlib
/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/crtbeginS.o pulls in dynamic
dependencies.

As a temporary workaround, I'm using slibtool:

    https://github.com/midipix-project/slibtool

But I think this use case is very common and needs to be fixed in
libtool as well.

When using libtool with autotools (my original setting), I would want to
just pass these flags to configure:

    ./configure LDFLAGS="-static-libstdc++ -static-libgcc"

Currently I also have to override libtool program in make:

    make LIBTOOL=slibtool


-- 
Ulya
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.