cmake - 带分号的 CMake 变量
问题描述
假设有一个程序需要输入 form <prog> --param "one;two;three"
:一个标志--param
,后跟一个由分号分隔的单词字符串(用引号括起来)。例如,可以使用以下 Bash 脚本:
flag=${1}
items=(${2//;/ })
echo "flag: ${flag}"
echo "items: ${items[@]}"
显然,输出将是:
flag: --param
items: one two three
分隔符;
是必须的,因此我们需要传递一个用引号括起来的字符串,否则 shell 会将分号之间的内容视为单独的命令。
这个问题有点类似于这个问题,但那里提出的答案不适用于以下问题。
考虑这个CMakeLists.txt
文件:
cmake_minimum_required(VERSION 3.16.2)
project(clumsy)
add_custom_command(OUTPUT foo.txt
COMMAND bash ${CMAKE_SOURCE_DIR}/script.sh --param "one;two;three" &>> foo.txt
WORKING_DIRECTORY ${CMAKE_BUILD_DIR}
VERBATIM
)
add_custom_target(foo DEPENDS foo.txt)
set(PARAMS "one;two;three")
add_custom_command(OUTPUT bar.txt
COMMAND bash ${CMAKE_SOURCE_DIR}/script.sh --param "${PARAMS}" &>> bar.txt
WORKING_DIRECTORY ${CMAKE_BUILD_DIR}
VERBATIM
)
add_custom_target(bar DEPENDS bar.txt)
配置后运行make foo
按预期工作:
[100%] Generating foo.txt
flag: --param
items: one two three <----
[100%] Built target foo
但是make bar
会导致错误的输出,因为变量PARAMS
被扩展为列表并且实际输入--param one two three
不是--param "one;two;three"
:
[100%] Generating bar.txt
flag: --param
items: one <----
[100%] Built target bar
如何使用变量PARAMS
并仍然使外部命令的输入包含两个参数?
更新
我CMakeLists.txt
使用涉及&
(like &>>
) 的输出重定向使代码变得更加复杂,这与使用VERBATIM
标志相冲突,这对于使变量引用工作很重要。
解决方案
在对为什么变量用法与字面用法(用于定义变量)不同的问题有些头疼之后,我决定发布此答案以说明问题。
正如@KamilCuk 所建议的那样,使用带引号的变量--params "${PARAMS}"
有效,但前提是也使用了VERBATIM
选项。在大多数情况下,这不是问题,但由于缺乏 CMake 支持将输出重定向到文件的能力,因此无法&>>
在VERBATIM
模式下使用(它被引号包围)。
因此,在 中似乎不可能有重定向和非扩展变量add_custom_command
,您可能只有其中任何一个。
推荐阅读
- speech-recognition - 从谷歌语音 api 结果中检测流畅度
- perl - 切换到新安装的 Perl 版本以在 CentOS 6 上迁移 otrs 配置文件
- glib - 如何将 glib 信号回调附加到某些线程上下文
- javascript - D3 v4:具有嵌套 g 标签的任意复杂数组的元素之间的间距和绑定
- reactjs - 低阶组件路由不起作用
- android - “dagger-android”库,如何注入Dialog类的属性?
- java - 在 Windows 7 上使用 Java SE DK 10.0.01 安装 Oracle SOA Suite 12c
- javascript - 即使表单具有有效值,Angular 4 按钮也被禁用
- docker - Win10 Pro删除后Docker安装失败
- php - 在所有字段类型上加载新的高级字段