我正在尝试在我的C ++项目中使用ANTLR。我为指定的语法运行了ANTLR生成器,并使主要的prjct依赖它。
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)
问题是每次构建项目时都会运行ANTLR生成器并消耗足够的时间。我怎样才能让它只运行我的语法?或者也许可以使ANTLR以某种方式仅为过时语法生成解析器。
答案 0 :(得分:12)
add_custom_command 将 执行此操作。
这样的事情应该有效:
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)
这里,自定义目标每次都会“构建”,但它唯一要做的就是在它依赖的输出上构建自定义命令,但是当且仅当自定义命令的输出过时时才会过时到其DEPENDS文件。
答案 1 :(得分:3)
add_custom_command会不会这样做?在这里,您可以指定DEPENDS [depends ...],这将使命令仅在从属文件更改时执行。
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])
答案 2 :(得分:3)
除了提供自定义目标的解决方案外,如果您的目标依赖于某些生成的源,则常见的工作流程如下:
添加生成源文件的目标。我建议使用完整路径以避免错误。
add_custom_command(OUTPUT ${GENERATED_SOURCE_FILE}
COMMAND ${GENERATION COMMAND}
DEPENDS ${DEPENDENCIES}
)
设置生成的源文件的GENERATED属性。所以cmake不会抱怨缺少源文件。
set_source_files_properties(${GENERATED_SOURCE_FILE} PROPERTIES
GENERATED TRUE
)
照常将生成的源添加到目标。
add_executable(${YOUR_TARGET} SOURCES ${GENERATED_SOURCE_FILE})
因此,在提议的示例中,只有在某些$ {DEPENDENCIES}文件发生更改时才会启动$ {GENERATION COMMAND}。
答案 3 :(得分:0)
我有完全相同的问题。在阅读了如何生成makefile之后(因为cmake文档有很多不足之处),看起来最好的解决方案是使用OUTPUT表单的add_custom_command。这是我的例子
add_custom_command(OUTPUT
# In my cmake file I list every file generated
${PROJECT_SOURCE_DIR}/src/MyGrammar/file1
${PROJECT_SOURCE_DIR}/src/MyGrammar/file2
COMMAND ${ANTLR_COMMAND} ${PROJECT_SOURCE_DIR}/src/MyGrammar.g
-o {PROJECT_SOURCE_DIR}/src/MyGrammar
# In my case I used a script checked into source control,
# so I want to know when it changes too
DEPENDS ${ANTLR_COMMAND} ${PROJECT_SOURCE_DIR}/src/MyGrammar.g)
# cmake caches are problematic, so list the files in a variable
set(generated_sources src/MyGrammar/file1 src/MyGrammar/file2)
add_library(yourlib ${list_of_source_files} ${generated_sources})
然后在构建cmake时,会在决定重新生成源之前检查命令和语法文件是否有变化。