如何从autotools确定平台库是静态的还是动态的?

时间:2017-07-31 13:37:19

标签: c linux static cross-platform autotools

配置 我使用autotools(autoreconf -iv和./configure)生成正确的makefile。在我的开发机器(Fedora)上一切正常。对于make check,我使用了库libcheck,而autotools则使用了Libtools。在Fedora上,用于检查的库是动态的:libcheck.so.0.0.0或类似的东西。它有效。

问题 当我在github上将提交推送到我的repo并执行pull请求时,结果将在使用Ubuntu作为平台的Travis CI上进行测试。现在在Ubuntu上,libcheck是一个静态库:libcheck.alibcheck_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

这意味着我必须以某种方式让configure确定我需要的库。我怀疑我需要Ubuntu的libcheck_pic.a和Fedora的常规libcheck.so。

问题 有谁知道如何使用libtool将它集成到configure.ac和test / Makefile.am中?我宁愿与autotools的生活方式保持一致。

我无法使用谷歌找到有用的信息,但是有很多问题关于静态和动态之间的区别(这不是我需要的)。

如果有人能指出我正确的方向,或者甚至已经解决了这个问题,我会非常感激吗?

1 个答案:

答案 0 :(得分:2)

我怀疑你是对的,你想在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,那么你将无法找到makemake check。这是不可取的,你可以添加Autoconf代码来检测那种情况,如果它是不合适的。

作为一种完全不同的方法,您可以考虑静态构建测试(将-static添加到相应的*_LDFLAGS变量)。当然,这有相反的问题:如果库的静态版本不可用,则构建或测试失败。此外,如果您还没有这样做,则需要构建自己代码的静态版本,此外,它是将要测试的静态版本。

为了获得最大的灵活性,您可以考虑将这两种方法结合起来。您可以设置从一个到另一个的回退,或者您可以设置单独的目标来测试静态代码和PIC代码,并且可以使用构建系统上可用的库支持它们中的任何一个(可能两者)。