详解CMakeLists.txt

在前一篇文章 esp32 初识 cmake 构建工具 中,已经用"hellow world"程序介绍了cmake最基本的用法,今天详细讲解CMakeLists.txt文件。

CMakeLists.txt

CMakeLists.txt文件是CMake构建工具的核心配置文件。它包含了构建项目所需的一系列指令和参数,CMake会根据这些信息生成相应的构建文件。CMakeLists.txt文件通常位于项目的顶层目录,并可在子目录中包含其他的CMakeLists.txt文件以组织复杂项目的构建过程。

CMakeLists.txt文件包含以下几类指令:

  1. 项目设置:定义项目名称、版本、目标平台等信息
  2. 指定源文件和头文件:指定项目中要编译的源文件和头文件
  3. 添加子目录:将子目录加入构建过程,子目录中可以包含其它的CMakeLists.txt文件
  4. 设置编译器和链接器选项:例如,指定编译标志、链接库等
  5. 添加可执行文件和库:指定要生成的可执行文件、静态库或动态库
  6. 添加依赖和链接库:指定项目需要的外部库和头文件路径

以下是一个简单的C语言项目的CMakeLists.txt文件示例:

# 设置CMake的最低版本要求
cmake_minimum_required(VERSION 3.10)# 设置项目名称和版本
project(MyProject VERSION 1.0)# 设置C标准
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED True)# 添加子目录,子目录下应包含自己的CMakeLists.txt文件
add_subdirectory(src)# 指定源文件和头文件
set(SOURCES main.c)
set(HEADERS include/myheader.h)# 添加可执行文件
add_executable(MyProject ${SOURCES} ${HEADERS})# 添加库
add_library(MyLibrary STATIC src/mylibrary.c)# 添加库的头文件路径
target_include_directories(MyProject PUBLIC include)# 添加依赖库
target_link_libraries(MyProject PRIVATE MyLibrary)

这个示例中,我们创建了一个基于C语言的名为"MyProject"的项目,设置了C11标准,并添加了一个名为"MyLibrary"的静态库。我们还指定了源文件、头文件以及库的依赖关系。

CMakeLists.txt文件包含以下几种主要语法:

  1. 注释:以#开头的行表示注释。

    示例:

    # 这是一条注释
    
  2. 变量:使用set()函数设置变量值,通过${}使用变量值。

    示例:

    set(SOURCE_FILES main.cpp)
    add_executable(my_app ${SOURCE_FILES})
    
  3. 条件控制:使用if(), elseif(), else()endif()来进行条件控制。

    示例:

    if(WIN32)set(PLATFORM "Windows")
    elseif(APPLE)set(PLATFORM "macOS")
    elseif(UNIX)set(PLATFORM "Linux")
    else()message(FATAL_ERROR "Unsupported platform")
    endif()
    
  4. 循环:使用foreach() 相关语法进行循环。

    示例:

    set(SOURCE_FILES main.cpp file1.cpp file2.cpp)
    foreach(file ${SOURCE_FILES})message("source file: ${file}")
    endforeach()
    
  5. 函数和宏:使用function()endfunction()定义函数,使用macro()endmacro()定义宏。

    示例:

    function(print_files files)foreach(file ${files})message("file: ${file}")endforeach()
    endfunction()macro(my_macro arg1 arg2)message("arg1 is ${arg1}, arg2 is ${arg2}")
    endmacro()set(SOURCE_FILES main.cpp file1.cpp file2.cpp)
    print_files(${SOURCE_FILES})
    my_macro("Hello" "World")
    

示例

下面用一段示例来综合下上面的语法:

# 设置CMake最低版本要求
cmake_minimum_required(VERSION 3.0)# 创建项目hello_world
project(hello_world)# 设置C++11标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 检测平台类型
if(WIN32)set(PLATFORM "Windows")
elseif(APPLE)set(PLATFORM "macOS")
elseif(UNIX)set(PLATFORM "Linux")
else()# 如果平台不支持,给出错误提示message(FATAL_ERROR "Unsupported platform")
endif()# 定义一个函数print_files,用于打印文件列表
function(print_files)foreach(file ${ARGN})message("file: ${file}")endforeach()
endfunction()# 定义一个宏my_macro,用于打印平台和处理器信息
macro(my_macro arg1 arg2)message("PLATFORM is ${arg1}, CMAKE_HOST_SYSTEM_PROCESSOR is ${arg2}")
endmacro()# 设置文件列表
set(files main.cpp file1.cpp file2.cpp)# 调用print_files函数,打印文件列表
print_files(${files})# 调用my_macro宏,打印平台和处理器信息
my_macro(${PLATFORM} ${CMAKE_HOST_SYSTEM_PROCESSOR})# 添加可执行文件hello_world
add_executable(hello_world main.cpp)

