CMake安装(子目录中的目标)

29

请考虑以下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目录下,同样的构建目录也在我正在运行的cmakecmake ..)下:

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 ..

我该如何修复这个错误?

3个回答

21
根据这个bug报告install(TARGETS) 命令流只接受在相同目录中创建的目标
因此,您需要将 add_library() 调用移到顶层目录中,或者将 install(TARGETS) 调用拆分为每个目标,并将它们移动到相应的子目录中。
自从CMake 3.13以来,install(TARGETS) 可以使用其他目录中创建的目标。

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


2
此问题已于3.13版解决:install: 允许安装在其他目录中创建的目标 - phcerdan
add_library()移动到顶层不足以解决问题。 - woodz
@woodz:你能详细说明一下,为什么这还不够吗? - Tsyvarev
@Tsyvarev:因为顶层目录不同,如果你有多个子目录并且想从其中一个选择某些内容,而从另一个选择其他内容。 - woodz
如果您有多个子目录,其中包含您想要安装的库,则在CMake 3.13之前,您需要将与已安装库对应的所有 add_library 调用移动到顶层。我没有看到“多个子目录”与单个子目录的情况有什么具体区别。当然,在某些情况下,移动 add_library 调用并不方便。但我的答案并不意味着它适用于任何项目。 - Tsyvarev

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

5

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

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

以下是我的解决方案:

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

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

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


1
这听起来很有趣...但是如果没有你所说的示例,我就无法理解。 - AceFunk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接