Qt 子项目依赖管理:从原理到实践的最佳分析:depends还是 CONFIG += ordered

1. 问题背景

Qt项目开发中,当一个工程包含多个子项目(如库、插件、测试模块)时,如何正确管理它们的构建顺序依赖关系

如:
在开发一个包含核心库(core)、GUI模块(gui)、插件(plugins)和测试(tests)的Qt项目时,我们发现:
• 如果pluginscore完成构建前启动编译,会导致链接失败
• 当tests同时依赖coreplugins时,手动管理顺序极易出错

# 典型构建错误示例
ld: cannot find -lcore  # 核心库尚未编译完成

2. 为什么需要管理子项目依赖?

在复杂 Qt 项目中,模块通常存在依赖关系,例如:
插件(plugins) 依赖 核心库(core)
测试(tests) 依赖 主程序(app)和库(lib)

如果构建顺序错误,可能导致:
链接失败(未找到依赖库)
运行时错误(插件未正确初始化)
维护困难(新增模块时需手动调整顺序)

因此,Qt提供了两种方式管理依赖,但它们的适用场景不同。
常见的两种方式:

  1. depends 显式声明依赖
  2. CONFIG += ordered 顺序构建

但,哪种方式更符合现代 Qt 开发的最佳实践?


3. depends:显式依赖声明(官方推荐)

3.1 基本语法

TEMPLATE = subdirs
SUBDIRS = core gui plugins tests# 显式声明依赖
gui.depends = core           # gui 依赖 core
plugins.depends = core gui   # plugins 依赖 core 和 gui
tests.depends = core         # tests 仅依赖 core

3.2 优势

  1. 精准控制依赖
    • 明确指定谁依赖谁,避免隐式顺序问题。
    • 支持 非线性依赖(如多个插件依赖同一个库)。

  2. 可维护性高
    • 新增模块时,只需添加 depends,无需调整 SUBDIRS 顺序。
    • 适合大型项目,模块化清晰。

  3. 官方明确推荐

    “For complex dependencies between subprojects, use the depends variable instead of CONFIG += ordered.”
    —— Qt 6 官方文档

3.3 适用场景

• 模块化项目(库 + 插件 + 测试)。
• 存在交叉依赖(如多个子项目依赖同一个核心模块)。


4. CONFIG += ordered:顺序构建(旧式方案)

4.1 基本语法

TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = core gui plugins tests  # 严格按顺序构建:core → gui → plugins → tests

当新增database模块需要插入到coregui之间时:

  1. 必须手动调整SUBDIRS顺序
  2. 可能破坏既有依赖关系
  3. 需要全面回归测试

4.2 存在问题

  1. 过于死板
    • 必须确保 SUBDIRS 顺序完全匹配依赖关系,否则构建失败。
    • 新增模块时需手动调整顺序,容易出错。

  2. 无法表达复杂依赖
    • 如果 tests 依赖 core,但 plugins 也依赖 coreordered 无法直接表达。

4.3 残留用途

• 极简单的线性依赖项目(如 A → B → C)。
• 历史遗留代码维护。


5. 对比分析

