bug-libtool
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


From: Ulya Trofimovich
Subject: bug#34219: libtool cannot statically link dependencies into shared C++ library
Date: Sun, 27 Jan 2019 13:28:37 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1

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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]