如何从 autotools 确定平台库是静态的还是动态的?
How to determine if platform library is static or dynamic from autotools?
配置
我使用 autotools(autoreconf -iv 和 ./configure)生成正确的 makefile。在我的开发机器 (Fedora) 上,一切正常。对于 make check
,我使用库 libcheck
,对于 autotools
,我使用 Libtools
。在 Fedora 上,用于检查的库是动态的:libcheck.so.0.0.0
或类似的东西。有效。
问题
当我在 github 上将提交推送到我的 repo 并执行拉取请求时,结果在使用 Ubuntu 作为平台的 Travis CI 上进行测试。现在 Ubuntu 上的 libcheck 是一个静态库:libcheck.a
和 libcheck_pic.a
.
当 Travis 进行 make 检查时,我收到以下错误消息:
/usr/bin/ld: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../..
/../libcheck.a(check.o): relocation R_X86_64_32 against
.rodata.str1.1' 不能
制作共享对象时使用;使用 -fPIC`
重新编译
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../libcheck.a: could not read
symbols: Bad value
这意味着我必须以某种方式让配置确定我需要的库。我怀疑我需要 libcheck_pic.a 用于 Ubuntu 和常规 libcheck.so 用于 Fedora。
问题
有谁知道如何使用 libtool 将其集成到 configure.ac 和 test/Makefile.am 中?我更愿意与 autotools 的生活方式保持一致。
我无法使用 google 找到有用的信息,但是有很多关于静态和动态之间的区别的问题(这不是我需要的)。
如果有人能指出正确的方向,或者甚至已经解决了这个问题,我将不胜感激?
我怀疑你是对的,你想在 CI 系统上使用的库是 libcheck_pic.a
,因为它的名字表明其中的例程被编译为与位置无关的代码,确切地说正如您收到的错误消息所暗示的那样。
解决该问题的一种方法是,如果可用,则使用 libcheck_pic
,否则退回到普通的 libcheck
。配置基于 Autotools 的构建系统并不难。然后,您在输出变量中记录适当的库名称,并在您的(自动)生成文件中使用它。
Autoconf 的 SEARCH_LIBS
宏专门用于这种优先库搜索要求,但它有副作用,在这种情况下可能不需要修改 LIBS
变量。你仍然可以让它工作。像这样的事情可能会做到,例如:
LIBS_save=$LIBS
AC_SEARCH_LIBS([ck_assert], [check_pic check], [
# Optional: add a test to verify that the chosen lib really provides PIC code.
# Set LIBCHECK to the initial substring of $LIBS up to but excluding the first space.
LIBCHECK=${LIBS%% *}
], [
# or maybe make it a warning, and disable your test suite when libcheck
# is not available.
AC_MSG_ERROR([A PIC version of libcheck is required])
])
AC_OUTPUT([LIBCHECK])
LIBS=$LIBS_save
我想您知道如何在 Make 端使用 $(LIBCHECK)
。
如所写,这有一个限制,即如果没有可用的 libcheck 的 PIC 版本,那么您要等到 make
或 make check
才能发现。这是不可取的,如果这种情况足够不可取,您可以添加 Autoconf 代码来检测这种情况。
作为一种完全不同的方法,您可以考虑静态构建测试(将 -static
添加到适当的 *_LDFLAGS
变量)。当然,这有相反的问题:如果库的静态版本不可用,那么构建或测试就会失败。此外,如果您还没有这样做,它需要构建您自己代码的静态版本,此外,它将测试静态版本。
为了获得最大的灵活性,您可以考虑结合使用这两种方法。您可以设置从一个到另一个的回退,或者您可以设置单独的目标来测试静态代码和 PIC 代码,并练习构建系统上可用的库支持的任何一个(可能两者)。
配置
我使用 autotools(autoreconf -iv 和 ./configure)生成正确的 makefile。在我的开发机器 (Fedora) 上,一切正常。对于 make check
,我使用库 libcheck
,对于 autotools
,我使用 Libtools
。在 Fedora 上,用于检查的库是动态的:libcheck.so.0.0.0
或类似的东西。有效。
问题
当我在 github 上将提交推送到我的 repo 并执行拉取请求时,结果在使用 Ubuntu 作为平台的 Travis CI 上进行测试。现在 Ubuntu 上的 libcheck 是一个静态库:libcheck.a
和 libcheck_pic.a
.
当 Travis 进行 make 检查时,我收到以下错误消息:
/usr/bin/ld: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../..
/../libcheck.a(check.o): relocation R_X86_64_32 against
.rodata.str1.1' 不能
制作共享对象时使用;使用 -fPIC`
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../libcheck.a: could not read
symbols: Bad value
这意味着我必须以某种方式让配置确定我需要的库。我怀疑我需要 libcheck_pic.a 用于 Ubuntu 和常规 libcheck.so 用于 Fedora。
问题 有谁知道如何使用 libtool 将其集成到 configure.ac 和 test/Makefile.am 中?我更愿意与 autotools 的生活方式保持一致。
我无法使用 google 找到有用的信息,但是有很多关于静态和动态之间的区别的问题(这不是我需要的)。
如果有人能指出正确的方向,或者甚至已经解决了这个问题,我将不胜感激?
我怀疑你是对的,你想在 CI 系统上使用的库是 libcheck_pic.a
,因为它的名字表明其中的例程被编译为与位置无关的代码,确切地说正如您收到的错误消息所暗示的那样。
解决该问题的一种方法是,如果可用,则使用 libcheck_pic
,否则退回到普通的 libcheck
。配置基于 Autotools 的构建系统并不难。然后,您在输出变量中记录适当的库名称,并在您的(自动)生成文件中使用它。
Autoconf 的 SEARCH_LIBS
宏专门用于这种优先库搜索要求,但它有副作用,在这种情况下可能不需要修改 LIBS
变量。你仍然可以让它工作。像这样的事情可能会做到,例如:
LIBS_save=$LIBS
AC_SEARCH_LIBS([ck_assert], [check_pic check], [
# Optional: add a test to verify that the chosen lib really provides PIC code.
# Set LIBCHECK to the initial substring of $LIBS up to but excluding the first space.
LIBCHECK=${LIBS%% *}
], [
# or maybe make it a warning, and disable your test suite when libcheck
# is not available.
AC_MSG_ERROR([A PIC version of libcheck is required])
])
AC_OUTPUT([LIBCHECK])
LIBS=$LIBS_save
我想您知道如何在 Make 端使用 $(LIBCHECK)
。
如所写,这有一个限制,即如果没有可用的 libcheck 的 PIC 版本,那么您要等到 make
或 make check
才能发现。这是不可取的,如果这种情况足够不可取,您可以添加 Autoconf 代码来检测这种情况。
作为一种完全不同的方法,您可以考虑静态构建测试(将 -static
添加到适当的 *_LDFLAGS
变量)。当然,这有相反的问题:如果库的静态版本不可用,那么构建或测试就会失败。此外,如果您还没有这样做,它需要构建您自己代码的静态版本,此外,它将测试静态版本。
为了获得最大的灵活性,您可以考虑结合使用这两种方法。您可以设置从一个到另一个的回退,或者您可以设置单独的目标来测试静态代码和 PIC 代码,并练习构建系统上可用的库支持的任何一个(可能两者)。