Cmake基础(7)

这次是Cmake的重点,多项目

文章目录

  • add_subdirectory
    • get_filename_component
    • 变量作用域
      • 全局变量
      • 主目录定义变量可以在子目录访问到
      • 字目录定义PARENT_SCOPE变量可以在主目录访问到
  • 添加依赖项

其实我们在一个cmake中使用多个add_excuatable 和add_library就能有多个项目了。但是这样维护十分不方便。一般而言,一个项目一个cmake文件,并且放在一个独立的文件夹是常规做法。

add_subdirectory

add_subdirectory是cmake提供的函数,把其他目录下的cmake文件添加到此处。
add_subdirectory(subdirectory)
subdirectory 是相对于当前 CMakeLists.txt 文件的子目录路径。
.
.
add_subdirectory 是 CMake 中的一个命令,其语法如下:

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
  • source_dir:指定包含 CMakeLists.txt 文件的源代码目录。
  • binary_dir:可选参数,指定生成输出文件的二进制目录。如果未提供,CMake 将使用与源目录对应的二进制目录。
  • EXCLUDE_FROM_ALL:可选参数,如果存在,则将在默认构建目标中排除在子目录中生成的目标。
    EXCLUDE_FROM_ALL是make all的时候可以忽略这个文件,一般很少用。

binary_dir是用来存放cmake生成的文件

假如说我们有多个cmake文件,我们可以遍历:

# 当前cmake文件夹中的module文件夹下的所有的文件夹,存放在moduledirs 中
file(GLOB moduledirs "${CMAKE_SOURCE_DIR}/module/*")
# 遍历刚才的文件夹列表
foreach(dir in ${moduledirs})
# 如果文件夹下存在一个CMakeLists.txt文件if(EXISTS ${dir}/CMakeLists.txt)get_filename_component(MODULE ${dir} NAME)message("MODULE : " ${MODULE})add_subdirectory(${dir} ${CMAKE_SOURCE_DIR}/build/${MODULE})endif()
endforeach()

get_filename_component

是 CMake 中的一个命令,用于提取文件路径的不同部分。其语法如下:

get_filename_component(<variable> <filename> <component> [CACHE])
  • <variable>:指定一个变量来存储提取的组件的结果。
  • <filename>:指定要提取组件的文件路径。
  • <component>:指定要提取的组件,可以是以下之一:
    • DIRECTORY:目录部分。
    • NAME:文件名部分。
    • EXT:文件扩展名。
    • NAME_WE:文件名部分(不包含扩展名)。
  • [CACHE]:可选参数,如果存在,则将结果缓存,以便后续调用 get_filename_component 时直接使用缓存的值。

add_subdirectory 在 CMake 中用于将其他目录的 CMakeLists.txt 文件包含到当前项目中。关于变量的访问,有一些规则:

变量作用域

全局变量

PS E:\workspace\cmake_demo\simple_demo\build> cmake ..
-- Building for: Visual Studio 16 2019
-- ^^^^^^Compiler: MSVC
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^E:/workspace/cmake_demo/simple_demo/Lib/x64/Debug
MODULE : module1
-- ^^^^^^Compiler: MSVC
MODULE : module2
-- ^^^^^^Compiler: MSVC
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^E:/workspace/cmake_demo/simple_demo/Lib/x64/Debug
-- Configuring done (0.0s)
-- Generating done (0.1s)
-- Build files have been written to: E:/workspace/cmake_demo/simple_demo/build

子目录和主目录同时打印下面这个,打印出来是同样的结果。

message(STATUS ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG})

E:/workspace/cmake_demo/simple_demo/Lib/x64/Debug
E:/workspace/cmake_demo/simple_demo/Lib/x64/Debug
子目录打印

message(STATUS ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^${CMAKE_SOURCE_DIR}/Lib/${platform}/Debug)

结果还是E:/workspace/cmake_demo/simple_demo/Lib/x64/Debug说明子目录的CMAKE_SOURCE_DIR是主目录一致

