# Trouble with specifying CONFIGURATIONS in installs

**URL:** https://discourse.cmake.org/t/trouble-with-specifying-configurations-in-installs/13126
**Category:** Code
**Created:** [December 4, 2024, 11:36pm UTC](https://discourse.cmake.org/t/trouble-with-specifying-configurations-in-installs/13126 "2024-12-04T23:36:42Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![EosPengwern](https://discourse.cmake.org/user_avatar/discourse.cmake.org/eospengwern/32/3904_2.png) [@EosPengwern](https://discourse.cmake.org/u/EosPengwern)
#### Post date: [December 4, 2024, 11:36pm UTC](https://discourse.cmake.org/t/trouble-with-specifying-configurations-in-installs/13126/1 "2024-12-04T23:36:42Z")

</div>

I’m trying to install a static library into my company’s directory structure, which has separate branches for debug and release versions of libraries.

Clearly, I want the debug build to go to the debug branch and the release build to go to the release branch. So my installation code looks like this:

```auto
        install(TARGETS ${target_name} ARCHIVE
                DESTINATION ${LIBS_INSTALL_DIR_CMAKE_D}
                PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR_ROOT}/${target_name}_${VER}/${target_name}
                CONFIGURATIONS Debug)

        install(TARGETS ${target_name} ARCHIVE
                DESTINATION ${LIBS_INSTALL_DIR_CMAKE_R}
                PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR_ROOT}/${target_name}_${VER}/${target_name}
                CONFIGURATIONS Release RelWithDebInfo MinSizeRel)

```

For the example of the debug build, I set up the build system (on Linux) thus:

```auto
    cmake -S . -B ../../build/solutions/myLib/debug -DAPPLICATION_NAME=myLib -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug 

```

…and then compile and install the library by typing:

```auto
cmake --build ../../build/solutions/myLib/debug --target install 

```

Everything compiles and installs, and what I _expect_ to happen is that, since I’m using the debug makefile, the debug version of the library will be built and installed in ‘LIBS\_INSTALL\_DIR\_CMAKE\_D’. What _actually_ happens is that the debug version of the library builds and then gets installed in _both_ LIBS\_INSTALL\_DIR\_CMAKE\_D _and_ LIBS\_INSTALL\_DIR\_CMAKE\_R, overwriting whatever release version library may already have been there.

Needless to say, the same thing happens the other way around.

What am I doing wrong?

…

---

<div class="post-metadata">

### Author: ![hsattler](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/59ef9b/32.png) [@hsattler](https://discourse.cmake.org/u/hsattler)
#### Post date: [December 5, 2024, 8:17am UTC](https://discourse.cmake.org/t/trouble-with-specifying-configurations-in-installs/13126/2 "2024-12-05T08:17:29Z")

</div>

ARCHIVE and PUBLIC\_HEADER each take a set of following options. So your ARCHIVE artifact is actually missing the CONFIGURATIONS option.

Read the help for the install commands again 😉

---

<div class="post-metadata">

### Author: ![EosPengwern](https://discourse.cmake.org/user_avatar/discourse.cmake.org/eospengwern/32/3904_2.png) [@EosPengwern](https://discourse.cmake.org/u/EosPengwern)
#### Post date: [December 5, 2024, 9:43am UTC](https://discourse.cmake.org/t/trouble-with-specifying-configurations-in-installs/13126/3 "2024-12-05T09:43:08Z")

</div>

I must admit it’s not at all clear to me from the documentation; but having read it through again, I can only think that you mean the section that says.

> If this option is used multiple times in a single call, its list of configurations accumulates. If an [`install(TARGETS)`](https://cmake.org/cmake/help/latest/command/install.html#targets) call uses arguments, a separate list of configurations is accumulated for each kind of artifact.

If I’m reading that correctly in the context of your reply, that means I think I need to write

```auto
        install(TARGETS ${target_name} 
                ARCHIVE DESTINATION ${LIBS_INSTALL_DIR_CMAKE_D}
                CONFIGURATIONS Debug
                PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR_ROOT}/${target_name}_${VER}/${target_name}
                CONFIGURATIONS Debug)

        install(TARGETS ${target_name} 
                ARCHIVE DESTINATION ${LIBS_INSTALL_DIR_CMAKE_R}
                CONFIGURATIONS Release RelWithDebInfo MinSizeRel
                PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR_ROOT}/${target_name}_${VER}/${target_name}
                CONFIGURATIONS Release RelWithDebInfo MinSizeRel)

```

i.e. with each install component having its own CONFIGURATIONS specification.

Am I on the right track now?

---

<div class="post-metadata">

### Author: ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)
#### Post date: [December 5, 2024, 10:18am UTC](https://discourse.cmake.org/t/trouble-with-specifying-configurations-in-installs/13126/4 "2024-12-05T10:18:08Z")

</div>

That looks like it will work, but in future you might also need to add similar things for `RUNTIME` and `LIBRARY` destinations.

What I would do (_instead of explicit `DESTINATION` for different `CONFIGURATIONS`_) is setting `CMAKE_INSTALL_PREFIX`, especially that you do already run configuration twice (_in order to change `CMAKE_BUILD_TYPE`_), so:

```sh
$ cmake [...] -DCMAKE_BUILD_TYPE=Debug \
    -DCMAKE_INSTALL_PREFIX="/path/to/your/company/folders/debug"
$ cmake --build [...] --target install

$ cmake [...] -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX="/path/to/your/company/folders/release"
$ cmake --build [...] --target install

```

That way you won’t need to split `install` statements to set different `DESTINATION` values for different `CONFIGURATIONS`:

```cmake
# for CMAKE_INSTALL_LIBDIR, CMAKE_INSTALL_BINDIR, CMAKE_INSTALL_INCLUDEDIR and others
include(GNUInstallDirs)

install(TARGETS ${target_name}
    #EXPORT "${target_name}Targets"
    # these get default values from GNUInstallDirs, no need to set them
    #RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # bin
    #LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # lib
    #ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # lib
    PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR_ROOT}/${target_name}_${VER}/${target_name}
    #PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${target_name}"
    #INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

```

---

<div class="post-metadata">

### Author: ![EosPengwern](https://discourse.cmake.org/user_avatar/discourse.cmake.org/eospengwern/32/3904_2.png) [@EosPengwern](https://discourse.cmake.org/u/EosPengwern)
#### Post date: [December 5, 2024, 5:05pm UTC](https://discourse.cmake.org/t/trouble-with-specifying-configurations-in-installs/13126/5 "2024-12-05T17:05:19Z")

</div>

Yes, that was the right track, and it worked.

I had some other problems because there were a lot of lines in my codebase of the form:

```auto
install(CODE "...."
        CONFIGURATIONS Release RelWithDebInfo MinSizeRel )

```

…and it took me a while to realise that, even though this didn’t cause any errors or warnings, the CONFIGURATIONS specifier is completely ignored for install(CODE…). I couldn’t find the place in the documentation, if any, where this was mentioned.

To achieve the desired result, I had to resort to some very baroque generator expressions of the form:

```auto
    set(do_the_thing_if_not_debug "$<$<CONFIG:Debug>:\"${CMAKE_COMMAND} -E echo \">$<$<NOT:$<CONFIG:Debug>>:The thing I wanted to do...>")
    INSTALL(CODE "execute_process(COMMAND ${do_the_thing_if_not_debug})") 

```

Either way I got there in the end.
