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 特性),因此首选更通用的解决方案。

4

3 回答 3

2

编译器只是构建过程的一部分。您还需要链接器工具,并且可能是其他附加程序。在 Scons 中,它被命名为 - Tool。from box您可以在手册页中查看支持的工具列表,按语句搜索:SCons supports the following tool specifications out of the box:...工具集必要的 scons 环境变量,在此处记录。

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

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

现在env强制使用mingw。

因此,clang 是目前from boxscons 不支持的工具之一。您需要实现它,或者设置环境变量,例如 CC、CXX,它们使用 scons 生成构建命令。

于 2012-07-09T08:53:48.540 回答
1

您可以只使用此处指定的 Pythonos.path.basename()或函数。os.path.split()

您可以通过将这个问题分成 2 个不同的问题来做人们在评论中建议的事情,但我认为能够使用编译器指定路径可能是个好主意,因为您可以安装 2 个版本的 g++,如果用户只指定 g++,他们可能得不到预期的版本。

于 2012-07-07T20:41:13.193 回答
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++)。然后我的脚本假定您正在使用的编译器的名称是可执行文件的名称(最终目录分隔符之后的所有内容,由 by 确定os.path.basename)。

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

它使用名称来确定要打开哪些警告/优化。我什至在名称上添加了一些规范化,因此就编译器名称而言,g++、gcc 和 GcC 都被视为同一事物。

它还有很多工作要做,比如支持更多编译器,更好地支持mingw编译器,以及检测编译器版本以便更好地处理只有xyz+版本才有的标志。如果我可以做类似的事情scons --compiler-command=/path/to/gcc-4.7.1并让它检测到编译器是 gcc 而我不必明确告诉它,那也很好。

但是,它解决了我打算解决的最初问题。这要归功于 Voo 在评论中让我走上正轨。

于 2012-12-19T04:41:44.083 回答