【CMake】CMake从入门到实战系列(十五)—— CMake中添加编译选项的几种方法

news2024/11/18 2:39:13

文章目录

      • 一、前言
      • 二、add_compile_options
        • 【1】基本语法
        • 【2】参数含义
        • 【3】示例
        • 【4】备注
      • 三、target_compile_options
        • 【1】基本语法
        • 【2】参数含义
        • 【3】示例
        • 【4】备注
      • 四、CMAKE_C_FLAGS 或 CMAKE_CXX_FLAGS

一、前言

在嵌入式工作开发调试过程中,我们常会遇到需要添加编译选项的情况。添加适当的编译选项能够帮助我们更好地控制程序行为,优化代码,确保稳定性和性能。常见的编译选项有-s、-g、-O3、-fPIC、-Wall、-Werror、-Wextra等。

在CMake中为项目增加编译选项有多种方法,下面我们来详细介绍几种常见的方法。

二、add_compile_options

add_compile_options 添加全局编译选项,为整个项目添加编译选项。

【1】基本语法
add_compile_options(<option> ...)
【2】参数含义

<option>:一个或多个要添加的编译选项,这些选项会传递给编译器

【3】示例

项目目录结构如下

add_compile_options_pro
  ├── CMakeLists.txt
  └── main.c

main.c源码

#include <stdio.h>

int main(int argc, char *argv[])
{
	printf("hello world\n");
	return 0;
}

CMakeLists.txt源码

cmake_minimum_required(VERSION 3.10)
project(Demo)

add_compile_options(-Wall -Wextra)

add_executable(app main.c)

上面的CMake配置将会为项目中的所有源文件添加 -Wall 和 -Wextra 编译选项。

编译运行
在add_compile_options_pro目录中

mkdir build
cd build
cmake ..
make

在这里插入图片描述

【4】备注

使用 add_compile_options 针对不同的编译器(如C和C++编译器)设置编译选项是可以的,但需要确保生成器表达式的使用符合CMake的语法要求。

# 添加编译选项,适用于C++编译器
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wall> $<$<COMPILE_LANGUAGE:CXX>:-Wextra>)

# 添加编译选项,适用于C编译器
add_compile_options($<$<COMPILE_LANGUAGE:C>:-Wall> $<$<COMPILE_LANGUAGE:C>:-Wextra>)


示例
下面是一个示例:
目录结构

c++_add_compile_options_pro
├── CMakeLists.txt
└── main.cpp

main.cpp源码

#include <iostream>

int main() 
{
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

CMakeLists.txt源码

cmake_minimum_required(VERSION 3.10)
project(HelloWorld)

# 添加编译选项,适用于C++编译器
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wall> $<$<COMPILE_LANGUAGE:CXX>:-Wextra>)

add_executable(hello main.cpp)

编译运行
在这里插入图片描述

三、target_compile_options

target_compile_options针对某个特定的目标(如库或可执行文件)添加编译选项 。

