With the cmake generator "Ninja Multi-Config" what is the proper way to handle CMAKE_INSTALL_PREFIX
. For instance, if you do:
$ cmake -DCMAKE_INSTALL_PREFIX=../install -G "Ninja Multi-Config" ..
$ cmake --build . --config Release --target install
And then afterwards do
$ cmake --build . --config Debug --target install
will the files in ../install
be overwritten by the Debug
install? What is the normal way to handle the install location in such cases?
By default they will be overwritten- Ie. with multi-config, the configurations' files install to the same locations.
If you don't mind having to do this kind of thing manually on the command-line each time you install, you can just use the --prefix
parameter for cmake --install <...>
.
From the docs for CMAKE_INSTALL_PREFIX
:
The
CMAKE_INSTALL_PREFIX
may be defined when configuring a build tree to set its installation prefix. Or, when using the cmake(1) command-line tool's--install
mode, one may specify a different prefix using the--prefix
option.
In that sense, CMAKE_INSTALL_PREFIX
can be seen as a default value set per-generated buildsystem that can be overridden on the commandline.
So you can do something like cmake --install <build_dir> --config <config> --prefix <install_dir_unique_to_config>
.
See this CMake mailing thread for various workarounds. Summarized here:
You can (with some exceptions- see the docs) use the <CONFIG>_POSTFIX
target property to append a postfix to an output name of a target.
set_target_properties(my_target <more targets can be listed here> PROPERTIES
DEBUG_POSTFIX "-debug"
RELEASE_POSTFIX "-release"
# etc.
)
Workaround using install(DESTINATION)
parameters:
This is hinted at in https://cmake.org/cmake/help/latest/command/install.html#example-install-targets-to-per-config-destinations.
install(TARGETS ${LIB_NAME}
CONFIGURATIONS DEBUG
EXPORT ${LIB_NAME}Config-d
PUBLIC_HEADER DESTINATION "include/${LIB_NAME}"
LIBRARY DESTINATION "bin/${LIB_NAME}/debug/"
ARCHIVE DESTINATION "lib/${LIB_NAME}/debug"
)
install(TARGETS ${LIB_NAME}
CONFIGURATIONS RELEASE
EXPORT ${LIB_NAME}Config
PUBLIC_HEADER DESTINATION "include/${LIB_NAME}"
LIBRARY DESTINATION "bin/${LIB_NAME}/release/"
ARCHIVE DESTINATION "lib/${LIB_NAME}/release/"
)
Nothing great here. I wish I could say you can use the installDir
property of your configuration presets and the ${presetName}
variable, but that just uses the configuration preset's name, and assuming you have multiple build presets for that configuration preset for various build configurations, this is not going to help. I've raised an issue ticket about this: Feature-request: Allow CMake Presets with multi-config generators to refer to build configuration name in installDir.
Note also that CMake 3.29 adds an environment variable option to set CMAKE_INSTALL_PREFIX
.