如何为CMake指定新的GCC路径?

时间:2020-12-01 12:46:52

My OS is centos which has a default gcc in path /usr/bin/gcc. But it is old, I need a new version of gcc. So I install a new version in a new path /usr/local/bin/gcc.

我的操作系统是centos,它有一个默认的gcc在path / usr/bin/gcc。但它已经过时了,我需要一个新版本的gcc。因此,我在新的路径/ usr/local/bin/gcc中安装了一个新版本。

But when I run cmake, it still uses the old version gcc path(/usr/bin/gcc) . How can I specify the gcc to new path(/usr/local/bin/gcc).

但是当我运行cmake时,它仍然使用旧版本的gcc路径(/usr/bin/gcc)。如何指定gcc到新路径(/usr/local/bin/gcc)。

I have tried to overwrite /usr/bin/gcc with /usr/local/bin/gcc, but it not work.

我试图用/usr/local/bin/gcc来覆盖/usr/bin/gcc,但它不起作用。

4 个解决方案

#1


125  

Do not overwrite CMAKE_C_COMPILER, but export CC (and CXX) before calling cmake:

在调用cmake之前,不要覆盖CMAKE_C_COMPILER,而是导出CC(和CXX):

export CC=/usr/local/bin/gcc
export CXX=/usr/local/bin/g++
cmake /path/to/your/project
make

The export only needs to be done once, the first time you configure the project, then those values will be read from the CMake cache.

导出只需要完成一次,第一次配置项目时,这些值将从CMake缓存读取。


UPDATE: longer explanation on why not overriding CMAKE_C(XX)_COMPILER after Jake's comment

更新:在杰克的评论之后,更长的解释为什么不覆盖CMAKE_C(XX)_COMPILER。

I recommend against overriding the CMAKE_C(XX)_COMPILER value for two main reasons: because it won't play well with CMake's cache and because it breaks compiler checks and tooling detection.

我建议不要将CMAKE_C(XX)_COMPILER值重写为两个主要原因:因为它不能很好地使用CMake的缓存,因为它会破坏编译器检查和工具检测。

When using the set command, you have three options:

在使用set命令时,您有三个选项:

  • without cache, to create a normal variable
  • 没有缓存,创建一个正常的变量。
  • with cache, to create a cached variable
  • 使用缓存,创建缓存的变量。
  • force cache, to always force the cache value when configuring
  • 强制缓存,在配置时总是强制缓存值。

Let's see what happens for the three possible calls to set:

让我们看看这三个可能的调用会发生什么:

Without cache

没有缓存

set(CMAKE_C_COMPILER /usr/bin/clang)
set(CMAKE_CXX_COMPILER /usr/bin/clang++)

When doing this, you create a "normal" variable CMAKE_C(XX)_COMPILER that hides the cache variable of the same name. That means your compiler is now hard-coded in your build script and you cannot give it a custom value. This will be a problem if you have multiple build environments with different compilers. You could just update your script each time you want to use a different compiler, but that removes the value of using CMake in the first place.

在执行此操作时,您将创建一个“normal”变量CMAKE_C(XX)_COMPILER,它将隐藏相同名称的缓存变量。这意味着您的编译器现在在构建脚本中是硬编码的,您不能给它一个自定义值。如果有不同编译器的多个构建环境,这将是一个问题。您可以在每次使用不同的编译器时更新您的脚本,但是这将首先删除使用CMake的值。

Ok, then, let's update the cache...

那么,让我们更新缓存…

With cache

与缓存

set(CMAKE_C_COMPILER /usr/bin/clang CACHE PATH "")
set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE PATH "")

This version will just "not work". The CMAKE_C(XX)_COMPILER variable is already in the cache, so it won't get updated unless you force it.

这个版本只会“不起作用”。CMAKE_C(XX)_COMPILER变量已经在缓存中,所以除非您强制它,否则它不会被更新。

Ah... let's use the force, then...

啊…让我们用原力,然后…

Force cache

力缓存

set(CMAKE_C_COMPILER /usr/bin/clang CACHE PATH "" FORCE)
set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE PATH "" FORCE)

