当前位置: 首页 > news >正文

CmakeList教程

一、CmakeList介绍:

cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。它会通过写的语句自动生成一个MakeFile,从而实现高效编译

二、CmakeList的常用指令

1.指定 cmake 的最小版本(可选)

cmake_minimum_required(VERSION 2.8)

这条语句规定了执行这个cmake的版本不能低于2.8,否则会报错,要求升级cmake版本

2.设置项目名称(可选)

project(HELLO)

这个命令不是强制性的,但最好都加上。它会引入两个变量 HELLO_BINARY_DIR 和 HELLO_SOURCE_DIR,同时,cmake 自动定义了两个等价的变量 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR

3.添加生成的二进制文件

add_executable(name source…)

参数解释:
(1)name为需要生成的可执行文件名,也就是例如gcc demo.c -o demo,-o生成的demo就是这里的参数name,生成后就可以在可执行文件目录执行./demo运行
(2)第二个参数source为源文件,也就是.c或者.cpp文件,这个参数可以有多个,实现多个源文件一起编译

知道了上面三个指令,我们就可以写一个简单的CmakeList文件啦,先写一个小demo试试水~
在这里插入图片描述

在当前目录下,有一个function的文件夹,里面存放着一个叫fun.cpp的文件,文件中有一个add的函数,实现的是对输入的两数相加并返回。function文件夹外面存放着CmakeList.txt与我们的主函数demo.cpp。
现在编写CmakeList.txt:

cmake_minimum_required(VERSION 2.8)
project(HELLO)
add_executable(hello ./demo.cpp function/fun.cpp)

接着在CmakeList.txt所在的目录下执行

cmake .

就会生成几个文件以及文件夹,其中的MakeFile就是我们需要的
在这里插入图片描述
接着执行

make

就可以看到目录下出现了我们需要的可执行文件hello,运行./hello 可以看到成功打印出了结果15
在这里插入图片描述

4. 收集指定目录下的源码文件

很多时候我们构建一个二进制文件的时候,可能有几十或上百个.c或.cpp源码参与编译,如果我们在add_executable后一个个指定,效率非常低下,这时候就可以使用aux_source_directory

aux_source_directory(<dir> <variable>)

5.生成库文件

add_library(library_name [STATIC | SHARED | MODULE] EXCLUDE_FROM_ALL source_files)

library_name为要生成库的名称,例如生成一个名为libadd.so的动态库时,填add就行,lib与后面的.so会自动生成
STATIC表示生成静态库,SHARED表示生成动态库,MODULE表示生成一个模块,这是可选参数,但是最好根据需要生成的库类型都加上
使用 EXCLUDE_FROM_ALL 选项时,库目标将不会被自动构建,而是需要通过其他目标或手动指令进行显式构建。这个选项通常用于一些可选的或测试相关的库,它们不需要作为构建过程的一部分,但可以在需要时手动构建。这个也是可选参数
source_files为生成库的源文件

6. 指定连接库

这里有两种方式,第一种为link_directories与link_libraries搭配使用,还有一种是find_library与target_link_libraries搭配,更加推荐使用第二种,因为可读性更好,可以让我们更好的了解代码的依赖关系,并且可以确保在构建过程中只链接指定的库文件

第一种方式

link_directories(directory1 directory2 …)
添加库的查找路径

其中directory1、directory2等是你要添加的附加库文件目录。
需要注意的是link_directories默认路径在当前目录下,也就是说如果不提供绝对路径的话,只能在当前目录的子目录下找

link_libraries(library1 library2 …)
设置需要链接的文件

其中,library1、library2等参数是要链接的库文件名。
link_libraries可以把库链接到后续所有的目标中,库名以libpthread为例,可以写libpthread.so、pthread,都可以识别

第二种方式(推荐使用)

find_library(LIBRARY_PATH mylibrar PATHS /path/to/library/directory1 /path/to/library/directory2)

LIBRARY_PATH为一个变量,find_library会把找到的库存到这个变量中。可以供下面target_link_libraries使用
mylibrar为需要查找的库名称
PATHS为开始的字段不是必须的,它可以指定除当前目录下的其他路径,后面跟的都是需要查找的路径

target_link_libraries(target [item1] [item2] …)

其中 <target> 是要链接库文件的目标(例如可执行文件、静态库等),[item1]、[item2] 等是要链接到目标的库文件或目标。
item1的设置方式:

  • 可以是写死的库,例如库名为libadd.so,可以写成target_link_libraries(demo add)
  • 使用set设置变量的方式,set(LIBRARY_PATH /path/to/library),item1使用${LIBRARY_PATH}代替
  • add_library(my_library STATIC my_library.cpp) 这种方式会生成一个新的库供使用
  • 使用find_library设置的变量来链接

