CMake install (TARGETS in subdirectories)
Even though it would help seeing the CMakeLists.txt
files contained in the subdirectories, I guess they contain add_executable
and/or add_library
statements to create your stuff.
Also, because of your example, I guess you are using the same name of your directories for your targets.
That said, you should know that symbols defined in a CMakeLists.txt
file in a subdirectory are not visible by default within the context of the CMakeLists.txt
file in the parent directory. Because of that, you should rather move your install
statements within the CMakeLists.txt
files within your subdirectories.
This should solve the problem, if my thoughts were right. Otherwise, I strongly suggest you to post in your question also the content of the other files above mentioned.
Anyway, the error is quite clear.
The file that contains the install
statement for the target named X
does not contain a target creation statement (add_executable
and the others) that gives birth to that target, so it goes on saying that that target does not exist in that directory.
This still seems to be a pain point in CMake 3.11.
In our codebase, we have many targets defined in subdirectories and need to create an assortment of installers with different configurations and (potentially overlapping) combinations of targets.
Here's my solution:
- Before calling
add_subdirectory
in your root CMakeLists.txt file, create aGLOBAL
property with the names of the target(s) you want to include in your installer. - Wrap target creation functions (
add_executable
, etc.) in your own custom functions. Within those functions check if the target is present in the global property, and invokeinstall
accordingly.
That approach allows you to centralize installer configuration.
Also: To support creation of multiple installers, we populate our global list along with other installer properties in separate .cmake files. When we invoke cmake
, we pass the name of the installer configuration CMake file as a command-line argument. Our root CMakeLists.txt file simply calls include
with that file.
According to this bugreport, install(TARGETS)
command flow accepts only targets created within the same directory.
So you need either move the add_library()
call into the top-level directory, or split install(TARGETS)
call into per-target ones, and move each of them into the corresponding subdirectory.
Since CMake 3.13 install(TARGETS)
can work even with targets created in other directories.
install(TARGETS)
can install targets that were created in other directories. When using such cross-directory install rules, runningmake install
(or similar) from a subdirectory will not guarantee that targets from other directories are up-to-date.