【问题标题】:CMake subdirectory install/uninstall targetsCMake 子目录安装/卸载目标
【发布时间】:2017-01-14 14:59:22
【问题描述】:

我有一个包含两个子目录项目(添加了 add_subdirectory)的项目,每个项目都有自己的库、二进制文件和安装/卸载目标。所以:

main_project
|
|--CMakeLists.txt
|--src/
   |--CMakeLists.txt (with binary target, install()
|
|--project_a
   |--CMakeLists.txt
   |--src/
      |--CMakeLists.txt (with library, install())
|
|--project_b
   |--CMakeLists.txt
   |--src/
      |--CMakeLists.txt (with library, install())

我希望顶级项目 (main_project) 自动安装库 a 和 b(包含在 target_link_libraries() 的 main_project 中)。所以,我希望能够去:

cd main_project/build
cmake ..
make
sudo make install

并自动安装 main_project 二进制文件和 project_a/b 库。我试过这个:

main_project/src/CMakeLists.txt
...
install(FILES main project_a project_b DESTINATION bin
        LIBRARY DESTINATION lib)

cmake .. 导致

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

正如预期的那样。

我也尝试过指定路径:

main_project/src/CMakeLists.txt
...
install(FILES main ${CMAKE_SOURCE_DIR}/project_a/ ${CMAKE_SOURCE_DIR}/project_b DESTINATION bin
        LIBRARY DESTINATION lib)

它还抱怨 project_a/b 不在此目录中(我猜也是预期的?)

我还尝试使用 install() 中的 FILES 选项“手动”安装库,效果很好,但考虑到子项目中有非常好的 install(),这似乎很麻烦。

还有一个问题:由于 project_a 和 project_b 也有 uninstall() 自定义目标,我无法在没有 CMake 抱怨自定义目标已经存在的情况下将卸载目标添加到 main_project。当我尝试将卸载指令添加到顶级目录 CMakeLists 时:

add_custom_target(uninstall
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)

但是,由于我的 project_a 有一个卸载指令,我得到:

CMake Error at CMakeLists.txt:37 (add_custom_target):
  add_custom_target cannot create target "uninstall" because another
  target with the same name already exists.  The existing target is a
  custom target created in source directory "/main_project/project_a".
  See documentation for policy CMP0002 for more details.

那么,如何从我的主项目旁边的子项目中安装和卸载必要的库文件?

【问题讨论】:

  • 不清楚你有什么,你想要什么。向我们展示您尝试过的代码。
  • 已编辑以包含我尝试过的内容。感谢您的帮助。
  • 由于子项目的CMakeLists.txt 已经发出install() 命令,那么主项目就不需要再安装它了。至于“卸载”,由于子项目已经给定了目标,您可能不会在主项目中创建它。顺便说一句,对于 3d 方子项目,当您不能(或不想)更改其代码时,最好的方法是使用 ExternalProject_Add 来配置和构建它们。与主项目一起安装子项目,您可以使用install(SCRIPT)install(CODE)
  • 嗯,当从顶层构建目录调用make install时,在子目录中发出的每个install()命令(添加add_subdirectory())都应该有效果。如果您的情况不是这样,请尝试创建触发该行为的minimal reproducible example。至于覆盖自定义目标,我不知道这样做的方法。
  • 我发现了问题。我正在添加要使用EXCLUDE_FROM_ALL 安装的子目录,这样它就不会在子目录中构建所有内容,而只会构建我需要的库。该标志似乎阻止了子目录install() 的发生。或许ExternalProject_Add 确实是最好的去处……

标签: cmake


【解决方案1】:

我发现了问题。我正在添加要使用 EXCLUDE_FROM_ALL 安装的子目录,这样它就不会在子目录中构建所有内容,而只会构建我需要的库。该标志似乎阻止了子目录 install() 的发生。也许 ExternalProject_Add 确实是最好的方法......

此外,RE 覆盖自定义目标,这对我有用:http://public.kitware.com/pipermail/cmake/2011-July/045269.html

【讨论】:

    猜你喜欢
    • 2016-03-30
    • 2023-01-25
    • 1970-01-01
    • 2018-08-17
    • 2018-07-16
    • 1970-01-01
    • 1970-01-01
    • 2022-12-18
    • 2013-12-29
    相关资源
    最近更新 更多