如果指定文件被更改,如何执行CMake目标?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果指定文件被更改,如何执行CMake目标?相关的知识,希望对你有一定的参考价值。
我正在尝试在我的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以某种方式仅为过时语法生成解析器。
如果正确构造对它的调用,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过期时文件(S)。
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])
除了提出的自定义目标解决方案,如果您的目标依赖于某些生成的源,常见的工作流程如下:
添加生成源文件的目标。我建议使用完整路径以避免错误。
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}。
我有完全相同的问题。在阅读了如何生成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时,将在决定重新生成源之前检查命令和语法文件的更改。
以上是关于如果指定文件被更改,如何执行CMake目标?的主要内容,如果未能解决你的问题,请参考以下文章