如何处理 Mercurial 存储库和子存储库之间的目标名称冲突?

How to deal with target name conflicts between Mercurial repositories and subrepositories?

我的 Mercurial 存储库 repo1 有一个名为 foo 的自定义目标;别管它做了什么。我还有另一个存储库 repo2,我想将其用作 repo1 的子存储库。 repo2 以与 repo1 类似的方式开发,并且还有一个名为 foo 的自定义目标,做同样的事情(当然只是针对 repo2 目录)。

如果我尝试 运行 在 CMakeLists.txt 中使用 add_subdirectory(relative/path/to/repo2) 为 repo1 CMake,我得到:

CMake Error at CMakeLists.txt:123 (add_custom_target):
  add_custom_target cannot create target "foo" because another target with
  the same name already exists.  The existing target is a custom target
  created in source directory

我想我可以将存储库名称作为自定义目标名称的前缀,但这似乎是解决此问题的粗略方法;我有点喜欢 make foo 在概念上在 repo1 和 repo2 中做同样的事情。那么我可以在这里做些更聪明的事情吗?

方法取决于您的期望

make foo
  1. 仅为当前项目构建目标。也就是说,作为项目 1 目录中的 运行,make foo 应该为该项目构建目标。项目 2 相同。

    在那种情况下,使用 ExternalProject_Add 而不是 add_subdirectory 将项目绑定在一起。

  2. 两个项目的构建目标

    通常这样的目标是 "project-wide actions",例如 make uninstallmake test

    在这种情况下,在将目标添加到项目之前,您需要检查目标是否存在并采取适当的措施:

    if(NOT TARGET foo)
        <create target foo>
    endif()
    <append-new-actions-to-foo>
    

    步骤 "create" 和 "append" 取决于目标类型。

    例如,经典 uninstall 目标通过读取 install_manifest.txt 文件自动处理所有子项目:

    if(NOT TARGET uninstall)
        add_custom_target(uninstall ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
    endif()
    

    对于一般情况,您可以创建 每个项目目标 并通过 add_dependencies 将它们附加到 "shared" 目标:

    if(NOT TARGET foo)
        add_custom_target(foo)
    endif()
    add_custom_target(foo_${CMAKE_PROJECT_NAME} <do-something>)
    add_dependencies(foo foo_${CMAKE_PROJECT_NAME})