2012-03-08 18 views
5

Chciałbym zmienić nazwę pliku instalatora, który tworzy CPack (v2.8.7), aby zawierał numer wersji uzyskany w czasie kompilacji z systemu kontroli wersji. Wygląda na to, że nie można tego zrobić, ustawiając zmienne CPACK_ *, ponieważ dzieje się to w czasie "cmake".Zmień nazwę wyjściową CPack

Co chcę zrobić, to uruchomić "(n) make package" i utworzyć plik instalatora bez żadnych dodatkowych poleceń. Dwa możliwe podejścia, o których mi wiadomo, to manipulowanie zmiennymi nazw pliku CPack w czasie kompilacji i zmiana nazwy końcowego wyniku CPack.

Jeśli używasz "include (CPack)" w pliku CMakeLists.txt, to wydaje się, że CPack zawsze działa jako ostatni i nie możesz mieć polecenia po instalacji. This mailing list message sugeruje, że niestandardowy cel można zapisać do uruchomienia CPack, ale nie byłem w stanie wymyślić, jak to zrobić bez tworzenia nieskończonej rekursji.

Jak można tego dokonać?

Odpowiedz

5

Przy odrobinie pomocy z listy dyskusyjnej CMake zorientowałem się, jak to zrobić, używając 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 "@[email protected]${CPACK_PACKAGE_VERSION}[email protected]@-${CPACK_SYSTEM_NAME}") 
+0

Możesz pójść o krok dalej i wygenerować 'CPackOptions.cmake.in' oraz' create-cpackoptions.cmake' z pliku CMakeFile.txt. Oznacza to, że nie potrzebujesz dwóch plików w drzewie źródłowym. Na przykład: 'file (WRITE $ {CMAKE_BINARY_DIR} /CPackOptions.cmake.in" zestaw (CPACK_PACKAGE_FILE_NAME \ "@ proj_name @ - \ $ {CPACK_PACKAGE_VERSION} r @ revision @ - \ $ {CPACK_SYSTEM_NAME} \") ")") –

4

Dlaczego nie wyodrębnić informacji o projekcie z VCS w czasie cmake? Następnie możesz łatwo zmodyfikować plik CPACK_PACKAGE_FILE_NAME tak, aby zawierał numer wersji.

Dodatkowa premia: robiąc to w CMake-time, można np. wypełnij plik "Readme.txt" git-info za pomocą CMake'a configure_file i dodaj go do swojego pakietu. Lub może użyć go do wypełnienia "config.h", który jest używany w twoich kompilacjach.

Przykład: w jednym z moich własnych projektów, Mam mały kawałek kodu CMake która znajduje Git i ekstraktów aktualny changeset hash z repozytorium kodu źródłowego. To nie może być najlepszym sposobem Git ekstrakcji informacji, ale to działa na mnie ...

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

Rezultatem będzie Git_Commit_Hash zmienna o wartości hash 7-char, który jest używany podczas konfigurowania 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

ja naprawdę potrzebne to być w czasie kompilacji zamiast czasu cmake , ale dzięki za odpowiedź. – glennr

+0

Obawiałem się, że powiesz, że ... altenative ma wtedy uruchomić polecenie niestandardowe w czasie kompilacji, które robi to za ciebie. –

+0

To nie jest takie proste. Nie możesz przesłonić CPACK_PACKAGE_FILE_NAME w czasie kompilacji, ponieważ CPack odczytuje ją z pliku konfiguracyjnego. Musisz ustawić CPACK_PROJECT_CONFIG_FILE na plik generowany w czasie kompilacji. Oto, co robi kod w mojej odpowiedzi. – glennr