在CMake中,CMAKE_SOURCE_DIR 是一个全局变量,代表顶层CMakeLists.txt所在的目录,不是当前CMakeLists.txt文件所在的目录。因此,无论在主目录还是在子目录中使用 CMAKE_SOURCE_DIR,都将得到同样的结果,即顶层CMakeLists.txt所在的目录。
如果你想要在子目录中获取当前CMakeLists.txt所在的目录,可以使用 CMAKE_CURRENT_SOURCE_DIR。这个变量表示当前处理的 CMakeLists.txt 文件所在的目录。

所以,在你的例子中,如果想在子目录中获取与子目录相关的路径,可以使用 CMAKE_CURRENT_SOURCE_DIR,而不是 CMAKE_SOURCE_DIR。例如:

message(STATUS "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ${CMAKE_CURRENT_SOURCE_DIR}/Lib/${platform}/Debug")

这样可以确保在子目录中获取到正确的路径。

主目录定义变量可以在子目录访问到

主目录添加 set(fock “fock”)
子目录可以打印出来 message(STATUS ^^^^^^^^^^${fock})
多层级的子目录也可以访问到,也就是多次执行add_subdirectory

字目录定义PARENT_SCOPE变量可以在主目录访问到

子目录设置变量 set(MY_VARIABLE “Hello” PARENT_SCOPE)
主目录可以打印出来
后加载的子目录可以把先加载的子目录中的PARENT_SCOPE变量打印出来:假如MY_VARIABLE 在module1中定义,module2后加载那么module2可以打印MY_VARIABLE 。

PARENT_SCOPE 只能穿透到上一层的作用域,即它将变量传递到调用 add_subdirectory 的上一层目录。如果有多层的 add_subdirectory,则需要多次使用 PARENT_SCOPE 才能传递到更上一层目录。

例如:

# CMakeLists.txt (Level 1)
set(MY_VARIABLE "Value" PARENT_SCOPE)
add_subdirectory(subdir)
# subdir/CMakeLists.txt (Level 2)
set(MY_VARIABLE "NewValue" PARENT_SCOPE)

在这个例子中,subdir/CMakeLists.txt 中的 MY_VARIABLE 通过 PARENT_SCOPE 被传递到 CMakeLists.txt (Level 1) 中,但如果存在更上一层的目录,你需要在更上一层再次使用 PARENT_SCOPE 才能传递到更上一层。

添加依赖项

# 设置依赖库
SET(Dependsmodule1)# 设置依赖关系和链接库
foreach(loop_var ${Depends})if(EXISTS ${PROJECT_SOURCE_DIR}/${loop_var})add_dependencies(${LIN_NAME} ${loop_var})endif()
# 顺势加载库SET(LINK_LIBRARY optimized ${PROJECT_SOURCE_DIR}/Lib/x64/Release/${loop_var}${CMAKE_RELEASE_POSTFIX}.lib debug ${PROJECT_SOURCE_DIR}/Lib/x64/Debug/${loop_var}${CMAKE_DEBUG_POSTFIX}.lib)target_link_libraries(${SAMPLE_NAME} PRIVATE ${LINK_LIBRARY})
endforeach()

两个子目录,一个是module1,一个是module2,module1先被add_subdirectory,module2即使还没有被add_subdirectory,module1也可以依赖于module2。

但是不要循环依赖

CMake Error: The inter-target dependency graph contains the following strongly connected component (cycle):"MYLIBADD" of type SHARED_LIBRARYdepends on "MYLIBSUB" (strong)"MYLIBSUB" of type SHARED_LIBRARYdepends on "MYLIBADD" (strong)
At least one of these targets is not a STATIC_LIBRARY.  Cyclic dependencies are allowed only among static libraries.

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

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

相关文章

电影小镇智慧旅游项目技术方案:PPT全文111页,附下载

