使用CMake在GCC和Clang / LLVM之间切换

问题描述 投票:237回答:9

我有许多使用CMake构建的项目,我希望能够轻松地在使用GCC或Clang / LLVM进行编译之间进行切换。我相信(请纠正我,如果我错了!)使用Clang我需要设置以下内容:

    SET (CMAKE_C_COMPILER             "/usr/bin/clang")
    SET (CMAKE_C_FLAGS                "-Wall -std=c99")
    SET (CMAKE_C_FLAGS_DEBUG          "-g")
    SET (CMAKE_C_FLAGS_MINSIZEREL     "-Os -DNDEBUG")
    SET (CMAKE_C_FLAGS_RELEASE        "-O4 -DNDEBUG")
    SET (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")

    SET (CMAKE_CXX_COMPILER             "/usr/bin/clang++")
    SET (CMAKE_CXX_FLAGS                "-Wall")
    SET (CMAKE_CXX_FLAGS_DEBUG          "-g")
    SET (CMAKE_CXX_FLAGS_MINSIZEREL     "-Os -DNDEBUG")
    SET (CMAKE_CXX_FLAGS_RELEASE        "-O4 -DNDEBUG")
    SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")

    SET (CMAKE_AR      "/usr/bin/llvm-ar")
    SET (CMAKE_LINKER  "/usr/bin/llvm-ld")
    SET (CMAKE_NM      "/usr/bin/llvm-nm")
    SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump")
    SET (CMAKE_RANLIB  "/usr/bin/llvm-ranlib")

有没有一种简单的方法可以在这些和默认的GCC变量之间切换,最好是作为系统范围的变更而不是项目特定的(即不只是将它们添加到项目的CMakeLists.txt中)?

另外,在使用clang而不是gcc编译时,是否有必要使用llvm-*程序而不是系统默认值?有什么不同?

cmake llvm clang
9个回答
304
投票

在检测到要使用的C和C ++编译器时,CMake尊重环境变量CCCXX

$ export CC=/usr/bin/clang
$ export CXX=/usr/bin/clang++
$ cmake ..
-- The C compiler identification is Clang
-- The CXX compiler identification is Clang

可以通过将它们放入系统范围的CMake文件并将CMAKE_USER_MAKE_RULES_OVERRIDE变量指向它来覆盖编译器特定标志。使用以下内容创建文件~/ClangOverrides.txt

SET (CMAKE_C_FLAGS_INIT                "-Wall -std=c99")
SET (CMAKE_C_FLAGS_DEBUG_INIT          "-g")
SET (CMAKE_C_FLAGS_MINSIZEREL_INIT     "-Os -DNDEBUG")
SET (CMAKE_C_FLAGS_RELEASE_INIT        "-O4 -DNDEBUG")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")

SET (CMAKE_CXX_FLAGS_INIT                "-Wall")
SET (CMAKE_CXX_FLAGS_DEBUG_INIT          "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT     "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE_INIT        "-O4 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")

后缀_INIT将使CMake使用给定值初始化相应的*_FLAGS变量。然后以下列方式调用cmake:

$ cmake -DCMAKE_USER_MAKE_RULES_OVERRIDE=~/ClangOverrides.txt ..

最后强制使用LLVM binutils,设置内部变量_CMAKE_TOOLCHAIN_PREFIX。这个变量受到CMakeFindBinUtils模块的尊重:

$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=llvm- ..

把这一切放在一起你就可以编写一个shell包装器来设置环境变量CCCXX,然后使用上面提到的变量覆盖来调用cmake。


114
投票

Ubuntu上的系统范围的C ++更改:

sudo apt-get install clang
sudo update-alternatives --config c++

将打印这样的东西:

  Selection    Path              Priority   Status
------------------------------------------------------------
* 0            /usr/bin/g++       20        auto mode
  1            /usr/bin/clang++   10        manual mode
  2            /usr/bin/g++       20        manual mode

然后选择clang ++。


21
投票

您可以使用选项命令:

option(USE_CLANG "build application with clang" OFF) # OFF is the default

然后在if()s中包含clang-compiler设置:

if(USE_CLANG)
    SET (...)
    ....
endif(USE_CLANG)

这样它在gui-configuration工具中显示为cmake选项。

为了使它成为系统范围,您当然可以使用环境变量作为默认值,或者继续使用Ferruccio的答案。


16
投票

Ubuntu上的系统范围C更改:

sudo update-alternatives --config cc

Ubuntu上的系统范围的C ++更改:

sudo update-alternatives --config c++

对于上述每一项,按选择号(1)和Enter选择Clang:

  Selection    Path            Priority   Status
------------------------------------------------------------
* 0            /usr/bin/gcc     20        auto mode
  1            /usr/bin/clang   10        manual mode
  2            /usr/bin/gcc     20        manual mode
Press enter to keep the current choice[*], or type selection number:

9
投票

你绝对不需要使用各种不同的llvm-ar等程序:

SET (CMAKE_AR      "/usr/bin/llvm-ar")
SET (CMAKE_LINKER  "/usr/bin/llvm-ld")
SET (CMAKE_NM      "/usr/bin/llvm-nm")
SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump")
SET (CMAKE_RANLIB  "/usr/bin/llvm-ranlib")

这些都是在llvm内部格式上工作的,因此对构建应用程序没有用。

作为注释-O4将在您的程序上调用您可能不需要的LTO(它将大大增加编译时间)并且将默认值设置为c99模式,因此也不一定需要标志。


7
投票

您可以使用cmake的工具链文件机制来实现此目的,请参阅例如here。您为包含相应定义的每个编译器编写工具链文件。在配置时,您运行例如

 cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/clang-toolchain.cmake ..

并且在从工具链文件调用project()期间将设置所有编译器信息。虽然文档仅在交叉编译的上下文中提及,但它对于同一系统上的不同编译器也同样适用。


4
投票

根据cmake的帮助:

-C <initial-cache>
     Pre-load a script to populate the cache.

     When cmake is first run in an empty build tree, it creates a CMakeCache.txt file and populates it with customizable settings for the project.  This option may be used to specify a  file  from
     which to load cache entries before the first pass through the project's cmake listfiles.  The loaded entries take priority over the project's default values.  The given file should be a CMake
     script containing SET commands that use the CACHE option, not a cache-format file.

您可以创建gcc_compiler.txtclang_compiler.txt等文件,以包含CMake语法中的所有相关配置。

Clang示例(clang_compiler.txt):

 set(CMAKE_C_COMPILER "/usr/bin/clang" CACHE string "clang compiler" FORCE)

然后运行它

GCC:

cmake -C gcc_compiler.txt XXXXXXXX

锵:

cmake -C clang_compiler.txt XXXXXXXX

3
投票

您可以在$ENV{environment-variable}中使用语法:CMakeLists.txt来访问环境变量。您可以创建脚本,适当地初始化一组环境变量,并在CMakeLists.txt文件中引用这些变量。


2
投票

如果cmake选择的默认编译器是gcc并且您已安装clang,则可以使用简单的方法使用clang编译项目:

$ mkdir build && cd build
$ CXX=clang++ CC=clang cmake ..
$ make -j2
© www.soinside.com 2019 - 2024. All rights reserved.