CMake生成器表达式命令

时间:2018-10-01 06:23:36

标签: 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语句中,因为如果这样做,则目录标记不会扩展。

2 个答案:

答案 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>
    ...
)