You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake生成器表达式中列表展开报错的解决咨询

CMake生成器表达式错误修复:多源文件条件添加问题

问题重现

用户编写的CMakeLists.txt代码如下:

set(MAIN_SOURCES
  src/main.cpp
  src/main.hpp
)

set(FEATURE_SOURCES
  src/feature.cpp
  src/feature.hpp
)

option(ENABLE_FEATURE "Enable feature in app" ON)

add_executable(app)

target_sources(app PRIVATE
  ${MAIN_SOURCES}
  $<$<BOOL:${ENABLE_FEATURE}>:${FEATURE_SOURCES}>
)

配置时触发错误:

CMake Error in CMakeLists.txt:
  Cannot find source file:

    src/feature.hpp>

用户尝试给生成器表达式添加引号后,错误依然存在。

问题原因

当FEATURE_SOURCES作为多元素列表展开时,生成器表达式会被拆分成多个部分:原本的$<$<BOOL:ON>:${FEATURE_SOURCES}>会展开为$<$<BOOL:ON>:src/feature.cpp src/feature.hpp>,CMake会将空格视为元素分隔符,把src/feature.hpp>当成独立的源文件(末尾多余的>是生成器表达式的闭合符号被拆分导致的),自然找不到这个文件。

生成器表达式中,冒号:后面只能接收单个参数,直接展开多元素列表会触发解析错误。

正确写法

方法1:用$<JOIN>拼接列表

通过$<JOIN>将多源文件列表用分号(CMake的列表分隔符)拼接成单个参数,避免拆分:

target_sources(app PRIVATE
  ${MAIN_SOURCES}
  $<$<BOOL:${ENABLE_FEATURE}>:$<JOIN:${FEATURE_SOURCES},;>>
)

方法2:使用传统if条件判断(更直观)

如果不需要生成器表达式的跨配置特性,直接用CMake的if语句实现条件添加,代码可读性更高:

add_executable(app)
target_sources(app PRIVATE ${MAIN_SOURCES})

if(ENABLE_FEATURE)
  target_sources(app PRIVATE ${FEATURE_SOURCES})
endif()

为什么加引号没用?

CMake在解析生成器表达式时,不会将引号视为列表的包裹符号,引号会被当作普通字符处理,展开后依然会按空格拆分元素,因此无法解决问题。

内容的提问来源于stack exchange,提问作者Arthur Pinheiro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 23:42:39