autoconf:在进行本机编译时执行AC_RUN_IFELSE,否则进行AC_COMPILE_IFELSE

问题描述

从rsync修改了configrue.ac:

if test x"$host_cpu" = x"x86_64"; then
    if test x"$host_cpu" = x"$build_cpu"; then
        AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
#include <immintrin.h>
/* some long C++ code here */
]],[[if (test_ssse3(42) != 42 || test_sse2(42) != 42 || test_avx2(42) != 42) exit(1);]])],[CXX_OK=yes],[CXX_OK=no])
    else
        AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[#include <stdio.h>
#include <immintrin.h>
/* the same C++ code again */
]]),[CXX_OK=no])
    fi
fi

如何改进?有没有办法避免重复C ++代码

解决方法

是否有避免重复C ++代码的方法?

好的。毕竟,Autoconf本质上是一种宏语言。您可以定义和(重新)使用一个扩展为该代码的宏,而不用复制代码。 AC_DEFUN()m4_define()都可以使用,但是前者对于我认为您想要的东西有点过大。所以,

m4_define([_EDO1_LONG_CODE],[[
// long C++ code ...
]])

在使用时要格外小心。您正在使用双引号来确保程序源不受宏扩展的影响,但是实际上您想要想要宏扩展的地方,则需要将引号级别降低一,例如:

if test x"$host_cpu" = x"x86_64"; then
    if test x"$host_cpu" = x"$build_cpu"; then
        AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
#include <immintrin.h>
]_EDO1_LONG_CODE],[[if (test_ssse3(42) != 42 || test_sse2(42) != 42 || test_avx2(42) != 42) exit(1);]])],[CXX_OK=yes],[CXX_OK=no])
    else
        AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[#include <stdio.h>
#include <immintrin.h>
]_EDO1_LONG_CODE]),[CXX_OK=no])
    fi
fi