7.添加编译宏

很多时候我们的代码中存在类似#ifdef XXX 这样的编译宏,可以决定代码编译出不同功能或架构的代码,例如gcc编译时为gcc demo.c -DDEBUG,这时候如果代码中存在DEBUG这样的宏,就会编译被ARM宏包着的那段代码,设置宏与库一样,也有两种方式
第一种:add_definitions

add_definitions(-DXXX)

-D为必须的,XXX为需要设置的宏,这样设置会让下面所有构建的目标都带上这个宏参与编译,同样不推荐使用

第二种:target_compile_definitions (推荐使用)

target_compile_definitions(<target> <DEFINE1> <DEFINE2> …)

<target> 是要添加宏定义的目标(例如可执行文件、静态库等)
<scope> 是定义的作用范围(例如 PUBLIC、PRIVATE 或 INTERFACE)
<DEFINE1>、<DEFINE2> 等是要添加的宏定义。
需要注意的是,target_compile_definitions需要写在已经构建的目标后,例如target是demo这个可执行文件,那么在target前需要首先调用add_executable,在有demo这个目标后再再调用target_compile_definitions,否则会出现构建报错

8. 检查软件包

find_package( [version] # 指定要查找的库或者模块(版本号可选)
[EXACT] # 要求version完全匹配
[QUIET] # 无论找到与否,都不产生任何提示性消息
[REQUIRED] # 要求必须找到 xxx.cmake,找不到就提示报错
[[COMPONENTS] [components…]] 查找 Package 中的指定模块,COMPONENTS 跟的是一个列表,只要列表中任意一个模块没有被找到,则认为整个 Package 没有被找到,即 <PackageName>_FOUND 为 false(如果存在REQUIRED选项,则可以省略COMPONENTS关键字)
[OPTIONAL_COMPONENTS [components…]]
[MODULE] # 仅使用模块模式
[CONFIG|NO_MODULE] # 仅使用配置模式(两种写法是等效的)
[GLOBAL]
[NO_POLICY_SCOPE]
[BYPASS_PROVIDER]
)

find_package 一般都内置了一些变量:
_FOUND:可以判断是否找到对应的包或者模块
_INCLUDE_DIR:表示头文件目录(前提是包被找到才会被自动设置)
_LIBRARIES:表示库文件

以opencv为例

# 检索OpenCV库
find_package(OpenCV REQUIRED)add_executable(main src/main.cpp)
if(OpenCV_FOUND)# 引入头文件目录include_directories(${OpenCV_INCLUDE_DIRS})# 链接库文件target_link_libraries(main ${OpenCV_LIBRARIES})
else(OpenCV_FOUND)message(FATAL_ERROR "OpenCV library not found")
endif()

9.添加头文件搜索路径

include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 …])

AFTER|BEFORE: 指定添加的搜索路径的位置,默认是 AFTER,即添加到已有的搜索路径之后。可以使用 BEFORE 将搜索路径添加到已有的搜索路径之前。
SYSTEM: 表示目录是系统目录,编译器会忽略其中的头文件的警告。可以不加
dir1 [dir2 …]: 要添加到搜索路径的目录列表。

10.构建带有层级目录的工程

如果我们想编译一个二进制文件,而这个二进制文件需要链接一个动态库,这个动态库也是需要实时编译出来给二进制使用的,这时候我们就可以使用add_subdirectory、add_dependencies来建构

add_subdirectory(subdirectory_path binary_output_path)

subdirectory_path为子目录的路径:指定要添加的子目录的路径。
binary_output_path为二进制输出目录:指定生成的二进制文件(库或可执行文件)的输出路径。
当我们执行cmake 时,它会进入指定的子目录中,执行该子目录下的 CMakeLists.txt 文件,并将生成的二进制文件输出到指定的二进制输出目录。

add_dependencies(target_name dependency_target_name)

target_name为目标名称:指定当前目标的名称。
dependency_target_name为依赖目标名称:指定当前目标所依赖的目标的名称。
当运行 cmake 构建项目时,如果当前目标依赖于另一个目标,则会先构建所依赖的目标,然后再构建当前目标。这可以确保在构建当前目标之前,其所依赖的目标已经被正确地构建完成。
下面是示例:
这是主目录与子目录的CMakeList内容

