如何为CMake指定新的GCC路径

6g8kf2rb  于 2023-10-19  发布在  其他
关注(0)|答案(8)|浏览(211)

我的操作系统是centos,它在路径/usr/bin/gcc中有一个默认的gcc。但它是旧的,我需要一个新版本的gcc。所以我在新路径/usr/local/bin/gcc中安装了一个新版本。
但是当我运行cmake时,它仍然使用旧版本的gcc路径(/usr/bin/gcc)。如何将gcc指定为新路径(/usr/local/bin/gcc)。
我尝试用/usr/local/bin/gcc覆盖/usr/bin/gcc,但它不工作。

ux6nzvsh

ux6nzvsh1#

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

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

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

更新:在Jake的评论之后,详细解释为什么不覆盖CMAKE_C(XX)_COMPILER

我建议不要覆盖CMAKE_C(XX)_COMPILER值,主要有两个原因:因为它不能很好地使用CMake的缓存,而且它破坏了编译器检查和工具检测。
使用set命令时,有三个选项:

  • 不带缓存,创建普通变量
  • 使用缓存,创建缓存变量
  • 强制缓存,在配置时始终强制该高速缓存值

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

无缓存

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

在执行此操作时,您将创建一个“普通”变量CMAKE_C(XX)_COMPILER,该变量隐藏同名的该高速缓存变量。这意味着编译器现在是硬编码在构建脚本中的,您不能给予它一个自定义值。如果您有多个构建环境,使用不同的编译器,这将是一个问题。你可以在每次想使用不同的编译器时更新你的脚本,但是这首先就消除了使用CMake的价值。
好的,那么,让我们更新该高速缓存.

带缓存

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

这个版本只是“不工作”。CMAKE_C(XX)_COMPILER变量已经在该高速缓存中,因此除非强制更新,否则不会更新。
那就用原力吧

强制缓存

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

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

破坏编译器检查和工具

在配置过程的早期,CMake对编译器执行检查:能用吗它能生成可执行文件吗?它还使用编译器来检测相关工具,如arranlib。当你在脚本中覆盖编译器的值时,就“太晚了”,所有的检查和检测都已经完成了。
例如,在我使用gcc作为默认编译器的机器上,当使用set命令到/usr/bin/clang时,ar被设置为/usr/bin/gcc-ar-7。在运行CMake之前使用导出时,它被设置为/usr/lib/llvm-3.8/bin/llvm-ar

cvxl0en2

cvxl0en22#

这个问题很老了,但仍然出现在谷歌搜索。这个被接受的问题对我不再起作用了,似乎已经过时了。关于cmake的最新信息写在cmake FAQ中。
改变编译器路径的方法有很多。一种方法是
在命令行中使用cmake -D将相应的CMAKE_FOO_COMPILER变量设置为有效的编译器名称或完整路径。举例来说:

cmake -G "Your Generator" -D CMAKE_C_COMPILER=gcc-4.2 -D CMAKE_CXX_COMPILER=g++-4.2 path/to/your/source

可以这样写path/to/your/compiler,而不是gcc-4.2

cmake -D CMAKE_C_COMPILER=/path/to/gcc/bin/gcc -D CMAKE_CXX_COMPILER=/path/to/gcc/bin/g++ .
ghhkc1vu

ghhkc1vu4#

修改CMAKE_<LANG>_COMPILER路径不触发reconfigure

我想用另一个编译器编译,但也在命令行上传递-D选项,这将通过设置不同的编译器来消除。这是因为它触发了重新配置。技巧是用NONE禁用编译器检测,用FORCE设置路径,然后用enable_language

project( sample_project NONE )

set( COMPILER_BIN /opt/compiler/bin )
set( CMAKE_C_COMPILER ${COMPILER_BIN}/clang CACHE PATH "clang" FORCE )
set( CMAKE_CXX_COMPILER ${COMPILER_BIN}/clang++ CACHE PATH "clang++" FORCE )

enable_language( C CXX )

使用Toolchain文件

更明智的选择是创建一个工具链文件。

set( CMAKE_SYSTEM_NAME Darwin )

set( COMPILER_BIN /opt/compiler/bin )
set( CMAKE_C_COMPILER ${COMPILER_BIN}/clang CACHE PATH "clang" )
set( CMAKE_CXX_COMPILER ${COMPILER_BIN}/clang++ CACHE PATH "clang++" )

然后使用一个附加标志调用Cmake

cmake -D CMAKE_TOOLCHAIN_FILE=/path/to/toolchain_file.cmake ...
tuwxkamq

tuwxkamq5#

导出应该具体说明要使用哪个版本的GCC/G++,因为如果用户有多个编译器版本,它将无法成功编译。

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

如果项目使用C++11,这可以通过使用CMakeList.txt中的-std=C++-11标志来处理

f87krz0w

f87krz0w6#

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

rxztt3cl

rxztt3cl7#

这不仅适用于cmake,也适用于./configuremake

./configure CC=/usr/local/bin/gcc CXX=/usr/local/bin/g++

这导致:

checking for gcc... /usr/local/bin/gcc
checking whether the C compiler works... yes
7kqas0il

7kqas0il8#

Guillaume的回答:
为什么是的,你可以只交换交换CMAKE_C_COMPILERCMAKE_CXX_COMPILER,但你需要在“初始化”项目之前这样做:

set(CMAKE_C_COMPILER <path/to/c/compiler>)
    set(CMAKE_CXX_COMPILER <path/to/c++/compiler>)
    project(PROJECT_NAME)

CMake实际上执行这些检查(在这种情况下,它实际上没有,因为这些变量的存在表明它已经检测到一个工作的编译器,所以不需要检查它),当你做项目“初始化”时,所以如果你在那之前做交换,它会检查你新交换的变量。
但是,最好设置CCCXX环境变量:

set(ENV{CC} <path/to/compiler>)
    set(ENV{CXX} <path/to/compiler>)
    project(PROJECT_NAME)

这样CMake也会执行编译器检查。
不确定这是不是“正确”的方法,但对我来说很有效(“计算”运行CMake脚本时需要的编译器位置,并将其交换为默认位置)。

相关问题