Autoconf:链接器错误链接自定义库

时间:2012-02-24 16:37:49

标签: c cross-compiling autoconf automake

1)我有一个项目,其中包含一个链接某些外国图书馆的共享库(即gcryptgpg-errorzssh2)。让我们称之为“mylib”。 这个库构建得很完美,我可以看到libtool正确地链接了依赖项。

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)同一个项目有几个链接到“mylib”的程序。 但是,当我尝试链接它们时,我收到有关以前相同库的链接器错误:

/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'

在“mylib”configure.ac中,我明确搜索了这些库:

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])

我是否还必须使用“mylib”在每个项目中明确包含所有这些库? 当我第一次在“mylib”中链接它们时,它不应该已经解决了吗?

有没有更好的方法呢?

感谢。

P.S。:autoconf问题我不是很聪明,抱歉。

注意:我正在使用(旧的)ELDK 3.1交叉编译PowerPC。

2 个答案:

答案 0 :(得分:1)

注意:由于我已经收到了2年后的答案,而这并不能解决我的问题,我认为最好与大家分享我的所作所为。


<强> 解答:

我发现在基于autoconf的项目中自动包含链接器依赖项的更好方法是将pkg-config信息添加到我的库中。

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])

第二个输出文件libMyLib-1.0-uninstalled.pc允许我继续使用卸载的MyLib版本开发项目。

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

添加到项目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

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}/

在每个依赖项目中:

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)

答案 1 :(得分:0)

如果不知道Makefile.amconfigure.ac中的内容,但是因为我看到你正在使用,很难确切地说出你在做什么-Wl,-rpath,当您致电LDFLAGS时,我认为您从外部传递./configure

libtool通常不会存储-rpath值,但会存储-L;所以我通常的建议是传递-L-rpath,以便.la文件包含找到要链接到它的库的路径。

虽然您不必在每个二进制文件上传递它,libtool将会,然后让链接编辑器正确解析它。