1. 问题背景
在Qt项目开发中,当一个工程包含多个子项目(如库、插件、测试模块)时,如何正确管理它们的构建顺序和依赖关系?
如:
 在开发一个包含核心库(core)、GUI模块(gui)、插件(plugins)和测试(tests)的Qt项目时,我们发现:
 • 如果plugins在core完成构建前启动编译,会导致链接失败
 • 当tests同时依赖core和plugins时,手动管理顺序极易出错
# 典型构建错误示例
ld: cannot find -lcore  # 核心库尚未编译完成
2. 为什么需要管理子项目依赖?
在复杂 Qt 项目中,模块通常存在依赖关系,例如:
 • 插件(plugins) 依赖 核心库(core)
 • 测试(tests) 依赖 主程序(app)和库(lib)
如果构建顺序错误,可能导致:
 • 链接失败(未找到依赖库)
 • 运行时错误(插件未正确初始化)
 • 维护困难(新增模块时需手动调整顺序)
因此,Qt提供了两种方式管理依赖,但它们的适用场景不同。
 常见的两种方式:
- depends显式声明依赖
- 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 优势
-  精准控制依赖 
 • 明确指定谁依赖谁,避免隐式顺序问题。
 • 支持 非线性依赖(如多个插件依赖同一个库)。
-  可维护性高 
 • 新增模块时,只需添加depends,无需调整SUBDIRS顺序。
 • 适合大型项目,模块化清晰。
-  官方明确推荐 “For complex dependencies between subprojects, use the dependsvariable instead ofCONFIG += ordered.”
 —— Qt 6 官方文档
3.3 适用场景
• 模块化项目(库 + 插件 + 测试)。
 • 存在交叉依赖(如多个子项目依赖同一个核心模块)。
4. CONFIG += ordered:顺序构建(旧式方案)
 
4.1 基本语法
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = core gui plugins tests  # 严格按顺序构建:core → gui → plugins → tests
当新增database模块需要插入到core和gui之间时:
- 必须手动调整SUBDIRS顺序
- 可能破坏既有依赖关系
- 需要全面回归测试
4.2 存在问题
-  过于死板 
 • 必须确保SUBDIRS顺序完全匹配依赖关系,否则构建失败。
 • 新增模块时需手动调整顺序,容易出错。
-  无法表达复杂依赖 
 • 如果tests依赖core,但plugins也依赖core,ordered无法直接表达。
4.3 残留用途
• 极简单的线性依赖项目(如 A → B → C)。
 • 历史遗留代码维护。
5. 对比分析
| 特性 | depends | CONFIG += 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. 结论
-  优先使用 depends
 • 它是 Qt 官方推荐的方案,适合绝大多数项目。
 • 提供更好的可读性、可维护性和灵活性。
-  避免 CONFIG += ordered
 • 仅用于旧代码兼容或极其简单的线性构建。
-  保持依赖声明清晰 
 • 使用注释分组依赖,例如:# Core dependencies gui.depends = core plugins.depends = core gui
提示:在Qt Creator中,右键点击项目 → "Run qmake"可以实时验证依赖关系是否正确解析。