使用 gcc-ar 和 gcc-ranlib 的 autoconf 配方

Posted

技术标签:

【中文标题】使用 gcc-ar 和 gcc-ranlib 的 autoconf 配方【英文标题】:autoconf recipe to use gcc-ar and gcc-ranlib 【发布时间】:2016-11-02 06:57:32 【问题描述】:

我在 project 中使用链接时优化 (LTO),它可以在 GCC 和 Clang 下编译并构建静态库。它适用于 GCC 4.8,但 GCC 5.4 会生成瘦 LTO 对象,当 automake 尝试使用 ar 构建静态库时,它会失败,因为它需要包装脚本 gcc-ar

有没有一个很好的例子可以让我看看如何让 automake 使用 gcc-ar 而不是 argcc-ranlib 也是如此)?我可能可以破解一些东西,但理想情况下应该:

为编译器使用适当的工具(Clang 有其own instructions)。 即使用户将编译器覆盖为非系统默认编译器,也能正常工作。 交叉编译时工作

【问题讨论】:

【参考方案1】:

您可以通过调用覆盖默认工具

./configure AR=gcc-ar RANLIB=gcc-ranlib

我担心./configure 默认会选择它们,必须修复 autoconf/automake 才能了解默认检查集中的那些。

【讨论】:

可以编写一组自定义检查来执行此操作(autoconf 是完全可扩展的)。我的问题是是否有任何项目已经这样做了,以便我可以效仿他们的例子,而不是弄清楚如何自己处理所有编译器。【参考方案2】:

使用这个:

AC_ARG_VAR([AR], [AR command (default is gcc-ar)])
AC_CHECK_TOOL([AR], [gcc-ar])

AC_ARG_VAR([RANLIB], [RANLIB command (default is gcc-ranlib)])
AC_CHECK_TOOL([RANLIB], [gcc-ranlib])

AC_ARG_VAR 在调用./configure --help 时只是为了记录它。

AC_CHECK_TOOL 用于这些工具,而不是AC_CHECK_PROGS,因此交叉编译时使用正确的版本。

您仍然可以在调用 ./configure 时覆盖 ARRANLIB

要回退到常规 ar 和常规 ranlib,您可以改用 AC_CHECK_TOOLS

AC_CHECK_TOOLS([AR], [gcc-ar ar])

可以将可选的第三个参数设置为 : 之类的东西,这样您就可以测试是否找不到任何工具:

AC_CHECK_TOOLS([AR], [gcc-ar ar], [:])
AS_VAR_IF([AR], [:], AC_MSG_ERROR([could not find AR tool.]))

对于 Clang,它们遵循不同的命名约定:llvm-arllvm-ranlibllvm-objcopy 等。我将使用两个辅助宏。

首先,我们定义MY_CHECK_TOOL_PREFIX,使用AX_COMPILER_VENDOR,这会尝试猜测使用什么工具前缀;它可以被TOOL_PREFIX 变量覆盖。它将测试当前语言的编译器(默认为 C);如果需要,请务必提前致电AC_LANG(C++)。供下一个宏使用,不需要手动调用。

AC_DEFUN([MY_CHECK_TOOL_PREFIX],
[
    AC_REQUIRE([AX_COMPILER_VENDOR])
    AC_ARG_VAR([TOOL_PREFIX], [tool prefix (gcc, llvm)])
    AC_MSG_CHECKING([toolchain prefix])
    # only convert vendor to prefix if not already set
    AS_VAR_SET_IF([TOOL_PREFIX],
        [],
        [
            AS_CASE([$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor],
                [gnu], [TOOL_PREFIX="gcc"],
                [clang], [TOOL_PREFIX="llvm"],
                [TOOL_PREFIX="unknown"])
        ])
    AC_MSG_RESULT([$TOOL_PREFIX])
])

然后是您将使用的宏:MY_CHECK_TOOL。如果未找到该工具的变体,则默认操作是中止。

dnl MY_CHECK_TOOL(TOOL, PROGRAM-TO-CHECK, [ACTION-IF-NOT-FOUND])
AC_DEFUN([MY_CHECK_TOOL],
[
    AC_REQUIRE([MY_CHECK_TOOL_PREFIX])
    AC_ARG_VAR($1, [$1 command (default is TOOL_PREFIX-$2, $2)])
    AC_CHECK_TOOLS($1, [$TOOL_PREFIX-$2 $2], [:])
    AS_VAR_IF($1, [:],
        [m4_ifblank($3,
            [AC_MSG_ERROR([could not find $1])],
            $3)])
])

如果您不想弄乱您的 configure.ac,可以将两者保存在 M4 目录中的 my_prefix_tools.m4 文件中。

下面是您在configure.ac 中使用它的方法:

AC_PROG_CXX
AC_LANG(C++)
MY_CHECK_TOOL([AR], [ar])
MY_CHECK_TOOL([RANLIB], [ranlib])
MY_CHECK_TOOL([OBJCOPY], [objcopy])
MY_CHECK_TOOL([NM], [nm])

当运行./configure 时,g++ 是默认的 C++ 编译器,输出如下:

checking for C++ compiler vendor... gnu
checking toolchain prefix... gcc
checking for gcc-ar... gcc-ar
checking for gcc-ranlib... gcc-ranlib
checking for gcc-objcopy... no
checking for objcopy... objcopy
checking for gcc-nm... gcc-nm

当运行./configure CXX=clang++ 时,输出如下:

checking for C++ compiler vendor... clang
checking toolchain prefix... llvm
checking for llvm-ar... llvm-ar
checking for llvm-ranlib... llvm-ranlib
checking for llvm-objcopy... llvm-objcopy
checking for llvm-nm... llvm-nm

【讨论】:

是否会自动处理 Clang,而不需要用户覆盖 CXX=clang++ 以外的任何内容? 我把它变成了宏,使用起来更方便。

以上是关于使用 gcc-ar 和 gcc-ranlib 的 autoconf 配方的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 php 和 mysql 使用纬度和经度进行几何搜索

CPU使用率和正在使用的内存之间有啥关系?

使用同一文件的校验和加密文件

Ajax 跨域和同源策略的解释和使用,使用jQuery跨域,模板引擎artTemplate的使用详细解释+案例

什么是menuconfig和menuconfig的使用方法和技巧

java 能不能和sdl配合使用