CMakeLists.txt中如何添加编译选项?

1. 引子

编译器有多种可供选择,如g++c++clang++等,如下以c++作为示例。

2. 使用CMAKE_CXX_FLAGS添加编译选项

Makefile中可能用类似如下的指令来添加编译选项:
/usr/bin/c++ -Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -O2

那么-Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -O2这些在CMakeLists.txt中如何添加呢?
方法是通过给变量CMAKE_CXX_FLAGS赋值来实现。

如果对于DebugRelease有不同的编译选项,可分别通过CMAKE_CXX_FLAGS_DEBUGCMAKE_CXX_FLAGS_RELEASE来设置。

对于Debug模式,编译选项实际使用的值是CMAKE_CXX_FLAGSCMAKE_CXX_FLAGS_DEBUG的值的组合(不管CMAKE_CXX_FLAGS_RELEASE设置什么值都不会被加入到编译选项中)。
对于Release模式,编译选项实际使用的值是CMAKE_CXX_FLAGSCMAKE_CXX_FLAGS_RELEASE的值的组合(不管CMAKE_CXX_FLAGS_DEBUG设置什么值都不会被加入到编译选项中)。

所以编译器实际使用的编译选项不只是来源于CMAKE_CXX_FLAGS,而是来自CMAKE_CXX_FLAGS与其它变量(如CMAKE_CXX_FLAGS_DEBUGCMAKE_CXX_FLAGS_RELEASECMAKE_CXX_STANDARD 等)的组合。

例如上面的编译选项可在CMakeLists.txt中添加:
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter") 实现。

3. 通过CMAKE_CXX_FLAGS添加编译选项的示例

工程目录如下:
在这里插入图片描述
文件一,CMakeLists.txt

if(" ${CMAKE_SOURCE_DIR}" STREQUAL " ${CMAKE_BINARY_DIR}")message(FATAL_ERROR "
FATAL: In-source builds are not allowed.You should create a separate directory for build files.
")
endif()cmake_minimum_required(VERSION 3.4.1)set(CMAKE_VERBOSE_MAKEFILE ON)  # !!!楔子,此句对于在make时展示实际使用的编译选项很重要!!!set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)project(learnCMake VERSION 1.0.0.0 DESCRIPTION "setting cxx flags" HOMEPAGE_URL "https://blog.csdn.net/liugan528" LANGUAGES C CXX)#set (CMAKE_C_COMPILER "aarch64-linux-gnu-gcc")
#set (CMAKE_CXX_COMPILER "aarch64-linux-gnu-g++")message(STATUS "000--->${CMAKE_BUILD_TYPE}<---000")
if(NOT CMAKE_BUILD_TYPE)set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
set(CMAKE_CXX_FLAGS_DEBUG "-D NDEBUG -Og -g -pg")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter")
message(STATUS "111--->${CMAKE_BUILD_TYPE}<---111")
message(STATUS "222--->${CMAKE_CXX_FLAGS}<---222")add_executable(runMain main.cpp)

文件二,main.cpp

#include <iostream>int main(){std::cout << "Hello CMake World!" << std::endl;
}

进入build之后执行cmake ..结果如下:

root@tegra-ubuntu:/mnt/learnCMake/build# cmake ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- 000---><---000
-- 111--->Release<---111
-- 222--->-Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter<---222
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/learnCMake/build

再执行make进行编译:

root@tegra-ubuntu:/mnt/learnCMake/build# make
Scanning dependencies of target runMain
[ 50%] Building CXX object CMakeFiles/runMain.dir/main.cpp.o
[100%] Linking CXX executable runMain
[100%] Built target runMain

执行可执行程序:

root@tegra-ubuntu:/mnt/learnCMake/build# ./runMain 
Hello CMake World!

4. 如何直观地看到使用CMAKE_CXX_FLAGS添加的编译选项被编译器使用了呢?

4.1 Release模式,执行cmake时不加参数,或加上参数-DCMAKE_BUILD_TYPE=Release(默认)。

通过在CMakeLists.txt中添加语句set(CMAKE_VERBOSE_MAKEFILE ON) ,然后在make时加上参数VERBOSE=1即可看到详细的编译过程,其中就会展示实际的编译选项。
章节3的示例已经加了set(CMAKE_VERBOSE_MAKEFILE ON) ,只是make的时候没加参数VERBOSE=1,加上VERBOSE=1之后编译的过程如下:

