Reputation: 3716
1) I have a project containing a shared library that links against some foreign libraries (namely gcrypt
, gpg-error
, z
and ssh2
). Lets call it "mylib".
This library builds perfectly and I can see libtool
linking the dependencies correctly.
libtool: link: ppc-linux-gcc -shared -fPIC -DPIC .libs/mylib1.o .libs/mylib2.o .libs/mylib3.o
-Wl,-rpath -Wl,/opt/ELDK/ppc_8xx/lib -Wl,-rpath \
-Wl,/opt/ELDK/ppc_8xx/lib /opt/ELDK/ppc_8xx/lib/libssh2.so \
-L/opt/ELDK/ppc_8xx/lib -lz /opt/ELDK/ppc_8xx/lib/libgcrypt.so \
/opt/ELDK/ppc_8xx/lib/libgpg-error.so -lpthread -O2 \
-Wl,-soname -Wl,mylib.so.0 -o .libs/mylib.so.0.0.0
2) The same project has several programs that link to "mylib". When I try to link them, though, I got linker errors about the same previous libraries:
/opt/ELDK-3.1/usr/bin/../lib/gcc-lib/ppc-linux/3.3.3/../../../../ppc-linux/bin/ld: \
warning: libssh2.so.1, needed by ./../myLib/.libs/mylib.so, not found (try using -rpath or -rpath-link)
/opt/ELDK-3.1/usr/bin/../lib/gcc-lib/ppc-linux/3.3.3/../../../../ppc-linux/bin/ld: \
warning: libz.so.1, needed by ./../myLib/.libs/mylib.so, not found (try using -rpath or -rpath-link)
/opt/ELDK-3.1/usr/bin/../lib/gcc-lib/ppc-linux/3.3.3/../../../../ppc-linux/bin/ld: \
warning: libgcrypt.so.11, needed by ./../myLib/.libs/mylib.so, not found (try using -rpath or -rpath-link)
/opt/ELDK-3.1/usr/bin/../lib/gcc-lib/ppc-linux/3.3.3/../../../../ppc-linux/bin/ld: \
warning: libgpg-error.so.0, needed by ./../myLib/.libs/mylib.so, not found (try using -rpath or -rpath-link)
./../myLib/.libs/mylib.so: undefined reference to `libssh2_channel_process_startup'
./../myLib/.libs/mylib.so: undefined reference to `libssh2_scp_send_ex'
In the "mylib" configure.ac
I explicitly search for the libraries:
AC_SEARCH_LIBS(gpg_err_set_errno,[gpg-error])
AC_SEARCH_LIBS(gcry_check_version,[gcrypt])
AC_SEARCH_LIBS(deflate,[z])
AC_SEARCH_LIBS(libssh2_init,[ssh2])
Must I also explicitly include all of those libraries in every project using "mylib"? Shouldn't it be already resolved when I first link them in "mylib"?
Is there any better way to do this?
Thanks.
P.S.: I am not very clever in autoconf
matter, sorry.
NOTE: I am cross compiling for PowerPC using (the yet old) ELDK 3.1.
Upvotes: 1
Views: 1585
Reputation: 3716
NOTE: Since I have received an answer 2 years latter and that was not what solved my problem, I think it is better to share with everyone what I have done.
ANSWER:
The better way I found out to automatically include linker dependencies in a autoconf
based project was to add pkg-config
information to my library.
Changes to configure.ac
:
export PKG_CONFIG_PATH=../MyLibPath:${PKG_CONFIG_PATH}
PKG_CHECK_MODULES([DEPS], [libssh2 >= 1.3.0])
# Output configuration files.
AC_CONFIG_FILES([Makefile libMyLib-1.0.pc libMyLib-1.0-uninstalled.pc])
The second output file libMyLib-1.0-uninstalled.pc
is to allow me to continue developing my project with an uninstalled version of MyLib.
Changes to Makefile.am
:
libMyLib_la_CPPFLAGS = $(DEPS_CPPFLAGS)
libMyLib_la_CFLAGS = $(DEPS_CFLAGS)
libMyLib_la_CXXFLAGS = $(DEPS_CXXFLAGS)
libMyLib_la_LIBADD = $(DEPS_LIBS)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libMyLib-1.0.pc
Add to project libMyLib-1.0.pc
:
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: MyLib
Description: My library.
Requires: libssh2
Requires.private:
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lMyLib -lstdc++ -lm -lslog -lpthread
Libs.private:
Cflags: -I${includedir}/libMyLib-1.0
and libMyLib-1.0-uninstalled.pc
:
prefix=@abs_builddir@
exec_prefix=@exec_prefix@
libdir=${prefix}/.libs
includedir=${prefix}
Name: MyLib
Description: My library.
Requires: libssh2
Requires.private:
Version: @PACKAGE_VERSION@
Libs: -Wl,-rpath-link,${libdir} -L${libdir} -lMyLib -lstdc++ -lm -lslog -lpthread
Libs.private:
Cflags: -I${includedir}/
In each dependent project:
configure.ac
:
export PKG_CONFIG_PATH=../MyLibPath:${PKG_CONFIG_PATH}
PKG_CHECK_MODULES([MYLIB], [libMyLib-1.0 >= 1.0.0])
Makefile.am
:
dependent_CPPFLAGS = $(MYLIB_CPPFLAGS)
dependent_CFLAGS = $(MYLIB_CFLAGS)
dependent_CXXFLAGS = $(MYLIB_CXXFLAGS)
dependent_LIBADD = $(MYLIB_LIBS)
Upvotes: 1
Reputation: 3240
It's harder to tell exactly what you're doing without knowing what's in your Makefile.am
or configure.ac
, but since I see you're using -Wl,-rpath
, I assume that you're passing it as LDFLAGS
from the outside when you call ./configure
.
What happens is that libtool
will not usually store the -rpath
values but it'll store -L
; so my usual suggestion is to pass both -L
and -rpath
so that the .la
files will contain the path where to find the libraries to link to it.
While you don't have to pass it on every single binary, libtool
will, and will then let the link editor resolve it properly.
Upvotes: 0