CMake中$<CONFIG:cfg_list>与$<IN_LIST:str,list>的正确语法是什么
CMake构建配置校验及生成器表达式使用问题解答
核心问题1:生成器表达式不能在if()语句中使用
CMake生成器表达式的求值时机为构建系统生成阶段(CMake完成所有CMakeLists解析、准备输出构建规则时),而if()语句是配置阶段就会直接解析执行的语法,配置阶段不会对生成器表达式做任何求值,只会将其识别为普通字符串。
此外你传入的CMAKE_CONFIGURATION_TYPES是带分号的列表,CMake解析命令参数时会将分号识别为参数分隔符,直接把$<CONFIG:Debug;Release>拆为$<CONFIG:Debug和Release>两个独立参数,因此触发参数不识别的报错。
生成器表达式仅可用于明确标注支持该语法的场景,例如编译选项、链接选项、安装路径配置等,示例正确用法:
# 仅Debug配置下开启DEBUG宏 target_compile_definitions(your_target PRIVATE $<$<CONFIG:Debug>:DEBUG_BUILD>)
核心问题2:IN_LIST语法的规则要求
CMake的if(IN_LIST)语法有严格要求:右操作数必须是列表变量的名称,不能是展开后的列表值,也不能是带引号的分号分隔字符串。
你之前错误写法的问题对应如下:
if( NOT ${CMAKE_BUILD_TYPE} IN_LIST ${CMAKE_CONFIGURATION_TYPES} ):将CMAKE_CONFIGURATION_TYPES手动展开后,得到Debug Release两个独立参数,if语法无法识别为单个列表,触发参数错误。if( NOT ( "Debug" IN_LIST "Debug;Release" ) ):右操作数传入了带引号的字符串,if不会将其解析为列表,只会作为单个完整字符串做匹配,因此无法匹配到Debug,判断结果错误。- 你最终使用的
if( NOT ( CMAKE_BUILD_TYPE IN_LIST CMAKE_CONFIGURATION_TYPES ) )是标准正确写法:右操作数直接传列表变量名CMAKE_CONFIGURATION_TYPES,if会自动读取该变量的列表值做匹配,括号包裹确保NOT作用于整个IN_LIST判断结果,逻辑完全正确。
内容的提问来源于stack exchange,提问作者PfunnyGuy
相关产品推荐
相关产品推荐