root@tegra-ubuntu:/mnt/learnCMake/build# cmake ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- 000---><---000
-- 111--->Release<---111
-- 222--->-Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter<---222
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/learnCMake/build

make加上VERBOSE=1进行编译,可展示详细的编译过程(同时会有编译选项的输出):

root@tegra-ubuntu:/mnt/learnCMake/build# make VERBOSE=1
/usr/bin/cmake -S/mnt/learnCMake -B/mnt/learnCMake/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /mnt/learnCMake/build/CMakeFiles /mnt/learnCMake/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/mnt/learnCMake/build'
make -f CMakeFiles/runMain.dir/build.make CMakeFiles/runMain.dir/depend
make[2]: Entering directory '/mnt/learnCMake/build'
cd /mnt/learnCMake/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /mnt/learnCMake /mnt/learnCMake /mnt/learnCMake/build /mnt/learnCMake/build /mnt/learnCMake/build/CMakeFiles/runMain.dir/DependInfo.cmake --color=
Dependee "/mnt/learnCMake/build/CMakeFiles/runMain.dir/DependInfo.cmake" is newer than depender "/mnt/learnCMake/build/CMakeFiles/runMain.dir/depend.internal".
Dependee "/mnt/learnCMake/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/mnt/learnCMake/build/CMakeFiles/runMain.dir/depend.internal".
Scanning dependencies of target runMain
make[2]: Leaving directory '/mnt/learnCMake/build'
make -f CMakeFiles/runMain.dir/build.make CMakeFiles/runMain.dir/build
make[2]: Entering directory '/mnt/learnCMake/build'
[ 50%] Building CXX object CMakeFiles/runMain.dir/main.cpp.o
/usr/bin/c++    -Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -O2   -std=gnu++2a -o CMakeFiles/runMain.dir/main.cpp.o -c /mnt/learnCMake/main.cpp
[100%] Linking CXX executable runMain
/usr/bin/cmake -E cmake_link_script CMakeFiles/runMain.dir/link.txt --verbose=1
/usr/bin/c++  -Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -O2   CMakeFiles/runMain.dir/main.cpp.o  -o runMain 
make[2]: Leaving directory '/mnt/learnCMake/build'
[100%] Built target runMain
make[1]: Leaving directory '/mnt/learnCMake/build'
/usr/bin/cmake -E cmake_progress_start /mnt/learnCMake/build/CMakeFiles 0

由上可看到实际使用的编译选项是:/usr/bin/c++ -Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -O2 -std=gnu++2a,确实是CMAKE_CXX_FLAGSCMAKE_CXX_FLAGS_RELEASE的值的组合的结果。

执行可执行程序:

root@tegra-ubuntu:/mnt/learnCMake/build# ./runMain 
Hello CMake World!

4.2 Debug模式,执行cmake时加上参数-DCMAKE_BUILD_TYPE=Debug

root@tegra-ubuntu:/mnt/learnCMake/build# cmake -DCMAKE_BUILD_TYPE=Debug ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- 000--->Debug<---000
-- 111--->Debug<---111
-- 222--->-Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter<---222
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/learnCMake/build

make加上VERBOSE=1进行编译,可展示详细的编译过程(同时会有编译选项的输出):

root@tegra-ubuntu:/mnt/learnCMake/build# make VERBOSE=1
/usr/bin/cmake -S/mnt/learnCMake -B/mnt/learnCMake/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /mnt/learnCMake/build/CMakeFiles /mnt/learnCMake/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/mnt/learnCMake/build'
make -f CMakeFiles/runMain.dir/build.make CMakeFiles/runMain.dir/depend
make[2]: Entering directory '/mnt/learnCMake/build'
cd /mnt/learnCMake/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /mnt/learnCMake /mnt/learnCMake /mnt/learnCMake/build /mnt/learnCMake/build /mnt/learnCMake/build/CMakeFiles/runMain.dir/DependInfo.cmake --color=
Dependee "/mnt/learnCMake/build/CMakeFiles/runMain.dir/DependInfo.cmake" is newer than depender "/mnt/learnCMake/build/CMakeFiles/runMain.dir/depend.internal".
Dependee "/mnt/learnCMake/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/mnt/learnCMake/build/CMakeFiles/runMain.dir/depend.internal".
Scanning dependencies of target runMain
make[2]: Leaving directory '/mnt/learnCMake/build'
make -f CMakeFiles/runMain.dir/build.make CMakeFiles/runMain.dir/build
make[2]: Entering directory '/mnt/learnCMake/build'
[ 50%] Building CXX object CMakeFiles/runMain.dir/main.cpp.o
/usr/bin/c++    -Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -D NDEBUG -Og -g -pg   -std=gnu++2a -o CMakeFiles/runMain.dir/main.cpp.o -c /mnt/learnCMake/main.cpp
[100%] Linking CXX executable runMain
/usr/bin/cmake -E cmake_link_script CMakeFiles/runMain.dir/link.txt --verbose=1
/usr/bin/c++  -Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -D NDEBUG -Og -g -pg   CMakeFiles/runMain.dir/main.cpp.o  -o runMain 
make[2]: Leaving directory '/mnt/learnCMake/build'
[100%] Built target runMain
make[1]: Leaving directory '/mnt/learnCMake/build'
/usr/bin/cmake -E cmake_progress_start /mnt/learnCMake/build/CMakeFiles 0

