One CMakeLists.txt file creating multiple relocatable install packages.

I have a CMake project that is something like:

top
  CMakeLists.txt
  +---foo
  |     CMakeLists.txt
  |     source/header files
  +---bar
        CMakeLists.txt
        source/header files

In this configuration the foo folder creates a CMake library name foo and has relocatable CMake package files, and header files.

The folder bar is the same, except for a library named bar.

The top/CMakeLists.txt is pretty much a helper that just does add_subdirectory() on foo and bar

The problem I’m having is with install. When I run install I want this to go to:

<CMAKE_INSTALL_PREFIX>
  +--foo
  |   +--cmake
  |   +--include
  |   +--lib
  +--bar
      +--cmake
      +--include
      +--lib

But I cannot figure out how to have the foo and bar sub-folders.

My desire is to run

cd <top>
cmake -B Build .
cmake --build Build --target install

And foo and bar are compiled and then installed to the CMAKE_INSTALL_PREFIX folder.

I kept reading and digging and figured it out.

This install page was really helpful.

In short, I need to add foo or bar as part of the relative install paths for all the various install functions. I was thinking there might be a directory level setting that would work for this, but it’s a per install setting such as

install(TARGETS foo
    EXPORT foo_Targets
    LIBRARY       DESTINATION  "foo/bin"
    ARCHIVE       DESTINATION  "foo/lib"
    RUNTIME       DESTINATION  "foo/bin"
    PUBLIC_HEADER DESTINATION  "foo/include")

install(EXPORT foo_Targets FILE "FooTargets.cmake" DESTINATION "foo/cmake")
install(FILES "${PROJECT_BINARY_DIR}/FooConfig.cmake" DESTINATION "foo/cmake")

Yarg! This isn’t quite complete. The generated reloctable CMake package from install(EXPORT is wrong.

It sets the include path as <install-prefix>/include instead of <install-prefix>/foo/include

Does anyone have any insights on how to correct this?

Rather than using PUBLIC_HEADER, consider using file sets and specify INCLUDES DESTINATION instead. Among other things, this has the advantage of preserving directory structure if your headers need to be located in a subdirectory below foo/include.

1 Like

Thank you @craig.scott! Using that tip along with some additional google searches I was able to achieve what I wanted.

I created a simple POC for this on github, cmake-multi-pkg.

This allowed me to play with the functionality to do what I wanted in the simple case, and now I can translate this into my complex case much easier.

Thank you!