主目录cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(DEMO)include_directories(./include)# 添加可执行文件目标
add_executable(demo ./demo.c)# 将 demo 目标与 lib 目标链接
target_link_libraries(demo add)add_subdirectory(lib ./lib/)
add_dependencies(demo add)子目录:cat lib/CMakeLists.txt
cmake_minimum_required(VERSION 2.8project)
project(ADD)
add_library(add SHARED add.c)

下面是目录结构

.
├── CMakeLists.txt
├── demo.c
├── include
│   └── add.h
└── lib├── add.c└── CMakeLists.txt
10:30 上午 cmake cat demo.c
#include <stdio.h>
#include "add.h"int main()
{printf("%d\n",add(1,2));return 0;
}10:31 上午 cmake cat lib/add.c
int add(int a,int b)
{return a+b;
}

在主目录下执行cmake. && make,发现lib下生成了libadd.so,并且主目录下生成了我们需要的demo可执行文件,运行结果为3

11.设置二进制的生成路径

当我们执行add_executable后,通常需要把二进制放到指定的目录,这时候就可以通过install来实现,相当于操作了make install

install([Target | File | Directory | Script] my_executable DESTINATION you_path)

目标(Target):可以使用构建生成的目标名称作为第一个参数。
文件(File):可以使用文件路径作为第一个参数。
目录(Directory):可以使用目录路径作为第一个参数。
脚本(Script):可以使用脚本文件路径作为第一个参数。

示例:
install(TARGETS my_executable
DESTINATION bin)

install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.md
DESTINATION share)
示例中,my_executable 是一个已经定义的可执行目标,它将被安装到 bin 目录中。同时,项目根目录下的 README.md 文件将被安装到 share 目录中。

相关文章:

CmakeList教程

一、CmakeList介绍&#xff1a; cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。它会通过写的语句自动生成一个MakeFile,从而实现高效编译 二、CmakeList的常用指令 1.指定…...

JavaWeb之JavaScript-Vue --黑马笔记

什么是JavaScript&#xff1f; JavaScript&#xff08;简称&#xff1a;JS&#xff09; 是一门跨平台、面向对象的脚本语言。是用来控制网页行为的&#xff0c;它能使网页可交互。 JavaScript 和 Java 是完全不同的语言&#xff0c;不论是概念还是设计。但是基础语法类似。 …...

pikachu_ssrf攻略

ssrf&#xff08;curl&#xff09;&#xff1a; 打开pikachu靶场&#xff1a; http://127.0.0.1/pikachu-master/vul/ssrf/ssrf_curl.php?urlhttp://127.0.0.1/pikachu-master/vul/ssrf/ssrf_info/info1.php 发现URL地址最后面是info1.php 猜测一下有没有可能存在info2.php?…...

门面模式 Facade Pattern

门面模式 门面模式&#xff08;Facade Pattern&#xff09;&#xff0c;也称之为外观模式&#xff0c;其核心为&#xff1a;外部与一个子系统的通信必须通过一个统一的外观对象进行&#xff0c;使得子系统更易于使用。 在软件开发领域有这样一句话&#xff1a;计算机科学领域…...

Linux基础指令大汇总

Linux的指令比较多&#xff0c;在学习的过程中要学会总结和归纳&#xff0c;同时结合实践多多使用&#xff0c;就像学数学一样&#xff0c;不是背过公式就等于掌握的&#xff0c;而是要知道在什么时候用&#xff0c;怎么用才是关键。 这篇文章会列举一系列常用的指令&#xff0…...

Unity配置表xlsx/xls打包后读取错误问题

前言 代码如下&#xff1a; //文本解析private void ParseText(){//打开文本 读FileStream stream File.Open(Application.streamingAssetsPath excelname, FileMode.Open, FileAccess.Read, FileShare.Read);//读取文件流IExcelDataReader excelRead ExcelReaderFactory…...

CSS基本知识总结

目录 一、CSS语法 二、CSS选择器 三、CSS样式表 1.外部样式表 2.内部样式表 3.内联样式 四、CSS背景 1.背景颜色&#xff1a;background-color 2.背景图片&#xff1a;background-image 3.背景大小&#xff1a;background-size 4.背景图片是否重复&#xff1a;backg…...

3dmax效果图渲染出现曝光怎么解决?

在使用3ds Max完成效果图渲染工作时&#xff0c;有时会遇到曝光过度的问题&#xff0c;这会使得渲染的图像出现光斑或者过亮&#xff0c;损害了效果的真实感和美观度。那么解决解决3dmax曝光问题呢&#xff1f;一起看看吧&#xff01; 3dmax效果图渲染出现曝光解决方法 1、相机…...

科技、文化与旅游的融合创新:智慧文旅的未来之路