This is almost the same as the "normal" variable version, the only difference is your value will be set in the cache, so users can see it. But any change will be overwritten by the set command.

这几乎与“正常”变量版本相同,唯一的区别是您的值将被设置在缓存中,因此用户可以看到它。但是任何更改都将由set命令覆盖。

Breaking compiler checks and tooling

破坏编译器检查和工具。

Early in the configuration process, CMake performs checks on the compiler: Does it work? Is it able to produce executables? etc. It also uses the compiler to detect related tools, like ar and ranlib. When you override the compiler value in a script, it's "too late", all checks and detections are already done.

在配置过程的早期,CMake对编译器进行检查:是否有效?它能够生成可执行文件吗?它还使用编译器来检测相关的工具,如ar和ranlib。当您在一个脚本中重写编译器值时,已经“太晚”了,所有的检查和检测都已经完成了。

For instance, on my machine with gcc as default compiler, when using the set command to /usr/bin/clang, ar is set to /usr/bin/gcc-ar-7. When using an export before running CMake it is set to /usr/lib/llvm-3.8/bin/llvm-ar.

例如,在我的机器上使用gcc作为默认编译器时,当使用set命令到/usr/bin/clang时,ar被设置为/ usr/bin/gccar -7。在运行CMake前使用导出时,将其设置为/usr/lib/llvm-3.8/bin/llvm- ar。

#2


6  

Set CMAKE_C_COMPILER to your new path.

将CMAKE_C_COMPILER设置为新路径。

See here: http://www.cmake.org/Wiki/CMake_Useful_Variables

在这里看到的:http://www.cmake.org/Wiki/CMake_Useful_Variables

#3


2  

Export should be specific about which version of GCC/G++ to use, because if user had multiple compiler version, it would not compile successfully.

导出应该特定于使用哪个版本的GCC/G++,因为如果用户有多个编译器版本,则无法成功编译。

 export CC=path_of_gcc/gcc-version
 export CXX=path_of_g++/g++-version
 cmake  path_of_project_contain_CMakeList.txt
 make 

In case project use C++11 this can be handled by using -std=C++-11 flag in CMakeList.txt

如果项目使用c++ 11,可以在CMakeList.txt中使用-std= c++ -11标记来处理。

#4


2  

An alternative solution is to configure your project through cmake-gui, starting from a clean build directory. Among the options you have available at the beginning, there's the possibility to choose the exact path to the compilers

另一种解决方案是通过cmake-gui来配置您的项目,从一个干净的构建目录开始。在开始的选项中,有可能为编译器选择正确的路径。

#1


125  

Do not overwrite CMAKE_C_COMPILER, but export CC (and CXX) before calling cmake:

在调用cmake之前,不要覆盖CMAKE_C_COMPILER,而是导出CC(和CXX):

export CC=/usr/local/bin/gcc
export CXX=/usr/local/bin/g++
cmake /path/to/your/project
make

The export only needs to be done once, the first time you configure the project, then those values will be read from the CMake cache.

导出只需要完成一次,第一次配置项目时,这些值将从CMake缓存读取。


UPDATE: longer explanation on why not overriding CMAKE_C(XX)_COMPILER after Jake's comment

更新:在杰克的评论之后,更长的解释为什么不覆盖CMAKE_C(XX)_COMPILER。

I recommend against overriding the CMAKE_C(XX)_COMPILER value for two main reasons: because it won't play well with CMake's cache and because it breaks compiler checks and tooling detection.

我建议不要将CMAKE_C(XX)_COMPILER值重写为两个主要原因:因为它不能很好地使用CMake的缓存,因为它会破坏编译器检查和工具检测。

When using the set command, you have three options:

在使用set命令时,您有三个选项:

  • without cache, to create a normal variable
  • 没有缓存,创建一个正常的变量。
  • with cache, to create a cached variable
  • 使用缓存,创建缓存的变量。
  • force cache, to always force the cache value when configuring
  • 强制缓存,在配置时总是强制缓存值。

Let's see what happens for the three possible calls to set:

让我们看看这三个可能的调用会发生什么:

Without cache

没有缓存

