配置
我使用自动工具(autoreconf -iv 和 ./configure)来生成正确的 makefile。在我的开发机器(Fedora)上一切正常。对于 make check
,我使用库 libcheck
,在 autotools
中,我使用 Libtools
。在 Fedora 上,用于检查的库是动态的:libcheck.so.0.0.0
或类似的东西。它有效。
问题
当我将提交推送到 github 上的存储库并执行拉取请求时,结果在使用 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):针对
.rodata.str1.1'重定位R_X86_64_32可以
创建共享对象时不使用;使用-fPIC`重新编译
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../libcheck.a:无法读取
符号:错误值
这意味着我必须以某种方式让配置确定我需要什么库。我怀疑 Ubuntu 需要 libcheck_pic.a,Fedora 需要常规 libcheck.so。
问题 有谁知道如何使用 libtool 将其集成到 configure.ac 和 test/Makefile.am 中?我更愿意与自动工具的生活方式保持一致。
我无法使用谷歌找到可用的信息,但是有很多关于静态和动态之间区别的问题(这不是我需要的)。
如果有人能指出我正确的方向,或者甚至已经解决了这个问题,我将不胜感激?
最佳答案
我怀疑你是对的,你想在 CI 系统上使用的库是 libcheck_pic.a
,因为它的名字表明其中的例程被编译为位置无关的代码,就像您收到的错误消息表明您已这样做。
解决这个问题的一种方法是使用libcheck_pic
(如果可用),否则就回退到普通的libcheck
。配置基于 Autotools 的构建系统并不难。然后,您在输出变量中记录适当的库名称,并在(自动)make 文件中使用它。
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)
。
正如所写,它有一个限制,即如果没有可用的 PIC 版本的 libcheck,那么直到 make
或 make check
之前您不会发现。这是不可取的,如果这种情况足够不可取,您可以添加 Autoconf 代码来检测这种情况。
作为一种完全不同的方法,您可以考虑静态构建测试(将 -static
添加到适当的 *_LDFLAGS
变量)。当然,这会带来相反的问题:如果库的静态版本不可用,则构建或测试会失败。此外,如果您还没有这样做,它还需要构建您自己的代码的静态版本,而且,将测试的是静态版本。
为了获得最大的灵活性,您可以考虑将这两种方法结合起来。您可以设置从一个到另一个的回退,或者您可以设置单独的目标来测试静态代码和 PIC 代码,并练习构建系统上可用的库支持的其中一个(可能是两者)。
关于c - 如何从autotools确定平台库是静态还是动态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45417496/