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

[C++][CMake][嵌套的CMake]详细讲解

目录

  • 0.前言 & 准备
  • 1.节点关系
  • 2.添加子目录
  • 3.解决问题
    • 1.根目录
    • 2.calc目录
    • 3.sort目录
    • 4.calc_test目录
    • 5.sort_test
  • 4.注意


0.前言 & 准备

  • 如果项目很大,或者项目中有很多的源码目录,在通过CMake管理项目的时候如果只使用一个CMakeLists.txt,那么这个文件相对会比较复杂
  • 有一种化繁为简的方式就是给每个源码目录都添加一个CMakeLists.txt文件(头文件目录不需要),这样每个文件都不会太复杂,而且更灵活,更容易维护
  • 以下目录结构为例
    .
    ├── CMakeLists.txt
    ├── bin
    ├── build
    ├── calc
    │   ├── CMakeLists.txt
    │   ├── add.c
    │   ├── div.c
    │   ├── mult.c
    │   └── sub.c
    ├── calc_test
    │   ├── CMakeLists.txt
    │   └── calc_main.c
    ├── include
    │   ├── calc.h
    │   └── sort.h
    ├── lib
    ├── sort
    │   ├── CMakeLists.txt
    │   └── sort.c
    └── sort_test├── CMakeLists.txt└── sort_main.c
    

1.节点关系

  • Linux的目录是树状结构,所以嵌套的CMake也是一个树状结构,最顶层的CMakeLists.txt根节点,其次都是子节点
  • 因此,需要了解一些关于CMakeLists.txt文件变量作用域的一些信息:
    • 根节点CMakeLists.txt中的变量全局有效
    • 父节点CMakeLists.txt中的变量可以在子节点中使用
    • 子节点CMakeLists.txt中的变量只能在当前结点中使用

2.添加子目录

  • CMake中建立父子节点关系
    add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
    
  • 参数
    • source_dir:指定了CMakeLists.txt源文件和代码文件的位置,其实就是指定子目录
    • binary_dir:制定了输出文件的路径,一般不需要指定,忽略即可
    • EXCLUDE_FROM_ALL:在子路径下的目标默认不会被包含到父路径的ALL目标里,并且也会被排除在IDE工程文件之外。用户必须显式构建在子路径下的目标

3.解决问题

1.根目录

  • 根目录中的CMakeLists.txt文件
    cmake_minimum_required(VERSION 3.15)
    project(mult_test)# 设置静态库生成路径
    set(LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
    # 测试程序生成的路径
    set(EXEC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin)
    # 头文件目录
    set(HEAD_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include)# 静态库名字
    set(CALC_LIB calc)
    set(SORT_LIB sort)# 可执行程序的名字
    set(APP_NAME_1 calc_test)
    set(APP_NAME_2 sort_test)# 给当前结点添加子目录目录
    add_subdirectory(calc)
    add_subdirectory(sort)
    add_subdirectory(sort_test)
    add_subdirectory(calc_test)
    
  • 在根节点对应的文件中主要做了两件事情:定义全局变量和添加子目录
    • 定义的全局变量主要是给子节点使用,目的是为了提高子节点中的CMakeLists.txt文件的可读性和可维护性,避免冗余并降低出错的概率
    • 一共添加了四个子目录,每个子目录中都有一个CMakeLists.txt文件,这样它们的父子关系就被确定下来了

2.calc目录

  • calc目录中的CMakeLists.txt文件
    cmake_minimum_required(VERSION 3.15)
    project(calc)# 搜索源文件
    aux_source_directory(./ SRC)
    include_directories(${HEAD_PATH})set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_PATH})
    add_library(${CALC_LIB} STATIC ${SRC})
    

3.sort目录

  • sort目录中的CMakeLists.txt文件
    cmake_minimum_required(VERSION 3.15)
    project(sort)# 搜索源文件
    aux_source_directory(./ SRC)
    include_directories(${HEAD_PATH})set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_PATH})
    add_library(${SORT_LIB} STATIC ${SRC})
    

