简体   繁体   中英

Autoconf: linker error linking against custom library

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.

PS: I am not very clever in autoconf matter, sorry.

NOTE: I am cross compiling for PowerPC using (the yet old) ELDK 3.1.

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM