2011-10-22 26 views
12

Tôi đang cố gắng sử dụng ANTLR trong dự án C++ của mình. Tôi đã thực hiện một mục tiêu để chạy máy phát điện ANTLR cho ngữ pháp được chỉ định và làm cho prjct chính phụ thuộc vào nó.Làm thế nào để thực hiện mục tiêu CMake được thực hiện cho dù tập tin được chỉ định đã được thay đổi?

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) 

Vấn đề là máy phát điện ANTLR chạy mỗi khi tôi xây dựng dự án và tiêu thụ đủ thời gian. Làm thế nào tôi có thể làm cho nó chạy chỉ cho dù ngữ pháp của tôi đã được thay đổi? Hoặc có thể làm cho ANTLR bằng cách nào đó tạo ra trình phân tích cú pháp chỉ cho ngữ pháp lỗi thời.

Trả lời

9

add_custom_command sẽ làm các trick, nếu bạn xây dựng cuộc gọi đến nó một cách chính xác.

Something như thế này nên làm việc:

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) 

Ở đây, mục tiêu tùy chỉnh sẽ "xây dựng" mọi thời gian, nhưng điều duy nhất nó sẽ làm là xây dựng các lệnh tùy chỉnh trên có đầu ra nó phụ thuộc, nhưng nếu và chỉ khi đầu ra của lệnh tùy chỉnh đã lỗi thời đối với (các) tệp DEPENDS của nó.

3

Add_custom_command có thực hiện thủ thuật không? Ở đây bạn có thể chỉ định DEPENDS [depends ...] sẽ làm cho lệnh chỉ thực hiện khi tệp phụ thuộc thay đổi.

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

Dường như không hoạt động. Như tôi đã hiểu, DEPENDS chỉ hoạt động với các mục tiêu, ví dụ: bất cứ khi nào các mục tiêu phụ thuộc đã được thay đổi (libary xây dựng lại, vv) lệnh được thực hiện. – DikobrAz

2

Bên cạnh đó đề xuất giải pháp với mục tiêu tùy chỉnh, nếu mục tiêu của bạn phụ thuộc vào một số nguồn tạo ra các quy trình làm việc chung như sau:

Thêm mục tiêu mà tạo ra tập tin nguồn của bạn. Tôi khuyên bạn nên sử dụng đường dẫn đầy đủ để tránh những sai lầm.

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

Đặt tính chất GENERATED của tệp nguồn được tạo. Vì vậy, cmake sẽ không phàn nàn về việc thiếu tập tin nguồn.

set_source_files_properties(${GENERATED_SOURCE_FILE} PROPERTIES 
    GENERATED TRUE 
) 

Thêm nguồn được tạo vào mục tiêu như bình thường.

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

Vì vậy, trong ví dụ được đề xuất $ {GENERATION COMMAND} sẽ chỉ được khởi chạy nếu một số tệp $ {DEPENDENCIES} bị thay đổi.

+0

Theo [tài liệu] (https://cmake.org/cmake/help/v3.6/command/add_custom_command.html) không cần phải đánh dấu thủ công các tệp là 'GENERATED', chúng được đánh dấu như vậy bởi mặc định. –

Các vấn đề liên quan