2011-10-22 21 views
12

Estoy tratando de usar ANTLR en mi proyecto C++. Hice un objetivo para ejecutar el generador de ANTLR para la gramática especificada e hice el producto principal dependiente de él.¿Cómo se puede ejecutar el objetivo CMake si se modificó el archivo especificado?

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) 

El problema es que el generador ANTLR se ejecuta cada vez que construyo un proyecto y consume el tiempo suficiente. ¿Cómo puedo hacer que funcione solo si mi gramática ha sido modificada? O puede ser que sea posible hacer que ANTLR de alguna manera genere el analizador solo para la gramática desactualizada.

Respuesta

9

add_custom_command se hacer el truco, si construye la llamada a ella correctamente.

Algo como esto debería funcionar:

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) 

Aquí, el objetivo de encargo será "construir" cada vez, pero lo único que hará es construir el comando personalizado en cuya salida depende, pero si y solo si el resultado del comando personalizado está desactualizado con respecto a su (s) archivo (s) DEPENDE (s).

3

Add_custom_command ¿Hacer el truco? Aquí puede especificar DEPENDS [depende ...] que haría que el comando solo se ejecute cuando el archivo dependiente cambie.

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

Parece que no funciona. Como entendí, DEPENDS solo trabaja con objetivos, p. cada vez que se modifica el objetivo dependiente (se reconstruye la biblioteca, etc.) se ejecuta el comando. – DikobrAz

2

Además solución propuesta con el objetivo de costumbre, si su destino depende de algunas fuentes generado el flujo de trabajo común es la siguiente:

Agregar objetivo que genera el archivo de origen. Recomiendo usar rutas completas para evitar errores.

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

Establezca las propiedades GENERADAS de su archivo fuente generado. Entonces, cmake no se quejará por la falta del archivo fuente.

set_source_files_properties(${GENERATED_SOURCE_FILE} PROPERTIES 
    GENERATED TRUE 
) 

Agregue la fuente generada a su destino como de costumbre.

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

Así, en el ejemplo propuesto $ {} GENERACIÓN DE COMANDO serán sólo podrá iniciarse si algunas de $ {} Dependencias archivos fueron cambiados.

+0

De acuerdo con [documentos] (https://cmake.org/cmake/help/v3.6/command/add_custom_command.html), no es necesario marcar manualmente los archivos como 'GENERADOS', están marcados como tales por defecto. –

Cuestiones relacionadas