目前用 CMake 作为 C/C++ 项目构建工具,但在 天河二号 等使用 module 管理软件版本的系统上,编译MPI程序会出现第三方依赖库和主程序使用不同编译器导致无法链接成功的问题。解决该问题需要让所有源代码使用同一个编译器。

本文介绍编译C/C++程序时,CMake指定编译器的几种方法。

CMake指定编译器

1. 设置环境变量

如果CC/CXX环境变量存在,*nix系统默认使用其值作为C/C++程序的编译器。因此使用gcc 7.4作为CMake项目编译器的方法如下:

# 加载gcc 7.4模块
module load gcc/7.4.0
# 设置CC和CXX环境变量
export CC=$(which gcc)
export CXX=$(which g++)
# 然后使用cmake构建项目
cmake . #一些其他参数

export导出环境变量可能会影响后续命令,可以临时指定所用编译器避免该问题:

CC=$(which gcc) CXX=$(which g++) cmake . # 其他项目参数

这两种方式都可以,在需要指定编译器的情况下建议使用。

2. 使用-D定义

CMake使用 CMAKE_C_COMPILERCMAKE_CXX_COMPILER 两个变量的值作为C/C++程序的编译器,因此可以在cmake时用-D定义:

cmake . -DCMAKE_C_COMPILER=$(which gcc) -DCMAKE_CXX_COMPILER=$(which g++) # 其他参数

-D指定较CC/CXX环境变量稍微麻烦点。

3. 使用set指令

既然知道CMake使用 CMAKE_C_COMPILERCMAKE_CXX_COMPILER 两个变量的值作为C/C++程序的编译器,那么自然可以在 CMakeLists.txt 设置这两个变量的值。CMake使用set指令设置变量的值:

# 编辑 CMakeLists.txt 文件,使用set指令
set(CMAKE_C_COMPILER, "/usr/local/bin/gcc")
set(CMAKE_CXX_COMPILER, "/usr/local/bin/g++")

正常情况下,应该尽量避免使用set的方式指定编译器。该方法有: 硬编码不灵活、开启缓存情况下不起作用、容易被覆盖、以及工具链可能未被检查 等问题。

参考

  1. How to specify a compiler in CMake?
  2. How to specify new GCC path for CMake