2012-03-08 51 views
5

我想重命名CPack(v2.8.7)生成的安装程序文件,以包含在版本控制系统中生成的版本号。看来这不能通过设置CPACK_ *变量来完成,因为这发生在“cmake”时间。重命名CPack的输出

我想要做的就是运行“(n)make package”并且创建安装程序文件,而不需要进一步的命令。我知道的两种可能的方法是在构建时操作CPack文件名变量并重命名CPack的最终输出。

如果在CMakeLists.txt文件中使用“include(CPack)”,那么看起来CPack总是最后一次运行,并且不能有后期编译命令。 This mailing list message表示可以编写自定义目标来运行CPack,但我无法弄清楚如何在不创建无限递归的情况下如何实现这一点。

这怎么办?

回答

5

在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 "@[email protected]${CPACK_PACKAGE_VERSION}[email protected]@-${CPACK_SYSTEM_NAME}") 
+0

您可以更进一步,从CMakeFile.txt生成'CPackOptions.cmake.in'和'create-cpackoptions.cmake'。这意味着你不需要源代码树中的两个文件。例如:'file(WRITE $ {CMAKE_BINARY_DIR} /CPackOptions.cmake.in“set(CPACK_PACKAGE_FILE_NAME \”@proj_name @ - \ $ {CPACK_PACKAGE_VERSION} r @ revision @ - \ $ {CPACK_SYSTEM_NAME} \“)”)' – 2015-09-23 16:26:05

4

为什么不在cmake-time从VCS提取构建信息?然后,您可以轻松修改CPACK_PACKAGE_FILE_NAME以包含您的版本号。

新增奖金:在CMake时间进行此操作时,您可以使用CMake的configure_file用git-info填充“Readme.txt”文件并将其添加到您的包中。或者可以用它来填充一个“config.h”,它在你的版本中使用。

实施例:在自己的项目之一 ,我有一个小片的指找到GIT中并提取从源代码库中的当前变更散列CMake的代码。它可能不是提取信息的最佳方式的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}) 

其结果将是一个Git_Commit_Hash变量与7字符的哈希值,这是建立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}") 
+2

我真的需要它是在编译的时候,而不是cmake的时间,但无论如何感谢您的回答。 – glennr 2012-03-09 01:41:00

+0

我很害怕你会这样说......那么候选人就是在编译时运行一个自定义命令,它会为你做到这一点。 – 2012-03-09 09:04:23

+0

并不那么简单。您不能在构建时重载CPACK_PACKAGE_FILE_NAME,因为CPack会从配置文件中读取它。您必须将CPACK_PROJECT_CONFIG_FILE设置为在构建时生成的文件。这是我答案中的代码。 – glennr 2012-03-10 01:11:45