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

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

相关文章:

  • [Python] 如何使用 Python 调用 Dify 工作流服务实现自动化翻译
  • 自学嵌入式 day 24 -系统编程 文件
  • JS逆向 【QQ音乐】sign签名| data参数加密 | AES-GCM加密 | webpack实战 (上)
  • 黑马程序员C++核心编程笔记--2 引用
  • ISOLAR软件生成报错处理(三)
  • 中大型企业 CIO List
  • LangChain + Redis:实现持久化的聊天历史记录管理
  • LVS -DR
  • Vue3对接deepseek实现ai对话
  • 数据结构-排序(1)
  • Spring AI 多模型智能协作工作流实现指南
  • Cookie与Session简介-笔记
  • 漫画Android:Handler机制是怎么实现的?
  • 机器学习:线性回归、损失函数、导数、偏导
  • EC800GCN 华系列 DTU 开发板介绍
  • 挖o心得(4)
  • PINN是否需要对空间进行网格化
  • 前端识别用户在某些页面的停留时间过长,提示可能存在问题
  • Python 包管理工具 uv的一些常用指令
  • 体育智能认知革命:当AI阅读器遇上实时数据API—— 打造体育产业的「数据消化中枢」
  • 网站设计心得/最新新闻热点话题
  • 怎么弄一个电商平台/天津seo排名
  • 什么网站做adsense好/网站快速优化排名官网
  • 小米网站建设/做竞价推广大概多少钱
  • 贵州移动端网站建设/个人建网站步骤
  • 建设信息网怎么进入/seo薪资seo