4.calc_test目录

  • calc_test目录中的CMakeLists.txt文件
    cmake_minimum_required(VERSION 3.15)
    project(calc_test)# 搜索源文件
    aux_source_directory(./ SRC)
    include_directories(${HEAD_PATH})link_directories(${LIB_PATH})
    link_libraries(${CALC_LIB})set(EXECUTABLE_OUTPUT_PATH ${EXEC_PATH})
    add_executable(${APP_NAME_1} ${SRC})
    

5.sort_test

  • sort_test目录中的CMakeLists.txt文件
    cmake_minimum_required(VERSION 3.15)
    project(calc_test)# 搜索源文件
    aux_source_directory(./ SRC)
    include_directories(${HEAD_PATH})link_directories(${LIB_PATH})
    link_libraries(${SORT_LIB})set(EXECUTABLE_OUTPUT_PATH ${EXEC_PATH})
    add_executable(${APP_NAME_2} ${SRC})
    

4.注意

  • 在实际开发中,一个大型的 CMake 项目中,project() 命令通常只在最外层的 CMakeLists.txt 文件中出现一次
  • 顶层 CMakeLists.txt 文件是项目的入口点,在这里应该定义项目名称、全局设置和添加子目录
    cmake_minimum_required(VERSION 3.10)
    project(MyLargeProject)# 设置全局属性
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED True)# 添加子目录
    add_subdirectory(src)
    add_subdirectory(lib)
    
  • 在子目录的 CMakeLists.txt 文件中,通常不需要重复使用 project() 命令,相反,应该专注于定义目标(例如:库或可执行文件)、设置目标属性和包含路径
    # 添加库文件
    add_library(MyLibrary mylibrary.cpp)
    # 设置包含路径
    target_include_directories(MyLibrary PUBLIC ${CMAKE_SOURCE_DIR}/include)
    

相关文章:

[C++][CMake][嵌套的CMake]详细讲解

目录 0.前言 & 准备1.节点关系2.添加子目录3.解决问题1.根目录2.calc目录3.sort目录4.calc_test目录5.sort_test 4.注意 0.前言 & 准备 如果项目很大,或者项目中有很多的源码目录,在通过CMake管理项目的时候如果只使用一个CMakeLists.txt&#…...

尚品汇-(十三)

&#xff08;1&#xff09;查询sku列表 在ManageService 中添加 /*** SKU分页列表* param pageParam* return*/ IPage<SkuInfo> getPage(Page<SkuInfo> pageParam);接口实现类 Override public IPage<SkuInfo> getPage(Page<SkuInfo> pageParam) {Qu…...

python小练习04

三国演义词频统计与词云图绘制 import jieba import wordcloud def analysis():txt open("三国演义.txt",r,encodingutf-8).read()words jieba.lcut(txt)#精确模式counts {}for word in words:if len(word) 1:continueelif word "诸葛亮" or word &q…...

小试牛刀-Solana合约账户详解

目录 一.Solana 三.账户详解 3.1 程序账户 3.2 系统所有账户 3.3 程序派生账户(PDA) 3.4 Token账户 四、相关学习文档 五、在线编辑器 Welcome to Code Blocks blog 本篇文章主要介绍了 [Solana合约账户详解] ❤博主广交技术好友&#xff0c;喜欢文章的可以关注一下❤ …...

Spring Boot+Vue项目从零入手

Spring BootVue项目从零入手 一、前期准备 在搭建spring bootvue项目前&#xff0c;我们首先要准备好开发环境&#xff0c;所需相关环境和软件如下&#xff1a; 1、node.js 检测安装成功的方法&#xff1a;node -v 2、vue 检测安装成功的方法&#xff1a;vue -V 3、Visu…...

Vue+Xterm.js+WebSocket+JSch实现Web Shell终端

一、需求 在系统中使用Web Shell连接集群的登录节点 二、实现 前端使用Vue&#xff0c;WebSocket实现前后端通信&#xff0c;后端使用JSch ssh通讯包。 1. 前端核心代码 <template><div class"shell-container"><div id"shell"/>&l…...

用 adb 来模拟手机插上电源和拔掉电源的情形

实用的 ADB 命令 要模拟手机从 USB 充电器上拔掉的情形&#xff0c;你可以使用&#xff1a; adb shell dumpsys battery set usb 0或者&#xff0c;如果你使用的是 Android 6.0 或更高版本的设备&#xff0c;你可以使用&#xff1a; adb shell dumpsys battery unplug要重新…...

