在 CMake 中使用生成器表达式有什么好处?

Sea*_*ean 4 expression cmake

最近学习了如何使用CMake中的生成器表达式来做条件链接和条件定义。

但是,在我看来,我也可以使用 CMake 中的流控制语法来做同样的事情。不知道CMake中生成器表达式的优点是什么。例如,我可以使用以下生成器表达式语法。

$<STREQUAL:string1,string2> 
$<EQUAL:number1,number2> 
$<VERSION_EQUAL:version1,version2> 
$<VERSION_GREATER:version1,version2> 
$<VERSION_LESS:version1,version2>
Run Code Online (Sandbox Code Playgroud)

但我也可以使用if() elseif() endif()来达到相同的目标。非常感谢。

Tsy*_*rev 6

使用生成器表达式可以在多配置生成器中针对不同的构建类型对项目进行不同的配置。对于这样的发电机项目配置(与运行cmake一次,但可几个后构建类型。此类生成器的示例是 Visual Studio。

对于多配置生成器CMAKE_BUILD_TYPE在配置阶段未知。由于使用if-else切换不起作用:

# Doesn't work for multi-configuration generators:
#   CMAKE_BUILD_TYPE is not defined
#
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    add_compile_definitions("-DDEBUG_LEVEL=2")
elif(CMAKE_BUILD_TYPE STREQUAL "Release")
    add_compile_definitions("-DDEBUG_LEVEL=0")
endif()
Run Code Online (Sandbox Code Playgroud)

但是使用条件生成器表达式是有效的:

add_compile_definitions(
    $<$<CONFIG:Debug>:-DDEBUG_LEVEL=2>
    $<$<CONFIG:Release>:-DDEBUG_LEVEL=0>
    )
Run Code Online (Sandbox Code Playgroud)

CMake 不会立即扩展生成器表达式,当它们在CMakeLists.txt. 相反,它们会保持打包状态,直到全部CMakeLists.txt处理完毕。那时 CMake 知道项目创建的所有目标,以及该目标的属性,其中可能包含生成器表达式。

只有在创建特定于生成器的构建文件(例如.slnVisual Studio 的文件)时,CMake 才会在目标属性中扩展生成器表达式:当为“调试”构建实例化时,目标属性被评估为$<CONFIG>等于“调试”,当为“发布”构建实例化时,目标被评估为$<CONFIG>等于“Release”,依此类推。

因为生成器表达式只在配置过程结束时计算,所以它们不能用message()命令打印(更准确地说,可以调用message()一个包含生成器表达式的字符串,但这个字符串将被打印而没有扩展)。

通常,生成器表达式只能在那些 CMake 命令和目标属性中使用,它们明确记录了这种用法。