由上可看到实际使用的编译选项是:/usr/bin/c++ -Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unused-parameter -D NDEBUG -Og -g -pg -std=gnu++2a,确实是CMAKE_CXX_FLAGSCMAKE_CXX_FLAGS_DEBUG的值组合的结果。

执行可执行程序:

root@tegra-ubuntu:/mnt/learnCMake/build# ./runMain 
Hello CMake World!

Reference

CMAKE__FLAGS
CMake编译选项CMAKE_CXX_FLAGS详解
How to use gprof with cmake

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/315330.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Node.js】02 —— Path模块全解析

&#x1f31f;Node.js之Path模块探索&#x1f308; &#x1f4da;引言 在Node.js的世界中&#xff0c;path模块就像一把万能钥匙&#x1f511;&#xff0c;它帮助我们理解和操作文件与目录的路径。无论你是初入Node.js殿堂的新手&#xff0c;还是久经沙场的老兵&#xff0c;理…

什么样的内外网文档摆渡,可以实现安全高效传输?

内外网文档摆渡通常指的是在内网&#xff08;公司或组织的内部网络&#xff09;和外网&#xff08;如互联网&#xff09;之间安全地传输文件的过程。这个过程需要特别注意安全性&#xff0c;因为内网往往包含敏感数据&#xff0c;直接连接内网和外网可能会带来安全风险。因此会…

git 命令怎么回退到指定的某个提交 commit hash 并推送远程分支?

问题 如下图&#xff0c;我要回退到 【002】Babel 的编译流程 这一次提交 解决 1、先执行下面命令&#xff0c;输出日志&#xff0c;主要就是拿到提交 commit 的 hash&#xff0c;上图红框即可 git log或者 vscode 里面直接右击&#xff0c;copy sha 2、执行下面命令回退 g…

Flask 数据库前后端交互案例-1

Flask 数据库前后端交互案例 目录结构templates目录base.htmlheader.htmlleft.html首页职员管理页面添加员工界面员工编辑页面员工详情界面 后台main.pyapp.pymodels.pyviews.py 数据库数据position.sqlperson.sqlpermission.sqldepartment.sql 目录结构 静态文件链接&#xff…

ArcGIS Pro 和 Python — 分析全球主要城市中心的土地覆盖变化

第一步——设置工作环境 1–0. 地理数据库 在下载任何数据之前,我将创建几个地理数据库,在其中保存和存储所有数据以及我将创建的后续图层。将为我要分析的五个城市中的每一个创建一个地理数据库,并将其命名为: “Phoenix.gdb” “Singapore.gdb” “Berlin.gdb” “B…

Git--分布式版本控制系统

目录 一、理解分布式版本控制系统二、远程仓库三、克隆远程仓库四、向远程仓库推送五、拉取远程仓库六、配置Git七、给命令配置别名八、创建标签九、操作标签 一、理解分布式版本控制系统 我们⽬前所说的所有内容&#xff08;⼯作区&#xff0c;暂存区&#xff0c;版本库等等&a…

AI文章写作网站

最强AI文章写作网站——心语流光&#xff08; Super Ai Writer &#xff09; 特点 多轮问答写作&#xff0c;自动携带历史记录进行问答可以自定义携带历史记录的轮数&#xff0c;为0则携带全部历史记录&#xff0c;有效避免token浪费&#xff08;类似coze平台&#xff09;AI生…

探讨mfc100u.dll丢失的解决方法,修复mfc100u.dll有效方法解析

mfc100u.dll丢失是一个比较常见的情况&#xff0c;由于你电脑的各种操作&#xff0c;是有可能引起dll文件的缺失的&#xff0c;而mfc100u.dll就是其中的一个重要的dll文件&#xff0c;它的确实严重的话是会导致程序打不开&#xff0c;系统错误的。今天我们就来给大家科普一下mf…

