我想重命名 CPack (v2.8.7) 生成的安装程序文件,以包含在构建时从版本控制系统获取的版本号。看来这不能通过设置 CPACK_* 变量来完成,因为这发生在“cmake”时间。
我想要做的是运行“(n)make package”并创建安装程序文件,而不需要其他命令。我知道的两种可能的方法是在构建时操作 CPack 文件名变量并重命名 CPack 的最终输出。
如果在 CMakeLists.txt 文件中使用“include(CPack)”,那么 CPack 似乎总是最后运行,并且您无法使用构建后命令。 此邮件列表消息建议可以编写自定义目标来运行 CPack,但我无法弄清楚如何在不创建无限递归的情况下做到这一点。
这怎么办?
为什么不在 cmake 时从 VCS 中提取构建信息?然后您可以轻松修改 CPACK_PACKAGE_FILE_NAME 以包含您的版本号。
额外的好处:在 CMake 时执行此操作时,您可以例如使用 CMake 的 configure_file 使用 git-info 填充“Readme.txt”文件,并将其添加到您的包中。或者也许用它来填充“config.h”,它在您的构建中使用。
示例: 在我自己的一个项目中,我有一小段 CMake 代码,它可以查找 Git 并从源代码存储库中提取当前的变更集哈希。它可能不是提取信息的最佳 Git 方式,但它对我有用......
# First try to find the git-executable
find_program( Git_EXECUTABLE NAMES git git.cmd PATHS
${Git_DIR}
ENV PATHS
$ENV{Git_DIR}
)
# Run "git log -n 1 --pretty="%h" for the current commit-hash
execute_process( COMMAND ${Git_EXECUTABLE} "log" "-n" "1" "--pretty=\"%h\""
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE Git_Commit_Hash
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# and use a regex to strip quotes.
string( REGEX REPLACE "^\"(.*)\"$" "\\1" Git_Commit_Hash ${Git_Commit_Hash} )
结果将是一个带有 7 个字符哈希值的
Git_Commit_Hash
变量,在设置 CPack 时使用:
set( CPACK_PACKAGE_NAME "MyProject" )
message( STATUS " CPack options: " ${CPACK_PACKAGE_NAME} )
message( STATUS " Preparing CPACK: " )
message( STATUS " and hash: ${Git_Commit_Hash}" )
set( CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${Git_Build_Version}_${CPACK_PACKAGE_VERSION}" )
在 CMake 邮件列表的一些帮助下,我找到了如何使用 subversion 来做到这一点。
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(myapp)
add_executable(main main.cpp)
install(TARGETS main DESTINATION .)
add_custom_target(first ALL
# update the working copy
COMMAND ${Subversion_SVN_EXECUTABLE} update ${CMAKE_SOURCE_DIR}
# generate cpackoptions.cmake at build time so we get the
# most recent revision number
COMMAND ${CMAKE_COMMAND}
-DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-DBINARY_DIR=${CMAKE_BINARY_DIR}
-Dproj_name=${CMAKE_PROJECT_NAME}
-P ${CMAKE_SOURCE_DIR}/create-cpackoptions.cmake
)
add_dependencies(main first)
set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_BINARY_DIR}/CPackOptions.cmake)
include(CPack)
创建cpackoptions.cmake
include(FindSubversion)
Subversion_WC_INFO(${SOURCE_DIR} ${proj_name})
set(revision ${${proj_name}_WC_REVISION})
configure_file(${SOURCE_DIR}/CPackOptions.cmake.in
${BINARY_DIR}/CPackOptions.cmake
@ONLY)
cpackOptions.cmake.in
set(CPACK_PACKAGE_FILE_NAME "@proj_name@-${CPACK_PACKAGE_VERSION}r@revision@-${CPACK_SYSTEM_NAME}")
这是一个老问题,但我最近遇到了类似的问题。 根据文档,CPack 将在打包构建的每个包之前重新运行 CPackOption 文件。
从此,您可以简单地在 CMakeLists.txt 中设置 CPackOption 文件。
set(CPACK_PROJECT_CONFIG_FILE ${PROJECT_SOURCE_DIR}/CPackOptions.cmake)
在 CPackOptions.cmake 中,您可以执行一个过程来查找版本并重命名包。
execute_process(
COMMAND get_my_version_from_VCS
OUTPUT_VARIABLE CPACK_PACKAGE_VERSION
)
# optionally rename the file if you need or do stuff
set(CPACK_PACKAGE_FILE_NAME "blabla-${CPACK_PACKAGE_VERSION}")
在更改 CPack 变量之前先阅读它们的默认值,以减少需要维护的行数。