使用CMake的CPack工具打包项目
为了介绍如何使用CMake的CPack工具进行项目打包,这里使用了前文 CMake项目使用ctest+gtest进行单元测试中的示例。
为了更接近实际开发中项目的情况,自行下载gtest并进行源码编译来模拟实际项目中的依赖项;在实际的开发中,可能会有各种各样的配置文件需要在打包的时候一起发布出去,这里在根目录下创建一个bin目录(将所有项目生成的文件全部指定生成到此目录下的各个项目目录中),下面再创建一个demo目录(根据项目来取名),在demo目录中创建一个config.ini文件。
根目录的CMakeLists.txt
如下:
1cmake_minimum_required(VERSION 3.12.0)
2project(demo VERSION 0.1.0)
3
4# 这里不管系统有没安装GTest都从网络上下载源码进行编译,使用自己编译的GTest
5cmake_policy(SET CMP0135 NEW)
6message("download GTest...")
7include(FetchContent)
8FetchContent_Declare(googletest URL https://github.com/google/googletest/archive/refs/heads/main.zip)
9FetchContent_MakeAvailable(googletest)
10
11include(CTest)
12
13enable_testing()
14#设置编译后的可执行文件存放路径
15set(BIN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin)
16
17add_subdirectory(test)
18
19# 根据项目存放到以项目名命名的目录中
20set(EXECUTABLE_OUTPUT_PATH ${BIN_DIR}/${PROJECT_NAME})
21add_executable(${PROJECT_NAME} main.cpp)
22
23# 设置需要安装的文件
24install(DIRECTORY ${BIN_DIR}
25 DESTINATION ./
26 FILES_MATCHING
27 PATTERN "*.exe"
28 PATTERN "*.ini"
29)
30
31# 设置包的模式,可以是7Z、ZIP等等,参见cpack --help
32set(CPACK_GENERATOR 7Z)
33include(CPack)
为了让各个项目都将编译后的可执行文件按指定要求存放,需要在每个子项目中(project后)添加如下指令:set(EXECUTABLE_OUTPUT_PATH ${BIN_DIR}/${PROJECT_NAME})
本例中需要在test目录中修改CMakeLists.txt
:
1project(t)
2
3set(EXECUTABLE_OUTPUT_PATH ${BIN_DIR}/${PROJECT_NAME})
4
5add_executable(${PROJECT_NAME} test.cpp ../func.cpp)
6target_link_libraries(${PROJECT_NAME} PRIVATE gtest gtest_main)
7
8include(GoogleTest)
9gtest_discover_tests(t)
然后设置需要安装的文件,根据前面的设定,这里使用目录的方式设定安装文件:
1install(DIRECTORY ${BIN_DIR}
2 DESTINATION ./
3 FILES_MATCHING
4 PATTERN "*.exe"
5 PATTERN "*.ini"
6)
即将所有输出目录中的exe文件以及ini文件打包。
此时编译后的目录结构如下:
在build目录(有CMakeCache.txt的目录),运行cpack,即可得到打包后的文件,笔者的为demo-0.1.0-win64.7z
可以在build_CPack_Packages\win64\7Z\demo-0.1.0-win64查看打包的情况,这里有额外的include与lib,并不是想要的,是因为使用的GTest为自行编译的库,如果不想让它们出现在包中,可以在引入GTest之前设置INSTALL_GTEST
为OFF
现在很多项目都是使用的Git来管理项目,可以在打包的时候以Git的分支名时期时间,SHA组合的方式来命名包。
在根CMakeLists.txt
中的install指令前添加如下指令:
1string(TIMESTAMP vTimeStamp "%Y%m%d%H%M%S")
2execute_process(
3 COMMAND git log -1 --format=%h
4 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
5 OUTPUT_VARIABLE vGitCommit
6 OUTPUT_STRIP_TRAILING_WHITESPACE
7)
8
9execute_process(
10 COMMAND git rev-parse --abbrev-ref HEAD
11 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
12 OUTPUT_VARIABLE vGitBranch
13 OUTPUT_STRIP_TRAILING_WHITESPACE
14)
在include(CPack)
前加上set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${vGitBranch}-${vTimeStamp}-${vGitCommit}")
即可。
附上最终根CMakeLists.txt
:
1cmake_minimum_required(VERSION 3.12.0)
2project(demo VERSION 0.1.0)
3
4set(INSTALL_GTEST OFF)
5cmake_policy(SET CMP0135 NEW)
6message("GTest not found, download it...")
7include(FetchContent)
8FetchContent_Declare(googletest URL https://github.com/google/googletest/archive/refs/heads/main.zip)
9FetchContent_MakeAvailable(googletest)
10include(CTest)
11
12enable_testing()
13
14set(BIN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/bin)
15
16add_subdirectory(test)
17
18set(EXECUTABLE_OUTPUT_PATH ${BIN_DIR}/${PROJECT_NAME})
19add_executable(${PROJECT_NAME} main.cpp)
20
21string(TIMESTAMP vTimeStamp "%Y%m%d%H%M%S")
22execute_process(
23 COMMAND git log -1 --format=%h
24 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
25 OUTPUT_VARIABLE vGitCommit
26 OUTPUT_STRIP_TRAILING_WHITESPACE
27)
28
29execute_process(
30 COMMAND git rev-parse --abbrev-ref HEAD
31 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
32 OUTPUT_VARIABLE vGitBranch
33 OUTPUT_STRIP_TRAILING_WHITESPACE
34)
35
36install(DIRECTORY ${BIN_DIR}
37 DESTINATION ./
38 FILES_MATCHING
39 PATTERN "*.exe"
40 PATTERN "*.ini"
41)
42
43set(CPACK_GENERATOR 7Z)
44set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${vGitBranch}-${vTimeStamp}-${vGitCommit}")
45include(CPack)
- 原文作者:Witton
- 原文链接:https://wittonbell.github.io/posts/2023/2023-04-18-使用CMake的CPack工具打包项目/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。