2015-06-25 6 views
5

Mam następujące polecenia w moim pliku CMakeLists.txtSiła CUpewnij wygenerować configure_file cel każdego budować

configure_file([...]/Version.h.in [...]/Version.h @ONLY) 

Jak zrobić to uruchomić na każdej budowie, ale nie tylko, gdy Version.h.in zmiany? Potrzebuję tego, ponieważ Version.h ma w sobie makro i faktycznie powinno być traktowane jako nowe dla każdej kompilacji, nawet jeśli pozostaje taka sama.

Version.h.in wygląda

static const char VERSION[] = "Bla-bla-bla " @F[email protected] " built on " __DATE__; 
+0

Witam @uranix !!! Czy mógłbym zapytać cię o kalkulację błędu zastosowanej metody? http://chat.stackexchange.com/rooms/31813/calculation-of-error –

Odpowiedz

4

ja przeniesiony moje pokolenie ciąg wersji do własnego scenariusza CMake że nazywam się ${CMAKE_COMMAND} -P ... w add_custom_command()/add_custom_target() i uczynić mój cel stosując to zależy od niego.

W twoim przypadku powiedzmy masz DateToVersionH.cmake skrypt tak:

string(TIMESTAMP _date "%d %m %Y %H:%M") 
file(WRITE ${VERSION_FILE_NAME} "#define MY_VERSION \"Bla-bla-bla ${FOOBAR} built on ${_date}\"\n") 

można zrobić coś takiego:

add_custom_command(
    TARGET MyExe 
    PRE_BUILD 
    COMMAND ${CMAKE_COMMAND} -DVERSION_FILE_NAME=Version.h -DFOOBAR="${FOOBAR}" -P "${CMAKE_CURRENT_LIST_DIR}/DateToVersionH.cmake" 
) 

Zobacz także use CMake to get build-time svn revision

To może nie wystarczyć, jeśli twoje środowisko make sprawdza wszystkie "potrzeby przebudowania" przed wywołaniem niezbędnych kroków (np. w Ninja tylko wyjścia poleceń niestandardowych są ponownie skanowane; aby uzyskać więcej informacji, zobacz Ninja documentation dla zmiennej reguły i this discussion, co doprowadziło do wprowadzenia opcji BYPRODUCTS w add_custom_command()).

Można więc po prostu dodać do skryptu powłoki kompilacji - przed wywołaniem faktycznego make - usunięcie pliku obiektu zawierającego informacje o wersji.

Albo wymuszasz ponowną kompilację obiektu przed połączeniem. Byłoby to - przy założeniu, że masz Version.c który zawiera Version.h - wyglądać tak:

include_directories(${CMAKE_CURRENT_BINARY_DIR}) 
execute_process(COMMAND "${CMAKE_COMMAND}" -DVERSION_FILE_NAME=Version.h -DFOOBAR="${FOOBAR}" -P "${CMAKE_CURRENT_LIST_DIR}/DateToVersionH.cmake") 
add_library(MyVersionObj OBJECT Version.c) 

add_executable(MyExe ... $<TARGET_OBJECTS:MyVersionObj>) 

add_custom_command(
    TARGET MyExe 
    PRE_LINK 
    COMMAND "${CMAKE_COMMAND}" -DVERSION_FILE_NAME=Version.h -DFOOBAR="${FOOBAR}" -P "${CMAKE_CURRENT_LIST_DIR}/DateToVersionH.cmake" 
    COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --config $<CONFIG> --target "MyVersionObj" 
) 

Myśląc o tym, po prostu usuwając plik obiektowy i wykorzystując aktualna __DATE__ rozwiązanie jest najprostszym rozwiązaniem.

Dla innej wersji rozwiązania "git" zobaczyć CMake: Automatically use git tags as version strings i How can I pass git SHA1 to compiler as definition using cmake?

+0

Dziękuję za zaktualizowaną odpowiedź, całkowicie rozwiązuję mój problem! Właśnie zamieniłem makro '__DATE__' na' @ _date @ 'w moim' Version.h.in' – uranix

+0

@uranix Cieszę się, że pomogło. Dla uzupełnienia dodałem kilka komentarzy na temat Ninja i jak wymusić kompilację czegoś jako etapu wstępnego linkowania. – Florian