微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

带有代码生成器的CMake + Ninja需要两个构建周期

如何解决带有代码生成器的CMake + Ninja需要两个构建周期

我有一个代码生成器(第三方Java可执行文件),该代码生成器使用xml输入(不同的第三方API定义)来生成我需要在项目中使用的C ++头文件。我不知道生成的头文件名会是什么。我只需要查看生成器在其输出目录中生成内容。实际上,它是50多个文件,并且在更新xml时添加/删除/修改文件名。

我继承了这样的代码,该代码创建了一个目标generated_lib,项目的其他部分可以用来添加所需的包含目录:

add_custom_command(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/subdir_with_generated
  COMMENT "Generating C++ headers"
  PRE_BUILD
  DEPENDS api_deFinition.xml
  COMMAND java
    ARGS -Doptions.to.the.java.thing=123
    ARGS -jar ${JAVA_GENERATOR} ${CMAKE_SOURCE_DIR}/subdir/api_deFinition.xml
  )

add_custom_target(generated_stubs DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/subdir_with_generated)
add_library(generated_lib INTERFACE)
add_dependencies(generated_lib generated_stubs)
target_include_directories(generated_lib SYstem INTERFACE ${CMAKE_CURRENT_BINARY_DIR})

如果我使用Make作为CMake的-G选项,则结果系统将无法正常运行。最初的干净构建很好。典型的增量构建很好。但是,如果我touch subdir/api_deFinition.xml,那么每个随后的增量构建将重新生成标头,然后重新编译所有依赖于这些标头的内容,即使我不再触摸xml文件也是如此。很快就变得烦人了。

如果我将忍者用作我的-G(我的偏爱),则结果系统将以不同的方式运行不正常。初始构建很好。典型的增量构建很好。但是,如果我touch subdir/api_deFinition.xml,则下一个增量构建将重新生成文件,但将重新编译依赖于它们的文件。如果在此之后重新运行构建命令(ninja),那么所有依赖于标头的文件都将重新编译,然后一切都将恢复正常。

这些行为都不是“正确的”。我要么一遍又一遍地编译东西,要么必须非常小心地运行两次ninja,才能真正完成构建。

有没有办法让CMake在这里“做正确的事”?

我更喜欢使用忍者。我正在使用CMake 3.12.1,但可以升级

额外研究

基于this answer,我一直试图使用“时间戳记”文件标记生成文件的最后更改时间。

add_custom_command(
  OUTPUT generated.timestamp
  COMMENT "Generating C++ headers"
  DEPENDS ${JAVA_GENERATOR} api_deFinition.xml
  COMMAND java
    ARGS -Doptions.to.the.java.thing=123
    ARGS -jar ${JAVA_GENERATOR} ${CMAKE_SOURCE_DIR}/subdir/api_deFinition.xml
  COMMAND touch generated.timestamp
  )
                                                                                                      
add_custom_target(generated_stubs DEPENDS generated.timestamp)
add_library(generated_lib INTERFACE)
add_dependencies(generated_lib generated_stubs)
target_include_directories(generated_lib SYstem INTERFACE ${CMAKE_CURRENT_BINARY_DIR})

使用Make可以正常工作。始终不会重新生成和重新编译它。但是使用忍者,仍然存在需要两次ninja调用才能到达正确状态的问题。如果有人能够解决这个难题,我真的更愿意坚持忍者……

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。