CMake 生成器表达式中的三元运算符

问题描述 投票:0回答:4

Cmake 的 生成器表达式 允许我在某些函数调用中使用逻辑表达式。例如,如果我想在调试模式下添加

/MTd
编译器标志,我可以说

add_compile_options($<$<CONFIG:Debug>:/MTd>)

如果

CONFIG
等于“Debug”,则会使用值“/MTd”调用
add_compile_options
,否则使用空字符串。

但通常,我不想在一个值和空字符串之间做出决定,而是在两个值之间做出决定。在上面的示例中,如果

CONFIG
not“调试”,我想传递
/MT
(不带尾随 d)。我希望有这样的语法:

add_compile_options($<$<CONFIG:Debug>:/MTd:/MT>)

请注意,根据 CMake 规范,上述内容是“无效代码”。我想出的最有效的方法是: add_compile_options($<$<CONFIG:Debug>:/MTd>$<$<NOT:$<CONFIG:Debug>>:/MT>)

这对我来说似乎非常多余。有没有更短、更易读的方法来在两个值之间做出决定?

注意:我意识到在这种特殊情况下,我可以这样写:

add_compile_options(/MT$<$<CONFIG:Debug>:d>)

但这对我来说似乎相当老套,并且仅在一个选项是另一个选项的子字符串的情况下才有效。

cmake ternary-operator
4个回答
35
投票

$<IF:?,true-value...,false-value...> true-value... if ? is 1, false-value... if ? is 0

使用示例:

target_link_libraries(MyLib PUBLIC $<IF:$<CONFIG:Debug>,cppzmq,cppzmq-static> )

其中 
cppzmq

是在

Debug
构建中使用的共享库,而
cppzmq-static
是在其他情况下使用的静态库,例如
Release
    


6
投票

cmake_minimum_required(VERSION 2.8.12) macro(ternary var boolean value1 value2) set(${var} $<${${boolean}}:${value1}>$<$<NOT:${${boolean}}>:${value2}>) endmacro() set(mybool 0) ternary(myvar mybool hello world) add_custom_target(print ${CMAKE_COMMAND} -E echo ${myvar} )

创建一个 
CMakeLists.txt

文件并运行

cmake . && make print
(生成器表达式仅在构建时评估)。

尝试将

mybool

的值更改为

0
1
,看看会发生什么。

下面的定义也有效,而且更清晰:

cmake_minimum_required(VERSION 2.8.12) macro(ternary var boolean value1 value2) if(${boolean}) set(${var} ${value1}) else() set(${var} ${value2}) endif() endmacro() set(mybool 0) ternary(myvar mybool hello world) add_custom_target(print ${CMAKE_COMMAND} -E echo ${myvar} )

TL;博士

ternary(var boolean value1 value2)


意味着,与 C/C++ 相比:

int var = boolean ? value1 : value2;

    


0
投票

add_custom_command(TARGET myProject PRE_BUILD COMMAND cd \"D:/projects/$<IF:$<CONFIG:Debug>,Debug,Release>\" COMMAND call prebuild.bat)

然后在生成的 Visual Studio 项目中,在项目“myProject”的属性窗口中。

当构建配置为“Debug”时,评估过程为:

    $<IF:$<CONFIG:Debug>,Debug,Release>
  1. $<IF:1,Debug,Release>
  2. Debug
  3. 
    
    

当构建配置为“Release”时,评估过程为:

    $<IF:$<CONFIG:Debug>,Debug,Release>
  1. $<IF:0,Debug,Release>
  2. Release
  3. 
    
    


0
投票
工作,我正在使用 cmake 3.28

macro(build_target src_dir install_dir i2c_addr is_prod_build) set(SUB_PROJ_PROD_QA $<IF:$<BOOL:${is_prod_build}>,PROD,QA>) message("SUB_PROJ_PROD_QA=${SUB_PROJ_PROD_QA}") endmacro()

然后我明白了,表达式根本没有被评估

[cmake] SUB_PROJ_PROD_QA=$<IF:$<BOOL:0>,PROD,QA>

	
© www.soinside.com 2019 - 2024. All rights reserved.