关键词&#xff1a;智慧旅游项目平台&#xff0c;智慧文旅建设&#xff0c;智慧城市建设&#xff0c;智慧文旅解决方案&#xff0c;智慧旅游技术应用&#xff0c;智慧旅游典型方案&#xff0c;智慧旅游景区方案&#xff0c;智慧旅游发展规划 一、智慧旅游的起源 智慧地球是IB…

机器学习:增强式学习Reinforcement learning

收集有标签数据比较困难的时候同时也不知道什么答案是比较好的时候可以考虑使用强化学习通过互动&#xff0c;机器可以自己知道什么结果是好的&#xff0c;什么结果是坏的 Outline 什么是RL Action就是一个functionEnvironment就是告诉这个Action是好的还是坏的 例子 Space i…

算法专题二:滑动窗口

算法专题二&#xff1a;滑动窗口 一.长度最小的子数组&#xff1a;1.思路一&#xff1a;暴力解法2.思路二&#xff1a;滑动窗口双指针3.GIF题目解析&#xff1a;思路一&#xff1a;思路二&#xff1a; 二.无重复字符的最长子串&#xff1a;1.思路一&#xff1a;滑动窗口2.GIF题…

【selenium】自动化使用 chrome 的 user-data-dir

jwensh2023.12.18 文章目录 背景当前位置默认位置windowsMac OS XLinuxChrome操作系统AndroidiOS系统 覆盖用户数据目录命令行环境&#xff08;Linux&#xff09;编写 AppleScript 包装器 (Mac OS X) 用户缓存目录在 Mac OS X 和 iOS 上&#xff0c;用户缓存目录源自配置文件目…

Android-----AndroidManifests.xml 之meta-data

一、概念 meta-data&#xff1a;元数据、文件元数据。主要用来定义一些组件相关的配置值。 metadata是一组供父组件使用的名值对&#xff08;name-value pair&#xff09;&#xff0c;一个组件元素可以包含任意数量的meta-data子元素。这些子元素的值存放在一个 Bundle 对象中…

【具身智能评估9】Open X-Embodiment: Robotic Learning Datasets and RT-X Models

论文标题&#xff1a;Open X-Embodiment: Robotic Learning Datasets and RT-X Models 论文作者&#xff1a;– 论文原文&#xff1a;https://arxiv.org/abs/2310.08864 论文出处&#xff1a;– 论文被引&#xff1a;–&#xff08;12/18/2023&#xff09; 论文代码&#xff1a…

【数据库设计和SQL基础语法】--连接与联接--内连接和外连接的概念

一、引言 1.1 SQL连接的基本概念 SQL连接是一种在关系型数据库中使用的操作&#xff0c;用于将两个或多个表中的行关联起来。连接允许在查询中同时检索来自多个表的数据&#xff0c;通过共享一个或多个共同的列&#xff08;通常是主键或外键&#xff09;来建立关系。连接操作…

轻量封装WebGPU渲染系统示例<53>- 多盏灯灯光照在地面的效果

WebGPU实时渲染实现模拟多盏灯的灯光照在地面的效果灯光效果 。 当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/MultiLightsTest.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源…

2018年第七届数学建模国际赛小美赛B题世界杯足球赛的赛制安排解题全过程文档及程序

2018年第七届数学建模国际赛小美赛 B题 世界杯足球赛的赛制安排 原题再现&#xff1a; 有32支球队参加国际足联世界杯决赛阶段的比赛。但从2026年开始&#xff0c;球队的数量将增加到48支。由于时间有限&#xff0c;一支球队不能打太多比赛。因此&#xff0c;国际足联提议改变…

IDE:DevEco Studio

简介 DevEco Studio是华为为开发者提供的一款集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于开发鸿蒙操作系统&#xff08;HarmonyOS&#xff09;的应用程序。作为一款全场景分布式开发工具&#xff0c;DevEco Studio支持多端开发、调试和模拟&#xff0c;为开…

计网02-计算机网络参考模型

一、OSI七层参考模型 1、分层的思想 分层模型用于网络协议的设计方法&#xff0c;本质是将网络节点间复杂的通信问题分成若干简单的问题逐一解决&#xff0c;通过网络的层次去找问题&#xff0c;将复杂问题简单化。 2、OSI参考模型 由于早期计算机厂商使用的是私有的网络模…

