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

CMake指令:source_group()

目录

1.简介

2.核心功能与用法

2.1. 按文件类型分组(如头文件、源文件)

2.2.按目录结构分组(自动映射文件夹层级)

2.3.与 target_sources 结合使用

3. TREE 参数

4.高级用法

5.总结


1.简介

        在 CMake 中,source_group 命令用于在集成开发环境(IDE,如 Visual Studio、Xcode、CLion 等)中组织源代码的逻辑分组显示,使项目结构在 IDE 的文件视图中更清晰易读,类似Visual Studio提供的filter机制来分类显示源文件。它不会影响编译逻辑,仅用于调整 IDE 中源文件的分组展示方式。

        该命令相当于VS里面给编译需要的文件归类,把一些相同性质的文件放一个类里面,这些“类”,可以在VS 图形界面下左边(一般情况下),看到header文件夹下面的H文件,source文件夹下的C/C++源文件,resource文件夹下的res资源脚本文件。

        基本语法:

source_group(<group_name> FILES <file1> <file2> ...)
  • <group_name>:指定 IDE 中显示的分组名称(支持嵌套路径,如 Headers/Utils)。
  • <file1> <file2>...:需要归入该分组的源文件路径(相对当前 CMake 目录)。

2.核心功能与用法

2.1. 按文件类型分组(如头文件、源文件)

