cmake - 使用CMake,切换GCC和Clang/LLVM

我使用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变量,最好是系统范围内的变更而不是项目本身,

另外,使用clang代替gcc编译时,是否需要使用llvm-*程序而不是系统默认值? 有什么区别?

时间:

在检测到要使用的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")

suffix _INIT将使CMake用给定值初始化相应的*_FLAGS变量,然后按以下方式调用:


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

最后,为了强制使用LLVM binutils,设置内部变量_CMAKE_TOOLCHAIN_PREFIX ,此变量由CMakeFindBinUtils MODULE授予:


$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=llvm- ..

把这些综合起来,你可以编写一个shell包装器来设置环境变量CC和CXX,然后使用前面提到的变量替代调用cmake 。

在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 ++即可。

你可以使用命令:


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

然后将clang编译器设置封装在if():


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

这种方式在gui配置工具中显示为一个cmake选项。

你绝对不需要使用各种不同的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,你可能不希望( 它将大大增加编译时间) 和clang默认为c99模式,因此不需要使用。

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

在Ubuntu上进行系统范围的C更改:

sudo update-alternatives --config cc

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

sudo update-alternatives --config c++

对于上述每个选项,按选择号(1)并输入select :


 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:

...