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.mzph.cn/bicheng/4357.shtml

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

相关文章

flutter笔记-主要控件及布局

文章目录 1. 富文本实例2. Image2.1 本地图片2.2 网络图片 笔记3. 布局4. 滑动相关view4.1 GridView类似九宫格view4.2 ListView 关于widget的生命周期的相关知识这里就不做介绍&#xff0c;和很多语言类似&#xff1b; 1. 富文本实例 Dart中使用richtext&#xff0c;示例如下…

Vue3+Vite开发的项目进行加密打包

本文主要介绍Vue3+Vite开发的项目如何进行加密打包。 目录 一、vite简介二、混淆工具三、使用方法1. 安装插件:2. 配置插件:3. 运行构建:4. 自定义混淆选项:5. 排除文件:下面是Vue 3+Vite开发的项目进行加密打包的方法。 一、vite简介 Vite 是一个由 Evan You 创造的现代…

XBoot:基于Spring Boot 2.x的一站式前后端分离快速开发平台

XBoot&#xff1a;基于Spring Boot 2.x的一站式前后端分离快速开发平台 摘要 随着信息技术的迅速发展&#xff0c;快速构建高质量、高可靠性的企业级应用成为了迫切需求。XBoot&#xff0c;作为一个基于Spring Boot 2.x的一站式前后端分离快速开发平台&#xff0c;通过整合微信…

针对icon报错

针对上篇文章生成图标链接中图标报错 C# winfrom应用程序添加图标-CSDN博客 问题&#xff1a;参数“picture”必须是可用作Icon的参数 原因&#xff1a;生成的ico图标类型不匹配 解决方法&#xff1a; 更改导出的ico类型

iOS - 多线程-读写安全

文章目录 iOS - 多线程-读写安全1. 多读单写1.1 场景1.2 实现方案1.2.1 pthread_rwlock&#xff1a;读写锁1.2.1.1 示例 1.2.2 dispatch_barrier_async&#xff1a;异步栅栏调用1.2.2.1 示例 iOS - 多线程-读写安全 假设有一个文件&#xff0c;A线程进行读取操作&#xff0c;B…

数智时代的AI人才粮仓模型解读白皮书(2024版)

来源&#xff1a;极客邦科技 自 2023 年上半年起&#xff0c;ChatGPT 等大模型技术蓬勃发展&#xff0c;AI 技术不断突破边界&#xff0c;展现 出惊人的潜力和发展速度。从早期的逻辑推理、专家系统&#xff0c;到如今的深度学习、神经网络&#xff0c; AI 技术显著缩小了科学…

ASP.NET企业投资价值分析系统

摘 要 本文将影响股票投资价值的宏观因素、行业因素、企业内部等诸多因素予以量化分析&#xff0c;对钢铁板块和汽车板块各上市公司进行综合评估&#xff0c;为广大股民的投资方向和资金安全提供了有力的支持。本文还阐述了企业投资价值分析的必要性&#xff0c;说明了企业投…

分类算法——模型评估(八)

1混淆矩阵 在分类任务下&#xff0c;预测结果与正确标记之间存在四种不同的组合&#xff0c;构成混淆矩阵&#xff08;适用于多分类&#xff09; TP True Possitive FN False Negative 2精确率&#xff08;Precision&#xff09;与召回率&#xff08;Recall&#xff09; 精…

mysql-sql-练习题-2

日期topN 日期最值 topN 任意区间topN 每年温度top2建表排名函数万能公式&#xff08;条关&#xff09; 任意区间 各科第1,3,5名排名函数万能公式 日期 本周过生日 -- 本周表示 加减日期 格式化 拼接 select * from student where date_format(s_age,concat(year(curdate()),…

微信小程序开发六(自定义组件)

自定义组件的创建&#xff1a; 如何创建&#xff1a; 右键选择新建component 创建完成之后需要打开app.json&#xff0c;这是全局使用这个组件&#xff0c;想要单独的页面使用&#xff0c;就在当前页面的json文件中定义 "usingComponents": {"my-zj": &quo…

