第 10 步:添加生成器表达式
Generator expressions在构建系统生成期间进行评估,以生成特定于每个构建配置的信息。
Generator expressions在许多目标属性的上下文中是允许的,例如LINKLIBRARIES, INCLUDEDIRECTORIES,COMPILEDEFINITIONS和别的。它们也可以在使用命令填充这些属性时使用,例如 targetlinklibraries(),targetincludedirectories(), targetcompile_definitions()和别的。
Generator expressions 可用于启用条件链接、编译时使用的条件定义、条件包含目录等。条件可以基于构建配置、目标属性、平台信息或任何其他可查询信息。
有不同类型的 generator expressions包括逻辑、信息和输出表达式。
逻辑表达式用于创建条件输出。基本表达式是0 and 1表达式。A$<0:...>产生空字符串,并<1:...>产生 的内容...。它们也可以嵌套。
的一个常见用法 generator expressions是有条件地添加编译器标志,例如语言级别或警告的标志。一个很好的模式是将此信息与INTERFACE 允许此信息传播的目标相关联。让我们首先构造一个 INTERFACE目标并指定所需的 C++ 标准级别,11 而不是使用CMAKECXXSTANDARD.
所以下面的代码:
*CMakeLists.txt*
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
将被替换为:
*CMakeLists.txt*
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
注意:接下来的部分将需要更改 cmakeminimumrequired()代码中的用法。即将使用的生成器表达式是在3.15中引入的。更新调用以要求更新版本:
*CMakeLists.txt*
cmake_minimum_required(VERSION 3.15)
接下来,我们为项目添加所需的编译器警告标志。由于警告标志因编译器而异,我们使用COMPILELANGAND_ID 生成器表达式来控制在给定语言和一组编译器 ID 的情况下应用哪些标志,如下所示:
*CMakeLists.txt*
set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
target_compile_options(tutorial_compiler_flags INTERFACE
"$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)
看看这个,我们看到警告标志被封装在一个 BUILD_INTERFACE条件中。这样做是为了使我们已安装项目的消费者不会继承我们的警告标志。
练习:修改MathFunctions/CMakeLists.txt,使所有目标都有一个targetlinklibraries()打电话给tutorialcompilerflags.