How to link to the libabc.a instead of libabc.so?
-
23-02-2021 - |
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.
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.