如何在CMakeLists.txt中判断缓存变量未通过本次cmake命令行-D传入?
解决CMake中区分命令行传入变量与缓存变量的问题
要区分CMake变量是通过命令行-D传入还是仅存在于缓存中,可以通过遍历命令行参数列表实现,具体方案如下:
方法:检查命令行参数列表
CMake提供CMAKE_ARGV系列变量存储完整的命令行参数,我们可以遍历这些参数,判断是否存在目标变量的-D定义:
# 初始化标记,默认未从命令行传入 set(MYVAR_FROM_CMDLINE OFF) # 遍历所有命令行参数,检查是否包含-DMYVAR或-DMYVAR=... foreach(arg IN LISTS CMAKE_ARGV) if(arg MATCHES "^-DMYVAR($|=)") set(MYVAR_FROM_CMDLINE ON) break() endif() endforeach() # 仅当变量不是命令行传入时,清除缓存中的MYVAR if(NOT MYVAR_FROM_CMDLINE) unset(MYVAR CACHE) endif() # 后续正常判断变量是否存在,添加编译定义 if(DEFINED MYVAR) add_compile_definitions(MYVAR) endif()
说明
- 正则表达式
^-DMYVAR($|=)会匹配两种命令行传入形式:-DMYVAR(仅定义变量,无值)和-DMYVAR=xxx(带值定义)。 - 这段逻辑必须放在CMakeLists.txt最开头,确保在CMake加载缓存变量后、后续逻辑执行前完成判断与清理。
- 直接提前
unset(MYVAR CACHE)无效的原因是:CMake在执行脚本前会先加载缓存中的变量,若不做命令行传入判断就直接清理,会误删确实通过命令行传入的变量。
内容的提问来源于stack exchange,提问作者jf_
相关产品推荐
相关产品推荐

