Cmake 生成器表达式命令



如果某些布尔条件为真(例如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 语句中,因为如果我这样做,则目录令牌不会展开。

代码可读性方面,生成器表达式是 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>
...
)

您可以在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

最新更新