【SPIE独立出版】第四届智能交通系统与智慧城市国际学术会议(ITSSC 2024)

第四届智能交通系统与智慧城市国际学术会议&#xff08;ITSSC 2024&#xff09;将于2024年8月23-25日在中国西安举行。本次会议主要围绕智能交通、交通新能源、无人驾驶、智慧城市、智能家居、智能生活等研究领域展开讨论&#xff0c; 旨在为该研究领域的专家学者们提供一个分享…...

【Unity数据交互】如何Unity中读取Ecxel中的数据

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 专栏交流&#x1f9e7;&…...

基于深度学习LightWeight的人体姿态检测跌倒系统源码

一. LightWeight概述 light weight openpose是openpose的简化版本&#xff0c;使用了openpose的大体流程。 Light weight openpose和openpose的区别是&#xff1a; a 前者使用的是Mobilenet V1&#xff08;到conv5_5&#xff09;&#xff0c;后者使用的是Vgg19&#xff08;前10…...

SpringBoot 生产实践:没有父 starter 的打包问题

文章目录 前言一、搜索引擎二、Chat GPT三、官方文档四、小结推荐阅读 前言 今天刚准备写点文章&#xff0c;需要 SpringBoot 项目来演示效果。一时心血来潮&#xff0c;没有采用传统的方式&#xff08;即通过引入 spring-boot-starter-parent 父工程的方式&#xff09;。 &l…...

IDEA配Git

目录 前言 1.创建Git仓库&#xff0c;获得可提交渠道 2.选择本地提交的项目名 3.配置远程仓库的地址 4.新增远程仓库地址 5.开始进行commit操作 6.push由于邮箱问题被拒绝的解决方法&#xff1a; 后记 前言 以下操作都是基于你已经下载了Git的前提下进行的&#xff0c…...

51单片机STC89C52RC——14.1 直流电机调速

目录 目的/效果 1&#xff1a;电机转速同步LED呼吸灯 2 通过独立按键 控制直流电机转速。 一&#xff0c;STC单片机模块 二&#xff0c;直流电机 2.1 简介 2.2 驱动电路 2.2.1 大功率器件直接驱动 2.2.2 H桥驱动 正转 反转 2.2.3 ULN2003D 引脚、电路 2.3 PWM&…...

AI对于高考和IT行业的深远影响

目录 AI对IT行业的冲击及深远影响1. 工作自动化2. 新的就业机会3. 行业融合4. 技术升级和创新5. 数据的重要性 IT行业的冬天要持续多久&#xff1f;大学的软件开发类专业是否还值得报考&#xff1f;其他问题IT行业是否都是加班严重&#xff1f;35岁后就业困难是否普遍现象&…...

C语言下的文件详解

主要内容 文件概述文件指针文件的打开与关闭文件的读写 文件 把输入和输出的数据以文件的形式保存在计算机的外存储器上&#xff0c;可以确保数据能随时使用&#xff0c;避免反复输入和读取数据 文件概述 文件是指一组相关数据的有序集合 文件是存储数据的基本单位&#…...

Oracle PL / SQL块结构

在PL / SQL中&#xff0c;最小的有意义的代码分组被称为块。 块代码为变量声明和异常处理提供执行和作用域边界。 PL / SQL允许您创建匿名块和命名块。 命名块可以是包&#xff0c;过程&#xff0c;函数&#xff0c;触发器或对象类型。 PL / SQL是SQL的过程语言扩展&#x…...

MySQL的安装和启动

安装 版本 1&#xff0c;社区版&#xff1a;免费&#xff0c;不提供任何技术支持 2&#xff0c;商业版&#xff1a;可以试用30天&#xff0c;官方提供技术支持下载 1&#xff0c;下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 2&#xff0c;安装&#xff1a;傻…...

Prometheus概述

1.什么是prometheus Prometheus 是一个开源的服务监控系统和时序数据库&#xff0c;其提供了通用的数据模型和快捷数据采集、存储和查询接口。它的核心组件Prometheus server会定期从静态配置的监控目标或者基于服务发现自动配置的自标中进行拉取数据&#xff0c;当新拉取到的…...

【SQL】什么是最左前缀原则/最左匹配原则