这是一个基本的CMakeLists.txt文件,主要包含以下内容:

  1. 设置CMake的最低版本要求为3.0。
  2. 创建一个名为hello_world的项目。
  3. 设定C++11标准。
  4. 检测当前平台类型(Windows、macOS或Linux),并将其存储在变量PLATFORM中。
  5. 定义一个名为print_files的函数,用于打印文件列表。
  6. 定义一个名为my_macro的宏,用于打印平台和处理器信息。
  7. 设置一个文件列表,并使用print_files函数打印出来。
  8. 调用my_macro宏,打印平台和处理器信息。
  9. 添加一个名为hello_world的可执行文件,其源代码为main.cpp。

运行结果:

esp-test\hello\build via △ v3.24.3 
❯ cmake ..
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19045.
file: main.cpp
file: file1.cpp
file: file2.cpp
PLATFORM is Windows, CMAKE_HOST_SYSTEM_PROCESSOR is AMD64
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/yp.wang/Desktop/esp-test/hello/build

虽然基本语法并不复杂,但组合使用也是变化繁多,再加上还有各种内置变量,实际大型项目中的CMakeLists.txt可能非常复杂,需要持续认真学习和积累。好在cmake语法相对简单,比较接近自然语言,所以实际读起来还是很容易理解的。

公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top

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

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

相关文章

20230724----重返学习-vue3知乎日报项目实战

day-119-one-hundred-and-nineteen-20230724-vue3知乎日报项目实战 vue3项目实战-知乎日报 主要问题 pinia 和 vuex4 的区别 vue/cli和vite的区别 vue/cli脚手架的底层核心是webpack。vite脚手架: 开发环境:基于ESModule模块规范处理的生产环境&#…

PHPWord 实现合并多个word文件

PHPWord 本来想着当调包侠呢,结果翻了一遍文档,没有这种操作支持,阿这😂 GPT 不出意外的一顿胡扯,给👨‍🦳气的要中风啦 思路 word 也就是docx结尾的文件本质上就是xml字符串, …

为什么很多程序员不用switch,而是大量 的if......else if?

不会吧还有人用if else和switch case?三目运算符? 不会吧? 不会吧?大佬都是全都不用的!以JAVA为例 条件判断语句的四种写法,茴字的四种写法大家不会不知道吧 1.正常人写法: private static …

Linux中断(tasklet,工作队列,内核线程的使用)

