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

cmake_parse_arguments()构建清晰灵活的 CMake 函数接口

使用 cmake_parse_arguments() 构建清晰、灵活的 CMake 函数接口详解

在编写复杂的 CMake 函数或宏时,解析用户传入的参数是一项核心任务。相比手动解析 ${ARGV}${ARGN} 的繁琐做法,CMake 提供的 cmake_parse_arguments() 是一种更清晰、高效、可维护的方式。

本文将从基础语法讲起,结合多个实际例子,系统讲解 cmake_parse_arguments() 的使用方法、优势以及注意事项。


基础语法

cmake_parse_arguments(PREFIX<noValueKeywords><singleValueKeywords><multiValueKeywords>${ARGN})
  • PREFIX:用于生成变量前缀(如 ARG_ENABLE_NET
  • noValueKeywords:只需出现即可为 TRUE 的布尔参数
  • singleValueKeywords:后面跟一个值的参数
  • multiValueKeywords:后面跟多个值的参数(通常为列表)
  • ${ARGN}:表示传入的可变参数

CMake 关键字类型类似命令行参数说明
noValues--verbose出现即启用,布尔型
singleValues--target myApp后接一个值
multiValues--sources a.cpp b.cpp后接多个值(一般是文件列表)

示例代码

function(func)set(prefix ARG)set(noValues ENABLE_NET COOL_STUFF)set(singleValues TARGET)set(multiValues SOURCES IMAGES)include(CMakeParseArguments)cmake_parse_arguments(${prefix}"${noValues}""${singleValues}""${multiValues}"${ARGN})message("Option summary:")foreach(arg IN LISTS noValues)if(${${prefix}_${arg}})message(" ${arg} enabled")else()message(" ${arg} disabled")endif()endforeach()foreach(arg IN LISTS singleValues multiValues)message(" ${arg} = ${${prefix}_${arg}}")endforeach()
endfunction()

调用示例:

func(SOURCES main.cpp utils.cpp TARGET myApp ENABLE_NET)
func(COOL_STUFF TARGET dummy IMAGES logo.png banner.png)
Option summary:ENABLE_NET enabledCOOL_STUFF disabledTARGET = myAppSOURCES = main.cpp;utils.cppIMAGES = Option summary:ENABLE_NET disabledCOOL_STUFF enabledTARGET = dummySOURCES = IMAGES = logo.png;banner.png

为什么使用 cmake_parse_arguments()

  1. 清晰的结构
    你可以清楚地区分哪些参数是开关(布尔),哪些是单值,哪些是多值。

  2. 避免手动解析错误
    传统写法使用 while() + list(GET ...) 解析 ${ARGV},容易出错。cmake_parse_arguments() 自动完成所有解析工作。

  3. 可预测的变量命名
    每个参数会被映射到形如 ${PREFIX_KEYWORD} 的变量,如:
    ARG_ENABLE_NET, ARG_TARGET, ARG_SOURCES
    统一命名让代码更简洁,逻辑更清晰。

  4. 调用者顺序自由
    参数顺序不固定,使用者可以按任何顺序组合调用函数,函数本体依然能准确解析。


prefix 是什么意思?

set(prefix ARG)

这句的作用是设定所有变量的前缀。例如:

cmake_parse_arguments(${prefix} ...)

等价于:

cmake_parse_arguments(ARG ...)

所以在函数体内你会获得形如:

  • ARG_ENABLE_NET
  • ARG_TARGET
  • ARG_SOURCES

的变量,可以直接使用。你也可以用别的前缀(如 MYFUNC_),这样可以同时定义多个函数而不互相冲突。


参数类型详细解释

参数类别关键字示例调用方式解析结果
noValuesENABLE_NETfunc(ENABLE_NET)ARG_ENABLE_NET = TRUE
singleValueTARGETfunc(TARGET app)ARG_TARGET = app
multiValueSOURCES, IMAGESfunc(SOURCES a.cpp b.cpp)ARG_SOURCES = a.cpp;b.cpp (列表)

常见限制与注意事项

  1. 关键字不能重复出现在多个分类中

    # 错误示例
    set(singleValues SOURCES)
    set(multiValues SOURCES)  # 冲突!
    
  2. 每个关键字必须是单词
    不能写成 "ENABLE NET",否则会被拆成两个关键字。

  3. 多值参数会“吃”尽可能多的值
    直到遇到下一个合法关键字为止,所以关键字必须准确匹配。


多个关键字可以一起定义吗?

当然可以!

set(multiValues SOURCES IMAGES FILES CONFIGS HEADERS ...)

是否有上限?

理论上没有上限,你可以写几十个关键字也没问题,只要它们合法、互不冲突,CMake 都能解析。


实用建议

虽然没有硬性限制,但为保证代码的可读性和维护性,推荐将关键字分组管理:

set(resourceKeys IMAGES FILES)
set(sourceKeys SOURCES HEADERS)
set(multiValues ${resourceKeys} ${sourceKeys})

高级技巧建议

动态前缀支持

你可以把 prefix 作为函数参数,让调用者传入不同的前缀,实现函数行为复用。

function(myfunc prefix)cmake_parse_arguments(${prefix} ... ${ARGN})
endfunction()myfunc(MYLIB SOURCES a.cpp b.cpp)

这样会自动生成 MYLIB_SOURCES 变量,便于组件隔离。


总结

特性优点
关键字参数解析支持布尔、单值、多值
自动生成前缀变量简化代码,提高可读性
支持参数顺序任意调用更灵活
可维护性强易于添加/扩展参数
多个关键字支持理论无限制,推荐有结构地组织关键字
替代手动参数提取避免 list(GET ARGV...) 等易错逻辑

推荐使用场景

  • 多参数构建函数(如构建库、目标、测试组)
  • 需要布尔开关/选项控制的宏
  • 跨平台构建配置管理
  • 提高模块/函数的复用性与健壮性

如果你正打算规范你的 CMake 函数接口,那么从 cmake_parse_arguments() 开始是个非常不错的选择。

欢迎评论交流,或提出你想了解的更多 CMake 细节!

http://www.lryc.cn/news/605314.html

相关文章:

  • G9打卡——ACGAN
  • 获取TensorRT引擎文件(.engine)版本号的几种方法
  • 2022 年 NOI 最后一题题解
  • 数据集相关类代码回顾理解 | DataLoader\datasets.xxx
  • 【高等数学】第七章 微分方程——第四节 一阶线性微分方程
  • 【支持Ubuntu22】Ambari3.0.0+Bigtop3.2.0——Step4—时间同步(Chrony)
  • Spark的宽窄依赖
  • 《设计模式之禅》笔记摘录 - 11.策略模式
  • uniapp-vue3来实现一个金额千分位展示效果
  • uniapp实现微信小程序导航功能
  • 思途JSP学习 0730
  • LeetCode 刷题【22. 括号生成】
  • Winform 渐变色 调色板
  • 代码随想录算法训练营第五十六天|动态规划part6
  • C语言基础11——结构体1
  • AutoSAR(MCAL) --- ADC
  • VoIP技术全面深度学习指南:从原理到实践的认知进化
  • 【GEO从入门到精通】生成式引擎与其他 AI 技术的关系
  • Linux ARM 平台 C 语言操作 Excel 文件的常用库与工具汇总(支持 xls 和 xlsx)
  • Linux基本指令,对路径的认识
  • SringBoot入门
  • uvm-tlm-sockets
  • 关于MyBatis 的懒加载(Lazy Loading)机制
  • 腾讯云市场排名
  • linux进程概念(三)进程状态
  • COZE 开源,新一代 AI Agent 本地部署一条龙
  • 借助 Wisdom SSH 的 AI 助手构建 Linux 开发环境
  • 2. Agent与 React流程
  • 智能Agent场景实战指南 Day 26:Agent评估与性能优化
  • 【面试场景题】随机立减金额计算