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

cmake source_group 分组功能辅助函数

cmake 的 source_group 可以对VS工程的源码文件进行分组,使用方法参考

https://cmake.org/cmake/help/latest/command/source_group.html

但是该命令使用起来很不方便,必须跟 add_executable 或者 add_library 写在同一个CMakeLists.txt文件中才能生效,无法在 add_subdirectory 引入的子 CMakeLists.txt 使用。原因是官方文档中所述:The group is scoped in the directory where the command is called, and applies to sources in targets created in that directory。

为了实现类似 target_source 命令这种层级化的使用方式,开发了以下辅助函数(函数在文件SourceGroup.cmake 中)

# 添加分组(命令参数含义可参考 source_group 命令)
# group_name    分组名称
# FILES         分组包含的文件
# TREE          按给定的目录结构组织分组文件
function(add_source_group group_name)if(DEFINED group_name AND "${group_name}" STREQUAL "_add_source_group_<EMPTYNAME>")message(FATAL_ERROR "group name cannot be ${group_name}.")endif ()cmake_parse_arguments(_add_source_group """TARGET""FILES;TREE"${ARGN})# 分组名称get_property(group_names GLOBAL PROPERTY _add_source_group_names_${_add_source_group_TARGET})if(DEFINED group_name AND "${group_name}" STREQUAL "")if(NOT DEFINED _add_source_group_TREE)message(FATAL_ERROR "group name cannot be empty.")else()list(APPEND group_names "_add_source_group_<EMPTYNAME>")endif()else()list(APPEND group_names ${group_name})endif()set_property(GLOBAL PROPERTY _add_source_group_names_${_add_source_group_TARGET} ${group_names})# 分组树目录get_property(group_trees GLOBAL PROPERTY _add_source_group_trees_${_add_source_group_TARGET})if (DEFINED _add_source_group_TREE)list(APPEND group_trees ${_add_source_group_TREE})else()list(APPEND group_trees "_add_source_group_<EMPTYTREE>")endif()set_property(GLOBAL PROPERTY _add_source_group_trees_${_add_source_group_TARGET} ${group_trees})# 分组文件if (_add_source_group_FILES)string(REPLACE ";" "|" GROUP_SOURCES "${_add_source_group_FILES}")get_property(group_files GLOBAL PROPERTY _add_source_group_files_${_add_source_group_TARGET})list(APPEND group_files "${GROUP_SOURCES}")set_property(GLOBAL PROPERTY _add_source_group_files_${_add_source_group_TARGET} ${group_files})endif()       endfunction()# 应用分组(在所有分组添加完毕后调用)
function(apply_source_group)if(${ARGC} GREATER 1)message(FATAL_ERROR "too many parameters for apply_Source_group.")endif ()if (${ARGC} EQUAL 1)set(target_name ${ARGV0})else()set(target_name "")endif()get_property(group_names GLOBAL PROPERTY _add_source_group_names_${target_name})get_property(group_trees GLOBAL PROPERTY _add_source_group_trees_${target_name})get_property(group_files GLOBAL PROPERTY _add_source_group_files_${target_name})#message(apply_source_group_values: ${group_names}, ${group_trees}, ${group_files})# 确保两个列表长度相同list(LENGTH group_names NAME_LENGTH)list(LENGTH group_files FILE_LENGTH)if(NOT ${NAME_LENGTH} EQUAL ${FILE_LENGTH})message(FATAL_ERROR "source group names and files length must be equal.")endif()# 遍历列表索引math(EXPR MAX_INDEX "${NAME_LENGTH} - 1")foreach(INDEX RANGE ${MAX_INDEX})list(GET group_names ${INDEX} GROUP_NAME)list(GET group_trees ${INDEX} GROUP_TREE)list(GET group_files ${INDEX} GROUP_FILE)string(REPLACE "|" ";" GROUP_FILE "${GROUP_FILE}")if("${GROUP_TREE}" STREQUAL "_add_source_group_<EMPTYTREE>")source_group(${GROUP_NAME} FILES ${GROUP_FILE})else()if("${GROUP_NAME}" STREQUAL "_add_source_group_<EMPTYNAME>")source_group(TREE ${GROUP_TREE} FILES ${GROUP_FILE})else()source_group(TREE ${GROUP_TREE} PREFIX ${GROUP_NAME} FILES ${GROUP_FILE})endif()endif()endforeach()
endfunction()# 重置分组
function(reset_source_group)if(${ARGC} GREATER 1)message(FATAL_ERROR "too many parameters for reset_source_group.")endif ()if (${ARGC} EQUAL 1)set(target_name ${ARGV0})else()set(target_name "")endif()set_property(GLOBAL PROPERTY _add_source_group_names_${target_name} "")set_property(GLOBAL PROPERTY _add_source_group_trees_${target_name} "")set_property(GLOBAL PROPERTY _add_source_group_files_${target_name} "")
endfunction()

辅助函数使用方法

1. 在根 CMakeLists.txt 中引入辅助函数

include(SourceGroup.cmake)

2. 调用 add_source_group 设置需要分组的源码文件

add_source_group(<name> [TARGET <target>] [TREE <root>] FILES <src>...)

add_source_group 可在根 CMakeLists.txt 及子 CMakeLists.txt 中使用。

TARGET 参数在多工程时用于区分不同工程的分组设置

如果不设置参数 [TREE <root>] 对应 source_group 的

source_group(<name> FILES <src>...)

如果设置参数 [TREE <root>] 对应 source_group 的

source_group(TREE <root> [PREFIX <prefix>] FILES <src>...)

此时 <name> 对应 <prefix> 参数

3. 调用 apply_source_group 应用分组

apply_source_group([TARGET <target>])

apply_source_group 必须跟 add_executable 或者 add_library 写在同一个CMakeLists.txt文件中。

完整示例

https://download.csdn.net/download/ayang1986/90803035

效果如下图:

http://www.xdnf.cn/news/5348.html

相关文章:

  • 焊接与热切割作业理论考试难度分析
  • 未来通信中的大型人工智能模型:基础、应用与挑战的全面综述
  • 《P2415 集合求和》
  • Windows 操作系统 - BAT 脚本引入(BAT 脚本初识、窗口标题与颜色、输出文本)
  • 历史数据分析——北部湾港
  • 洗衣机电机驱动电路
  • M0基础篇之ADC
  • 【llama-factory】Lora微调和DPO训练
  • 论文分享➲ arXiv2025 | TTRL: Test-Time Reinforcement Learning
  • JavaSE核心知识点02面向对象编程02-06(泛型)
  • 多环境开发
  • Makefile中 链接库,同一个库的静态库与动态库都链接了,生效的是哪个库
  • 【RT-Thread Studio】W25Q128配置
  • unity通过transform找子物体只能找子级
  • OpenAI 结构改革:迈向民主化 AI 的新篇章
  • TCP的连接管理
  • lnx 0-1 积分
  • 多个python环境下,pip安装无法成功解决方案
  • 《P7167 [eJOI 2020] Fountain (Day1)》
  • 线程互斥与线程同步
  • HTML入门教学
  • 不同类型的 SAP 项目
  • 零件画图实战提升案例(下)
  • 7系列 之 I/O标准和终端技术
  • 2.商户查询缓存
  • 时钟晶振锁相环pll方向技术要点和大厂题目解析
  • MRNet 数据集分享
  • 流式数据(Streaming Data)和非流式数据(Batch Data)区别、使用场景、优化-来自前端的浅解
  • 微机控制电子式持久蠕变慢应变应力腐蚀试验机
  • sh脚本多卡顺序执行训练文件