【问题标题】:Custom object with dependencies in CMake在 CMake 中具有依赖关系的自定义对象
【发布时间】:2017-05-30 20:08:52
【问题描述】:

我正在为一个使用 CMake 并具有单独的源目录和构建目录的项目贡献一个自定义功能(例如,MyFeature)。 MyFeature 由单个二进制文件组成。 (MyFeature 实际上是一个自定义 Simulink 库,所以我必须调用 MATLAB 来创建它——这里重要的是创建对象不涉及 GCC 或 CMake 使用的其他标准构建工具默认情况下。)所以我有一个特殊的规则来构建对象——比如说myRule。我希望 ma​​ke 仅在 (a) MyFeature 不存在或 (b) 所在的一个源文件时运行 myRule MyFeature 取决于——例如,MySource——比当前存在的 MyFeature 更新。一个小的额外皱纹是我只需要在源代码树中的 MyFeature,这是 myRule 通常放置它的地方。我怎样才能完成这一切?

据我所知,我不能使用 add_executableadd_library,因为它们是为您使用 GCC 构建的对象(或者已经 -配置)工具链。我无法使用 add_custom_target,因为生成的目标总是过时。到目前为止,我使用 add_custom_targetadd_custom_command 的组合取得了一些进展,如下:

add_custom_target(fakeTarget
    DEPENDS MyFeature)

add_custom_command(OUTPUT MyFeature
    COMMAND myRule && touch ${CMAKE_CURRENT_BINARY_DIR}/MyFeature
    DEPENDS mySource)

add_dependencies(targetThatAlwaysRuns fakeTarget)

如果真正的 MyFeature 存在,那么在构建树中创建一个空 MyFeature 文件的命令似乎足以让 ma​​ke 不重建(在源代码树中),这实现了我的目标之一。但是,一旦这个假文件存在,即使我在源代码树中更新 MySourcema​​ke 也不会重建 MyFeature。这就是我卡住的地方。这似乎特别令人费解,因为我可以在 CMakeFiles 内部看到 MyFeature 的目标确实列出了 MySource (路径正确--在源代码树中!)作为依赖项。如果我要尝试在单个目录中使用更简单的(玩具)Makefile 来复制这种情况,如果我更新目标所依赖的源文件之一,即使目标输出文件已经存在,ma​​ke 会做正确的事——它将从更新的源重建对象,然后重建整个目标。那么为什么这种情况下的构建行为会有所不同呢?我能做些什么来实现目标(b)和目标(a)?谢谢!

【问题讨论】:

  • 假设add_custom_rule 你的意思是add_custom_command,你的方法应该有效。尝试在 DEPENDSOUTPUT 选项中使用绝对路径。 “一个小问题是我真的只需要源树中的 MyFeature” - 没有什么能阻止您在源树中创建文件。
  • 糟糕!是的,我的意思是 add_custom_command - 已编辑以解决此问题。没错,没有什么能阻止我在源代码树中创建文件。我正在解释我将一个空文件放入构建树中的原因。 CMake确实阻止我在源树中定义目标,因此,add_custom_command 中的输出文件也不能在源树中。
  • 将绝对路径添加到 add_custom_command 中的 DEPENDS 选项有效!谢谢!
  • 现在的问题是如何避免将虚拟 MyFeature 文件写入构建树以使 Make 跳过构建规则是否存在真正的 MyFeature。这个 hack 的问题在于,如果用户删除了源树中的真实 MyFeature:只要假的 MyFeature 仍在构建树,Make 不会重新生成 MyFeature
  • 不太明白:如果需要MyFeature源码树中生成,为什么要在二叉树中创建呢? ? add_custom_command 的 OUTPUT 也可以在源代码树中,使用绝对路径即可。

标签: cmake simulink custom-object build-dependencies


【解决方案1】:

正如 Tsyvarev 在他的评论中建议的那样,我所要做的就是用绝对路径指定 DEPENDS 依赖项:

add_custom_target(fakeTarget
    DEPENDS MyFeature)

add_custom_command(OUTPUT MyFeature
    COMMAND myRule && touch ${CMAKE_CURRENT_BINARY_DIR}/MyFeature
    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/mySource)

add_dependencies(targetThatAlwaysRuns fakeTarget)

但是,现在假设用户从源代码树中删除了真正的 MyFeature,然后再次运行 MakeMake 不会重新生成 MyFeature,因为伪造的 MyFeature 仍然存在于构建树中。我该如何克服这个问题?

【讨论】:

    猜你喜欢
    • 2011-12-31
    • 1970-01-01
    • 2017-06-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 2014-09-06
    相关资源
    最近更新 更多