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

时间:2016-11-02 06:57:33

标签: gcc autoconf automake lto

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

我是否有一个很好的例子,我可以看一下如何使用gcc-ar而不是ar(同样适用于gcc-ranlib)?我可能会破解某些东西,但理想情况下应该:

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

2 个答案:

答案 0 :(得分:2)

您可以覆盖调用

时使用的默认工具
./configure AR=gcc-ar RANLIB=gcc-ranlib

我担心./configure默认接听它们,必须修复autoconf / automake以了解默认检查中的那些。

答案 1 :(得分:0)

使用此:

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,因此在交叉编译时使用正确的版本。

  • 调用AR时,您仍然可以覆盖RANLIB./configure

  • 要回退到常规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等。我将使用两个帮助程序宏。

首先,我们使用AX_COMPILER_VENDOR定义MY_CHECK_TOOL_PREFIX,这将尝试猜测要使用的工具前缀;可以使用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)])
])

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

这是在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