Linking a shared library to a static libtool library using automake - automake

I have this directory structure
prog/libA
prog/libB
In libA, I have a Makefile.am that looks like this:
noinst_LTLIBRARIES = libA.la
libA_la_SOURCES = ...
libA_la_LIBADD = ... $(LAPACK)
where LAPACK is my system's lapack installation. This works as expected. However, in libB I have this:
noinst_LTLIBRARIES = libB.la
bin_PROGRAMS = compLibB
libB_la_SOURCES = ...
compLibB_SOURCES = ...
libB_LIBADD = $(top_builddir)/libA/libA.la ...
compLibB_LDADD = libB.la
which does not work. The linking stage of compLibB complains about undefined references to LAPACK unless I change the last line to
compLibB_LDADD = libB.la $(LAPACK)
but that seems redundant. Haven't I already linked in $(LAPACK) when I build the libA.la convenience lib? It's unclean because now compLibB has to concern itself with the details of libA. Is there no way to link in the LAPACK libs at the libA build stage so that I don't have to re-specify it at the compLibB build stage?

Haven't I already linked in $(LAPACK) when I build the libA.la convenience lib?
As your linker has already told you, no. libA.la being a convenience library is somewhat like a static library (a collection of object files).
It's unclean because now compLibB has to concern itself with the details of libA. Is there no way to link in the LAPACK libs at the libA build stage so that I don't have to re-specify it at the compLibB build stage?
You shouldn't need to specify the LAPACK libs when libA.la is built because the final link hasn't happened yet. There's no way I know of accomplishing what you want without making libA a shared library.

This is actually supposed to work, as the _LIBADD is intended to make the dependency transitive and working. On the other hand, you may have a different problem for using $(top_builddir), as libtool handles differently libraries that are linked in with relative paths and with absolute ones.

Related

cmake: using shared library while building when only headers exist

I would like to
build a binary that is relying on a shared library at runtime.
the library does not exist while compiling the binary.
the headers for the library are available
I would like to create a CMake project under those circumstances. Therefore I tried the following, but it will complain about the missing lib for sure:
cmake_minimum_required (VERSION 3.8)
project (example)
add_executable(${PROJECT_NAME}
main.c
)
target_link_libraries(${PROJECT_NAME}
PRIVATE
# system libs
lib_that_does_not_yet_exist
)
When removing the link instruction to lib_that_does_not_yet_exist, then I will get a undefined reference error.
Question: Is there any way to accomplish what I need?
Background: I am crosscompiling the binary, the lib is therefore having the wrong architecture to install it on the host. I know there may be some ways around that issue, but I am mainly interested in the above question.

automake program libtool wrapper linking

