生成器式是在构建系统
生成时,执行的用来生成特定
配置专有信息的工具.
可在诸如LINK_LIBRARIES,INCLUDE_DIRECTORIES,COMPILE_DEFINITIONS
等许多目标属性
内容中使用生成式
.
也可在如target_link_libraries(),target_include_directories(),target_compile_definitions()
等使用命令
的属性时使用生成式
.
可用生成式
来启用条件链接
,编译时
定义条件
,条件包含目录
等.条件可基于构建配置,目标属性,平台信息或其他可查询信息
.
生成式有包括逻辑式,信息式和输出式
等不同类型
.
逻辑式
用来创建条件输出
.基本式是01
式,$<0:...>
结果是个空串
,$<1:...>
结果是"..."
的内容.同样都可嵌套
.
一般用来根据不同条件
来添加编译器标志
,如语言级
或警告
.好的模式
是把这些信息
和允许传播这些信息
的INTERFACE
目标关联
起来.
从构建一个INTERFACE
目标,并指定需要C++11
标准级别,而非CMAKE_CXX_STANDARD
开始.
下述代码,把:
//指定`C++`标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
替换为:
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
下一步
添加项目期望的编译器警告标志
.因为警告标志
基于编译器,用COMPILE_LAND_AND_ID
生成器式,来控制在给定语言
和一系列编译器id
下,使用哪些标志
.如下:
set(gcc_like_cxx "$")
set(msvc_cxx "$")
target_compile_options(tutorial_compiler_flags INTERFACE
"$<${gcc_like_cxx}:$>"
"$<${msvc_cxx}:$>"
)
可见在BUILD_INTERFACE
条件内封装
警告信息.这样可让安装项目
的用户
不会继承警告标志
.
练习,修改MathFunctions/CMakeLists.txt
,使所有目标都有调用tutorial_compiler_flags
的target_link_libraries()
.
步11
增加导出配置第四步
中,为CMake
增加了安装库和头文件
的功能.第七步
增加了打包
这些信息以发布
给其他人
的能力.
下一步是增加
必要信息,使其他CMake
项目无论是构建目录,本地安装还是按包
,都可用我们的项目.
第一步
是更新install(TARGETS)命令,来不仅指定DESTINATION
也指定EXPORT
.
EXPORT
关键字生成,一个含有可导入
安装树中,安装命令列举的所有目标
代码的CMake
文件.于是可通过更新MathFunctions/CMakeLists.txt
里的install
命令,来显式导出(EXPORT)MathFunctions
库:
set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs}
DESTINATION lib
EXPORT MathFunctionsTargets)
install(FILES MathFunctions.h DESTINATION include)
现在已导出了MathFunctions
,也需要显式
安装生成的MathFunctionsTargets.cmake
文件.可在顶级CMakeLists.txt
底部添加:
install(EXPORT MathFunctionsTargets
FILE MathFunctionsTargets.cmake
DESTINATION lib/cmake/MathFunctions
)
这时应试运行CMake
.如果都正确设置
了,CMake
应该会如下报错
:
在源目录前缀中,
Target "MathFunctions" INTERFACE_INCLUDE_DIRECTORIES property contains
path:
"/Users/robert/Documents/CMakeClass/Tutorial/步11/MathFunctions"
CMake
报错描述的是,生成导出
信息时,会导出在其他设备
上可能无效的绑定到当前设备
的内在路径
.
方法是更新MathFunctions
的target_include_directories()
,以明确在构建目录
和安装包
使用时需要的不同INTERFACE
位置.
即应如下修改MathFunctions
中的target_include_directories()
调用:
target_include_directories(MathFunctions
INTERFACE $ $)
更新后,就可重新运行CMake
,且不再有警告了.
这里,已配置CMake
打包好了期望
目标信息.但是仍需要生成MathFunctionsConfig.cmake
,来使CMake
的find_package()
可找到我们的项目.
所以继续在顶级项目
下,创建名为Config.cmake.in
的文件,并写入:
@PACKAGE_INIT@
include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" )
然后为了正确配置
安装该文件
.在顶级CMakeLists.txt
尾写入:
install(EXPORT MathFunctionsTargets
FILE MathFunctionsTargets.cmake
DESTINATION lib/cmake/MathFunctions
)
include(CMakePackageConfigHelpers)
//生成包含导出的配置文件
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
INSTALL_DESTINATION "lib/cmake/example"
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
//生成配置文件的版本文件
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}"
COMPATIBILITY AnyNewerVersion
)
//安装配置文件
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake
DESTINATION lib/cmake/MathFunctions
)
这里,已生成了可重定位的且可在安装或打包项目
后使用的CMake
配置.如果想在构建目录
中使用项目
.只需要在顶级CMakeLists.txt
尾添加:
export(EXPORT MathFunctionsTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake"
)
有此导出,生成MathFunctionsTargets.cmake
后,其他项目可无需安装
就使用,在构建
目录里配置好的MathFunctionsConfig.cmake
.
步12
:打包Debug
和Release
注意,该示例
仅对单配置
生成器有效.而对多配置
生成器无效(如VS
)
默认,CMake
模型是只包含一个配置
的构建目录
,也就是Debug,Release,MinSizeRel
或RelWithDebInfo
等的构建目录
.
但是是可通过CPack
打包多个构建目录
,及构建一个同一项目包含多个配置
的包.
首先,要确认debug
和release
构建使用不同的可执行和库名字
.使用d作为调试的可执行和库
的后缀.
在顶级CMakeLists.txt
文件的开头设置CMAKE_DEBUG_POSTFIX
:
set(CMAKE_DEBUG_POSTFIX d)
add_library(tutorial_compiler_flags INTERFACE)
给tutorial
的可执行文件添加DEBUG_POSTFIX
属性:
add_executable(Tutorial tutorial.cxx)
set_target_properties(Tutorial PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
target_link_libraries(Tutorial PUBLIC MathFunctions)
并给MathFunctions
库添加版本号
.在MathFunctions/CMakeLists.txt
设置VERSION
和SOVERSION
属性:
set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0")
set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
从步12
目录,创建debug
和release
子目录,结构如下:
- 步12
- debug
- release
现在设置debug
和release
构建.可用CMAKE_BUILD_TYPE
来设置配置类型
:
cd debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
cd ../release
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
现在已完成了构建debug
和release
.可用自定义配置文件
在同一
发布包中打包
构建两个
.在步12
目录里,创建叫MultiConfig.cmake
的文件.在文件中,首先包含cmake
创建的默认配置文件
.
接着,用CPACK_INSTALL_CMAKE_PROJECTS
变量来指定安装哪个项目
.这时,想安装debug
和release
两个版本:
include("release/CPackConfig.cmake")
set(CPACK_INSTALL_CMAKE_PROJECTS
"debug;Tutorial;ALL;/"
"release;Tutorial;ALL;/"
)
从步12
目录下,运行cpack
命令,通过config
选项来指定自定义配置文件
:
cpack --config MultiCPackConfig.cmake