文章目录 前言一、tasklet二、工作队列三、内核线程总结 前言 本篇文章来讲解在Linux中tasklet,工作队列,内核线程的使用。 一、tasklet tasklet在内核里面其实就是下面这样的一个结构体: struct tasklet_struct {struct tasklet_struct *next;unsigned long st…

使用的华为云RDS数据库不小心把数据删了

目录 前言恢复qp文件帮助文档表级时间点恢复删除数据的时候要注意 前言 华为云查数据的时候前面是有个序号的,删除数据的时候不小心把序号看成id了,导致误删数据。 注:图片如果看不清楚可以点击放大观看! 恢复qp文件 华为云每天…

2023最新软件测试面试题(带答案)

1. 请自我介绍一下(需简单清楚的表述自已的基本情况,在这过程中要展现出自信,对工作有激情,上进,好学) 面试官您好,我叫###,今年26岁,来自江西九江,就读专业是电子商务,毕…

机器学习之主成分分析(Principal Component Analysis)

1 主成分分析介绍 1.1 什么是主成分分析 主成分分析(Principal Component Analysis)简称PCA,是一个非监督学习的机器学习算法,主要用于数据的降维,对于高维数据,通过降维,可以发现更便于人类理…

CVPR2023新作:pix2pix3D

Title: 3D-Aware Conditional Image SynthesisAffiliation: Carnegie Mellon University (卡内基梅隆大学)Authors: Kangle Deng, Gengshan Yang, Deva Ramanan, Jun-Yan ZhuKeywords: Image Synthesis, 3D-aware, Neural Radiance Fields, Interactive Editing, Conditional G…

Qt+GDAL开发笔记(一):在windows系统mingw32编译GDAL库、搭建开发环境和基础Demo

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/131931309 红胖子网络科技博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

驱动开发 day3 (模块化驱动启动led,蜂鸣器,风扇,震动马达)

模块化驱动启动led,蜂鸣器,风扇,震动马达并加上Makefile 封装模块化驱动,可自由安装卸载驱动,便于驱动更新(附图) 1.安装模块驱动同时初始化各个设备并使能 2.该驱动会自动创建驱动节点. 3.通过c函数程序输入控制各个设备 4.卸载模块驱动 //编译驱动…

K8s卷存储详解(一)

K8s卷存储详解(一) K8s 存储K8s卷分类K8s目前支持的卷类型 临时卷类型EmptyDirCSI 临时卷通用临时卷 K8s 存储 什么是卷?为什么要用卷? 我们知道K8s是基于容器,对各个Pod进行管理的。Pod是由容器构成的,我…

开发中遇到的 cookie 问题

1. cookie 无法跨域携带问题 尽管已经登录,但是请求接口返回状态码:202,msg: 未登录,如下图所示; 1.1 XMLHttpRequest.withCredentials未设置 如果需要跨域 AJAX 请求发送 Cookie,需要withCre…

使用wxPython和pillow开发拼图小游戏(四)

上一篇介绍了使用本地图片来初始化游戏的方法,通过前边三篇,该小游戏的主要内容差不多介绍完了,最后这一篇来介绍下游戏用时的计算、重置游戏和关闭窗口事件处理 游戏用时的计算 对于游戏用时的记录,看过前几篇的小伙伴可能也发现…

MATLAB实现图像处理:图像识别、去雨、去雾、去噪、去模糊等等(附上20个完整仿真源码)

图像处理是计算机视觉领域的重要研究方向,MATLAB是一种功能强大的数学计算软件,可以用于图像处理和分析。下面是一些简单的MATLAB图像处理代码示例,包括图像增强、边缘检测、形态学处理、特征提取等。 文章目录 1. 图像增强2. 边缘检测3. 形态…

【雕爷学编程】Arduino动手做(88)---水流量传感器模块3

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&am…

Springboot初识(二)

文章目录 前言一.Spring配置文件1.1 配置文件的作用1.2 配置文件的类型 二.properties配置⽂件说明2.1 基本语法2.2 读取配置文件 三.yml 配置⽂件说明2.1 基本语法2.2 读取配置文件2.3 注意事项 前言 上篇文章我们介绍了什么是SpringBoot和怎么去创建一个SpringBoot项目,现在…

Navicat连接服务器上Docker安装的mysql提示拒绝连接

一、报错的原因 英语翻译 --- ‘不允许主机连接到此MySQL服务器’ (意思是本地账号连接可以登录,但是远程登陆不行) 二、解决方法 ①进入docker中的mysql容器 docker exec -it mysql bash ②登陆mysql mysql -uroot -p ③执行以下步骤…

13.5.3 【Linux】PAM 模块设置语法

PAM 借由一个与程序相同文件名的配置文件来进行一连串的认证分析需求。我们同样以passwd 这个指令的调用 PAM 来说明好了。 当你执行 passwd 后,这支程序调用 PAM 的流程是: 1. 使用者开始执行 /usr/bin/passwd 这支程序,并输入密码&#xf…

Mongodb 多文档聚合操作处理方法(Map-reduce 函数)

聚合 聚合操作处理多个文档并返回计算结果。您可以使用聚合操作来: 将多个文档中的值分组在一起。 对分组数据执行操作以返回单个结果。 分析数据随时间的变化。 要执行聚合操作,您可以使用: 聚合管道 单一目的聚合方法 Map-reduce 函…

基于Java+SpringBoot+vue前后端分离在线商城系统设计实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…