2012-07-07 19 views
5

我的项目使用SCons来管理构建过程。我想支持多个编译器,因此我决定使用AddOption,以便用户可以指定在命令行上使用哪个编译器(缺省情况下是当前编译器的任何编译器)。如何确定请求了哪个编译器

AddOption('--compiler', dest = 'compiler', type = 'string', action = 'store', default = DefaultEnvironment()['CXX'], help = 'Name of the compiler to use.') 

我希望能够为各种编译器(包括诸如特定编译器的最大警告级别等内容)设置内置编译器设置。这是我的一个解决方案,第一次尝试目前的样子:

if is_compiler('g++'): 
    from build_scripts.gcc.std import cxx_std 
    from build_scripts.gcc.warnings import warnings, warnings_debug, warnings_optimized 
    from build_scripts.gcc.optimizations import optimizations, preprocessor_optimizations, linker_optimizations 
elif is_compiler('clang++'): 
    from build_scripts.clang.std import cxx_std 
    from build_scripts.clang.warnings import warnings, warnings_debug, warnings_optimized 
    from build_scripts.clang.optimizations import optimizations, preprocessor_optimizations, linker_optimizations 

不过,我不知道该怎么做一下is_compiler()功能等。我的第一个想法是直接比较编译器名称(例如'clang ++')和用户通过的内容。但是,当我尝试使用scons --compiler=~/data/llvm-3.1-obj/Release+Asserts/bin/clang++时,这立即失败。

所以我想我会得到一个有点小聪明,利用此功能

cxx = GetOption('compiler') 
def is_compiler (compiler): 
    return cxx[-len(compiler):] == compiler 

这仅着眼于编译字符串的结尾,所以它忽略目录。不幸的是,'clang ++'以'g ++'结尾,所以我的编译器被认为是g ++而不是clang ++。

我的下一个想法是做一个反向搜索并寻找第一个出现的路径分隔符('\'或'/'),但后来我意识到这不适用于具有多个编译器版本的人。有人用'g ++ - 4.7'编译不会注册为g ++。

那么,有没有一些简单的方法来确定哪个编译器被请求?

目前,由于支持C++ 11,所以只支持g ++和clang ++(并且只支持最新发布的版本),因此只适用于这两种版本的解决方案现在已经够用了。然而,我的最终目标是至少支持g ++,clang ++,icc和msvC++(一旦它们支持所需的C++ 11功能),所以更通用的解决方案是首选。

+2

我会在这里分开两个问题。问题#1)*哪个*编译器被请求和#2)*其中*是请求的编译器位于(为此,你可以在大多数时间使用合理的默认值,只有让他们指定它,如果他们不想默认的叮声/ GCC /不管)。这两件事并没有太大共同之处,毕竟我可以很容易地创建一个名为'msvc'的叮当连接,如果我想(实际上从来没有尝试过,但为什么不呢?) – Voo 2012-07-07 18:29:56

+0

我同意@Voo给你的建议。编辑这个缩小到一个问题,然后创建一个新的问题。你有两个很好的问题,这就是为什么我提出了你创建的那个(到目前为止)。 – octopusgrabbus 2012-07-07 19:50:00

+0

@Voo如果你把它写成答案,我会接受它,因为那是我用来解决问题的关键洞察力。 – 2012-07-28 14:06:37

回答

1

这个问题导致了SCons的项目,可以处理这个发展:

https://bitbucket.org/davidstone/scons-template/

相关的代码是在build_scripts/compiler_settings.py。利用Scons选项设置在SConstruct文件与下列行:

AddOption('--compiler', dest = 'compiler', type = 'string', action = 'store', help = 'Name of the compiler to use.') 
AddOption('--compiler-command', dest = 'compiler_command', type = 'string', action = 'store', help = 'Command to launch the compiler.') 

用户可指定0,1或2的命令行选项。

如果您没有指定任何内容(scons),那么它将使用来自DefaultEnvironment的编译器进行构建。

您可以选择指定编译器的名称(scons --compiler=g++)。然后,我的脚本假定用于编译的命令与名称相同。

您还可以选择指定要编译的命令(scons --compiler-command=~/llvm-3.1-obj/Release+Asserts/bin/clang++)。然后,我的脚本假定您使用的编译器的名称是可执行文件的名称(在最终目录分隔符之后的所有内容,由os.path.basename确定)。

您可以指定两者。这允许您处理奇怪的情况:scons --compiler-command=/path/to/executable/that/is/not/clang++ --compiler=g++

它使用名称来确定打开哪些警告/优化。我甚至为这个名称添加了一些标准化,所以就编译器名称而言,g ++,gcc和GcC都被视为相同的东西。

它还有很多工作要做,比如支持更多的编译器,更好地支持mingw编译器,以及检测编译器版本,以便更好地处理仅在版本x.y.z +中可用的标志。如果我能做到像scons --compiler-command=/path/to/gcc-4.7.1这样的东西,并且它能够检测到编译器是gcc,而我不必明确地告诉它,那也不错。

但是,它解决了我开始解决的最初问题。对于这一点,大部分的功劳必须在Voo的评论中让我走上正轨。

2

编译器只是构建过程的一部分。你也需要连接器工具,也可能是其他附加程序。在Scons它被命名为 - 工具。支持的工具列表from box您可以在man page中查看,通过声明搜索:SCons supports the following tool specifications out of the box: ... 工具集必需的scons环境变量,它记录为here

Scons自动检测操作系统中的编译器,并有一些优先选择其中之一,当然如果PATH变量设置为必要的目录,自动检测将正常工作。例如你在windows上有msvc和mingw,scons选择msvc工具。对于使用工具的强制使用工具('name')(env)。例如:

env = Environment() 
Tool('mingw')(env) 

Now env force using mingw。

所以,铛是目前不支持由scons from box工具之一。您需要实现它,或设置使用scons生成构建命令的CC,CXX等环境变量。

相关问题