set(CMAKE_C_COMPILER /usr/bin/clang)
set(CMAKE_CXX_COMPILER /usr/bin/clang++)

When doing this, you create a "normal" variable CMAKE_C(XX)_COMPILER that hides the cache variable of the same name. That means your compiler is now hard-coded in your build script and you cannot give it a custom value. This will be a problem if you have multiple build environments with different compilers. You could just update your script each time you want to use a different compiler, but that removes the value of using CMake in the first place.

在执行此操作时,您将创建一个“normal”变量CMAKE_C(XX)_COMPILER,它将隐藏相同名称的缓存变量。这意味着您的编译器现在在构建脚本中是硬编码的,您不能给它一个自定义值。如果有不同编译器的多个构建环境,这将是一个问题。您可以在每次使用不同的编译器时更新您的脚本,但是这将首先删除使用CMake的值。

Ok, then, let's update the cache...

那么,让我们更新缓存…

With cache

与缓存

set(CMAKE_C_COMPILER /usr/bin/clang CACHE PATH "")
set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE PATH "")

This version will just "not work". The CMAKE_C(XX)_COMPILER variable is already in the cache, so it won't get updated unless you force it.

这个版本只会“不起作用”。CMAKE_C(XX)_COMPILER变量已经在缓存中,所以除非您强制它,否则它不会被更新。

Ah... let's use the force, then...

啊…让我们用原力,然后…

Force cache

力缓存

set(CMAKE_C_COMPILER /usr/bin/clang CACHE PATH "" FORCE)
set(CMAKE_CXX_COMPILER /usr/bin/clang++ CACHE PATH "" FORCE)

This is almost the same as the "normal" variable version, the only difference is your value will be set in the cache, so users can see it. But any change will be overwritten by the set command.

这几乎与“正常”变量版本相同,唯一的区别是您的值将被设置在缓存中,因此用户可以看到它。但是任何更改都将由set命令覆盖。

Breaking compiler checks and tooling

破坏编译器检查和工具。

Early in the configuration process, CMake performs checks on the compiler: Does it work? Is it able to produce executables? etc. It also uses the compiler to detect related tools, like ar and ranlib. When you override the compiler value in a script, it's "too late", all checks and detections are already done.

在配置过程的早期,CMake对编译器进行检查:是否有效?它能够生成可执行文件吗?它还使用编译器来检测相关的工具,如ar和ranlib。当您在一个脚本中重写编译器值时,已经“太晚”了,所有的检查和检测都已经完成了。

For instance, on my machine with gcc as default compiler, when using the set command to /usr/bin/clang, ar is set to /usr/bin/gcc-ar-7. When using an export before running CMake it is set to /usr/lib/llvm-3.8/bin/llvm-ar.

例如,在我的机器上使用gcc作为默认编译器时,当使用set命令到/usr/bin/clang时,ar被设置为/ usr/bin/gccar -7。在运行CMake前使用导出时,将其设置为/usr/lib/llvm-3.8/bin/llvm- ar。

#2


6  

Set CMAKE_C_COMPILER to your new path.

将CMAKE_C_COMPILER设置为新路径。

See here: http://www.cmake.org/Wiki/CMake_Useful_Variables

在这里看到的:http://www.cmake.org/Wiki/CMake_Useful_Variables

#3


2  

Export should be specific about which version of GCC/G++ to use, because if user had multiple compiler version, it would not compile successfully.

导出应该特定于使用哪个版本的GCC/G++,因为如果用户有多个编译器版本,则无法成功编译。

 export CC=path_of_gcc/gcc-version
 export CXX=path_of_g++/g++-version
 cmake  path_of_project_contain_CMakeList.txt
 make 

In case project use C++11 this can be handled by using -std=C++-11 flag in CMakeList.txt

如果项目使用c++ 11,可以在CMakeList.txt中使用-std= c++ -11标记来处理。

#4


2  

An alternative solution is to configure your project through cmake-gui, starting from a clean build directory. Among the options you have available at the beginning, there's the possibility to choose the exact path to the compilers

另一种解决方案是通过cmake-gui来配置您的项目,从一个干净的构建目录开始。在开始的选项中,有可能为编译器选择正确的路径。