DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

1. 说明

在实际的项目平台中可能安装有多个版本的编译器,同时由于不同的功能可能会需要设置不同的编译参数,这篇笔记就记录如何选择指定的编译器和配置参数。

2. 选择编译器

2.1 初始状态

我使用的开发平台默认安装的gcc5.5.0,后面又安装了clang3.8.0,在默认path下C编译器会使用gcc 5.5.0,C++编译器使用clang3.8.0,如下所示:

/build$ cmake ..
-- The C compiler identification is GNU 5.5.0
-- The CXX compiler identification is Clang 3.8.0
...
 

后面由于项目开发的要求我又安装了gcc8.3.0版本,PATH也是设置为8.3.0,即在命令行下输入"gcc -v"默认显示8.3.0,但是在cmake会根据PATH路径去查找支持的编译器,还是会首先查找到原来的编译器版本。

2.2 使用命令行

在编译时可以通过参数直接选择指定的编译器的完整路径,比如我的gcc8.3.0安装在/usr/local/gcc/bin路径下,在编译时输入:

cmake .. -DCMAKE_CXX_COMPILER=/usr/local/gcc/bin/g++

就会在编译时选定gcc-8.3.0

2.3 在配置文件中指定

在CMakeLists.txt文件中添加:

set (CMAKE_C_COMPILER "/usr/local/gcc/bin/gcc")
set (CMAKE_CXX_COMPILER "/usr/local/gcc/bin/g++")

直接修改全局变量CMAKE_C_COMPILER和CMAKE_CXX_COMPILER为指定的编译器路径。

注:这两条命令应该放在文件的开始位置(cmake_minimum_required命令之下,其他命令之上),否则可能无效。

CMAKE_C_COMPILER
原本是保存环境变量"CC"值的变量,而CC是编译C语言的首选编译器,但是在新的CMP0054策略中如果设置的CMAKE_C_COMPILER则会忽略CC的值。

CMAKE_CXX_COMPILER
与CMAKE_C_COMPILER类似,不过这个变量对应的环境变量是CXX,是编译C++语言的编译器。

结果如下:

$ cmake ..
-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
...

3. 配置编译参数

假设我使用g++编译器,添加"-std=c++11", “-Wall"和”-Werror"等参数为例。

3.1 使用add_compile_options命令

通过在CMakeLists.txt文件中添加add_compile_options命令可以起到添加参数的作用,如:

add_compile_options(-std=c++11 -Wall -Werror)

但是这个命令是针对所有类型编译器的,也就是说这里添加的选项会在所有的编译器中运用,比如-std=c++11是针对C++的编译器参数,也会被运用在C语言编译器中,虽然不一定会报错但是终究体验感不好。而且此命令添加的参数是递归的,即在多层目录结构中,根文件下设置选项后,在所有的子目录编译时都会运用。

3.2 通过设置CMAKE_CXX_FLAGS来配置

CMAKE_CXX_FLAGS是针对C++编译器的参数选项,默认保存环境变量CXX_FLAGS的内容,但是如果直接修改这个参数值,那么系统会忽略原CXX_FLAGS的内容。设置方式如下:

set(CMAKE_CXX_FLAGS
    -std=c++11
    -Wall
    -Werror
)
 

这个变量只在当前文件有效,如果项目中有多个模块,多个编译文件,那么需在每一个CMakeLists.txt文件中都添加对应的命令和参数。

3.3 两种方式比较

add_compile_options CMAKE_CXX_FLAGS
对所有编译器有效 只针对C++编译器
作用域是全局,对所有编译文件有效 作用域是单个编译文件

综上,对于一些在整个项目中通用的编译选项可以使用add_compile_options命令来添加比较方便,对于各个模块中的独立选项则使用CMAKE_CXX_FLAGS变量更好。

4. 命令解析

4.1 add_compile_options

将编译器选项添加到当前及子目录的源文件的编译中。

用法

add_compile_options(<option> ...)
 
  • option:编译选项,注意对于不同编译器,支持的选项可能不一样。

示例

if (MSVC)
    # warning level 4 and all warnings as errors
    add_compile_options(/W4 /WX)
else()
    # lots of warnings and all warnings as errors
    add_compile_options(-Wall -Wextra -pedantic -Werror)
endif()

4.2 add_compile_definitions

将预编译参数添加到源文件的编译中,对下级子目录同样有效。

用法

add_compile_definitions(<definition> ...)

预编译命令会添加到COMPILE_DEFINITIONS目录属性中。

5. CMAKE__FLAGS变量

这里用到的CMAKE_CXX_FLAGS变量是只针对C++编译器的选项,对于其他编程语言,只要替换部分就可以,在当前cmake版本(3.17.2)中支持如下语言:

  • CMAKE_C_FLAGS:C语言编译器选项,对应于环境变量CFLAGS
  • CMAKE_CXX_FLAGS:C++语言编译器选项,对应于环境变量CXXFLAGS
  • CMAKE_CUDA_FLAGS:CUDA语言编译器选项,对应于环境变量CUDAFLAGS
  • CMAKE_Fortran_FLAGS:Fortran语言编译器选项,对应于环境变量FFLAGS
 
posted on   DoubleLi  阅读(27626)  评论(1编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2020-10-13 Linux下查看和添加PATH环境变量
2020-10-13 CMake和静态库顺序
2020-10-13 折腾gcc/g++链接时.o文件及库的顺序问题
2020-10-13 解决静态库之间相互依赖的问题(对‘*‘未定义的引用)
2020-10-13 库与库之间相互依赖解决方法
2020-10-13 Linux GCC lib库相互引用,互相依赖(交叉引用)链接解决办法
2020-10-13 gcc编译选项的循环重复查找依赖库等命令
点击右上角即可分享
微信分享提示