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

标签 c linux static cross-platform autotools

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

问题 当我将提交推送到 github 上的存储库并执行拉取请求时,结果在使用 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):针对.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,那么直到 makemake check 之前您不会发现。这是不可取的,如果这种情况足够不可取,您可以添加 Autoconf 代码来检测这种情况。


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

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

关于c - 如何从autotools确定平台库是静态还是动态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45417496/

相关文章:

c - 静态的生命周期真的在程序执行时开始吗?

c - BUG : unable to handle kernel paging request

c - 为什么 float 不起作用?

linux - 从一个文件测试多个服务器的 telnet 连接

linux - 执行 thermal_zone_device_unregister() 时内核崩溃

c - C 中的静态变量

java - fread() 读取零值

检查表示数字的字符串的有效性

linux - EC2实例的私有(private)IP

class - 类成员函数代码内存是分配一次还是在对象的每次实例化时分配?