Python爬虫--Ajax异步抓取腾讯视频评论

在某些网站 &#xff0c;当我们滑下去的时候才会显示出后面的内容 就像淘宝一样&#xff0c;滑下去才逐渐显示其他商品 这个就是采用 Ajax 做的 然后我们现在就是要编写这样的爬虫。 规律分析&#xff1a; 这个时候就要用到我们的 Fiddler 了 我们需要分析加载评论的规律 …

【Linux】NFS网络文件系统搭建

一、服务端配置 #软件包安装 [roothadoop01 ~]# yum install rpcbind nfs-utils.x86_64 -y [roothadoop01 ~]# mkdir /share#配置文件修改 #格式为 共享资源路径 [主机地址] [选项] # [roothadoop01 ~]# vi /etc/exports /share 192.168.10.0/24(rw,sync,no_root_squash) #…

Wi-Fi HaLow:重塑物联网的未来

Wi-Fi HaLow&#xff1a;引领物联网连接的革命 数字时代的蓬勃发展正在引发一场深刻的变革&#xff0c;物联网已经融入到我们的日常生活和工作中&#xff0c;成为不可或缺的一部分。随着新一代Wi-Fi技术一Wi-Fi HaLow的崭露头角&#xff0c;有望在2024年及未来&#xff0c;重新…

Android Studio开发之路(八)Spinner样式设置

一、需求 白色背景显示下拉框按钮 问题&#xff1a; 设置Spinner的背景可以通过设置background&#xff1a; android:background"color/white",但是一旦设置了这个值&#xff0c;右侧的下拉按钮就会消失 方法一、自定义一个style&#xff08;不成功&#xff09; …

OpenTelemetry-2.Go接入Jaeger(grpc,gin-http)

目录 1.什么是OpenTelemetry 2.搭建jaeger 3.链路追踪 本地调用 远程调用 GRPC proto server端 client端 Gin-HTTP 调用流程 api1 api2 grpc 4.完整代码 1.什么是OpenTelemetry 参考&#xff1a;OpenTelemetry-1.介绍-CSDN博客 2.搭建jaeger 参考&#xff1a;…

Win32 API 光标隐藏定位和键盘读取等常用函数

Win32 API 光标隐藏定位和键盘读取等常用函数 一、Win32 API二、控制台程序指令modetitlepausecls 三、控制台屏幕上坐标的结构体COORD四、句柄获取函数GetStdHandle五、控制台光标操作1.控制台光标信息结构体CONSOLE_CURSOR_INFO2.得到光标信息函数GetConsoleCursorInfo3. 设置…

【注解和反射】获取类运行时结构

继上一篇博客【注解和反射】类加载器-CSDN博客 目录 七、获取类运行时结构 测试 getFields()和getDeclaredFields() getMethods()和getDeclaredMethods() 七、获取类运行时结构 获取类运行时结构通常指的是在Java等面向对象编程语言中&#xff0c;使用反射&#xff08;Ref…

STL——List常用接口模拟实现及其使用

认识list list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素…

【IDEA】在IntelliJ IDEA中导入Eclipse项目:详细指南

IntelliJ IDEA和Eclipse是两款常用的集成开发环境&#xff08;IDE&#xff09;&#xff0c;在软件开发中经常会遇到需要在它们之间迁移项目的情况。本文将重点介绍如何在IntelliJ IDEA中导入Eclipse项目&#xff0c;以帮助开发者顺利地迁移他们的项目&#xff0c;并在IntelliJ …

大型语言模型高效推理综述

论文地址&#xff1a;2404.14294.pdf (arxiv.org) 大型语言模型&#xff08;LLMs&#xff09;由于在各种任务中的卓越表现而受到广泛关注。然而&#xff0c;LLM推理的大量计算和内存需求给资源受限的部署场景带来了挑战。该领域的努力已经朝着开发旨在提高LLM推理效率的技术方…

RustGUI学习(iced)之小部件(二):如何使用滑动条部件

前言 本专栏是学习Rust的GUI库iced的合集&#xff0c;将介绍iced涉及的各个小部件分别介绍&#xff0c;最后会汇总为一个总的程序。 iced是RustGUI中比较强大的一个&#xff0c;目前处于发展中&#xff08;即版本可能会改变&#xff09;&#xff0c;本专栏基于版本0.12.1. 概述…