CMake转义问题:add_custom_target命令中括号未正确转义
解决CMake传递含括号的环境变量到codesign的转义问题
核心问题
CMake默认仅转义参数中的空格,对于()这类shell特殊字符不做处理,导致生成的shell命令被/bin/sh解析时触发语法错误;手动添加引号又会让codesign收到带反斜杠的字面参数,无法正确识别证书。
解决方案
方案1:使用VERBATIM选项(推荐)
在add_custom_target中添加VERBATIM关键字,CMake会按照目标平台的shell规则自动转义所有特殊字符(包括空格、括号),既不会触发shell语法错误,也不会给codesign传递多余的转义符。
修改后的代码:
set(CODESIGN_CERT $ENV{CODESIGN_CERT}) # 内容为"My Name (My Team ID)" add_custom_target(make-package ALL COMMAND command1 COMMAND command2 COMMAND codesign ... --sign "${CODESIGN_CERT}" ... VERBATIM )
VERBATIM是CMake官方推荐的特殊字符处理方式,它会将每个COMMAND参数作为独立项传递给shell,避免手动转义的繁琐,同时保证跨平台兼容性。
方案2:手动转义特殊字符
如果因场景限制无法使用VERBATIM,可以通过CMake的字符串替换函数,手动将括号转义为shell可识别的形式:
set(CODESIGN_CERT $ENV{CODESIGN_CERT}) # 转义括号 string(REPLACE "(" "\\(" CODESIGN_CERT_ESCAPED "${CODESIGN_CERT}") string(REPLACE ")" "\\)" CODESIGN_CERT_ESCAPED "${CODESIGN_CERT_ESCAPED}") add_custom_target(make-package ALL COMMAND command1 COMMAND command2 COMMAND codesign ... --sign "${CODESIGN_CERT_ESCAPED}" ... )
这种方法需要逐个处理特殊字符,适合仅存在括号这类特定特殊字符的场景。
方案3:通过shell命令包裹执行
使用sh -c将codesign命令包裹起来,利用shell自身的引号机制处理特殊字符:
set(CODESIGN_CERT $ENV{CODESIGN_CERT}) add_custom_target(make-package ALL COMMAND command1 COMMAND command2 COMMAND sh -c "codesign ... --sign '${CODESIGN_CERT}' ..." )
注意:如果证书名称中包含单引号,此方法会失效,需提前处理单引号的转义。
内容的提问来源于stack exchange,提问作者fferri
相关产品推荐
相关产品推荐

