How can an autotools user specify a combination of static & dynamic linking?

tprk77 picture tprk77 · Dec 21, 2012 · Viewed 12.9k times · Source

I'm building a program with autoconf, automake, and libtool. My work requires that I statically link (most) libraries. This hasn't been a problem in the past because I could statically link everything with -all-static. Now it's a problem because I have to use a library which is only dynamic; it was given to us by a thirdparty, and we don't have the source.

Of course, -all-static now causes the build to fail. Is it possible to tell libtool to statically link everything, except for this one library? Is it possible to have libtool do any combination of static and dynamic linking, or is it all or nothing?

So far I've tried creating a convenience library with LDFLAGS = -static, which depends on the libraries I want to statically link. But libtool doesn't concatenate the static libraries, like I would have hoped. The program depending on the convenience library still dynamically links everything.

I've also tried --disable-shared, but that didn't affect the build.


These questions are similar, but don't really answer my question:

Force linking a static library into a shared one with Libtool

Is it possible to link some — but not all — libraries statically with libtool?

(I don't want to delete shared libraries from my system, and specifing the full path for everything is hardly better than linking by hand, but maybe it's the only way.)

Answer

NickW picture NickW · Dec 25, 2012

You did not specify the operating system, but let us assume that it is a relatively recent Unix/Linux/OSX. If it is not, then ignore the following warning.

Before I answer, you should know that mixing static and shared code on most ELF-based systems (Unix/Linux) is problematic. One reason is because it can lead to code getting out of sync if you forget to relink an updated dependency. Another is due to the nature of static code vs. PIC. This is why libtool tries to discourage it.

That being said, in the Makefile.am (assuming your final program is foo and the shared library is):

    .
    .
    .
    foo_SOURCES = foo.c abc.c def.c hij.c
    foo_LDFLAGS = -all-static -Wl,-Bdynamic,-L/path/to,-lshared,-Bstatic
    foo_LDADD = -L../path/to -lbar -lbaz

What is important here is that libtool allows you to short-circuit the checks and GNU gcc's -static flag (which is used by libtool) by passing -Wl, arguments directly to the linker (GNU ld). To put spaces between arguments, the comma , delimiter is used.

Both -Bstatic and -Bdynamic are documented in GNU ld's info pages as well as the help screen. Again, since you did not mention the os or compiler package being used, I am assuming GNU gcc and GNU ld on Linux. You may want to verify by using ld --help to see for yourself. If, for some reason, it is not GNU ld, then you will need to find the equivalent flags to -Bstatic and -Bdynamic, substituting where appropriate.