Am stumped on an automake link. Even after pouring over the manuals for hours and searching online it is probably a misunderstanding of autotools.
I have one .la library made by libtool, one .dylib shared library and am creating a program. The .la is linked to the .dylib and the program uses the .la.
Makefile.am for the .la library
lib_LTLIBRARIES = libA.la
libA_la_LDFLAGS = ${AM_LDFLAGS} -no-undefined
libA_la_LIBADD = $(LIBM) -Ldir/to/ -lB
libA_la_CPPFLAGS = ${AM_CPPFLAGS}
Makefile.am for program with libtool wrapper
noinst_PROGRAMS = test
test_SOURCES = test_source.c
test_LDADD = libA.la -Ldir/to/ -lB
libA.la is created and links to B.dylib but the test program "wrapper" created by automake is exporting DYLD_LIBRARY_PATH to find libA.la while not linking to B.dylib. Giving the error
dyld: Library not loaded: ./B.dylib
Referenced from: /dir/to/test/.libs/test
Reason: image not found
Trace/BPT trap: 5
Some things that I have tried are adding -Ldir/to/ -lB to test_LDFLAGS in addition to already being added in test_LDADD. And have tried setting test_LDFLAGS = -rpath -Ldir/to in the hopes that setting the runtime search path to the directory where B.dylib is would help.
If I manually export DYLD_LIBRARY_PATH to include /dir/to/B.dylib then the test program is able to run but I'm looking to have autotools take care of this rather than requiring someone to export a path before being able to run it.
libB.dylib includes an rpath that gets copied into your binary and that is used to resolve -lB at runtime.
And it seems that this rpath is not /path/to, so libB.dylib cannot be resolved by the runtime linker.
The reasons why it works for libA.la is that libtools knows that the rpath in libA.dylib is wrong anyhow (as you haven't done a make install) and so it needs to be set manually.
The only way around this that i have found is to use install_name_tool to fix the stored rpath in the resulting binary.
(that is: I don't think that libtool will do this for you, as it contradicts the intended use of libB.dylib - as declared in its rpath)
The problem is that Libtool wasn't involved in building libB.dylib, so it does not know how to fix up your environment to find it. That means it is up to you. You can add path/to/ libB in your environment, or add a hardcoded search path to libA.la so that libA will find it.
libA_la_LIBADD = $(LIBM) -Ldir/to/ -rpath dir/to/ -lB
This will not only add the path to B in libA's binary, but will add it to dependency-libs in Libtool's libA.la file so that on platforms that won't automatically inherit the rpath specification it can be added by Libtool when linking.

Is there a way to reference a library in Automake?

I'm trying to use LDADD to reference a prebuilt library and Automake insists that the library has to be built. The Automake manual says:
"If you need to link against libraries that are not found by configure, you can use LDADD to do so. This variable is used to specify additional objects or libraries to link with; it is inappropriate for specifying specific linker flags, you should use AM_LDFLAGS for this purpose."
In my code I have used both
LDADD = ../lib/library.a
and
prog_LDADD = ../lib/librarya.
In both cases make outputs
*** No rule to make target 'library.a', needed by 'SlipTest.exe'. Stop.
It's got me stumped.
art
check whether the file ../lib/library.a actually exists.
when building libraries with automake you should use libtool, and libtool-libraries use the (platform independent) .la extension:
prog_LDADD = ../lib/library.la

Building a Shared Library but linking against a Static One

I have an Autogen Makefile.am that I'm trying to use to build a test program for a shared library. To build my test binary, I want to continue building the shared library as target but I want the test program to be linked statically. I've spent the last few hours trying to craft my Makefile.am to get it to do this.
I've tried explicitly changing the LDADD line to use the .a version of the library and get a file not found error even though I can see this library is getting built.
I try to add the .libs directory to my link path via LDFLAGS and still it can't find it.
I tried moving my library sources to my test SOURCES list and this won't work because executable object files are built differently than those for static libraries.
I even tried replicating a lib_LIBRARIES entry for the .a version (so there's both a lib_LTLIBRARIES and a lib_LIBRARIES) and replicate all the LDFLAGS, SOURCES, dir and HEADERS for the shared version as part of the static version (replacing la with a of the form _a_SOURCES = _la_SOURCES. Still that doesn't work because now it can't figure out what to build.
My configure.ac file is using the default LT_INIT which should give me both static and dynamic libraries and as I said it is apprently building both even if the libtool can't see the .a file.
Please, anyone know how to do this?
As #Brett Hale mentions in his comment, you should tell Makefile.am that you want the program to be statically linked.
To achieve this you must append -static to your LDFLAGS.
Changing the LDFLAGS for a specific binary is achieved by changing binary_LDFLAGS (where binary is the name of the binary you want to build).
so something like this should do the trick:
binary_LDFLAGS = $(AM_LDFLAGS) -static

circularly linked static libraries (linux )undefined libraries

I did a build for static libraries and put then at a location. Now when i build my source i get UNDEFINED REFERENCES for inter library calls. For example:
/home/xyz/lib/libA.a(ClassA.a):undefined reference to classB::funB()
here classB.a is also a static library .
In my source's project file the static linking order is :
LIBS+= -lclassB -lclassA
Now when i reverse the libraries order i start getting error in classes of library B for function calls inside library A.
For this kind of situation you generally need e.g.
LIBS += -lclassA -lclassB -lclassA
Linking the classA library twice helps to resolve the circular dependencies.
Ok friends I have found the solution .
I was using qmake build tool on gcc , i just needeed to tell qmake that some of my static libraries are circularly dependent .
So i modified my .pro file with a qmake linker flag
QMAKE_LFLAGS += -Wl , --start-group --end-group
gcc's documentation says that you need to put your archive names between --start-group --end-group , but qmake is smart enough to find out the dependent libs , and will do that automatically .
Have Fun .

Resources