Autoconf:链接自定义库时链接器出错
1) 我有一个包含一个共享库的项目,该库链接到一些外国库(即Autoconf:链接自定义库时链接器出错,c,cross-compiling,autoconf,automake,C,Cross Compiling,Autoconf,Automake,1) 我有一个包含一个共享库的项目,该库链接到一些外国库(即gcrypt,gpg error,z和ssh2)。让我们称之为“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
gcrypt
,gpg error
,z
和ssh2
)。让我们称之为“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'
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”configure.ac
中,我显式搜索库:
/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'
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”中链接它们时,它不应该已经解决了吗
有没有更好的办法
谢谢
附言:对不起,我不太擅长autoconf
这件事
注意:我正在使用(旧的)ELDK 3.1为PowerPC交叉编译。如果不知道
Makefile.am
或configure.ac
,就很难准确地说出您在做什么,但是因为我看到您正在使用-Wl,-rpath
,我假设在调用/configure
时,您正在以LDFLAGS
的形式从外部传递它
发生的情况是,libtool
通常不会存储-rpath
值,但它会存储-L
;因此,我通常的建议是传递-L
和-rpath
,这样.la
文件将包含找到要链接到它的库的路径
虽然您不必在每个二进制文件上传递它,
libtool
会,然后让链接编辑器正确地解析它。如果不知道Makefile.am
或configure.ac
中的内容,就很难准确地说出您在做什么,但是因为我看到您正在使用-Wl,-rpath
,我假设在调用/configure
时,您正在以LDFLAGS
的形式从外部传递它
发生的情况是,libtool
通常不会存储-rpath
值,但它会存储-L
;因此,我通常的建议是传递-L
和-rpath
,这样.la
文件将包含找到要链接到它的库的路径
虽然您不必将它传递给每个二进制文件,
libtool
会,然后让链接编辑器正确地解决它。注意:因为我在两年后收到了一个答案,而这并没有解决我的问题,我认为最好与大家分享我所做的
回答: 我发现在基于
autoconf
的项目中自动包含链接器依赖项的更好方法是将pkg config
信息添加到我的库中
对配置.ac的更改:
export PKG_CONFIG_PATH=../MyLibPath:${PKG_CONFIG_PATH}
PKG_CHECK_MODULES([MYLIB], [libMyLib-1.0 >= 1.0.0])
第二个输出文件libMyLib-1.0-uninstalled.pc
允许我使用已卸载的MyLib版本继续开发我的项目
更改Makefile.am
:
dependent_CPPFLAGS = $(MYLIB_CPPFLAGS)
dependent_CFLAGS = $(MYLIB_CFLAGS)
dependent_CXXFLAGS = $(MYLIB_CXXFLAGS)
dependent_LIBADD = $(MYLIB_LIBS)
添加到projectlibMyLib-1.0.pc
:
和libMyLib-1.0-uninstalled.pc
:
在每个相关项目中:
配置.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)
注意:由于两年后我收到了一个答案,而这并不是解决我问题的方法,我认为最好与大家分享我所做的事情
回答:
我发现在基于autoconf
的项目中自动包含链接器依赖项的更好方法是将pkg config
信息添加到我的库中
对配置.ac的更改:
export PKG_CONFIG_PATH=../MyLibPath:${PKG_CONFIG_PATH}
PKG_CHECK_MODULES([MYLIB], [libMyLib-1.0 >= 1.0.0])
第二个输出文件libMyLib-1.0-uninstalled.pc
允许我使用已卸载的MyLib版本继续开发我的项目
更改Makefile.am
:
dependent_CPPFLAGS = $(MYLIB_CPPFLAGS)
dependent_CFLAGS = $(MYLIB_CFLAGS)
dependent_CXXFLAGS = $(MYLIB_CXXFLAGS)
dependent_LIBADD = $(MYLIB_LIBS)
添加到projectlibMyLib-1.0.pc
:
和libMyLib-1.0-uninstalled.pc
:
在每个相关项目中:
配置.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)
您是否覆盖Makefile.am中程序的任何指令?我有类似于program1\u CPPFLAGS=-I$(top\u srcdir)$(MYLIB\CFLAGS)
的东西,其中MYLIB\CFLAGS
和MYLIB\LIBS
用configure.AC
中的AC\ARG\u定义,以允许我链接到本地“MYLIB”而不是系统安装的(请告诉我这是否是一种更好的方法)。CPPFLAGS不应该是相关的,但是如何在Makefile.am中使用MYLIB_LIBS?在您的最终生成文件中,应该有一个包含$(LINK)命令的program1$(EXEXT)目标,该命令应该有$(LIBS),如果AC_SEARCH_LIBS成功找到给定的库,则该命令应该包含库。在mylib.so上运行ldd的输出将非常有用,尽管我不确定交叉编译时这有多容易。另一个有趣的方法是检查readelf-a
,确保按照您的要求添加了RPATH。您是否在Makefile.am中覆盖了程序的任何指令?我有类似于program1\u CPPFLAGS=-I$(top\u srcdir)$(MYLIB\u CFLAGS)的内容
其中MYLIB\u CFLAGS
和MYLIB\code>在configure.AC
的“program1”中使用AC\u ARG\u来定义,以允许我链接到本地“MYLIB”,而不是系统安装的“MYLIB”(请告诉我这是否是一种更好的方法)。CPPFLAGS不应该相关,但是如何在Makefile.am中使用MYLIB_LIBS呢?在最终的生成文件中,应该有一个包含$(LINK)命令的program1$(EXEXT)目标,该命令应该有$(LIBS),如果AC_SEARCH_LIBS成功找到给定的库,该命令应该包含库。Th