Friday, September 2, 2022

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

Issue

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?


Solution

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:

Workaround that works for libraries (but not executables) using CMAKE_<CONFIG>_POSTFIX:

set(CMAKE_DEBUG_POSTFIX "-debug")

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


Answered By - David Fong
Answer Checked By - Katrina (WPSolving Volunteer)