CMake add_custom_command每次运行

时间:2020-11-05 20:55:52

标签: cmake

我正在使用自定义命令从ANTLR4语法生成C ++词法分析器。现在,我有以下内容:

set(MY_PARSER_INC
        ${PROJECT_SOURCE_DIR}/Headers/MyParser/MyLexer.h
        ${PROJECT_SOURCE_DIR}/Headers/MyParser/MyParser.h
        ${PROJECT_SOURCE_DIR}/Headers/MyParser/MyParserBaseVisitor.h
        ${PROJECT_SOURCE_DIR}/Headers/MyParser/MyParserVisitor.h
)
set(MY_PARSER_SRC
        ${PROJECT_SOURCE_DIR}/Sources/MyParser/MyLexer.cpp
        ${PROJECT_SOURCE_DIR}/Sources/MyParser/MyParser.cpp
)
add_custom_command(
        OUTPUT ${MY_PARSER_INC} ${MY_PARSER_SRC}
        DEPENDS ${PROJECT_SOURCE_DIR}/Grammars/MyGrammar.g4
        COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/Headers/MyParser/
        COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/Sources/MyParser/
        COMMAND java -cp "${ANTLR_CLASSPATH}" "org.antlr.v4.Tool" -Dlanguage=Cpp -visitor -no-listener -package MY::NESTED::NAMESPACE -encoding iso-8859-1 -o ${PROJECT_SOURCE_DIR}/Sources/MyParser/ ${PROJECT_SOURCE_DIR}/Grammars/MyGrammar.g4
        COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_SOURCE_DIR}/Sources/MyParser/*.h ${PROJECT_SOURCE_DIR}/Headers/MyParser/
        COMMAND ${CMAKE_COMMAND} -E remove -f ${PROJECT_SOURCE_DIR}/Sources/MyParser/*.h
        COMMENT "generating sources for My Parser"
)

然后使用add_library命令中的输出文件来维护依赖关系。

这完全符合我的预期。它正确创建了词法分析器和解析器。它也可以正确维护这些源与目标库之间的依赖关系。唯一的问题:它每次都运行!即使没有修改语法文件(我也会检查语法中的文件日期并确定会生成词法分析器/解析器)!我在网上看到了一些类似的问题,但仍然不知道为什么会这样。

有任何线索吗?!

EDIT1:

添加更多信息,因为可能尚不清楚。 在add_custom_command之后,我有以下内容:

include_directories(${PROJECT_SOURCE_DIR}/Headers/MyParser/)

add_library(MyLibrary SHARED
        ${MY_PARSER_INC} ${MY_PARSER_SRC}
        other_files.hpp other_files.cpp)

我认为这会在生成的源文件和目标库之间建立直接依赖关系。

1 个答案:

答案 0 :(得分:0)

这是我的猜测。

您需要创建一个自定义目标。

https://cmake.org/cmake/help/latest/command/add_custom_target.html?highlight=custom_target

add_custom_target(custom_target_create_parser_code DEPENDS
  ${MY_PARSER_INC} ${MY_PARSER_SRC}
)

这将使目标取决于您编写的自定义命令。

现在cmake可以附加命令了。

现在,您需要将依赖项添加到您提到的静态库中。 https://cmake.org/cmake/help/latest/command/add_dependencies.html

add_dependency(your_static_library custom_target_create_parser_code)

现在cmake不必每次都重新运行自定义命令代码。

编辑顺便说一句:

克雷格·斯科特(Craig Scott)的书实际上有一个专门讨论此主题的子章节:

https://crascit.com/professional-cmake/

第18章自定义目标

第18.3章生成文件的命令

编辑#2:

如果其他所有方法都失败,请尝试官方的cmake话语: https://discourse.cmake.org/

您的问题格式正确,cmake开发人员会寻找他们的问题。 所以你应该得到一个答案。

相关问题