【1】基本语法
target_compile_options(<target> [BEFORE]
  		<INTERFACE|PUBLIC|PRIVATE> [items1...]
  		[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
【2】参数含义

<target>: 目标名称,即你想要为其添加编译选项的库或可执行文件的名称。
target_compile_options要求构建目标已经存在,也就是目标被add_executable()或add_library()等函数创建出来。

PRIVATE | PUBLIC |INTERFACE: 这三个关键字控制了这些选项的应用范围。
PRIVATE: 选项只应用于当前目标。
PUBLIC:选项既应用于当前目标,也应用于那些链接到当前目标的其他目标。
INTERFACE: 选项只应用于链接到当前目标的其他目标。

items1…、items2…: 一个或多个要添加的编译选项。

【3】示例

项目目录结构main.c源码和add_compile_options示例中的一样,此处不再赘述。

CMakeLists.txt源码

cmake_minimum_required(VERSION 3.10)
project(Demo)

add_executable(app main.c)
target_compile_options(app 
					   PRIVATE -Wall -Wextra
					   PUBLIC -g)

这样,只有 app目标会应用 -Wall 和 -Wextra 编译选项。

编译运行结果同上,可自行编译运行测试。

【4】备注

target_compile_options 可以用于针对 C 和 C++ 编译器分别设置编译选项。使用生成器表达式,您可以为特定目标的不同编译语言添加不同的选项。

# 为 C++ 文件添加编译选项
target_compile_options(hello PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wall -Wextra>)

# 为 C 文件添加编译选项(当前没有 C 文件,但可以启用以下行)
target_compile_options(hello PRIVATE $<$<COMPILE_LANGUAGE:C>:-Wall -Wextra>)


示例
目录结构main.cpp源码和add_compile_options备注里的一样,此处不再赘述。

CMakeLists.txt源码

cmake_minimum_required(VERSION 3.10)

# 设置项目名称
project(HelloWorld)

# 添加可执行文件
add_executable(hello main.cpp)

# 为 C++ 文件添加编译选项
target_compile_options(hello PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wall -Wextra>)

# 为 C 文件添加编译选项(当前没有 C 文件,但可以启用以下行)
target_compile_options(hello PRIVATE $<$<COMPILE_LANGUAGE:C>:-Wall -Wextra>)

编译运行结果同add_compile_options备注里的一样,此处不再赘述。

四、CMAKE_C_FLAGS 或 CMAKE_CXX_FLAGS

直接设置全局编译选项。
通过set设置 CMAKE_C_FLAGS 变量来全局添加C编译选项。
通过set设置 CMAKE_CXX_FLAGS 变量来全局添加C++编译选项。
这种方法会将指定的编译选项应用于所有C源文件或C++源文件。

项目目录结构main.c源码和add_compile_options示例中的一样,此处不再赘述。

CMakeLists.txt源码

cmake_minimum_required(VERSION 3.10)
project(Demo)

# C编译选项
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
# C++编译选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")

add_executable(app main.c)

编译运行结果同上,可自行编译运行测试。

本文完整源码下载地址 CMake从入门到实战系列(十五)- CMake中添加编译选项的几种方法的完整源码

该专栏下一篇文章将总结如何修改CMake的编译器,以及实际嵌入式开发工作中常用到的编译器选项的归纳汇总。

有任何建议或疑问,欢迎评论区交流沟通。

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

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

相关文章

科技赋能,无障碍出行的新纪元

在现代社会&#xff0c;公共设施的建设不仅是衡量城市文明程度的标尺&#xff0c;更是实现社会公平与包容的重要载体。对于盲人群体而言&#xff0c;一个完善的公共设施网络&#xff0c;意味着他们能够更加独立、自信地融入社会&#xff0c;享受与视力健全者同等的公共服务与便…

【C语言之排序】-------六大排序

作者主页&#xff1a;作者主页 数据结构专栏&#xff1a;数据结构 创作时间 &#xff1a;2024年5月18日 前言&#xff1a; 今天我们就给大家带来几种排序的讲解&#xff0c;包括冒泡排序&#xff0c;插入排序&#xff0c;希尔排序&#xff0c;选择排序&#xff0c;堆排序&…

jmeter的infludb+grafana实时监控平台

目的&#xff1a;可以实时查看到jmeter拷机信息 框架&#xff1a;将 Jmeter 的数据导入 InfluxDB &#xff0c;再用 Grafana 从 InfluxDB 中获取数据并以特定的模板进行展示 性能监控平台部署实践 一、influxDB 官网&#xff1a;https://www.influxdata.com/downloads/ wget h…

Unity 自定义房间布局系统 设计与实现一个灵活的房间放置系统 ——物体占用的区域及放置点自动化

放置物体功能 效果&#xff1a; 功能&#xff1a; 自定义物体占用区域的大小一键调整占用区域调整旋转度数&#xff0c;分四个挡位&#xff1a; NoRotation&#xff1a;该物体不能调整旋转。MaximumAngle&#xff1a;每次转动90。NormalAngle&#xff1a;每次转动45&#xff…

Vue03-HelloWord

一、Hello World 1-1、示例1 1、现有html容器&#xff1b; 2、再有vue实例。 new Vue({});中的{}是配置对象。配置对象是&#xff1a;key&#xff1a;value的格式。 el&#xff1a;element元素。id对应#&#xff0c;class对应. 把容器中变化的数据&#xff0c;交给Vue实例去保…

嵌入式软件跳槽求指导?

嵌入式软件行业的跳槽确实需要一些特定的策略和技巧。我这里有一套嵌入式入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习嵌入式&#xff0c;不妨点个关注&#xff0c;给个评论222&#xff0c;私信22&#xff0c;我在后台发给你。 因为这个…

[Algorithm][动态规划][两个数组的DP][最长公共子序列][不相交的线][不同的子序列][通配符匹配]详细讲解

目录 1.最长公共子序列1.题目链接2.算法原理详解3.代码实现 2.不相交的线1.题目链接2.算法原理详解3.代码实现 3.不同的子序列1.题目链接2.算法原理详解3.代码实现 4.通配符匹配1.题目链接2.算法原理详解3.代码实现 1.最长公共子序列 1.题目链接 最长公共子序列 2.算法原理详…

Linux网络编程:数据链路层协议

目录 前言&#xff1a; 1.以太网 1.1.以太网帧格式 1.2.MTU&#xff08;最大传输单元&#xff09; 1.2.1.IP协议和MTU 1.2.2.UDP协议和MTU 1.2.3.TCP协议和MTU 2.ARP协议&#xff08;地址解析协议&#xff09; 2.1.ARP在局域网通信的角色 2.2.ARP报文格式 2.3.ARP报文…

SpringBoot高手之路02-全局异常处理器

RestControllerAdvice 可以将响应数据返回json格式然后响应 那么开始做全局异常处理器 首先先定义一个类 package com.healer.exception;import com.healer.common.Result; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.we…

AIGC专栏11——EasyAnimateV2结构详解与Lora训练 最大支持768x768 144帧视频生成

AIGC专栏11——EasyAnimateV2结构详解与Lora训练 最大支持768x768 144帧视频生成 学习前言源码下载地址EasyAnimate V2简介技术储备Diffusion Transformer (DiT)Motion ModuleU-VITLora 算法细节算法组成视频VAE视频DIT 数据处理视频分割视频筛选视频描述 模型训练视频VAE视频D…

Leetcode3168. 候诊室中的最少椅子数

Every day a Leetcode 题目来源&#xff1a;3168. 候诊室中的最少椅子数 解法1&#xff1a;模拟 代码&#xff1a; /** lc appleetcode.cn id3168 langcpp** [3168] 候诊室中的最少椅子数*/// lc codestart class Solution { public:int minimumChairs(string s){int chair…

前缀树的实现

前缀树的实现 何谓前缀树&#xff1f;实现前缀树节点的选择插入查找查找前缀完整代码 何谓前缀树&#xff1f; 前缀树&#xff08;字典树&#xff09;&#xff0c;使用树状的数据结构存储一个字典的所有单词。前缀树是一个多叉树&#xff0c;一个节点可能有多个子节点&#xf…

SpringMVC:转发和重定向

1. 请求转发和重定向简介 参考该链接第9点 2. forward 返回下一个资源路径&#xff0c;请求转发固定格式&#xff1a;return "forward:资源路径"如 return "forward:/b" 此时为一次请求返回逻辑视图名称 返回逻辑视图不指定方式时都会默认使用请求转发in…

优化你的WordPress网站:内链建设与Link Whisper Pro插件的利用

文章目录 内链的重要性WordPress SEO插件&#xff1a;Link Whisper Pro主要功能使用指南下载与安装 结语 在数字营销和网站管理领域&#xff0c;SEO内部优化是提升网站排名、增加流量和提高用户参与度的核心策略。在众多SEO技巧中&#xff0c;内链建设是构建良好网站结构和提升…

使用Django JWT实现身份验证

文章目录 安装依赖配置Django设置创建API生成和验证Token总结与展望 在现代Web应用程序中&#xff0c;安全性和身份验证是至关重要的。JSON Web Token&#xff08;JWT&#xff09;是一种流行的身份验证方法&#xff0c;它允许在客户端和服务器之间安全地传输信息。Django是一个…

docker实战流程:

Docker-compose是docker官方的开源项目&#xff0c;负责实现对docker容器的集群的快速编排&#xff08;通过yaml文件docker-compose.yml管理写好容器之间的调用关系只需一个命令就能实现容器的通识开启或关闭&#xff09;。 类比spring容器&#xff0c;spring管理的是bean而do…

【乐吾乐3D可视化组态编辑器】3D场景与大屏通信

乐吾乐大屏可视化可以实现大屏页面与内嵌2d/3d场景相互通信&#xff0c;底层原理是利用了iframe通过postMessage发送消息。 3D组态编辑器地址&#xff1a;3D可视化组态 - 乐吾乐Le5le 大屏组态编辑器地址&#xff1a;大屏可视化设计器 - 乐吾乐Le5le 下面以3d场景为例&#…

C# 判断字符串不等于空的示例

在C#中&#xff0c;要判断一个字符串是否不等于空&#xff08;即它既不是null也不是空字符串""&#xff09;&#xff0c;方法有如下几种&#xff0c;如下。 方法1 使用逻辑运算符和string.IsNullOrEmpty方法 string myString "123"; // 假设要检查的字…

Python第二语言(三、Python函数def)

目录 1. Python函数&#xff08;def 函数名():&#xff09; 1.1 sorted对容器进行排序&#xff1a;无法指定排序规则 1.2 sort对容器自定义排序&#xff1a;可以指定排序规则 1.3 获取变量长度函数&#xff08;len&#xff09; 1.4 函数的定义 1.5 函数-传参定义 1.6 函…

JFinal学习06 控制器——getPara()接收数据

JFinal学习06 控制器——getPara()接收数据 视频来源https://www.bilibili.com/video/BV1Bt411H7J9/?spm_id_from333.337.search-card.all.click 文章目录 JFinal学习06 控制器——getPara()接收数据零、JFinal数据提交的三种方式一、get提交二、post提交三、url参数化提交四、…