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

时间:2022-03-03 12:47:32

I have a number of projects built using CMake and I'd like to be able to easily switch between using GCC or Clang/LLVM to compile them. I believe (please correct me if I'm mistaken!) that to use Clang I need to set the following:

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

    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")

Is there an easy way of switching between these and the default GCC variables, preferably as a system-wide change rather than project specific (i.e. not just adding them into a project's CMakeLists.txt)?

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

Also, is it necessary to use the llvm-* programs rather than the system defaults when compiling using clang instead of gcc? What's the difference?

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

9 个解决方案

#1


265  

CMake honors the environment variables CC and CXX upon detecting the C and C++ compiler to use:

CMake在检测C和c++编译器使用时,尊重环境变量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

The compiler specific flags can be overridden by putting them into a system wide CMake file and pointing the CMAKE_USER_MAKE_RULES_OVERRIDE variable to it. Create a file ~/ClangOverrides.txt with the following contents:

可以将编译器特定的标志放在系统宽的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")

The suffix _INIT will make CMake initialize the corresponding *_FLAGS variable with the given value. Then invoke cmake in the following way:

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

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

Finally to force the use of the LLVM binutils, set the internal variable _CMAKE_TOOLCHAIN_PREFIX. This variable is honored by the CMakeFindBinUtils module:

最后,强制使用LLVM binutils,设置内部变量_CMAKE_TOOLCHAIN_PREFIX。这个变量被CMakeFindBinUtils模块授予:

$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=llvm- ..

Putting this all together you can write a shell wrapper which sets up the environment variables CC and CXX and then invokes cmake with the mentioned variable overrides.

将这些内容放在一起,您可以编写一个shell包装器,它设置环境变量CC和CXX,然后调用cmake,并使用前面提到的变量重写。

#2


104  

System wide C++ change on Ubuntu:

系统范围内的c++更改:

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

Will print something like this:

会打印这样的东西:

  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

Then just select clang++.

然后选择叮当声+ +。

#3


20  

You can use the option command:

您可以使用option命令:

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

and then wrap the clang-compiler settings in if()s:

然后,如果()s:

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

This way it is displayed as an cmake option in the gui-configuration tools.

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

To make it systemwide you can of course use an environment variable as the default value or stay with Ferruccio's answer.

为了使其系统化,您当然可以使用环境变量作为默认值,或者使用Ferruccio的答案。

#4


13  

System wide C change on Ubuntu:

系统范围C改变:

sudo update-alternatives --config cc

sudo update-alternatives——配置cc

System wide C++ change on Ubuntu:

系统范围内的c++更改:

sudo update-alternatives --config c++

sudo update-alternatives——配置c++

For each of the above, press Selection number (1) and Enter to select Clang:

对于上述每一项,按选择编号(1)并输入选择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:

#5


8  

You definitely don't need to use the various different llvm-ar etc programs:

您绝对不需要使用各种不同的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")

These are made to work on the llvm internal format and as such aren't useful to the build of your application.

这些都是用于llvm内部格式的,因此对应用程序的构建没有什么用处。

As a note -O4 will invoke LTO on your program which you may not want (it will increase compile time greatly) and clang defaults to c99 mode so that flag isn't necessarily needed either.

作为一个注释,o4将调用您的程序上的LTO,您可能不想(它将大大增加编译时间)和clang默认为c99模式,所以这标志也不一定需要。

#6


3  

You can use the syntax: $ENV{environment-variable} in your CMakeLists.txt to access environment variables. You could create scripts which initialize a set of environment variables appropriately and just have references to those variables in your CMakeLists.txt files.

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

#7


1  

According to the help of cmake:

根据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.

You make be able to create files like gcc_compiler.txt and clang_compiler.txt to includes all relative configuration in CMake syntax.

您可以创建像gcc_compiler这样的文件。txt和clang_compiler。txt包括CMake语法中的所有相对配置。

Clang Example (clang_compiler.txt):

叮当声的例子(clang_compiler.txt):

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

Then run it as

然后运行它

GCC:

GCC:

cmake -C gcc_compiler.txt XXXXXXXX

Clang:

铿锵声:

cmake -C clang_compiler.txt XXXXXXXX

#8


1  

You can use the toolchain file mechanism of cmake for this purpose, see e.g. here. You write a toolchain file for each compiler containing the corresponding definitions. At config time, you run e.g

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

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

and all the compiler information will be set during the project() call from the toolchain file. Though in the documentation is mentionend only in the context of cross-compiling, it works as well for different compilers on the same system.

所有的编译器信息都将在工具链文件的project()调用中设置。尽管在文档中仅在交叉编译的上下文中提到,但对于同一系统上的不同编译器也适用。

#9


1  

If the default compiler chose by cmake is gcc and you have installed clang, you can use the easy way to compile your project with clang:

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

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

#1


265  

CMake honors the environment variables CC and CXX upon detecting the C and C++ compiler to use:

CMake在检测C和c++编译器使用时,尊重环境变量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

The compiler specific flags can be overridden by putting them into a system wide CMake file and pointing the CMAKE_USER_MAKE_RULES_OVERRIDE variable to it. Create a file ~/ClangOverrides.txt with the following contents:

可以将编译器特定的标志放在系统宽的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")

The suffix _INIT will make CMake initialize the corresponding *_FLAGS variable with the given value. Then invoke cmake in the following way:

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

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

Finally to force the use of the LLVM binutils, set the internal variable _CMAKE_TOOLCHAIN_PREFIX. This variable is honored by the CMakeFindBinUtils module:

最后,强制使用LLVM binutils,设置内部变量_CMAKE_TOOLCHAIN_PREFIX。这个变量被CMakeFindBinUtils模块授予:

$ cmake -D_CMAKE_TOOLCHAIN_PREFIX=llvm- ..

Putting this all together you can write a shell wrapper which sets up the environment variables CC and CXX and then invokes cmake with the mentioned variable overrides.

将这些内容放在一起,您可以编写一个shell包装器,它设置环境变量CC和CXX,然后调用cmake,并使用前面提到的变量重写。

#2


104  

System wide C++ change on Ubuntu:

系统范围内的c++更改:

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

Will print something like this:

会打印这样的东西:

  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

Then just select clang++.

然后选择叮当声+ +。

#3


20  

You can use the option command:

您可以使用option命令:

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

and then wrap the clang-compiler settings in if()s:

然后,如果()s:

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

This way it is displayed as an cmake option in the gui-configuration tools.

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

To make it systemwide you can of course use an environment variable as the default value or stay with Ferruccio's answer.

为了使其系统化,您当然可以使用环境变量作为默认值,或者使用Ferruccio的答案。

#4


13  

System wide C change on Ubuntu:

系统范围C改变:

sudo update-alternatives --config cc

sudo update-alternatives——配置cc

System wide C++ change on Ubuntu:

系统范围内的c++更改:

sudo update-alternatives --config c++

sudo update-alternatives——配置c++

For each of the above, press Selection number (1) and Enter to select Clang:

对于上述每一项,按选择编号(1)并输入选择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:

#5


8  

You definitely don't need to use the various different llvm-ar etc programs:

您绝对不需要使用各种不同的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")

These are made to work on the llvm internal format and as such aren't useful to the build of your application.

这些都是用于llvm内部格式的,因此对应用程序的构建没有什么用处。

As a note -O4 will invoke LTO on your program which you may not want (it will increase compile time greatly) and clang defaults to c99 mode so that flag isn't necessarily needed either.

作为一个注释,o4将调用您的程序上的LTO,您可能不想(它将大大增加编译时间)和clang默认为c99模式,所以这标志也不一定需要。

#6


3  

You can use the syntax: $ENV{environment-variable} in your CMakeLists.txt to access environment variables. You could create scripts which initialize a set of environment variables appropriately and just have references to those variables in your CMakeLists.txt files.

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

#7


1  

According to the help of cmake:

根据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.

You make be able to create files like gcc_compiler.txt and clang_compiler.txt to includes all relative configuration in CMake syntax.

您可以创建像gcc_compiler这样的文件。txt和clang_compiler。txt包括CMake语法中的所有相对配置。

Clang Example (clang_compiler.txt):

叮当声的例子(clang_compiler.txt):

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

Then run it as

然后运行它

GCC:

GCC:

cmake -C gcc_compiler.txt XXXXXXXX

Clang:

铿锵声:

cmake -C clang_compiler.txt XXXXXXXX

#8


1  

You can use the toolchain file mechanism of cmake for this purpose, see e.g. here. You write a toolchain file for each compiler containing the corresponding definitions. At config time, you run e.g

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

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

and all the compiler information will be set during the project() call from the toolchain file. Though in the documentation is mentionend only in the context of cross-compiling, it works as well for different compilers on the same system.

所有的编译器信息都将在工具链文件的project()调用中设置。尽管在文档中仅在交叉编译的上下文中提到,但对于同一系统上的不同编译器也适用。

#9


1  

If the default compiler chose by cmake is gcc and you have installed clang, you can use the easy way to compile your project with clang:

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

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