2015-06-25 6 views
5

ho seguente comando nel mio file CMakeLists.txtForza CMake per generare bersaglio CONFIGURE_FILE ogni costruire

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

Come faccio a farlo funzionare su ogni costruzione, ma non solo quando Version.h.in cambiamenti? Ho bisogno di questo perché Version.h contiene la macro __DATE__ e in realtà dovrebbe essere trattato come nuovo per ogni build, anche se rimane lo stesso.

Il Version.h.in sembra

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

Ciao @uranix !!! Posso chiederti qualcosa sul calcolo dell'errore del metodo che abbiamo usato? http://chat.stackexchange.com/rooms/31813/calculation-of-error –

risposta

4

ho trasferito la mia versione generazione stringa in una propria scrittura CMake che io chiamo con ${CMAKE_COMMAND} -P ... in add_custom_command()/add_custom_target() e fare il mio obiettivo di utilizzarlo dipendono da questo.

Nel tuo caso diciamo che dispone di uno script DateToVersionH.cmake come questo:

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

si può fare qualcosa di simile:

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

Vedi anche use CMake to get build-time svn revision

Questo potrebbe non essere sufficiente se il tuo ambiente di produzione controlla tutte le "esigenze da ricostruire" prima di chiamare i passaggi necessari (ad esempio in Ninja solo le uscite dei comandi personalizzati vengono riesaminati; per ulteriori dettagli, vedere Ninja documentation per la variabile di regola restat e this discussion che ha portato all'introduzione dell'opzione BYPRODUCTS in add_custom_command()).

Quindi potresti semplicemente aggiungere al tuo script di shell di build - prima di chiamare il vero make - rimuovendo il file oggetto contenente le informazioni sulla versione.

Oppure si sta forzando la ri-compilazione dell'oggetto prima del collegamento. Questo sarebbe - a patto di avere un Version.c che comprende Version.h - simile a questa:

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

Pensandoci bene, basta eliminare il file oggetto e utilizzando il vostro attuale soluzione __DATE__ è la soluzione più semplice.

Per un altro "soluzione versione Git" vedere CMake: Automatically use git tags as version strings e How can I pass git SHA1 to compiler as definition using cmake?

+0

Grazie per la risposta aggiornata, risolve completamente il mio problema! Ho appena sostituito la macro '__DATE__' con' @ _date @ 'nel mio' Version.h.in' – uranix

+0

@uranix Felice di sentirlo aiutato. Solo per completezza ho aggiunto alcuni commenti su Ninja e su come forzare la compilazione di qualcosa come un passo pre-linker. – Florian