问题描述
我有一个代码生成器(第三方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 (将#修改为@)