cmake学习1

article/2025/6/16 8:49:10

基本起点

本笔记的主要参考文献是cmake文档,对文档的二次提炼和补充学习。

1. cmake_minimum_required()

任何项目的最顶层CMakeLists.txt都必须首先使用 cmake_minimum_required() 命令指定最低 CMake 版本。这建立策略设置并确保以下 CMake 函数以兼容的 CMake 版本运行。
cmake_minimum_required(VERSION <min>[...<policy_max>] [FATAL_ERROR])
要求 CMake 的最低版本,确保运行的 CMake 版本不低于该版本,否则会停止处理项目并报告错误。

  • <min>:必需的,指定项目的 CMake 最低版本,格式为 major.minor[.patch[.tweak]],例如 3.12、3.12.1 等。
    • major 是主版本号。
    • minor 是次版本号。
    • patch 是补丁版本号(可选)。
    • tweak 是修订版本号(可选)。
  • [...<policy_max>]:可选的,从 CMake 3.12 开始支持,用于指定策略版本的上限,格式同 <min>。如果指定,必须至少为<min>版本。在旧版本 CMake 中会被忽略。
  • [FATAL_ERROR]:可选的,CMake 2.6 及更高版本接受但忽略该选项。在 CMake 2.4 及更低版本中,若指定此选项,当运行的 CMake 版本低于 <min> 时会报错,而不是仅发出警告。

示例

cmake_minimum_required(VERSION 3.31)

2. add_executable()

使用指定的源文件向项目添加可执行文件。分为三类:普通可执行文件,普通可执行文件,别名可执行文件。

普通可执行文件

add_executable(<name> <options>... <sources>...)
add_executable(可执行文件名 源文件1 源文件2 ...)

添加一个名为<name>的 可执行 目标,该目标将从命令调用中列出的源文件构建。

  • WIN32
    自动设置 WIN32_EXECUTABLE 目标属性。 在 Windows 上构建一个带有 WinMain 入口点的可执行文件。当此属性设置为 true 时,在 Windows 上链接的可执行文件将使用 WinMain() 入口点而不是 main() 创建。 这使其成为 GUI 可执行文件而不是控制台应用程序。简单说 Windows 平台上生成“窗口程序”而非控制台程序(即不会弹出命令行黑框)。
  • MACOSX_BUNDLE
    自动设置 MACOSX_BUNDLE 目标属性。 (在 macOS 或 iOS 上将可执行文件构建为应用程序包,本次学习忽略)。
  • EXCLUDE_FROM_ALL
    自动设置 EXCLUDE_FROM_ALL 目标属性。 将此目标属性设置为 true(或 false)值,以将目标从包含目录及其祖先目录的“all”目标中排除(或包含)。如果排除,例如在包含目录或其祖先目录中运行 make 将默认不会构建该目标。简而言之就是排除目标项。
  • <name> 对应于逻辑目标名称,并且在项目中必须是全局唯一的。
  • CMake 默认会把构建的可执行程序放在 cmake-build-debug 目录中。

导入的可执行文件

add_executable(<name> IMPORTED [GLOBAL])
参数含义
<name>你给这个外部可执行文件起的内部名字(目标名)
IMPORTED说明这个目标是“外部导入的”,不由当前项目编译生成
GLOBAL(可选)使该目标在所有子目录中都可见
  • 使用场景:你已经有 .exe / .out 可执行文件,希望在构建流程中用它。

别名可执行文件

add_executable(<name> ALIAS <target>)

CMake 中的 目标别名(alias target)功能,虽然不像 IMPORTED 那样常见,但在模块化和大型项目中非常有用。假设你有个库或者程序,它的目标名很长、或者跟目录强绑定、或者不方便跨目录引用,CMake 提供 ALIAS 语法让你起个简单名字、跨模块引用。
示例:

add_executable(myproject_internal_app app.cpp)
# 给这个内部目标起个别名
add_executable(MyApp ALIAS myproject_internal_app)
  • 使用 ALIAS 的条件
    • 只能为已经定义好的目标起别名:所以你不能先写 add_executable(MyApp ALIAS something),必须something已经存在。
    • ALIAS 是只读的:你不能修改别名目标的属性。
    • ALIAS 主要用于公共接口:尤其是在 add_subdirectory()、install(EXPORT)、模块封装中,用于隐藏实现细节,导出简洁的接口。