View UI(iView) Upload 自定义多图上传列表提交

iView Upload 自定义多图上传列表提交 可以自由控制上传列表&#xff0c;完成各种业务逻辑&#xff0c;示例是一个照片墙&#xff0c;可以查看大图和删除。 设置属性 show-upload-list 为 false&#xff0c;可以不显示默认的上传列表。设置属性 default-file-list 设置默认已…

【PHP入门】2.1-运算符

-运算符- 运算符&#xff1a;operator&#xff0c;是一种将数据进行运算的特殊符号&#xff0c;在PHP中一共有十种运算符之多。 2.1.1赋值运算符 赋值运算&#xff1a;符号是“”&#xff0c;表示将右边的结果&#xff08;可以是变量、数据、常量和其它运算出来的结果&#…

scroll-behavior属性使用方法

定义和用法&#xff1a; scroll-behavior 属性规定当用户单击可滚动框中的链接时&#xff0c;是否平滑地&#xff08;具动画效果&#xff09;滚动位置&#xff0c;而不是直线跳转。 <style>element{/* 核心代码 */scroll-behavior: smooth;} </style> 属性值&am…

云原生之深入解析减少Docker镜像大小的优化技巧

一、什么是 Docker&#xff1f; Docker 是一种容器引擎&#xff0c;可以在容器内运行一段代码&#xff0c;Docker 镜像是在任何地方运行应用程序而无需担心应用程序依赖性的方式。要构建镜像&#xff0c;docker 使用一个名为 Dockerfile 的文件&#xff0c;Dockerfile 是一个包…

linux修改用户uid和gid并且修改文件所有权(所属用户及所属用户组)(chown命令、chgrp命令)(批量修改查找并修改文件、目录uid和gid)

文章目录 修改Linux用户UID和GID以及文件所有权1. 修改用户的UID和GID1.1 用户UID和GID的概念1.2 修改用户UID1.3 修改用户GID 2. 修改文件所有权2.1 文件所有权的概念2.2 修改文件所有者&#xff08;chown命令&#xff09;2.3 修改文件所属用户组&#xff08;chgrp命令&#x…

Gitlab仓库推送到Gitee仓库的一种思路

文章目录 Gitlab仓库推送到Gitee仓库的一种思路1、创建Gitee的ssh公钥&#xff08;默认已有Gitlab的ssh公钥&#xff09;2、添加Gitlab远程仓库地址3、添加Gitee远程仓库地址4、拉取Gitlab远程仓库指定分支到本地仓库指定分支&#xff08;以test分支为例&#xff09;5、推送本地…

PyTorch机器学习与深度学习

近年来&#xff0c;随着AlphaGo、无人驾驶汽车、医学影像智慧辅助诊疗、ImageNet竞赛等热点事件的发生&#xff0c;人工智能迎来了新一轮的发展浪潮。尤其是深度学习技术&#xff0c;在许多行业都取得了颠覆性的成果。另外&#xff0c;近年来&#xff0c;Pytorch深度学习框架受…

早期的OCR是怎么识别图片上的文字的?

现在的OCR技术融合了人工智能技术&#xff0c;通过深度学习&#xff0c;无论是识别的准确率还是效果都非常不错&#xff0c;那您知道在早期的OCR是通过什么技术来实现的吗&#xff1f;如果您不知道&#xff0c;那么&#xff0c;就让我来告诉您&#xff1a;它主要是基于字符的几…

【工具使用-Qt】Qt如何查看帮助文档

一&#xff0c;简介 Qt不需要单独下载帮助文档&#xff0c;在安装的时候&#xff0c;就已经帮你下载好了&#xff0c;在目录&#xff1a;安装目录/Qt5.14.2/Docs/目录下了。 二&#xff0c;查看方法 打开IDE&#xff0c;点击“帮助”&#xff1a; 输入想要查找的内容&…