CMake为ExternalProject外部项目命令添加冗余引号问题求解
CMake ExternalProject 传递带引号参数时多余引号问题解决
问题根因
CMake 对命令参数的解析基于列表结构,分号是列表的默认分隔符:
- 当你把命令和参数用分号拼接成字符串再传递时,只要列表元素包含空格、引号这类shell特殊字符,CMake会为了避免参数被shell错误拆分,自动给对应元素包裹额外引号,和你预期的命令格式不符。
- 如果把分号替换成空格把整个命令拼成单个字符串,CMake会把整串识别为单个可执行文件路径,直接给整个命令包裹引号,导致命令无法执行。
正确配置方法
核心规则:不要把命令和参数拼成单字符串,始终以独立列表元素的形式传递命令和每一个参数,配合正确的转义和参数展开选项即可。
可直接运行的示例
include(ExternalProject) # 命令、每个参数作为独立列表项,字面量引号用反斜杠转义,注意转义层级适配生成的Makefile/shell解析 set(bar echo cxxflags=\\"flag1 flag2\\") ExternalProject_Add(test PREFIX "" DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" # 传列表变量时不要加外层双引号,让CMake正确识别列表结构 COMMAND ${bar} # 开启列表自动展开,保证跨生成器转义行为一致 COMMAND_EXPAND_LISTS TEST "" )
如果命令是从外部获取的整串格式,不要手动替换分号,使用separate_arguments命令按shell解析规则拆分参数,避免破坏带引号的参数结构:
set(bar_raw "echo cxxflags=\\\"flag1 flag2\\\"") # 按原生shell命令规则拆分参数为CMake列表 separate_arguments(bar NATIVE_COMMAND "${bar_raw}")
注意事项
- 传递列表形式的命令参数时,不要给变量包裹双引号,否则CMake会将整个列表识别为单个参数,触发整串加引号的问题。
- 如果仅需要让带空格的参数作为单个整体传递,不需要手动加引号,直接将该参数作为独立列表元素即可,CMake会自动处理转义;只有当最终执行的命令里需要字面量
"字符时,才需要手动加反斜杠转义。 - 上述配置生成的最终执行命令完全符合预期:
cd /some/path && echo cxxflags=\"flag1 flag2\"
内容的提问来源于stack exchange,提问作者Mohammed Li
相关产品推荐
相关产品推荐