# 将所有头文件归入 "Headers" 分组
source_group("Headers" FILES ${PROJECT_SOURCE_DIR}/include/*.h ${PROJECT_SOURCE_DIR}/include/*.hpp)# 将所有源文件归入 "Sources" 分组
source_group("Sources" FILES ${PROJECT_SOURCE_DIR}/src/*.cpp ${PROJECT_SOURCE_DIR}/src/*.cxx)
  • 在 IDE 中会显示为独立的 Headers 和 Sources 文件夹分组。

2.2.按目录结构分组(自动映射文件夹层级)

若源代码目录结构为:

project/
├─ include/
│  ├─ utils/
│  │     └─ math.h
│  └─ main.h
└─ src/├─ utils/│     └─ math.cpp└─ main.cpp

可通过以下方式在 IDE 中映射目录结构:

# 递归按目录结构分组(需结合 file(GLOB_RECURSE))
file(GLOB_RECURSE HEADERS "${PROJECT_SOURCE_DIR}/include/**/*.h" "${PROJECT_SOURCE_DIR}/include/**/*.hpp")
file(GLOB_RECURSE SOURCES "${PROJECT_SOURCE_DIR}/src/**/*.cpp" "${PROJECT_SOURCE_DIR}/src/**/*.cxx")# 为头文件生成分组路径(如 "include/utils/math.h" 对应 IDE 中的 "include/utils" 分组)
foreach(HEADER ${HEADERS})get_filename_component(REL_PATH ${HEADER} RELATIVE_TO ${PROJECT_SOURCE_DIR}/include)string(REPLACE "\\" "/" GROUP_PATH "include/${REL_PATH}")string(REPLACE "/${REL_PATH}" "" GROUP_PATH ${GROUP_PATH})  # 提取目录部分作为分组名source_group(${GROUP_PATH} FILES ${HEADER})
endforeach()# 同理处理源文件(分组名以 "src/" 开头)
foreach(SOURCE ${SOURCES})get_filename_component(REL_PATH ${SOURCE} RELATIVE_TO ${PROJECT_SOURCE_DIR}/src)string(REPLACE "\\" "/" GROUP_PATH "src/${REL_PATH}")string(REPLACE "/${REL_PATH}" "" GROUP_PATH ${GROUP_PATH})source_group(${GROUP_PATH} FILES ${SOURCE})
endforeach()
  • 最终在 IDE 中,文件会按实际目录层级显示在对应的分组下(如 include/utils 和 src/utils 分组)。

2.3.与 target_sources 结合使用

通常在使用 target_sources 向目标添加文件前,先用 source_group 定义分组:

add_executable(my_app)# 定义分组
source_group("Headers" FILES ${HEADERS})
source_group("Sources" FILES ${SOURCES})# 添加文件到目标(分组信息会传递给 IDE)
target_sources(my_app PRIVATE ${HEADERS} ${SOURCES})

3. TREE 参数

首先看条命令:

source_group(TREE "${PROJECT_SOURCE_DIR}/include/minidocx"PREFIX "Header Files" FILES ${headers})

source_group 命令是 CMake 中用于在 IDE 中组织源代码显示的高级用法,特别是使用了 TREE 参数 来自动映射目录结构。这条命令的作用是:将 include/minidocx 目录下的头文件按原目录层级映射到 IDE 的 "Header Files" 分组中。

命令解析

source_group(TREE "${PROJECT_SOURCE_DIR}/include/minidocx"  # 源目录(作为分组根)PREFIX "Header Files"                         # 分组前缀(IDE 中显示的顶级分组名)FILES ${headers}                              # 要分组的文件列表(通常是头文件集合)
)

核心参数说明

1.TREE <directory>

  • 指定源目录,CMake 会递归遍历该目录的结构,并以此为基础生成 IDE 中的分组。
  • 例如,若源目录为 include/minidocx/utils,则该目录下的文件会在 IDE 中显示为 Header Files/utils 分组。

2.PREFIX <prefix>

  • 指定 IDE 中显示的顶级分组名称。所有子分组都会嵌套在这个名称下。
  • 例如,设置为 "Header Files" 时,IDE 会显示为:
Header Files/
├─ core/
├─ utils/
└─ format/

3.FILES <files>

  • 列出要分组的文件(通常是通过 file(GLOB) 收集的头文件列表)。
  • 这些文件必须位于 TREE 指定的目录或其子目录中。

实际效果示例

假设目录结构如下:

project/
└─ include/└─ minidocx/├─ core/│     └─ document.h├─ utils/│     ├─ string_utils.h│     └─ file_utils.h└─ format/└─ xml_writer.h

使用上述命令后,在 Visual Studio 或 CLion 中会显示为:

Header Files/
├─ core/
│     └─ document.h
├─ utils/
│     ├─ string_utils.h
│     └─ file_utils.h
└─ format/└─ xml_writer.h

与传统 source_group 的对比

传统方式需要手动为每个子目录定义分组:

source_group("Header Files\\core" FILES ${headers_core})
source_group("Header Files\\utils" FILES ${headers_utils})
source_group("Header Files\\format" FILES ${headers_format})

而 TREE 参数可以自动处理嵌套结构,避免手动维护大量分组定义,特别适合大型项目。

注意事项:路径匹配要求

  • FILES 中的文件必须位于 TREE 指定的目录或其子目录中,否则会被忽略。
  • 例如,若 TREE 为 include/minidocx,但 FILES 包含 src/main.cpp,则该文件不会被分组。

4.高级用法

1.正则表达式与动态分组

若需按文件名模式(如测试文件、生成文件)分组,可结合 file(GLOB) 和正则表达式:

# 提取所有测试文件并归入 "Tests" 分组
file(GLOB TEST_SOURCES "${PROJECT_SOURCE_DIR}/tests/*.cpp")
string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/" "" TEST_SOURCES "${TEST_SOURCES}")  # 转换为相对路径
source_group("Tests" FILES ${TEST_SOURCES})

2.同时处理头文件和源文件

# 头文件分组
source_group(TREE "${PROJECT_SOURCE_DIR}/include/minidocx"PREFIX "Header Files"FILES ${headers}
)# 源文件分组
source_group(TREE "${PROJECT_SOURCE_DIR}/src"PREFIX "Source Files"FILES ${sources}
)

3.排除特定目录

若要排除 include/minidocx/internal 目录,可先过滤文件列表:

file(GLOB_RECURSE headers "${PROJECT_SOURCE_DIR}/include/minidocx/*.h")
list(FILTER headers EXCLUDE REGEX "${PROJECT_SOURCE_DIR}/include/minidocx/internal/")source_group(TREE "${PROJECT_SOURCE_DIR}/include/minidocx"PREFIX "Header Files"FILES ${headers}
)

5.总结

  source_group适合需要多人协作或复杂目录结构的工程。source_group(TREE ...) 更是通过自动映射目录结构,避免了手动维护复杂分组的繁琐工作。提升了项目在 IDE 中的可读性和可维护性。

相关链接

  • CMake 官网 CMake - Upgrade Your Software Build System
  • CMake 官方文档:CMake Tutorial — CMake 4.0.2 Documentation
  • CMake 源码:https://github.com/Kitware/CMake
  • CMake 源码:Sign in · GitLab
http://www.xdnf.cn/news/9479.html

相关文章:

  • 【数据分析】特征工程-特征选择
  • Git 使用规范
  • 关于git的使用流程
  • 2025年中国电商618年中大促策略分析:存量博弈与生态重构
  • 深度 |推动公共数据按需有序安全流动
  • mock库知识笔记(持续更新)
  • 如何解决网站服务器的异常问题?
  • 班翎流程平台 | 流程变量赋值事件,简化流程配置,灵活构建流程
  • 8.8 Primary ODSA service without ODSA Portal
  • LLaDa——基于 Diffusion 的大语言模型 打平 LLama 3
  • DM达梦数据库开启SQL日志记录功能
  • java导入excel
  • 2025超全面Redis笔记!!!
  • Redis缓存设计与性能优化
  • 题目 3316: 蓝桥杯2025年第十六届省赛真题-数组翻转
  • mac 下安装Rust Toolchain(Nightly)
  • Redis--缓存穿透与缓存雪崩详解及解决方案
  • Cloudera Manager 学习笔记
  • 程序的 “内存舞台”:深入解析虚拟地址空间与内存管理
  • 3D Tiles高级样式设置与条件渲染(4)
  • 8Manage PM、Trello与飞书对比评测:哪款项目管理软件更适合企业使用?
  • 《仿盒马》app开发技术分享-- 确认订单页(数据展示)(端云一体)
  • 程序开发的 “瑞士军刀”:深入解析库文件的原理与实践
  • 六大常用查找算法对比分析
  • 电气行业PLM应用案例:国产PLM助力山西氪安研发转型
  • P1903 [国家集训队] 数颜色 / 维护队列(单点修改莫队)
  • 借教室--二分+查分
  • vue2 一分钟不动系统 系统将进行锁定
  • Android系统 TinyAlsa命令
  • 计算机科技笔记: 容错计算机设计05 n模冗余系统 特殊的双模系统 复杂结构 非并行串行结构的两种计算方法