在当今社会&#xff0c;科技、文化与旅游的融合已经成为文旅产业转型升级的重要趋势。这种融合不仅有助于提升文旅产业的核心竞争力&#xff0c;更有助于推动产业的数字化转型和可持续发展。 本文将深入探讨科技、文化与旅游的融合创新&#xff0c;以及智慧文旅场景的解决方案…...

【第四天】蓝桥杯备战

题 1、求和2、天数3、最大缝隙 1、求和 https://www.lanqiao.cn/problems/1442/learning/ 解法&#xff1a;字符串方法的应用 import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scann…...

计算机服务器中了halo勒索病毒怎么办,halo勒索病毒解密处理流程

计算机技术的发展与应用为企业的生产生活提供了坚实基础&#xff0c;但同时也为网络安全威胁制造了有利条件。近期&#xff0c;网络上的勒索病毒非常嚣张&#xff0c;给企业的计算机服务器带来严重威胁。近日&#xff0c;云天数据恢复中心接到山东某制造公司的求助&#xff0c;…...

基于LSTM的负荷预测,基于BILSTM的负荷预测,基于GRU的负荷预测,基于BIGRU的负荷预测,基于BP神经网络的负荷预测

目录 背影 摘要 代码和数据下载&#xff1a;基于LSTM的负荷预测&#xff0c;基于BILSTM的负荷预测&#xff0c;基于GRU的负荷预测&#xff0c;基于BIGRU的负荷预测&#xff0c;基于BP神经网络的负荷预测资源-CSDN文库 https://download.csdn.net/download/abc991835105/8876806…...

Linux命令-apachectl命令(Apache服务器前端控制工具)

apachectl命令 是Apache的Web服务器前端控制工具&#xff0c;用以启动、关闭和重新启动Web服务器进程。 语法 apachectl (参数)参数 configtest&#xff1a;检查设置文件中的语法是否正确&#xff1b;fullstatus&#xff1a;显示服务器完整的状态信息&#xff1b;graceful&a…...

5.【SpringBoot3】文件上传

1. 文件上传到本地 需求分析 在用户更换头像或发布文章时&#xff0c;需要携带一个图片的 url 地址&#xff0c;该 url 地址是当用户访问文件上传接口&#xff0c;将图片上传成功后&#xff0c;服务器返回的地址。所以&#xff0c;后台需要提供一个文件上传接口&#xff0c;用…...

网络安全态势感知平台概述

网络安全态势感知平台 文章目录 网络安全态势感知平台网络安全态势感知平台是什么一、网络安全态势感知平台是什么&#xff1f;二、网络安全态势感知很重要三、网络安全态势感知基础功能以某公司态势平台产品为例具体功能有以下&#xff1a; 网络安全态势感知平台是什么 网络安…...

PHP导出csv文件格式(最快捷的方式导出Excel文件)

php导出csv文件格式比起用PHPExcel插件导出excel文件速度快100倍&#xff01; 以下是几种不同的PHP导出CSV文件的方法&#xff1a; 方法一&#xff08;php://output方式用fputcsv函数格式化成csv数据&#xff09;&#xff1a; ----------------------------------------------…...

vue3常用代码

文章目录 监听路由vue3 警告Feature flag __VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.mitt、project/inject 无效解决方案 菜鸟做项目时发现很多 vue3 常用的代码&#xff0c;所以来总结一下&#xff01; 监听路由 import { useRoute } from "…...

【技术】SpringBoot 接口怎么加密解密

1. 介绍 在我们日常的Java开发中&#xff0c;免不了和其他系统的业务交互&#xff0c;或者微服务之间的接口调用 如果我们想保证数据传输的安全&#xff0c;对接口出参加密&#xff0c;入参解密。 但是不想写重复代码&#xff0c;我们可以提供一个通用starter&#xff0c;提…...

SqlAlchemy使用教程(六) -- ORM 表间关系的定义与CRUD操作

SqlAlchemy使用教程(一) 原理与环境搭建SqlAlchemy使用教程(二) 入门示例及编程步骤SqlAlchemy使用教程(三) CoreAPI访问与操作数据库详解SqlAlchemy使用教程(四) MetaData 与 SQL Express Language 的使用SqlAlchemy使用教程(五) ORM API 编程入门 本章内容&#xff0c;稍微有…...

嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM平台编程第五天-kernel配置(物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1eb94AaDM-cIZsbr929Isbw?pwd1688 提取码&#xff1a;1688 上午&#xff1a;linux内核介绍 徐登伟老师 下午&#xff1a;linux的配置 教学内容&#xff1a; 一、基本kernel的制作&#xff1a; 1、去开源社区下载原…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...