# How do I create multiple installation targets?

**URL:** <https://discourse.cmake.org/t/how-do-i-create-multiple-installation-targets/475>\
**Category:** Code\
**Created:** [January 10, 2020, 12:11pm UTC](https://discourse.cmake.org/t/how-do-i-create-multiple-installation-targets/475 "2020-01-10T12:11:28Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![xfbs](https://discourse.cmake.org/user_avatar/discourse.cmake.org/xfbs/32/284_2.png) [@xfbs](https://discourse.cmake.org/u/xfbs)\
**Post date:** [January 10, 2020, 12:11pm UTC](https://discourse.cmake.org/t/how-do-i-create-multiple-installation-targets/475/1 "2020-01-10T12:11:28Z")

</div>

Hey there. I am rewriting some build system for a larger project. Currently, we have multiple targets to install different components (install\_lib, install\_hdr, install\_data, etc). We need this because we generate different packages from the same code (a projectname.deb, projectname-dev.deb, projectname-data.deb).

Currently, this is implemented as add\_custom\_targets. I’d like to change this to use the native CMake install() statements. However, by doing that, everything is installed by the single `install` target — I can’t use that and separate them.

What is the best way to do this in CMake?

Cheers,  
-xfbs

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [January 11, 2020, 8:55am UTC](https://discourse.cmake.org/t/how-do-i-create-multiple-installation-targets/475/2 "2020-01-11T08:55:24Z")

</div>

Define COMPONENTS with your `install()` commands. That then opens up a few different ways to achieve what you describe. If you are invoking an install and creating packages manually (i.e. not using CPack), then you can use a command of the following form to install just the component you want:

```auto
cmake --install /path/to/build/dir --components MyComp ...

```

The `--install` option requires CMake 3.15 or later though. For earlier versions, you can achieve the same thing by running the `cmake_install.cmake` script in the top of your build tree through CMake’s `cmake -P` script mode. See the end of the `install()` command documentation in any recent version of the docs (even though it was only documented recently,it has worked for a long time, from what I recall).

If you are generating packages through CPack, you can let the package generator create the separate packages for each component (you can also create component groups). You control which components you want packages for with the `CPACK_COMPONENTS_ALL` variable just before you call `include(CPack)`.

---

<div class="post-metadata">

**Author:** ![xfbs](https://discourse.cmake.org/user_avatar/discourse.cmake.org/xfbs/32/284_2.png) [@xfbs](https://discourse.cmake.org/u/xfbs)\
**Post date:** [January 13, 2020, 10:54am UTC](https://discourse.cmake.org/t/how-do-i-create-multiple-installation-targets/475/3 "2020-01-13T10:54:04Z")

</div>

Ah, that makes sense. I think this is what I want. Now the issue is that I get errors from CMake if I use it the way I think.

See, I have a library target, and some public headers. The public headers should be a different component because they should go into the -dev package. So I have something like

```cmake
library(lib SHARED ...)
set_target_properties(lib
    PROPERTIES
    PUBLIC_HEADER
    path/to/public/header.h)

install(TARGETS lib
    LIBRARY DESTINATION lib
    COMPONENT Libraries)

install(TARGETS lib
    PUBLIC_HEADER DESTINATION include/path
    COMPONENT Headers)

```

But when I do this, I get warnings:

- Target lib has `PUBLIC_HEADER` files but no `PUBLIC_HEADER DESTINATION`
- Error: install `TARGETS` given no `LIBRARY DESTINATION` for shared library target ‘lib’.

What’s the best way to do this?

---

<div class="post-metadata">

**Author:** ![erk](https://discourse.cmake.org/user_avatar/discourse.cmake.org/erk/32/114_2.png) [@erk](https://discourse.cmake.org/u/erk)\
**Post date:** [January 13, 2020, 1:27pm UTC](https://discourse.cmake.org/t/how-do-i-create-multiple-installation-targets/475/4 "2020-01-13T13:27:18Z")

</div>

You should be able to specify all the required install part of the `lib` target at once:

```cmake
install(TARGETS lib
        LIBRARY
            DESTINATION lib
            COMPONENT Libraries
        PUBLIC_HEADER
            DESTINATION include/path
            COMPONENT Headers)

```
