Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Autoconf:链接自定义库时链接器出错_C_Cross Compiling_Autoconf_Automake - Fatal编程技术网

Autoconf:链接自定义库时链接器出错

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

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 \
     -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)
添加到project
libMyLib-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)
添加到project
libMyLib-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