Question

In the book Autotools: A Practioner's Guide to GNU Autoconf, Automake, and Libtool, chapter 6 (building libraries with libtool), an example of linking library is given.

In the example, a library libjupiter.so is linked to another library libjupcommon.a. The first attempt fails because libjupiter.so needs PIC, but libjupcommon.a is not. The author adds libjupcommon_a_CFLAGS = -fPIC to fix it. It gets much better, but the warning of 'Linking the shared library libjupiter.la against the static library ../common/libjupcommon.a is not portable!' appears.

Therefore the author modifies the Makefile.am's again, using libtool to build libjupcommon.la. The libjupiter links to the libjupcommon.la. Like this:

noinst_LTLIBRARIES = libjupcommon.la

libjupcommon_la_SOURCES = jupcommon.h print.c

and

...

libjupiter_la_LIBADD = ../common/libjupcommon.la

This time everything's OK.


Now, my problem:

I have a library needs another library, just like libjupiter needs libjupcommon. The difference is my libjupcommon is from another project and installed into the system. It is not a noinst_LTLIBRARIES. Both .so and .a version exist. When I try to link the libjupcommon.la like the example shows, the .so is chosen, but I don't want a dynamic linking relationship. I want to link to the .a, like the example in the book.

Linking to .a explicitly (by using _LIBADD=the .a file) gives a usable library, but the warning of '... not portable' is given.

What's the proper way to achieve linking to the .a in this case?

PS: Download the example from the book's official site. In autotools/book/jupiter-libtool-ch6/common, modify the Makefile.am's noinst_LTLIBRARIES to lib_LTLIBRARIES should be a close mimic to my problem.

Was it helpful?

Solution

There's a couple things you could try. You could try running configure with the --disable-shared option to turn off compilation of shared libs (and add the static lib to libfoo_LIBADD again). You could try adding -static to libfoo_LDFLAGS to get libtool to build it statically (again with the static lib added to libfoo_LIBADD).

EDIT: Since both static and shared libs are needed the above won't work.

Try adding:

AC_CHECK_LIB([abc],[some_function_in_libabc])

to configure.ac.

OTHER TIPS

You can force static linking to one library (while keeping all other links shared) using this construct:

-Wl,-Bstatic -Wl,-whole-archive -Xlinker -l$1 -Wl,-no-whole-archive -Wl,-Bdynamic

Replace $1 above with your library name.

Explanation: Most of the above monstrosity is to get around the fact that libtool will re-arrange the command line arguments, ever so helpfully. Using -Xlinker will force libtool to ignore the -l$1 and not re-arrange it. The -Wl,-Bstatic tells the linker to link all following libraries as static. -Wl,-Bdynamic switches back to dynamic linking for further libraries.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top