我正在为使用CMake且具有单独的源和构建目录的项目提供自定义功能(例如, MyFeature )。 MyFeature 由一个二进制文件组成。 ( MyFeature 实际上是一个自定义Simulink库,所以我必须调用MATLAB来创建它 - 重要的是创建对象不涉及GCC或CMake使用的其他标准构建工具默认情况下。)所以我有一个特殊的规则来构建对象 - 让我们说 myRule 。我希望 make 仅在(a) MyFeature 不存在时运行 myRule ,或者(b)上的一个源文件MyFeature 取决于 - 例如, MySource - 比当前存在的 MyFeature 更新。一个小小的附加皱纹是我只需要源树中的 MyFeature ,这是 myRule 通常放置的地方。我怎样才能完成这一切?
据我所知,我无法使用 add_executable 或 add_library ,因为它们是针对您使用GCC构建的对象(或者已经 - 配置)工具链。我无法使用 add_custom_target ,因为生成的目标始终已过期。到目前为止,我使用 add_custom_target 和 add_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 文件的命令似乎足以将 make 伪造为不重建在源树),它实现了我的目标之一。但是,一旦存在此假文件,即使我在源树中更新 MySource , make 也不会重建 MyFeature 。这是我被困的地方。这似乎特别令人费解,因为我可以在 CMakeFiles 内部看到 MyFeature 的目标确实列出了 MySource (具有正确的路径) - 在源树!)作为依赖。如果我试图在一个目录中使用更简单的(玩具)Makefile复制这种情况,如果我更新目标所依赖的源文件之一,即使目标输出文件已经存在, make < / strong>将做正确的事情 - 它将从更新的源重建对象,然后重建整个目标。那么为什么这种情况下的构建行为会有所不同呢?我能做些什么来实现目标(b)和目标(a)?谢谢!
答案 0 :(得分:0)
正如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 ,然后再次运行生成。 制作不会重新生成 MyFeature ,因为伪 MyFeature 仍然存在于构建树中。我怎样才能克服这个问题?