【问题标题】:CMake install (TARGETS in subdirectories)CMake 安装(子目录中的目标)
【发布时间】:2016-03-30 07:52:41
【问题描述】:

考虑以下CMakeLists.txt 文件:

add_subdirectory(execA)
add_subdirectory(libB)

install(TARGETS execA libB
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib)

我收到以下错误:

install TARGETS given target "execA" which does not exist in this
  directory

execAlibB 有自己的CMakeList.txt 文件,位于project 目录下,以及我正在运行的构建目录cmake (cmake ..):

project
  |------ CMakeList.txt (the one with the code)
  |----execA
  |      \- .cpp, .hpp and CMakelist.txt
  |----libB
  |      \- .cpp, .hpp and CMakelist.txt
  |---- lib
  |---- bin
  \---- build (where I´m commanding: $ cmake ..

如何解决这个错误?

【问题讨论】:

    标签: c++ makefile cmake


    【解决方案1】:

    尽管查看子目录中包含的 CMakeLists.txt 文件会有所帮助,但我猜它们包含 add_executable 和/或 add_library 语句来创建您的内容。
    另外,由于您的示例,我猜您正在为目标使用相同的目录名称。
    也就是说,您应该知道,在子目录的CMakeLists.txt 文件中定义的符号默认情况下在父目录中的CMakeLists.txt 文件的上下文中是不可见的。因此,您应该将 install 语句移动到子目录中的 CMakeLists.txt 文件中。
    如果我的想法是正确的,这应该可以解决问题。否则,我强烈建议您在问题中也发布上述其他文件的内容。

    无论如何,错误很明显。
    包含名为X 的目标的install 语句的文件不包含生成该目标的目标创建语句(add_executable 和其他),因此它继续说该目标不存在于那个目录。

    【讨论】:

      【解决方案2】:

      根据this bugreportinstall(TARGETS) 命令流只接受在同一目录中创建的目标

      因此,您需要将add_library() 调用移动到顶级目录,或者将install(TARGETS) 调用拆分为每个目标的调用,并将它们中的每一个移动到相应的子目录中。

      自从 CMake 3.13 install(TARGETS) can work 即使在其他目录中创建目标。

      install(TARGETS) 可以安装在其他目录中创建的目标。使用此类跨目录安装规则时,从子目录运行make install(或类似规则)并不能保证其他目录中的目标是最新的。

      【讨论】:

      • 这在 3.13 中已解决:安装:Allow installing targets created in another directory
      • add_library()移动到顶层是不够足够
      • @woodz:你能详细说明一下,为什么这还不够?
      • @Tsyvarev:因为顶层不是同一个目录,如果你有多个子目录并且你想从一个中选择一些东西,从另一个中选择一些东西
      • 如果您有多个子目录,其中包含要安装的库,那么在 CMake 3.13 之前,您需要将 all add_library 调用,对应于已安装的库,移动到顶层。对于具有单个子目录的情况,我没有看到“多个子目录”的情况的细节。当然,在某些情况下,移动add_library 呼叫并不方便。但我的回答并不意味着它适用于任何项目。
      【解决方案3】:

      这似乎仍然是 CMake 3.11 中的一个痛点。

      在我们的代码库中,我们在子目录中定义了许多目标,需要创建各种具有不同配置和(可能重叠)目标组合的安装程序。

      这是我的解决方案:

      • 在您的根 CMakeLists.txt 文件中调用 add_subdirectory 之前,使用您要包含在安装程序中的目标的名称创建一个 GLOBAL 属性。
      • 在您自己的自定义函数中包装目标创建函数(add_executable 等)。在这些函数中检查目标是否存在于全局属性中,并相应地调用 install

      这种方法允许您集中安装程序配置。

      另外:为了支持创建多个安装程序,我们将全局列表与其他安装程序属性一起填充到单独的 .cmake 文件中。当我们调用 cmake 时,我们将安装程序配置 CMake 文件的名称作为命令行参数传递。我们的根 CMakeLists.txt 文件只需使用该文件调用 include

      【讨论】:

      • 这听起来很有趣...但是没有您所说的示例...我无法理解。
      猜你喜欢
      • 2017-01-14
      • 1970-01-01
      • 2023-01-25
      • 2022-12-18
      • 2018-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-29
      相关资源
      最近更新 更多