[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)
    

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多表查询sql

概述:项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,分为三种: 一对多多对多一对一 一、多表关系 一对多 案例:部门与…

在CMD中创建虚拟环境并在VSCode中使用和管理

1. 使用Conda创建虚拟环境 在CMD或Anaconda Prompt中执行以下代码以创建一个新的虚拟环境: conda create -n my_env python 3.8 这样会创建一个名为 my_env 的环境,并在Anaconda环境目录下生成一个相应的文件夹,包含该虚拟环境所需的所有…

STM32-ADC+DMA

本内容基于江协科技STM32视频学习之后整理而得。 文章目录 1. ADC模拟-数字转换器1.1 ADC模拟-数字转换器1.2 逐次逼近型ADC1.3 ADC框图1.4 ADC基本结构1.5 输入通道1.6 规则组的转换模式1.6.1 单次转换,非扫描模式1.6.2 连续转换,非扫描模式1.6.3 单次…

时间、查找、打包、行过滤与指令的运行——linux指令学习(二)

前言:本节内容标题虽然为指令,但是并不只是讲指令, 更多的是和指令相关的一些原理性的东西。 如果友友只想要查一查某个指令的用法, 很抱歉, 本节不是那种带有字典性质的文章。但是如果友友是想要来学习的,…

如何确保 PostgreSQL 在高并发写操作场景下的数据完整性?

文章目录 一、理解数据完整性二、高并发写操作带来的挑战三、解决方案(一)使用合适的事务隔离级别(二)使用合适的锁机制(三)处理死锁(四)使用索引和约束(五)批…

系统学习ElastricSearch(一)

不知道大家在项目中是否使用过ElastricSearch?大家对它的了解又有多少呢?官网的定义:Elasticsearch是一个分布式、可扩展、近实时的搜索与数据分析引擎。今天我们就来揭开一下它的神秘面纱(以下简称ES)。 ES 是使用 J…

uniapp零基础入门Vue3组合式API语法版本开发咸虾米壁纸项目实战

嗨,大家好,我是爱搞知识的咸虾米。 今天给大家带来的是零基础入门uniapp,课程采用的是最新的Vue3组合式API版本,22年发布的uniappVue2版本获得了官方推荐,有很多同学等着我这个vue3版本的那,如果没有学过vu…

CH12_函数和事件

第12章:Javascript的函数和事件 本章目标 函数的概念掌握常用的系统函数掌握类型转换掌握Javascript的常用事件 课程回顾 Javascript中的循环有那些?Javascript中的各个循环特点是什么?Javascript中的各个循环语法分别是什么?…

网页封装APP:让您的网站变身移动应用

网页封装APP:让您的网站变身移动应用 随着移动设备的普及,越来越多的人开始使用移动设备浏览网站。但是,传统的网站设计并不适合移动设备的屏幕尺寸和交互方式,这导致了用户体验不佳和流失。 有没有办法让您的网站变身移动应用&…

【ROS2】初级:客户端-编写一个简单的服务和客户端(Python)

目标:使用 Python 创建并运行服务节点和客户端节点。 教程级别:初学者 时间:20 分钟 目录 背景 先决条件 任务 1. 创建一个包2. 编写服务节点3. 编写客户端节点4. 构建并运行 摘要 下一步 相关内容 背景 当节点通过服务进行通信时&#xff0c…

【项目日记(一)】梦幻笔耕-数据层实现

❣博主主页: 33的博客❣ ▶️文章专栏分类:项目日记◀️ 🚚我的代码仓库: 33的代码仓库🚚 🫵🫵🫵关注我带你了解更多项目内容 目录 1.前言2.后端模块3数据库设计4.mapper实现4.1UserInfoMapper4.2BlogMapper 5.总结 1.…

机器学习筑基篇,​Ubuntu 24.04 快速安装 PyCharm IDE 工具,无需激活!

[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ] Ubuntu 24.04 快速安装 PyCharm IDE 工具 描述:虽然在之前我们安装了VScode,但是其对于使用Python来写大型项目以及各类配置还是比较复杂的,所以这里我们还是推…

U盘非安全拔出后的格式化危机与数据拯救策略

在数字化时代,U盘作为便捷的数据携带工具,其重要性不言而喻。然而,许多用户在日常使用中往往忽视了安全退出的重要性,直接拔出U盘后再插入时可能会遭遇“需要格式化”的提示,这一状况不仅令人措手不及,更可…

YOLOv9报错:AttributeError: ‘list‘ object has no attribute ‘view‘

报错信息如下: red_distri, pred_scores torch.cat([xi.view(feats[0].shape[0], self.no, -1) for xi in feats], 2).split( AttributeError: ‘list’ object has no attribute ‘view’ 解决方法: 去yolov9/utils/loss_tal.py把167行代码更改&#…

Android最近任务显示的图片

Android最近任务显示的图片 1、TaskSnapshot截图1.1 snapshotTask1.2 drawAppThemeSnapshot 2、导航栏显示问题3、Recentan按键进入最近任务 1、TaskSnapshot截图 frameworks/base/services/core/java/com/android/server/wm/TaskSnapshotController.java frameworks/base/cor…

Blazor SPA 的本质是什么以及服务器端渲染如何与 Blazor 的新 Web 应用程序配合使用

Blazor 通常被称为单页应用程序 (SPA) 框架。当我第一次开始使用 Blazor 时,我对 SPA 的含义、组件如何为 SPA 架构做出贡献以及所有这些如何与交互性联系在一起感到困惑。 今天,我将解答大家可能关心的三个问题: 什么是 SPA?了…

Sentinel-1 Level 1数据处理的详细算法定义(一)

《Sentinel-1 Level 1数据处理的详细算法定义》文档定义和描述了Sentinel-1实现的Level 1处理算法和方程,以便生成Level 1产品。这些算法适用于Sentinel-1的Stripmap、Interferometric Wide-swath (IW)、Extra-wide-swath (EW)和Wave模式。 今天介绍的内容如下&…

14-42 剑和诗人16 - 如何从一个技术人员到CTO再到投资人的角色转变

​​​​​​ 我清楚地记得我的职业轨迹发生转变的那个关键时刻。当时,我正向整个执行领导团队和董事会成员介绍我们部门的技术路线图,感到说服这些有影响力的利益相关者资助一系列雄心勃勃的计划的压力。我知道他们的支持(和资金&#xff09…

英语学习交流小程序的设计

管理员账户功能包括:系统首页,个人中心,用户管理,每日打卡管理,备忘录管理,学习计划管理,学习资源管理,论坛交流 微信端账号功能包括:系统首页,学习资源&…

基于最大相邻夹角的边缘点提取(matlab)

1、背景介绍 边缘点是指点云数据中代表物体或场景几何形状突变的那些点。在三维点云中,边缘点通常标志着不同表面或物体的分界,或者是物体表面上的不规则性,如裂缝、棱角、突起等。点云边缘检测的作用非常重要,最常见是进行特征点…