Beau Simensen
Beau Simensen

Reputation: 4578

Why would autoconf/automake project link against installed library instead of local development library?

I'm creating a library libgdata that has some tests and non-installed programs. I am running into the problem that once I've installed the library once, the programs seem to be linking to the installed version and not the local version in ../src/libgdata.la any longer.

What could cause this? Am I doing something horribly wrong?

Here is what my test/Makefile.am looks like:

INCLUDES = -I$(top_srcdir)/src/ -I$(top_srcdir)/test/

# libapiutil contains all of our dependencies!
AM_CXXFLAGS = $(APIUTIL_CFLAGS)
AM_LDFLAGS = $(APIUTIL_LIBS)

LDADD = $(top_builddir)/src/libgdata.la

noinst_PROGRAMS = gdatacalendar gdatayoutube

gdatacalendar_SOURCES = gdatacalendar.cc

gdatayoutube_SOURCES = gdatayoutube.cc

TESTS = check_bare

check_PROGRAMS = $(TESTS)

check_bare_SOURCES = check_bare.cc

(libapiutil is another library that has some helper stuff for dealing with libcurl and libxml++)

So, for instance, if I run the tests without having installed anything, everything works fine. I can make changes locally and they are picked up by these programs right away.

If I install the package, these programs will compile (it seems like it does actually look locally for the headers), but once I run the program it complains about missing symbols.

As far as I can tell, it is linking against the newly built library (../src/libgdata.la) based on the make output, so I'm not sure why this would be happening. If i remove the installed files, the local changes to src/* are picked up just fine.

I've included the make output for gdatacalendar below.

g++ -DHAVE_CONFIG_H -I. -I.. -I../src/ -I../test/   -I/home/altern8/workspaces/4355/dev-install/include -I/usr/include/libxml++-2.6 -I/usr/lib/libxml++-2.6/include -I/usr/include/libxml2 -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include   -g -O2 -MT gdatacalendar.o -MD -MP -MF .deps/gdatacalendar.Tpo -c -o gdatacalendar.o gdatacalendar.cc
mv -f .deps/gdatacalendar.Tpo .deps/gdatacalendar.Po
/bin/bash ../libtool --tag=CXX   --mode=link g++ -I/home/altern8/workspaces/4355/dev-install/include -I/usr/include/libxml++-2.6 -I/usr/lib/libxml++-2.6/include -I/usr/include/libxml2 -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include   -g -O2 -L/home/altern8/workspaces/4355/dev-install/lib -lapiutil -lcurl -lgssapi_krb5 -lxml++-2.6 -lxml2 -lglibmm-2.4 -lgobject-2.0 -lsigc-2.0 -lglib-2.0    -o gdatacalendar gdatacalendar.o ../src/libgdata.la 
mkdir .libs
g++ -I/home/altern8/workspaces/4355/dev-install/include -I/usr/include/libxml++-2.6 -I/usr/lib/libxml++-2.6/include -I/usr/include/libxml2 -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -g -O2 -o .libs/gdatacalendar gdatacalendar.o  -L/home/altern8/workspaces/4355/dev-install/lib /home/altern8/workspaces/4355/dev-install/lib/libapiutil.so /usr/lib/libcurl.so -lgssapi_krb5 /usr/lib/libxml++-2.6.so /usr/lib/libxml2.so /usr/lib/libglibmm-2.4.so /usr/lib/libgobject-2.0.so /usr/lib/libsigc-2.0.so /usr/lib/libglib-2.0.so ../src/.libs/libgdata.so  -Wl,--rpath -Wl,/home/altern8/workspaces/4355/dev-install/lib
creating gdatacalendar

Help. :)

UPDATE

I get the following messages when I try to run the calendar program when I've added the addCommonRequestHeader() method to the Service class after I had installed the library without the addCommonRequestHeader() method.

/home/altern8/workspaces/4355/libgdata/test/.libs/lt-gdatacalendar:
symbol lookup error:
/home/altern8/workspaces/4355/libgdata/test/.libs/lt-gdatacalendar:
undefined symbol:
_ZN55gdata7service7Service22addCommonRequestHeaderERKSsS4_

Eugene's suggestion to try setting the $LD_LIBRARY_PATH variable did not help.

UPDATE 2

I did two tests. First, I did this after blowing away my dev-install directory (--prefix) and in that case, it creates test/.libs/lt-gdatacalendar. Once I have installed the library, though, it creates test/.libs/gdatacalendar instead. The output of ldd is the same for both with one exception:

# before install
# ldd test/.libs/lt-gdatacalendar
libgdata.so.0 => /home/altern8/workspaces/4355/libgdata/src/.libs/libgdata.so.0 (0xb7c32000)

# after install
# ldd test/.libs/gdatacalendar
libgdata.so.0 => /home/altern8/workspaces/4355/dev-install/lib/libgdata.so.0 (0xb7c87000)

What would cause this to create lt-gdatacalendar in one case but gdatacalendar in another?

The output of ldd on libgdata is:

altern8@goldfrapp:~/workspaces/4355/libgdata$ ldd /home/altern8/workspaces/4355/libgdata/src/.libs/libgdata.so.0
        linux-gate.so.1 =>  (0xb7f7c000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7f3b000)
        libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7dec000)
        /lib/ld-linux.so.2 (0xb7f7d000)

Upvotes: 14

Views: 1747

Answers (4)

rockdaboot
rockdaboot

Reputation: 736

Without -no-install libtool creates script wrappers and puts the executables into the .libs/ subdir (linked with the installed libraries). Calling the wrapper makes your executable load/link with your local (not installed) library - so everything works fine, e.g. make check does not test the installed but your freshly baken library.

In some cases (e.g. when debugging or valgrinding), you do not want to have those wrappers, but real executables directly linked with your local library. For this you use AM_LDFLAGS = -no-install (or just set it for single targets).

More details here

Upvotes: 0

user324075
user324075

Reputation: 21

I think I've sorted this out.

The problem should be that libtool sees the "-L" flag in the command line before it sees the "../src/libgdata.so" part. In this case, it executes the linker with "-Wl,-rpath,..." for that "-L" path. If that path contains "libgdata.so", then it will always be used, which is the case here.

In my case, I've rearranged "prog_LDADD" to like like this: "prog_LDADD = $(top_builddir)/src/my_lib.so $(DEPENDENCY_LIBS)"

In your case, try to delete AM_LDFLAGS and write:

LDADD = $(top_builddir)/src/libgdata.la $(APIUTIL_LIBS)

Upvotes: 2

Braden
Braden

Reputation: 1507

I know that for dependencies to work correctly, you need to refer to libgdata.la with a relative path in LDADD; it's possible that affects the situation you're describing as well.

I'm not sure why, though. The behavior you're describing does seem a bit odd; and perhaps worth reporting to the libtool developers.

Upvotes: 1

Eugene
Eugene

Reputation: 7258

Not sure how to do that in autoconf, but final command might need to have -L../src, so linker can find newly built library first.

Try manually running last command with that addition and see if that helps.

EDIT: Ok, I guess misread it, thought it wasn't linking, but you are saying it links but doesn't run?

If that is the case, run ldd on your binary and see which .so it picks up -- most likely installed (and outdated) ones.

In this case, either install updated libs before running, or export LD_LIBRARY_PATH env variable before running.

export LD_LIBRARY_PATH="/path to freshly built libs"

Upvotes: 1

Related Questions