3.project()

设置项目名称。

project(<PROJECT-NAME> [<language-name>...])
参数含义
<PROJECT-NAME>项目的名字
<language-name>项目使用的编程语言,如 C, CXX, Fortran
示例:
project(MyApp CXX)
  • 项目名叫 MyApp
  • 使用 C++ 编译器(CXX)
  • CMake 会自动启用 C++ 支持,并检查环境是否具备对应编译器
project(<PROJECT-NAME>[VERSION <major>[.<minor>[.<patch>[.<tweak>]]]][DESCRIPTION <project-description-string>][HOMEPAGE_URL <url-string>][LANGUAGES <language-name>...])
关键词说明
VERSION项目的版本号,支持最多四段(如 1.2.3.4
DESCRIPTION项目的简介说明
HOMEPAGE_URL项目的主页地址(可以是 GitHub 链接等)
LANGUAGES显式设置支持的语言,如 C CXX,可省略(自动推断)
  • 可以指定多个语言支持
project(MyProject LANGUAGES C CXX)

4.基本起点包含函数各种情况练习

练习 1:最基础的情况

项目结构

Cmake_learn/
├── CMakeLists.txt
└── main.cpp

CMakeLists.txt

cmake_minimum_required(VERSION 3.31)
project(Cmake_learn)
set(CMAKE_CXX_STANDARD 17)
add_executable(Cmake_learn main.cpp)

main.cpp

#include <iostream>
int main() {auto lang = "C++";std::cout << "Hello and welcome to " << lang << "!\n";for (int i = 1; i <= 5; i++) {std::cout << "i = " << i << std::endl;}return 0;}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

练习 2:指定项目版本号与描述

cmake_minimum_required(VESSION 3.31)
project(Cmake_learn CXX) #设定项目名称和语言
set(CMAKE_CXX_STANDARD 17) #设置C++标准为C++17
add_executable(Cmake_learn main.cpp) #添加可执行文件,指定源文件

main.cpp文件同练习1。

练习 3:添加多个源文件的可执行目标

//main.cpp
#include <iostream>
#include "add.h"
int main() {std::cout << "Add: " << add(2, 3) << "\n";return 0;
}
//add.cpp
#include "add.h"
int add(int a, int b) { return a + b; }
//add.h
int add(int a, int b);
#倘若main.cpp、 add.cpp、add.h在同一目录下
#CMakeList.txt
cmake_minimum_required(VERSION 3.31)
project(Cmake_learn)
set(CMAKE_CXX_STANDARD 17)
add_executable(MathApp main.cpp add.cpp)#为规范代码习惯,最好将头文件和源文件分开存放。#CMakeList.txt
cmake_minimum_required(VERSION 3.31)
project(Cmake_learn)
set(CMAKE_CXX_STANDARD 17) #设置C++标准为C++17
add_executable(Cmake_learn src/main.cpp src/add.cpp) #添加可执行文件,指定源文件x
target_include_directories(Cmake_learnPRIVATE ${CMAKE_SOURCE_DIR}/include
)

target_include_directories后面详细学习介绍,这里先记住大概格式。

练习 4:使用 IMPORTED 声明外部工具

cmake_minimum_required(VERSION 3.14)
project(CodeGenDemo)# 声明已存在的外部可执行程序
add_executable(CodeGen IMPORTED GLOBAL)
set_target_properties(CodeGen PROPERTIESIMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/tools/CodeGen.exe"
)# 假设 CodeGen.exe 生成一个 cpp 文件
add_custom_command(OUTPUT generated.cppCOMMAND CodeGenCOMMENT "Generating source code..."
)add_executable(MainApp generated.cpp)
add_dependencies(MainApp CodeGen)

练习 5:使用 ALIAS 简化内部目标命名

cmake_minimum_required(VERSION 3.10)project(CoreAliasDemo)# 真正的可执行程序
add_executable(core_exe main.cpp)# 给它起一个别名
add_executable(CoreRunner ALIAS core_exe)# 可以用别名参与链接、依赖等
add_custom_command(TARGET CoreRunnerPOST_BUILDCOMMAND CoreRunnerCOMMENT "Running CoreRunner post-build step"
)

5.configure_file()

configure_file(<input> <output> [@ONLY] [NEWLINE_STYLE [UNIX|DOS|WIN32]])

将一个模板文件(输入)拷贝为一个输出文件,并在其中替换 ${}@VAR@ 形式的变量。
没学会,项目不太用得上,暂时搁置后面补。

6.使用 file(GLOB) 动态获取文件

file(GLOB SOURCES "src/*.cpp")  # 匹配 src 目录下所有 .cpp 文件
add_executable(Cmake_learn ${SOURCES})

优点:无需手动维护文件列表。
缺点:如果 src 目录下没有 .cpp 文件,仍会报错。
若文件嵌套在多级目录中,可使用递归匹配:

file(GLOB_RECURSE SOURCES "src/**/*.cpp")  # 匹配 src 及子目录中所有 .cpp 文件
  • GLOB:只在当前目录及其指定的子目录中搜索文件,不会递归地搜索所有子目录。例如,file(GLOB files "src/*.cpp") 会搜索 src 目录下所有扩展名为 .cpp 的文件,但不会搜索 src 目录的子目录。
  • GLOB_RECURSE:会递归地搜索当前目录及其所有子目录,包括多级嵌套的子目录。例如,file(GLOB_RECURSE files "src/*.cpp") 会搜索 src 目录及其所有子目录下所有扩展名为 .cpp 的文件。
  • GLOB:适用于项目结构简单、文件分布较集中且不需要递归搜索的场景。
  • GLOB_RECURSE:适用于项目结构复杂、文件分布在多个子目录中,需要全面搜索的场景。

7.target_include_directories

向目标添加包含目录。用于为某个 目标(target) 添加头文件搜索路径,让编译器在编译该目标时知道去哪里找 .h 或 .hpp 文件。

target_include_directories(<target>[SYSTEM] [AFTER|BEFORE]<INTERFACE|PUBLIC|PRIVATE> [items...]
)
参数说明
<target>你要设置的目标,比如 MyAppMyLibrary
INTERFACE只对依赖该 target 的目标生效(自己不需要)
PUBLIC自己和依赖者都需要这个头文件路径
PRIVATE仅自己需要这个头文件路径
SYSTEM表示这是系统头文件路径,编译器不会警告其中的内容
AFTER / BEFORE控制添加顺序(极少使用)

练习示例

//hello.h
#ifndef HELLO_H
#define HELLO_H
void say_hello();
#endif //HELLO_H
//hello.cpp
#include <iostream>
#include "hello.h"void say_hello() {std::cout << "Hello from say_hello()!" << std::endl;
}
//main.cpp
#include "hello.h"int main() {say_hello();return 0;
}

