检测编译器并在调用时使用特定于编译器的标志

Detect compiler and use compiler-specific flags when invoking

我收到了一个变量 CC,其中包含引用系统编译器的可执行文件。我需要获取这个可执行文件并最终使用一些特定于编译器的 link 参数调用它。

我目前的方法似乎很脆弱:

def guess_compiler(cc):
    out = subprocess.check_output((cc, '--version'))
    for possible in (b'clang', b'gcc'):
        if possible in out:
            return possible.decode()
    else:
        # Fall back to gcc
        return 'gcc'

由此我使用了我关心的特定 linker 参数的映射:

return {
    'clang': '-Wl,-undefined,dynamic_lookup',
    'gcc': '-Wl,--unresolved-symbols=ignore-all',
}[cc]

简而言之,我希望有更好的(不那么脆弱的)方法来完成我所取得的成就。

对于那些想知道为什么我想要这样的东西的人来说,它主要是为了 a project I'm implementing 中的可移植性。

我宁愿使用一些伪代码调用编译器并传入这些标志。这也是 Autotools 和 CMake 等工具所做的。

您当前方法的问题是您在 --version 输出中看到的文本字符串实际上可以是任意的。例如,当 clang 不那么流行时,FreeBSD 的 cc --version 一直在提供

GCC 4.2.1 -compatible Clang bla bla

因此,只需使用您感兴趣的每个标志调用编译器,然后查看退出代码。

如何执行此操作的示例:

for flag in FLAGS:
    try:
        subprocess.check_call((cc, 'test.c', flag), cwd=tmpdir)
        return flag
    except subprocess.CalledProcessError:
        pass
else:
    # wellp, none of them worked, fall back to gcc and they'll get a
    # hopefully reasonable error message
    return FLAG_GCC