特性dependsCONFIG += ordered
依赖表达方式显式声明(A.depends = B隐式顺序(SUBDIRS 列表顺序)
适用项目规模中大型项目极简单项目
维护成本低(新增模块只需加依赖)高(需调整顺序)
官方推荐度✅ 推荐⚠️ 不推荐

6. 示例

6.1 现代 Qt 项目推荐写法

TEMPLATE = subdirs
SUBDIRS = core utils gui plugins tests #(与顺序无关)# 显式声明依赖
utils.depends = core          # utils 依赖 core
gui.depends = core utils      # gui 依赖 core 和 utils
plugins.depends = gui         # plugins 依赖 gui
tests.depends = core utils    # tests 依赖 core 和 utils

6.2 遗弃用法

TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = core utils gui plugins tests  # 依赖关系隐含在顺序中,难以维护

7. 结论

  1. 优先使用 depends
    • 它是 Qt 官方推荐的方案,适合绝大多数项目。
    • 提供更好的可读性、可维护性和灵活性。

  2. 避免 CONFIG += ordered
    • 仅用于旧代码兼容或极其简单的线性构建。

  3. 保持依赖声明清晰
    • 使用注释分组依赖,例如:

    # Core dependencies
    gui.depends = core
    plugins.depends = core gui
    

提示:在Qt Creator中,右键点击项目 → "Run qmake"可以实时验证依赖关系是否正确解析。

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

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

相关文章

业务幂等性技术架构体系-接口幂等

接口幂等 对于幂等的考虑,主要解决两点前后端交互与服务间交互。这两点有时都要考虑幂等性的实现。从前端的思路解决 的话,主要有三种:前端防重、PRG模式、Token机制。 前端防重 通过前端防重保证幂等是最简单的实现方式,前端相关…

AI工具导航大全 | 2025精选版(持续更新)

🚀 AI工具导航大全 | 2025精选版(持续更新) 更新日期:2025-04-11 | 适用场景:学术研究 | 办公提效 | 创意设计 | 开发编程 数据来源:综合高校实验室、企业实践及开发者社区推荐 🔍 导航目录 &…

驱动-内核空间和用户空间数据交换

内核空间与用户控件数据交换 前面了解的字符设备中对 file_operations 结构体的进行了填充, 该 结构体的每一个成员都对应着一个系统调用, 例如 read、 write 等, 在字符设备相关的文章中有实验过对 调用函数进行了标志打印, 并没…

5G_WiFi_CE_DFS

目录 一、规范要求 1、法规目录 2、定义 3、运行模式 4、主/从设备相关的运行行为及具体的动态频率选择(DFS)要求 5、产品角色确定测试项目 6、测试项目 测试项1:信道可用性检查(Channel Availability Check) …

Devops之GitOps:什么是Gitops,以及它有什么优势

GitOps 定义 GitOps 是一种基于版本控制系统(如 Git)的运维实践,将 Git 作为基础设施和应用程序的唯一事实来源。通过声明式配置,系统自动同步 Git 仓库中的期望状态到实际运行环境,实现持续交付和自动化运维。其核心…

【蓝桥杯】单片机设计与开发,第十二届

/*头文件声明区*/ #include <STC15F2K60S2.H>//单片机寄存器头文件 #include <init.h>//初始化底层驱动头文件 #include <led.h>//led,蜂鸣器,继电器底层驱动头文件 #include <key.h>//按键底层驱动头文件 #include <seg.h>//数码管底层驱动头…

Vue3连接MQTT作为客户端

先下载依赖 npx --yes --registry https://registry.npmmirror.com npm install mqtt 在src的api创建 mes.js // 导入axios import axios from axios;// 定义一个变量,记录公共的前缀, baseURL const baseURL http://localhost:8080; const instance axios.create({ base…

主服务器和子服务器之间通过NFS实现文件夹共享

背景&#xff1a; 子服务器想做一个备份服务器 但是之前有很多文件是上传到本地的&#xff0c;于是服务要从本地读取文件 但是在不在同一台服务器中&#xff0c;读取就会有问题&#xff0c;想 实现在两者之间创建一个共享文件夹 一 NFS挂载步骤&#xff1a; 在主服务器&#…

LeetCode算法题(Go语言实现)_39

题目 给定一个二叉树的根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 一、代码实现 type TreeNode struct {Val intLeft *TreeNodeRight *TreeNode }func rightSideView(root *TreeNode) []int {i…

【AI提示词】长期主义助手提供规划支持

提示说明 长期主义是一种关注长期利益和持续学习的思维模式&#xff0c;帮助个人和组织在快速变化的环境中保持耐心和系统性思考。 提示词 # Role: Long-termist Assistant## Profile - language: 中文 - description: 长期主义是一种关注长期利益和持续学习的思维模式&…

数组 array

1、数组定义 是一种用于存储多个相同类型数据的存储模型。 2、数组格式 &#xff08;1&#xff09;数据类型[ ] 变量名&#xff08;比较常见这种格式&#xff09; 例如&#xff1a; int [ ] arr0&#xff0c;定义了一个int类型的数组&#xff0c;数组名是arr0&#xff1b; &am…

基于JavaAPIforKml实现Kml 2.2版本的全量解析实践-以两步路网站为例

目录 前言 一、关于两步路网站 1、相关功能 2、数据结构介绍 二、JAK的集成与实现 1、JAK类图简介 2、解析最外层数据 3、解析扩展元数据和样式 4、递归循环解析Feature 5、解析具体的数据 三、结论 前言 随着地理信息技术的快速发展&#xff0c;地理空间数据的共享…

脑科学与人工智能的交叉:未来智能科技的前沿与机遇

引言 随着科技的迅猛发展&#xff0c;脑科学与人工智能&#xff08;AI&#xff09;这两个看似独立的领域正在发生深刻的交汇。脑机接口、神经网络模型、智能机器人等前沿技术&#xff0c;正带来一场跨学科的革命。这种结合不仅推动了科技进步&#xff0c;也在医疗、教育、娱乐等…

3.1.3.2 Spring Boot使用Servlet组件

在Spring Boot应用中使用Servlet组件&#xff0c;可以通过注解和配置类两种方式注册Servlet。首先&#xff0c;通过WebServlet注解直接在Servlet类上定义URL模式&#xff0c;Spring Boot会自动注册该Servlet。其次&#xff0c;通过创建配置类&#xff0c;使用ServletRegistrati…

《AI大模型应知应会100篇》第10篇:大模型的涌现能力:为什么规模如此重要

第10篇&#xff1a;大模型的涌现能力&#xff1a;为什么规模如此重要 摘要 在人工智能领域&#xff0c;“规模"始终是大模型发展的核心关键词。随着参数量从百万级跃升至万亿级&#xff0c;大模型展现出令人惊叹的"涌现能力”&#xff1a;这些能力在小模型中几乎不可…

安宝特案例 | Fundació Puigvert 医院应用AR技术开创尿石症治疗新纪元

案例介绍 在医疗科技不断进步的今天&#xff0c;Fundaci Puigvert 医院迈出了重要一步&#xff0c;成功应用AR技术进行了全球首例同时使用两台内窥镜的ECIRS手术&#xff08;内镜肾内联合手术&#xff09;&#xff0c;由Esteban Emiliani M.D. PhD F.E.B.U 博士主刀。这标志着…

从数据海洋中“淘金”——数据挖掘的魔法与实践

从数据海洋中“淘金”——数据挖掘的魔法与实践 在这个数据飞速膨胀的时代&#xff0c;每天产生的数据量可以用“天文数字”来形容。如果将数据比作金矿&#xff0c;那么数据挖掘&#xff08;Data Mining&#xff09;就是在数据的海洋中挖掘黄金的技术。作为一门结合统计学、机…

kotlin的takeIf使用

takeIf用于判断指定对象是否满足条件&#xff0c;满足就返回该对象自身&#xff0c;不满足返回null。因为可以返回对象自身&#xff0c;所以可以用作链式调用&#xff0c;以简化代码&#xff0c;又因takeIf可能返回空&#xff0c;所以常常和let结合使用&#xff0c;示例如下&am…

[定位器]晶艺LA1823,4.5V~100V, 3.5A,替换MP9487,MP9486A,启烨科技

Features  4.5V to 100V Wide Input Range  3.5A Typical Peak Current Limit  Integrated 500mΩ low resistance high side power MOS.  Constant On Time Control with Constant Switching Frequency.  180μA Low Quiescent Current  150kHz/240kHz/420kHz Swi…

火山RTC 4 音视频引擎 IRTCVideo,及 音视频引擎事件回调接口 IRTCVideoEventHandler

一、IRTCVideo、IRTCVideoEventHandler 音视频引擎 IRTCVideo&#xff0c;及 音视频引擎事件回调接口 IRTCVideoEventHandler 负责音视频管理、创建房间/获得房间实例 1、创建引擎、及事件回调示例 如&#xff1a; void VideoConfigWidget::initRTCVideo() {m_handler.res…