最左前缀原则&#xff08;或最左匹配原则&#xff09;是关系型数据库在使用复合索引时遵循的一条重要规则。该原则指的是&#xff0c;当查询条件使用复合索引时&#xff0c;查询优化器会首先使用索引的最左边的列&#xff0c;依次向右匹配&#xff0c;直到不再满足查询条件为止…...

java项目配置logback日志

在resource目录下添加logback配置文件 <?xml version"1.0" encoding"UTF-8"?> <configuration scan"true" scanPeriod"60 seconds" debug"false"><property name"log_dir" value"/APL/log…...

Python入门 2024/7/6

目录 元组的定义和操作 字符串的定义和操作 字符串 字符串的替换 字符串的分割 字符串的规整操作&#xff08;去除前后空格&#xff09; 字符串的规整操作&#xff08;去掉前后指定字符串&#xff09; 操作 字符串的替换 字符串的分割 字符串的规整操作 统计字符串的…...

ChatGPT4深度解析:探索智能对话新境界

大模型chatgpt4分析功能初探 目录 1、探测目的 2、目标变量分析 3、特征缺失率处理 4、特征描述性分析 5、异常值分析 6、相关性分析 7、高阶特征挖掘 1、探测目的 1、分析chat4的数据分析能力&#xff0c;提高部门人效 2、给数据挖掘提供思路 3、原始数据&#xf…...

触底加载的两种思路(以vue3前端和nodejs后端为例)

一:首先,nodejs后端的代码都是一样的. 需要前端返回page参数,然后nodejs逻辑进行处理,截取页数和每页条数和总条数, 总条数用来作为判断是否有数据的条件,也可以不用,注意看下文 一:不用获取容器高度的. pinia中进行的axios请求处理 在vue文件中进行pinia中数据的导入,继续进…...

tobias实现支付宝支付

tobias是一个为支付宝支付SDK做的Flutter插件。 如何使用 你需要在pubspec.yaml中配置url_scheme。url_scheme是一个独特的字符串&#xff0c;用来重新启动你的app&#xff0c;但是请注意字符串“_”是不合法的。 在iOS端&#xff0c;你还需要配置并传入一个universal link。…...

【音视频 | RTSP】RTSP协议详解 及 抓包例子解析(详细而不赘述)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

SQL Server 2022 中的 Tempdb 性能改进非常显著

无论是在我的会话中还是在我写的博客中&#xff0c;Tempdb 始终是我的话题。然而&#xff0c;当谈到 SQL Server 2022 中引入的重大性能变化时&#xff0c;我从未如此兴奋过。他们解决了我们最大的性能瓶颈之一&#xff0c;即系统页面闩锁并发。 在 SQL Server 2019 中&#x…...

C++ Lambda表达式第二篇, Lambda表达式

C Lambda表达式 Lambda 捕获含有模板参数的Lambda表达式无模板参数的Lambda表达式 Lambda 捕获 captures是零个或多个捕获的逗号分隔列表&#xff0c;可以选择以capture-default开头。捕获列表定义可从 lambda 函数体内访问的外部变量。唯一的捕获默认值是 &&#xff0c;…...

Linux系统的介绍和常用命令

文章目录 介绍常用命令文件和目录操作文件内容操作系统管理命令网络命令 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏&#xff1a;Liunx系统 ✨文章内容&#xff1a;Liunx系统介绍 &…...

IDEA安装IDE Eval Reset插件,30天自动续期,无限激活

第一步&#xff1a; 下载idea 注意&#xff1a;版本要是2021.2.2以下 第二步&#xff1a;快捷键CtrlAlts打开设置 第三步&#xff1a;打开下图中蓝色按钮 第四步&#xff1a;点击弹窗的 “” &#xff0c;并输入 plugins.zhile.io 点击 “ok” 第五步&#xff1a;搜索IDE Ea…...

【C++】初步认识C++

1. 初识C1.1 C概念相关1.2 C发展史及其重要性1.2.1 发展史1.2.2 重要性 2. C关键字3. 命名空间4. 输入和输出 个人主页&#xff1a;C_GUIQU 归属专栏&#xff1a;【C学习】 1. 初识C 1.1 C概念相关 C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。 【来源】…...