2011-10-22 18 views
12

Próbuję użyć ANTLR w moim projekcie C++. Zrobiłem cel dla uruchomienia generatora ANTLR dla określonej gramatyki i uzależniłem od niego główny element.Jak wykonać cel CMake, czy określony plik został zmieniony?

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) 

Problem polega na tym, że generator ANTLR działa za każdym razem, gdy buduję projekt i zużywa wystarczającą ilość czasu. Jak mogę go uruchomić tylko, czy moja gramatyka została zmieniona? Lub może być możliwe, aby ANTLR w jakiś sposób wygenerował parser tylko dla nieaktualnej gramatyki.

Odpowiedz

9

add_custom_command będzie rade, jeśli budować połączenia z nim poprawnie.

Coś jak to powinno działać:

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) 

Tutaj cel zwyczaj będą „budować” za każdym razem, ale jedyną rzeczą, będzie to zrobić, to zbudować polecenie niestandardowe na którego wyjście to zależy, ale jeśli i tylko wtedy, gdy wynik polecenia niestandardowego jest nieaktualny w odniesieniu do plików DEPENDS.

3

Czy polecenie add_custom_command załatwiłoby sprawę? Tutaj możesz określić DEPENDS [zależy ...], który spowodowałby, że polecenie wykona się tylko, gdy zmienia się plik zależny.

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

Wydaje się nie działać. Jak rozumiem, DEPENDS działają tylko z celami, np. za każdym razem, gdy zmieniono obiekt zależny (odbudowano bibliotekę itd.), wykonywane jest polecenie. – DikobrAz

2

Oprócz proponowanego rozwiązania z niestandardowym tarczy, jeśli cel zależy od pewnych źródeł generowanych wspólnej pracy jest następujący:

Dodaj cel, który generuje plik źródłowy. Zalecam stosowanie pełnych ścieżek, aby uniknąć błędów.

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

Ustaw GENEROWANE właściwości wygenerowanego pliku źródłowego. Więc cmake nie będzie narzekał na brakujący plik źródłowy.

set_source_files_properties(${GENERATED_SOURCE_FILE} PROPERTIES 
    GENERATED TRUE 
) 

Dodaj wygenerowane źródło do celu jak zwykle.

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

Więc w proponowanym przykład $ {GENERACJA polecenie} zostanie uruchomiona tylko wtedy, gdy niektórzy z zależnościami} $ {pliki zostały zmienione.

+0

Zgodnie z [docs] (https://cmake.org/cmake/help/v3.6/command/add_custom_command.html) nie ma potrzeby ręcznego oznaczania plików jako "GENERATED", są one oznaczone jako takie przez domyślna. –

Powiązane problemy