CMake install (TARGETS in subdirectories)

27,677

Solution 1

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, running make install (or similar) from a subdirectory will not guarantee that targets from other directories are up-to-date.

Solution 2

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 a GLOBAL 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 invoke install 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.

Solution 3

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.

Share:
27,677

Related videos on Youtube

Mendes
Author by

Mendes

BY DAY: Working hard to turn ideas into borderline software BY NIGHT: Family, fun, barbecue and rockn´roll - go to sleep and brand new ideas again... C++, Javascript, MEAN, ReactJs, Relay and naturally C++ (never missing it) Forerunner into future.... http://stackrating.com/badge/Mendes

Updated on July 09, 2022

Comments

  • Mendes
    Mendes almost 2 years

    Consider the following CMakeLists.txt file:

    add_subdirectory(execA)
    add_subdirectory(libB)
    
    install(TARGETS execA libB
            RUNTIME DESTINATION bin
            LIBRARY DESTINATION lib
            ARCHIVE DESTINATION lib)
    

    I get the following error:

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

    execA and libB have their own CMakeList.txt files and are located under project directory, as well as the build directory I'm running cmake (cmake ..):

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

    How do I fix this error?

  • phcerdan
    phcerdan over 5 years
  • AceFunk
    AceFunk almost 4 years
    This sounds interesting... but without samples of what you're talking about... I just can't follow it.
  • woodz
    woodz about 3 years
    moving add_library()to top level is not enough
  • Tsyvarev
    Tsyvarev about 3 years
    @woodz: Could you elaborate, why this is not enough?
  • woodz
    woodz about 3 years
    @Tsyvarev: because the top level is not the same dir, if you have multiple subdirs and you wanna pick something from the one and something from the other
  • Tsyvarev
    Tsyvarev about 3 years
    If you have multiple subdirs, which contains libraries you want to install, then before CMake 3.13 you need to move all add_library calls, corresponding to the installed libraries, into the top-level. I see no specifics of the case with "multiple subdirs" against the case with a single subdir. Of course, moving add_library call is not convenient in some cases. But my answer doesn't imply that it will fit for any project.