I've got a project with two subdirectory projects (added with add_subdirectory), each with their own libraries, binaries and install/uninstall targets. So:
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())
I'd like for the top-level project (main_project) to automatically install the libraries a and b (included in main_project from target_link_libraries()). So, I'd like to be able to go:
cd main_project/build
cmake ..
make
sudo make install
and have the main_project binary and project_a/b libraries installed automatically. I've tried this:
main_project/src/CMakeLists.txt
...
install(FILES main project_a project_b DESTINATION bin
LIBRARY DESTINATION lib)
but a cmake ..
results in
install TARGETS given target "project_a" which does not exist in this directory.
as expected.
I've also tried specifying a path:
main_project/src/CMakeLists.txt
...
install(FILES main ${CMAKE_SOURCE_DIR}/project_a/ ${CMAKE_SOURCE_DIR}/project_b DESTINATION bin
LIBRARY DESTINATION lib)
which also complains that project_a/b are not in this directory (also expected, I guess?)
I've also tried installing the libraries "manually" with the FILES option in install(), and that works just fine, but that seems very kludgy considering there are perfectly good install()s in the subprojects.
One additional issue: since project_a and project_b also have uninstall() custom targets, I can't add an uninstall target to the main_project without CMake complaining about the custom target already existing. When I try adding an uninstall directive to the top dir CMakeLists:
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
But, since my project_a has an uninstall directive, I get:
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.
So, how do I install and uninstall the necessary library files from my subproject alongside my main_project?
install()
command, then main project doesn't need to do anything more about installing it. As for "uninstall", as subprojects already have given target, you may not create it in the main project. BTW, in case of 3d-party subprojects, when you cannot (or don't want to) change their code, preferrable way is to use ExternalProject_Add for configure and build them. For install subprojects with the main project, you may useinstall(SCRIPT)
orinstall(CODE)
. – Tsyvarevmake install
is called from top-level build directory, everyinstall()
command issued in subdirectory (added withadd_subdirectory()
) shoul have an effect. If this is not true in your case, try to create minimal reproducible example which triggers that behaviour. As for overriding custom targets, I don't know the way for doing that. – TsyvarevEXCLUDE_FROM_ALL
such that it doesn't build everything in the subdirectory, only the library I need. That flag seems to prevent the subdirectoryinstall()
from happening. PerhapsExternalProject_Add
is indeed the best way to go here... – Allan