glennr
glennr

Reputation: 2199

Rename the output of CPack

I would like to rename the installer file that CPack (v2.8.7) produces to include a version number that is obtained at build time from the version control system. It appears this cannot be be done by setting the CPACK_* variables because that happens at "cmake" time.

What I want to be able to do is to run "(n)make package" and have the installer file be created with no further commands required. The two possible approaches that I am aware of are manipulating the CPack filename variables at build time and renaming the final output of CPack.

If using "include(CPack)" in a CMakeLists.txt file then it appears that CPack always runs last and you can't have a post-build command. This mailing list message suggests that a custom target can be written to run CPack, but I was unable to figure out how to do that without creating infinite recursion.

How can this be done?

Upvotes: 8

Views: 5708

Answers (3)

safesintesi
safesintesi

Reputation: 11

This is an old question, but I faced a similar problem recently. Based on the documentation, CPack will rerun the CPackOption file before packaging each package built.

From that, you can simply set the CPackOption file in your CMakeLists.txt.

set(CPACK_PROJECT_CONFIG_FILE ${PROJECT_SOURCE_DIR}/CPackOptions.cmake)

And in your CPackOptions.cmake you can execute a process to find the version and rename the package.

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}")

Read the defaults for CPack variables before changing them, to reduce the lines to maintain.

Upvotes: 0

glennr
glennr

Reputation: 2199

With a bit of help from the CMake mailing list I figured out how to do it, using 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)

create-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}")

Upvotes: 5

André
André

Reputation: 19337

Why not extract the build-info from the VCS at cmake-time? Then you can easily modify the CPACK_PACKAGE_FILE_NAME to include your version-number.

Added bonus: When doing this at CMake-time, you can e.g. fill a "Readme.txt" file with the git-info using CMake's configure_file and add it to your package. Or perhaps use it to fill a "config.h", which is used in your builds.

Example: in one of my own projects, I have a little piece of CMake code which finds Git and extracts the current changeset hash from the source code repository. It may not be the best Git way of extracting the info, but it works for me...

# 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} )

The result will be a Git_Commit_Hash variable with the 7-char hash value, which is used when setting up 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}" )

Upvotes: 5

Related Questions