2011-10-22 9 views
12

Sto provando ad usare ANTLR nel mio progetto C++. Ho creato un obiettivo per l'esecuzione del generatore ANTLR per la grammatica specificata e ne ha reso il principale prjct dipendente da esso.Come rendere eseguito il target CMake se il file specificato è stato modificato?

ADD_CUSTOM_TARGET(GenerateParser 
    COMMAND ${ANTLR_COMMAND} ${PROJECT_SOURCE_DIR}/src/MyGrammar.g 
          -o ${PROJECT_SOURCE_DIR}/src/MyGrammar 
) 

ADD_LIBRARY(MainProject ${LIBRARY_TYPE} ${TARGET_SOURCES} ${TARGET_OPTIONS}) 
ADD_DEPENDENCIES(MainProject GenerateParser) 

Il problema è che il generatore ANTLR è in esecuzione ogni volta che progetto un progetto e consuma abbastanza tempo. Come posso farlo funzionare solo se la mia grammatica è stata modificata? O forse è possibile che ANTLR generi in qualche modo parser solo per grammatica obsoleta.

risposta

9

add_custom_command sarà fare il trucco, se si costruisce la chiamata a correttamente.

Qualcosa del genere dovrebbe funzionare:

ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/src/MyGrammar 
    COMMAND ${ANTLR_COMMAND} ${PROJECT_SOURCE_DIR}/src/MyGrammar.g 
    -o ${PROJECT_SOURCE_DIR}/src/MyGrammar 
    DEPENDS ${PROJECT_SOURCE_DIR}/src/MyGrammar.g 
) 

ADD_CUSTOM_TARGET(GenerateParser ALL 
    DEPENDS ${PROJECT_SOURCE_DIR}/src/MyGrammar 
) 

ADD_LIBRARY(MainProject ${LIBRARY_TYPE} ${TARGET_SOURCES} ${TARGET_OPTIONS}) 
ADD_DEPENDENCIES(MainProject GenerateParser) 

Qui, l'obiettivo personalizzato "costruire" ogni volta, ma l'unica cosa che farà è costruire il comando personalizzato sulla cui uscita dipende, ma se e solo se l'output del comando personalizzato non è aggiornato rispetto ai file DEPENDS.

3

Add_custom_command farebbe il trucco? Qui è possibile specificare DEPENDS [dipende ...] che renderebbe il comando eseguito solo quando il file dipendente cambia.

http://www.cmake.org/cmake/help/cmake2.6docs.html#command:add_custom_command

add_custom_command(OUTPUT output1 [output2 ...] 
       COMMAND command1 [ARGS] [args1...] 
       [COMMAND command2 [ARGS] [args2...] ...] 
       [MAIN_DEPENDENCY depend] 
       [DEPENDS [depends...]] 
       [IMPLICIT_DEPENDS <lang1> depend1 ...] 
       [WORKING_DIRECTORY dir] 
       [COMMENT comment] [VERBATIM] [APPEND]) 
+1

Sembra non funzionare. Come ho capito, DEPENDS funziona solo con gli obiettivi, ad es. ogni volta che il target dipendente è stato modificato (comando di ricostruzione della libra, ecc.) viene eseguito. – DikobrAz

2

Oltre soluzione proposta con l'obiettivo personalizzato, se l'obiettivo dipende da alcune fonti generato il flusso di lavoro comune è il seguente:

Add destinazione che genera il file di origine. Raccomando di utilizzare percorsi completi per evitare errori.

add_custom_command(OUTPUT ${GENERATED_SOURCE_FILE} 
    COMMAND ${GENERATION COMMAND} 
    DEPENDS ${DEPENDENCIES} 
) 

Imposta le proprietà GENERATE del file sorgente generato. Quindi cmake non si lamenterà del file sorgente mancante.

set_source_files_properties(${GENERATED_SOURCE_FILE} PROPERTIES 
    GENERATED TRUE 
) 

Aggiungi sorgente generata all'obiettivo come al solito.

add_executable(${YOUR_TARGET} SOURCES ${GENERATED_SOURCE_FILE}) 

Così nella proposta di esempio $ {} generazione di comando sarà lanciato solo se alcuni dei file $ {} Dipendenze sono stati cambiati.

+0

Secondo [documenti] (https://cmake.org/cmake/help/v3.6/command/add_custom_command.html) non è necessario contrassegnare manualmente i file come 'GENERATI', sono contrassegnati come tali da predefinito. –

Problemi correlati