2012-03-08 16 views
5

Desidero rinominare il file di installazione che CPack (v2.8.7) produce per includere un numero di versione ottenuto in fase di compilazione dal sistema di controllo della versione. Sembra che questo non può essere fatto impostando le variabili CPACK_ * perché ciò accade nel tempo "cmake".Rinomina l'output di CPack

Quello che voglio essere in grado di fare è eseguire "(n) make package" e fare in modo che il file di installazione sia creato senza ulteriori comandi richiesti. I due possibili approcci di cui sono a conoscenza sono la manipolazione delle variabili del nome file CPack durante la compilazione e la ridenominazione dell'output finale di CPack.

Se si utilizza "include (CPack)" in un file CMakeLists.txt, sembra che CPack venga sempre eseguito per ultimo e non si possa avere un comando post-compilazione. This mailing list message suggerisce che è possibile scrivere un target personalizzato per eseguire CPack, ma non sono riuscito a capire come farlo senza creare una ricorsione infinita.

Come si può fare?

risposta

5

Con un po 'di aiuto da parte della mailing list CMake ho capito come farlo, con la sovversione.

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) 

creare-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

Si potrebbe fare un ulteriore passo avanti e generare 'CPackOptions.cmake.in' e' create-cpackoptions.cmake' da CMakeFile.txt. Ciò significa che non hai bisogno di due file nell'albero dei sorgenti. Ad esempio: 'file (WRITE $ {CMAKE_BINARY_DIR} /CPackOptions.cmake.in" set (CPACK_PACKAGE_FILE_NAME \ "@ proj_name @ - \ $ {CPACK_PACKAGE_VERSION} r @ revision @ - \ $ {CPACK_SYSTEM_NAME} \") ")' –

4

Perché non estrarre le informazioni di compilazione dal VCS in cmake-time? Quindi puoi facilmente modificare il CPACK_PACKAGE_FILE_NAME per includere il numero di versione.

Bonus aggiuntivo: quando si esegue questa operazione in CMake-time, è possibile ad es. riempire un file "Readme.txt" con git-info usando il configure_file di CMake e aggiungerlo al pacchetto. O forse usarlo per riempire un "config.h", che è usato nelle tue build.

Esempio: in uno dei miei progetti, ho un piccolo pezzo di codice CMake che trova Git ed estrae il hash di modifiche corrente dal repository del codice sorgente. Esso non può essere il modo migliore per Git di estrarre le informazioni, ma funziona per 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}) 

Il risultato sarà una variabile Git_Commit_Hash con il valore hash 7-char, che viene utilizzato quando si imposta 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

avevo davvero bisogno di essere al momento della compilazione piuttosto che il tempo cmake , ma grazie per la tua risposta comunque. – glennr

+0

Avevo paura che tu dicessi che ... l'altenativo è quindi eseguire un comando personalizzato al momento della compilazione che fa questo per te. –

+0

Non è così semplice. Non puoi eseguire l'override di CPACK_PACKAGE_FILE_NAME al momento della compilazione perché CPack lo legge da un file di configurazione. Devi impostare CPACK_PROJECT_CONFIG_FILE su un file che viene generato al momento della compilazione. Questo è ciò che fa il codice nella mia risposta. – glennr