CMakeList.txt

cmake_minimum_required(VERSION 3.10)
project(CodeGenDemo LANGUAGES CXX)# 创建可执行程序
add_executable(CodeGenDemosrc/main.cppsrc/hello.cpp
)# 添加头文件搜索路径
target_include_directories(CodeGenDemoPRIVATE ${CMAKE_SOURCE_DIR}/include
)

也可以用file进阶编写cmakeLists:

cmake_minimum_required(VERSION 3.14)
project(CodeGenDemo LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS"${CMAKE_SOURCE_DIR}/src/*.cpp""${CMAKE_SOURCE_DIR}/include/*.h"
)
add_executable(CodeGenDemo ${SOURCES})
target_include_directories(CodeGenDemo PRIVATE ${CMAKE_SOURCE_DIR}/include)
  • GLOB_RECURSE:会递归地搜索当前目录及其所有子目录,包括多级嵌套的子目录。
  • CONFIGURE_DEPENDS:如果文件系统发生了变化(新增或删除了文件),下次重新 cmake 配置时自动重新扫描这个 GLOB。没有这个选项的话,哪怕你新加了 .cpp 文件,CMake 也不会知道,除非你手动删掉 build/ 目录重新配置。
字符串含义
${CMAKE_SOURCE_DIR}当前项目的根目录(CMakeLists.txt 所在)
/src/*.cpp查找 src/ 目录下以及其子目录中所有 .cpp 文件
/include/*.h查找 include/ 目录下以及其子目录中所有 .h 文件

在这里插入图片描述


http://www.hkcw.cn/article/kEKZWxYxbZ.shtml

相关文章

基与OpenCV实现单目相机实时追踪对物体的测量算法(Android版)

本人原创转载请注明出处 前言 本算法是基于摄像头到测量物体的已知距离和摄像头像素焦距的前提下测量物体的宽高&#xff0c;并根据参照物的实际尺寸测量其他物体。 效果图 准备环境 1.首先硬件你要有一个摄像头&#xff0c;最好是USB即插即用免驱的 2.我使用的是12寸的安…

【计算机视觉】单目深度估计模型-Depth Anything-V2

概述 本篇将简单介绍Depth Anything V2单目深度估计模型&#xff0c;该模型旨在解决现有的深度估计模型在处理复杂场景、透明或反射物体时的性能限制。与前一代模型相比&#xff0c;V2版本通过采用合成图像训练、增加教师模型容量&#xff0c;并利用大规模伪标签现实数据进行学…

常见离线语音识别模块功能说明——天问ASR;机芯智能;海凌科;轻语音

本文章从开发方式及功能等方面上进行说明&#xff0c;便于开发者进行选择与开发。 本文章依据截至2024年8月1日各网站资料进行整理编写。 总结&#xff1a; 开发方式上&#xff1a; 天文ASR 有着最灵活的开发方式&#xff0c;可完全按照程序员意愿进行开发&#xff0c;同时有…

Whisper.cpp + GPU 加速全攻略:Mac M 芯片高效转录音频教程

内容预告 本文将手把手教你如何利用 GPU 加速&#xff0c;在 Mac M 芯片上使用 Whisper 进行音频转文字&#xff0c;大幅提升转录效率。 本教程涵盖&#xff1a; Whisper.cpp 简介&#xff1a;为什么它适用于本地语音转写&#xff1f;Mac M 芯片的 GPU 加速&#xff1a;如何…

ROS2 与机器人视觉入门教程(ROS2 OpenCV)

系列文章目录 目录 系列文章目录 前言 一、 1.1 先决条件 1.1.1 安装 0. 安装要求 1. 安装 ROS2&#xff1a; 2. cv_bridge 1.2 获取机器人视觉库简介&#xff1a; 1.2.1 克隆该资源库 1.2.2 下载附加数据 1.2.3 编译代码 1.3 测试代码 二、ROS2 中的图像发布者…

计算机视觉:扩散模型(Diffusion Models)在图像生成中的突破

计算机视觉:扩散模型(Diffusion Models)在图像生成中的突破 一、前言二、扩散模型基础概念​2.1 马尔可夫链(Markov Chain)​2.2 扩散过程(Diffusion Process)​2.3 逆扩散过程(Reverse Diffusion Process)​三、扩散模型在图像生成中的原理​3.1 训练阶段​3.2 推理阶…

深入了解视频质量诊断的关键技术要点

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;视频质量诊断是IT行业中的关键任务&#xff0c;它包括多个领域的专业知识&#xff0c;用于确保视频内容的高质量呈现。本文将详细解析与视频质量诊断相关的各个技术要点&#xff0c;包括视频编码技术、分辨率和…

高效降噪不求人!精选6款音频降噪免费软件助你一键消噪

你是否也常常被音频中的噪音困扰&#xff1f;环境杂音、设备电流声、甚至呼吸声&#xff0c;都可能让精心录制的内容大打折扣。 本文从百款工具中实测筛选出6款还不错的会议录音降噪处理工具。无论你是剪辑小白还是职业后期&#xff0c;3分钟快速匹配你的降噪刚需&#xff01;…

深度学习目标检测构建基于YOLOv8的人体动作识别系统,如何使系统能够通过GUI界面支持图片、视频和摄像头输入,来识别人体动作站立,行走,摔倒,弯腰,坐立进行检测

深度学习目标检测构建基于YOLOv8的人体动作识别系统&#xff0c;如何使系统能够通过GUI界面支持图片、视频和摄像头输入&#xff0c;来识别人体动作站立&#xff0c;行走&#xff0c;摔倒&#xff0c;弯腰&#xff0c;坐立进行检测 文章目录 1. 环境配置2. 数据准备与模型训练…

猫粮哪个牌子质量好性价比高?安全猫粮选购推荐

从开始养猫到现在也算是有10年的铲屎年龄了&#xff0c;先后经历了膨化粮、烘焙猫粮以及猫罐头的喂养时期。结果这么多年过去了&#xff0c;现在喂的最多的还是烘焙猫粮&#xff0c;低温工艺留住大部分营养&#xff0c;不会让猫咪黑下巴&#xff0c;适口性也更好&#xff0c;性…

重塑在线软件开发新纪元:集成高效安全特性,深度解析与评估会员与促销管理系统的系统架构设计

案例 阅读以下关于软件架构设计与评估的叙述&#xff0c;回答问题1和问题2。 【题目】 某电子商务公司拟升级其会员与促销管理系统&#xff0c;向用户提供个性化服务&#xff0c;提高用户的粘性。在项目立项之初&#xff0c;公司领导层一致认为本次升级的主要目标是提升会员管…

【Linux探索学习】第三十弹——线程互斥与同步(上):深入理解线程保证安全的机制

Linux学习笔记&#xff1a; https://blog.csdn.net/2301_80220607/category_12805278.html?spm1001.2014.3001.5482 前言&#xff1a; 在上篇我们已经学习了关于线程的大部分知识&#xff0c;包括线程概念和线程控制等内容&#xff0c;今天我们来学习一下使用线程要做到的很…

飞牛的ipv6已动态解析到阿里云,访问显示不安全?教你绑定免费SSL证书

前言 最近有很多小伙伴陆续通过DDNS-GO做好了飞牛的ipv6动态解析了&#xff0c;如果还没有弄&#xff0c;又不知道文章在哪&#xff0c;可以点击下方这篇教程&#xff1a; 飞牛NAS有IPV6&#xff0c;想用DDNS-GO动态解析到域名&#xff1f;这简单了&#xff01; 很多搞定了的…

银河麒麟桌面操作系统V10 SP1:取消安装应用的安全授权认证

银河麒麟桌面操作系统V10 SP1&#xff1a;取消安装应用的安全授权认证 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 使用银河麒麟V10 SP1安装应用时&#xff0c;若频繁遇到安全授权认证提示&#xff0c;可按以下步骤设置&#xff1a; 打开…

最新Spring Security实战教程(十二)CORS安全配置 - 跨域请求的安全边界设定

&#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Micro麦可乐的博客 &#x1f425;《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程&#xff0c;入门到实战 &#x1f33a;《RabbitMQ》…

解决Windows安全中心显示空白页面

1、电脑重装系统后&#xff0c;发现原本一些软件打不开了&#xff0c;电脑莫名认为有病毒&#xff0c;自动删除插件。附图。 2、第一反应是电脑防火墙的原因&#xff0c;默认威胁防护识别到了病毒软件&#xff0c;自动删除。在开始屏幕搜Windows安全中心&#xff0c;打开之后发…

Python全流程开发实战:基于IMAP协议安全下载个人Gmail邮箱内所有PDF附件

文章目录 一、需求分析与安全前置&#xff1a;为什么需要专用工具&#xff1f;1.1 痛点场景1.2 技术方案选择 二、准备工作&#xff1a;Gmail账号安全配置与环境搭建2.1 开启两步验证&#xff08;必做&#xff01;&#xff09;2.2 创建应用专用密码&#xff08;替代普通密码&am…

【网络安全论文】筑牢局域网安全防线:策略、技术与实战分析

【网络安全论文】筑牢局域网安全防线:策略、技术与实战分析 简述一、引言1.1 研究背景1.2 研究目的与意义1.3 国内外研究现状1.4 研究方法与创新点二、局域网网络安全基础理论2.1 局域网概述2.1.1 局域网的定义与特点2.1.2 局域网的常见拓扑结构2.2 网络安全基本概念2.2.1 网络…

评论员点评郑钦文无缘四强 体能优势未转化

北京时间6月3日,在2025年法网女单1/4决赛中,郑钦文以0-2的成绩不敌萨巴伦卡,遗憾未能晋级四强。赛后,资深评论员许旸对比赛进行了点评。许旸表示,这场比赛让人感到不甘心,郑钦文未能将体能优势转化为战斗力。特别是在第二盘,不仅体能没有得到充分利用,技术上的发挥也非…

【吾爱】逆向实战crackme160破解记录(一)

前言 最近想拿吾爱上的crackme程序练练手&#xff0c;发现论坛上已经有pk8900总结好的160个crackme&#xff0c;非常方便&#xff0c;而且有很多厉害的前辈已经写好经验贴和方法了&#xff0c;我这里只是做一下自己练习的记录&#xff0c;欢迎讨论学习&#xff0c;感谢吾爱论坛…