我有许多使用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-*程序而不是系统默认值?有什么不同?


当前回答

您可以使用option命令:

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

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

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

通过这种方式,它将在gui配置工具中显示为cmake选项。

当然,要使其成为系统范围,您可以使用一个环境变量作为默认值,或者沿用Ferruccio的答案。

其他回答

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

布景(CMAKE_AR /usr/bin/llvm-ar) 集(CMAKE_LINKER "/usr/bin/llvm-ld") 布景(CMAKE_NM /usr/bin/llvm-nm) SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump") SET (CMAKE_RANLIB“/usr/bin/llvm-ranlib”)

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

注意-O4会在你的程序上调用LTO,这可能是你不想要的(这会大大增加编译时间),clang默认为c99模式,所以这个标志也不一定需要。

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

$ mkdir build && cd build
$ CXX=clang++ CC=clang cmake ..
$ make -j2

或者为cmake指定编译器:

$ cmake -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang ..

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++。

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:

在检测到C和c++编译器使用时,CMake尊重环境变量CC和CXX:

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

编译器特定的标志可以通过将它们放入一个make覆盖文件并将CMAKE_USER_MAKE_RULES_OVERRIDE变量指向它来覆盖。创建一个包含以下内容的文件~/ClangOverrides.txt:

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

SET (CMAKE_CXX_FLAGS_INIT                "-Wall -std=c++17")
SET (CMAKE_CXX_FLAGS_DEBUG_INIT          "-g")
SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT     "-Os -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELEASE_INIT        "-O3 -DNDEBUG")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O2 -g")

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

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

最后,为了强制使用LLVM二进制代码,设置内部变量_CMAKE_TOOLCHAIN_PREFIX。这个变量由CMakeFindBinUtils模块提供:

$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=llvm- ..

在CMake 3.9或更新版本中不再需要设置_CMAKE_TOOLCHAIN_LOCATION。

把这些放在一起,您可以编写一个shell包装器,它设置环境变量CC和CXX,然后使用上述变量重写调用cmake。

也请参阅这个CMake常见问题解答关于重写文件。