如果某些布尔条件为真(例如ENABLE_TESTING),那么我想运行以下内容:
COMMAND ./b2 --with-filesystem --with-program_options --with-test
如果布尔条件为假,那么我反而想要:
COMMAND ""
似乎我可以通过以下非常丑陋的代码来实现:
COMMAND $<$<BOOL:${ENABLE_TESTING}>:./b2> $<$<BOOL:${ENABLE_TESTING}>:--with-filesystem> $<$<BOOL:${ENABLE_TESTING}>:--with-program_options> $<$<BOOL:${ENABLE_TESTING}>:--with-test>
但是正如您所看到的,我必须一遍又一遍地重复布尔测试。如果我天真地尝试将它们组合成一个表达式:
COMMAND $<$<BOOL:${ENABLE_TESTING}>:./b2 --with-filesystem --with-program_options --with-test>
然后我得到错误/bin/sh: 1: $<1:./b2: not found
。显然,在生成器表达式被求值之前已对空格进行了解析。所以我引用了整个内容:
COMMAND "$<$<BOOL:${ENABLE_TESTING}>:./b2 --with-filesystem --with-program_options --with-test>"
但这会产生错误/bin/sh 1: /b2 --with-filesystem --with-program_options --with-test: not found
。我想它将整个内容当作命令的名称而不是带有选项的命令。如何以一种干净且有效的方式编写此代码?
编辑:我试图简化代码,以作为一个最小的示例,但是我遗漏了一个额外的麻烦。此命令发生在ExternalProject_Add
部分中,我需要依赖于特殊标记,例如<BINARY_DIR>
。
COMMAND ./b2 "--stagedir=<BINARY_DIR>" --with-filesystem --with-program_options --with-test
我无法将命令移到其他地方的if语句中,因为如果这样做,则目录标记不会扩展。
答案 0 :(得分:0)
您可以在COMMAND_EXPAND_LISTS
的帮助下完成此操作:
cmake_minimum_required(VERSION 3.11)
set(ENABLE_TESTING 1)
add_custom_target(
foo COMMAND "$<$<BOOL:${ENABLE_TESTING}>:./b2;--with-filesystem;--with-program_options;--with-test>"
COMMAND_EXPAND_LISTS)
让我们检查一下它是否有效:
$ cmake .
$ VERBOSE=1 make foo
...
./b2 --with-filesystem --with-program_options --with-test
Built target foo
答案 1 :(得分:0)
在代码可读性方面,生成器表达式是CMake语言的不幸补充。在无法避免生成器表达式的情况下,我使用常规CMake变量来避免代码重复,即:
set (_runB2GenEx "$<BOOL:${ENABLE_TESTING}>")
ExternalProject_Add(example
...
COMMAND
$<${_runB2GenEx}:./b2>
$<${_runB2GenEx}:--stagedir=<BINARY_DIR>>
$<${_runB2GenEx}:--with-filesystem>
$<${_runB2GenEx}:--with-program_options>
$<${_runB2GenEx}:--with-test>
...
)