CMake Tutorial 巡礼(12)_ 打包debug及release版本
这是本系列的第十三篇,也是完结篇。
上一篇我们学习了如何添加导出参数。这一篇我们来学习如何打包debug及release版本。
本章导读
第十二步 打包debug及release版本
Note: This example is valid for single-configuration generators and will not work for multi-configuration generators (e.g. Visual Studio).
注意:本例在单配置生成器中合法,但不适用于多配置生成器(例如 Visual Studio)。
By default, CMake’s model is that a build directory only contains a single configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo. It is possible, however, to setup CPack to bundle multiple build directories and construct a package that contains multiple configurations of the same project.
默认情况下,CMake的模型是构建目录,只包含单个配置,无论是调试、发布、MinSizeRel,还是RelWithDebInfo。但是,可以设置CPack来捆绑多个构建目录,并构建包含同一项目的多个配置的包。
First, we want to ensure that the debug and release builds use different names for the executables and libraries that will be installed. Let’s use d as the postfix for the debug executable and libraries.
首先,我们希望确保调试版本和发布版本使用不同的名称作为将要安装的可执行文件和库。让我们使用d作为debug模式下调试可执行文件和库的后缀。
Set
CMAKE_DEBUG_POSTFIX
near the beginning of the top-levelCMakeLists.txt
file:
在顶层的CMakeLists.txt
文件靠近开头的地方设置 CMAKE_DEBUG_POSTFIX
:
CMakeLists.txt
set(CMAKE_DEBUG_POSTFIX d)
add_library(tutorial_compiler_flags INTERFACE)
And the
DEBUG_POSTFIX
property on the tutorial executable:
以及tutorial可执行文件中的 DEBUG_POSTFIX
属性:
CMakeLists.txt
add_executable(Tutorial tutorial.cxx)
set_target_properties(Tutorial PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
target_link_libraries(Tutorial PUBLIC MathFunctions)
小白按: 此时CMakeLists.txt
全文件为:
cmake_minimum_required(VERSION 3.15)
# set the project name and version
project(Tutorial VERSION 1.0)
set(CMAKE_DEBUG_POSTFIX d)
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
# add compiler warning flags just when building this project via
# the BUILD_INTERFACE genex
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>>"
)
# control where the static and shared libraries are built so that on windows
# we don't need to tinker with the path to run the executable
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
if(APPLE)
set(CMAKE_INSTALL_RPATH "@executable_path/../lib")
elseif(UNIX)
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
endif()
# configure a header file to pass the version number only
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
set_target_properties(Tutorial PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
target_link_libraries(Tutorial PUBLIC MathFunctions)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
)
# add the install targets
install(TARGETS Tutorial DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
DESTINATION include
)
# enable testing
enable_testing()
# does the application run
add_test(NAME Runs COMMAND Tutorial 25)
# does the usage message work?
add_test(NAME Usage COMMAND Tutorial)
set_tests_properties(Usage
PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
)
# define a function to simplify adding tests
function(do_test target arg result)
add_test(NAME Comp${arg} COMMAND ${target} ${arg})
set_tests_properties(Comp${arg}
PROPERTIES PASS_REGULAR_EXPRESSION ${result}
)
endfunction()
# do a bunch of result based tests
do_test(Tutorial 4 "4 is 2")
do_test(Tutorial 9 "9 is 3")
do_test(Tutorial 5 "5 is 2.236")
do_test(Tutorial 7 "7 is 2.645")
do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
include(CPack)
# install the configuration targets
install(EXPORT MathFunctionsTargets
FILE MathFunctionsTargets.cmake
DESTINATION lib/cmake/MathFunctions
)
include(CMakePackageConfigHelpers)
# generate the config file that is includes the exports
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
)
# generate the version file for the config file
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}"
COMPATIBILITY AnyNewerVersion
)
# install the generated configuration files
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake
DESTINATION lib/cmake/MathFunctions
)
# generate the export targets for the build tree
# needs to be after the install(TARGETS ) command
export(EXPORT MathFunctionsTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake"
)
Let’s also add version numbering to the
MathFunctions
library. InMathFunctions/CMakeLists.txt
, set theVERSION
andSOVERSION
properties:
让我们也给MathFunctions
库添加一个版本号。在MathFunctions/CMakeLists.txt
中,设置VERSION
和SOVERSION
属性。
MathFunctions/CMakeLists.txt
set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0")
set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
From the
Step12
directory, createdebug
andrelease
subbdirectories. The layout will look like:
从Step12
的文件夹下,创建debug
和release
子文件夹。层级关系如下所示:
- Step12
- debug
- release
Now we need to setup debug and release builds. We can use
CMAKE_BUILD_TYPE
to set the configuration type:
现在我们需要创建debug和release生成。我们可以使用 CMAKE_BUILD_TYPE
来指定参数类型:
cd debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
cd ../release
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
小白按: 在Release版的编译时,应采用以下语句:
cd ../release
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --config release
Now that both the debug and release builds are complete, we can use a custom configuration file to package both builds into a single release. In the
Step12
directory, create a file calledMultiCPackConfig.cmake
. In this file, first include the default configuration file that was created by thecmake
executable.
至此,debug和release构建完成,我们可以使用一个自定义参数文件将两个生成文件打包到一个单独的安装包中。在Step12
路径下,创建一个名为MultiCPackConfig.cmake
的文件。在该文件中,首先包含由cmake
可执行地文件生成的默认参数文件。
Next, use the
CPACK_INSTALL_CMAKE_PROJECTS
variable to specify which projects to install. In this case, we want to install both debug and release.
接下来,使用CPACK_INSTALL_CMAKE_PROJECTS
变量来指定安装哪一个项目。在此例中,我们想要安装debug和release两个。
MultiCPackConfig.cmake
include("release/CPackConfig.cmake")
set(CPACK_INSTALL_CMAKE_PROJECTS
"debug;Tutorial;ALL;/"
"release;Tutorial;ALL;/"
)
From the
Step12
directory, runcpack
specifying our custom configuration file with theconfig
option:
从Step12
文件夹下,通过config
选项运行 cpack
指定我们的自定义参数文件:
cpack --config MultiCPackConfig.cmake
小白按: 此处小白并没有成功,报了一个错误,要先安装NSIS:
CPack Error: Cannot find NSIS compiler makensis: likely it is not installed, or not in your PATH
CPack Error: Could not read NSIS registry value. This is usually caused by NSIS not being installed. Please install NSIS from http://nsis.sourceforge.net
CPack Error: Cannot initialize the generator NSIS
安装完成后仍然会报错误,这里原因主要是路径不符合要求。方法是将release下生成的Release文件夹整个拷贝到debug目录下。最后执行:
"C:\Program Files\CMake\bin\cpack" --config MultiCPackConfig.cmake
如果一切顺利则会得到
CPack: Create package using NSIS
CPack: Install projects
CPack: - Install project: Tutoriald []
CPack: - Install project: Tutorial []
CPack: Create package
CPack: - package: C:/Users/Admin/Desktop/cmake-3.24.0-rc3-tutorial-source/Step12/Tutorial-1.0-win64.exe generated.
将会在以下路径得到一个安装包:
C:\Users\Admin\Desktop\cmake-3.24.0-rc3-tutorial-source\Step12\_CPack_Packages\win64\NSIS
小白按: 至此本系列告一个段落了。这份教材只是简单地对CMake官方教程做了一个翻译以及按部就班地跟着做。对于这份教材,小白个人也觉得远不够完美。不完美的原因也很简单,因为CMake中的内容艰深,小白的水平太次,比如在第九、第十节的小练习,小白还是没能完全解决。
但小白也有一些值得肯定的地方,对于这份语焉不详的教材,也踩通了一些坑点。
路漫漫其修远。小白觉得对于一个工具的学习,仅凭浮光掠影式、蜻蜓点水般的学习是远远不够的,要多用,多思,多练习。对于这份巡礼教程,它是到此为止了,但是对于CMake工具的学习要坚持深入下去。
【水平所限,错漏难免,创作不易,轻喷勿骂】