叮当声:可靠地检测受支持的C++;来自命令行或Python的标准 在Python脚本中,我尝试用确定安装的Cuang< > /P>支持的最高C++标准。

叮当声:可靠地检测受支持的C++;来自命令行或Python的标准 在Python脚本中,我尝试用确定安装的Cuang< > /P>支持的最高C++标准。,c++,clang,clang++,llvm-clang,C++,Clang,Clang++,Llvm Clang,一个问题是我不能依赖clang--version的输出总是相同的,最好的例子是OSX上的AppleClang。 正在尝试编译一个helloworld.cpp文件,其中包含测试标志,如-std=c++11,-std=c++14。。。这似乎不是最可靠的方法,需要创建临时文件 是否有任何命令可以运行来测试某个方言是否可用,而无需实际编译任何东西 是否有任何命令可以运行来测试某个方言是否可用,而无需实际编译任何东西 对。您可以要求编译器只预处理一个空文件。它会做到的 毫无怨言: $ clang++ --

一个问题是我不能依赖
clang--version
的输出总是相同的,最好的例子是OSX上的AppleClang。 正在尝试编译一个helloworld
.cpp
文件,其中包含测试标志,如
-std=c++11
-std=c++14
。。。这似乎不是最可靠的方法,需要创建临时文件


是否有任何命令可以运行来测试某个方言是否可用,而无需实际编译任何东西


是否有任何命令可以运行来测试某个方言是否可用,而无需实际编译任何东西

对。您可以要求编译器只预处理一个空文件。它会做到的 毫无怨言:

$ clang++ --version
clang version 4.0.1-6 (tags/RELEASE_401/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

$ echo '' | clang++ -x c++ -E -
# 1 "<stdin>"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 329 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "<stdin>" 2

$ echo $?
0
仍然没有抱怨。但如果不是:

$ echo '' | clang++ -std=c++17 -x c++ -E -
error: invalid value 'c++17' in '-std=c++17'
$ echo $?
1
在python脚本中,您可以方便地以空字符串的形式向执行编译器探测命令的
subprocess.run
调用提供一个空输入文件, 同时吞下不想要的食物。你应该反复这样做 调用按时间顺序排序的
-std
-值列表以查找 支持最新版本。谨慎的做法是,不只是测试返回代码,而是 还可以捕获stderr,并在出现故障时对其进行正确的解析 一种诊断,以防命令因某种意外原因失败

下面是一个为GCC和clang服务的镜头:

$ cat std_max.py
#!/usr/bin/python3
import subprocess

standards = ['98','03','11','14','17']
gpp_barf_pattern = "error: unrecognized command line option ‘-std=c++{0}’"
clangpp_barf_pattern = "error: invalid value 'c++{0}'"

def has_standard(compiler, std_year, barf_pattern):
    std_opt = '-std=c++' + std_year
    try:
        subprocess.run([compiler,std_opt,'-x','c++','-E','-'],\
            check=True,input=b'',stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    except subprocess.CalledProcessError as e:
        barf = barf_pattern.format(std_year)
        strerr = e.stderr.decode('utf8','strict')
        if barf in strerr:
            return False
        raise
    return True

def get_std_max(compiler,standards,barf_pattern):
    max_std = standards[0] if len(standards) else ''
    for std_year in standards:
        if not has_standard(compiler,std_year,barf_pattern):
            break
        max_std = 'c++' + std_year
    return max_std
这将正确地告诉我:

$ python3
Python 3.6.3 (default, Oct  3 2017, 21:45:48) 
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from std_max import *
>>> get_std_max('clang++',standards,clangpp_barf_pattern)
'c++14'
>>> get_std_max('g++',standards,gpp_barf_pattern)
'c++17'
>>>
还没有C++20:

>>> has_standard('g++','20',gpp_barf_pattern)
False
>>>

我会尝试编译我感兴趣的特性,它将是最健壮的。。。如果clang像gcc一样工作,那么您也可以从stdin中获取源代码,并避免使用tempfiles.@Prof.Falken Yes。Autoconf,
/configure
,不是这样吗?并不是给定标准的所有功能都受支持。我认为这取决于一个版本。这是文档和参考资料。@gurka,是的。现在,Autoconf是一个怪兽,我知道如果有人想在某些情况下避免它,“没有实际编译任何东西?”-没有发布版本和功能的数据库。cmake和autoconf的方法是实际编译代码片段并检查流程的返回代码。
>>> has_standard('g++','20',gpp_barf_pattern)
False
>>>