How to install in multiple locations (prefixes) without building again?

I use a top-level CMake projects with ExternalProject to manage the build/assembling of a big software release consisting of many CMake subprojects (each one builds install with cmake --build / --install).

e.g. an entry for a subproject in the top-level CMakeLists.txt would look like:

    DEPENDS dependency1 dependency2 ...
    SOURCE_DIR ${CMAKE_BINARY_DIR}/Source/subproject1
    BUILD_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/Build/subproject1 --config ${CMAKE_BUILD_TYPE}
    INSTALL_COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR}/Build/subproject1 --config ${CMAKE_BUILD_TYPE}

Because the project can be built in various “flavours”, I repeat the top-level build N times once for each flavor, passing CMake variables to differentiate the flavour. But only a few of the subprojects actually build differently based on the flavour, so this is a waste of time.

A more optimized approach would be to declare only those flavor-dependent subprojects multiple times (i.e. one ExternalProject_Add call per flavour, with same git repo, but different CMake variables, which would end up installing the items in different locations depending on flavour)…
But then how to have the other subprojects (independent of flavour) installed into the multiple (flavour) locations from the same build, i.e. without building N times?
I want to keep using the install rules defined in the subproject’s CMakeLists.txt, i.e.:


and not a custom copy command such as:


Is there an option (to --install ideally) to switch install location without having to reconfigure/rebuild the subproject?

I have found only CMAKE_INSTALL_PREFIX / --prefix… doesn’t look like it is meant for this job.

Maybe I am complicating my life with using CMake for release engineering, and there is a simpler tool that does the job? But since I want to re-use the install rules defined in each subproject’s CMakeLists.txt, the question stands: how to avoid rebuilding the subproject, and install it into multiple locations?

I would have expected the --prefix option for cmake --install to do what you want here. If you’ve tried it, in what way does it not work for your scenario?

The reason I think it won’t work is that I have all my subprojects install their files in a specific directory (supplied at configuration time) or subdirectories of it, which is not a relative path, therefore ${CMAKE_INSTALL_PREFIX} is ignored by install().

To support ${CMAKE_INSTALL_PREFIX} I would have to change the install logic of those subprojects. (I was trying to keep backwards compatibility)

I kind of locked myself into a corner with that…

EDIT: I solved that by passing “.” as install directory variable mentioned above (but I also had that typed as a CACHE variable of type PATH, and I had to remove that as that would cause the path to become absolute, and ultimately ignoring CMAKE_INSTALL_PREFIX)

i.e. this is the part I had to remove in subprojects:
set(INSTALL_DIR "" CACHE PATH "If specified, it will be used as install destination")

If you are using cmake --install <build-dir> --prefix <somewhere>, that overrides CMAKE_INSTALL_PREFIX. The value of CMAKE_INSTALL_PREFIX is not used if you specify the --prefix option to cmake --install. The relative path of each installed item below the prefix is still used though, so your executables would still end up in bin below the prefix, libraries in lib, and so on.

I don’t know what INSTALL_DIR is, I don’t think that’s something CMake defines or uses. I’m assuming it is used somehow by your project.