【发布时间】: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