冰箱主控 32位MCU,多通道、高精度的AD采样配合温度传感器,实现冰箱各温室的精确控温;低功耗设计

概览 小华高性价比32位MCU&#xff0c;多通道、高精度的AD采样配合温度传感器&#xff0c;实现冰箱各温室的精确控温&#xff1b;低功耗设计&#xff0c;绿色低碳、节能环保&#xff1b;模块化设计&#xff0c;充分利用丰富的通讯接口&#xff0c;使主控板、显示板和驱动板灵活…

远程连接docker,实现本地发布版本到服务器

最近在学jenkins的时候&#xff0c;发现涉及到了docker的远程发布调用。后续应该还要自己搭建一个docker的本地仓库。 简单描述一下具体是如何实现的&#xff1a; 1、将docker的服务器开启2375端口&#xff08;注意&#xff0c;这里的开启是将端口直接暴露出去&#xff0c;不用…

38-1 防火墙了解

一、防火墙的概念: 防火墙(Firewall),也称防护墙,是由Check Point创立者Gil Shwed于1993年发明并引入国际互联网(US5606668 [A]1993-12-15)。它是一种位于内部网络与外部网络之间的网络安全系统,是一项信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。…

移远通信推出“全系统+全频段”GNSS定位模组LG290P,赋能高精度导航应用

近日&#xff0c;全球领先的物联网整体解决方案供应商移远通信正式对外宣布&#xff0c;其将推出全新款支持“全系统全频段”的工规级RTK高精度GNSS定位模组LG290P&#xff0c;用于满足智能机器人、无人机、精准农业、测量测绘等高精度定位应用场景所需。 高精度 LG290P 作为移…

Ubuntu+Systemd服务+实现开机自启/关机启动脚本

开机自启 1.创建一个新的 systemd 服务文件 现在随便一个地方创建txt文档 如果想要启动sh脚本&#xff0c;就把下面的代码输入到txt文档中 [Unit] DescriptionRun Python script on specific executable run Afternetwork.target[Service] Typesimple ExecStart/home/tech/…

记录些AI Agents设计模式和NL2SQL知识

吴恩达分享的四种 自我反思&#xff08;Reflection&#xff09;&#xff1a;可以自我修正&#xff1b;使用工具&#xff08;Tool Use&#xff09;&#xff1a;链接其他系统去做一些事情&#xff0c;比如把电脑里面的未归档文件做好归档&#xff1b;规划&#xff08;Planning&a…

红米K40手机刷机详解

了解什么是卡刷、什么是线刷 卡刷&#xff0c;就是把系统包放到你手机的SD卡&#xff0c;这一步&#xff0c;不用手机解BL锁&#xff0c;不用root&#xff0c;直接小米助手下载就可以刷。线刷就是用数据线连接电脑&#xff0c;通过XiaoMiFlash直接刷到手机&#xff0c;这一步权…

Pytorch实现线性回归模型

在机器学习和深度学习的世界中&#xff0c;线性回归模型是一种基础且广泛使用的算法&#xff0c;简单易于理解&#xff0c;但功能强大&#xff0c;可以作为更复杂模型的基础。使用PyTorch实现线性回归模型不仅可以帮助初学者理解模型的基本概念&#xff0c;还可以为进一步探索更…

WebSocket 深入浅出

WebSocket 深入浅出 1. WebSocket 是什么2. WebSocket 建立连接通信的过程3. WebSocket 和http的联系与区别4. WebSocket 的使用场景及限制 1. WebSocket 是什么 定义&#xff1a;WebSocket 是一种网络通信协议&#xff0c;它允许在单个TCP连接上进行全双工通信。是HTML5规范提…

电商技术揭秘三十七:电商智能风控业务架构设计

相关系列文章 电商技术揭秘相关系列文章合集&#xff08;1&#xff09; 电商技术揭秘相关系列文章合集&#xff08;2&#xff09; 电商技术揭秘二十八&#xff1a;安全与合规性保障 电商技术揭秘二十九&#xff1a;电商法律合规浅析 电商技术揭秘三十&#xff1a;知识产权保…