What is the proper way to handle `CMAKE_INSTALL_PREFIX` when using the Ninja Multi-Config cmake generator?

989 views Asked by At

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?

1

There are 1 answers

0
starball On BEST ANSWER

By default they will be overwritten- Ie. with multi-config, the configurations' files install to the same locations.

Command-line "manual" approach

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

defaults in CMakeLists.txt approach

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:

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/"
)

If you're using CMake Presets

You can use the installDir property of your configuration presets and the ${presetName} variable.


Note also that CMake 3.29 adds an environment variable option to set CMAKE_INSTALL_PREFIX.