# Installing headers the modern way

**URL:** <https://discourse.cmake.org/t/installing-headers-the-modern-way/2934>\
**Category:** Code\
**Created:** [March 10, 2021, 3:46pm UTC](https://discourse.cmake.org/t/installing-headers-the-modern-way/2934 "2021-03-10T15:46:59Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Braden](https://discourse.cmake.org/user_avatar/discourse.cmake.org/braden/32/358_2.png) [@Braden](https://discourse.cmake.org/u/Braden)\
**Post date:** [March 10, 2021, 3:46pm UTC](https://discourse.cmake.org/t/installing-headers-the-modern-way/2934/1 "2021-03-10T15:46:59Z")

</div>

I find myself doing this:

```auto
target_sources(mylib PUBLIC mypublic.h)
get_target_property(MYLIB_PUBLIC_HEADERS mylib INTERFACE_SOURCES)
set_target_properties(mylib PROPERTIES PUBLIC_HEADER "${MYLIB_PUBLIC_HEADERS}")
install(TARGETS mylib PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/mylib")

```

Now, I’m well aware that CMake offers multiple ways to skin this cat. The above feels Mostly Modern; however, copying the INTERFACE\_SOURCES property value to the PUBLIC\_HEADER property feels awkward. (Why doesn’t `target_sources..PUBLIC` set this property?)

What is considered the Modern way to do something as straightforward as installing a library and its headers these days?

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [March 10, 2021, 4:33pm UTC](https://discourse.cmake.org/t/installing-headers-the-modern-way/2934/2 "2021-03-10T16:33:53Z")

</div>

`target_sources(PUBLIC)` adds those files to the source list for any consuming target. It’s not quite the same thing. That said, I still use `install(FILES)` myself out of habit, so I don’t have much input to the question itself.

---

<div class="post-metadata">

**Author:** ![Braden](https://discourse.cmake.org/user_avatar/discourse.cmake.org/braden/32/358_2.png) [@Braden](https://discourse.cmake.org/u/Braden)\
**Post date:** [March 11, 2021, 3:26am UTC](https://discourse.cmake.org/t/installing-headers-the-modern-way/2934/3 "2021-03-11T03:26:02Z")

</div>

> [@ben.boeckel](#):
>
> `target_sources(PUBLIC)` adds those files to the source list for any consuming target. It’s not quite the same thing.

I understand it’s not quite the same thing; but, as a practical matter, if I’m providing an install target, is there a scenario in which I would _not_ want `INTERFACE_SOURCES` to be installed?

---

<div class="post-metadata">

**Author:** ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)\
**Post date:** [March 11, 2021, 3:41pm UTC](https://discourse.cmake.org/t/installing-headers-the-modern-way/2934/4 "2021-03-11T15:41:16Z")

</div>

Hmm. Probably not. I expect that would only lead to errors when the source file cannot be found upon usage of the target.

---

<div class="post-metadata">

**Author:** ![Kerstin\_Keller](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kerstin_keller/32/180_2.png) [@Kerstin\_Keller](https://discourse.cmake.org/u/Kerstin_Keller)\
**Post date:** [April 30, 2021, 11:31am UTC](https://discourse.cmake.org/t/installing-headers-the-modern-way/2934/5 "2021-04-30T11:31:46Z")

</div>

@Braden: Does the way you described work for you? Also when exporting / installing the targets? Which CMake Version are you using?  
I am either getting

```auto
CMake Error in CMakeLists.txt:
 Target "mylib" INTERFACE_SOURCES property contains path:

   "D:/Some/path/include/mypbulic.h"

 which is prefixed in the source directory.

```

or

```auto
CMake Error in CMakeLists.txt:
  Target "mylib" INTERFACE_SOURCES property contains relative path:

    "include/mypbulic.h"

```

(First was minimum cmake 3.6, and some policy warning, second one minimum cmake 3.15)

So apparently it can be neither relative nor absolute? Do I need to work here with generator expressions as well? I am a bit confused.

(I am using CMake 3.20 here)

---

<div class="post-metadata">

**Author:** ![Braden](https://discourse.cmake.org/user_avatar/discourse.cmake.org/braden/32/358_2.png) [@Braden](https://discourse.cmake.org/u/Braden)\
**Post date:** [April 30, 2021, 12:57pm UTC](https://discourse.cmake.org/t/installing-headers-the-modern-way/2934/6 "2021-04-30T12:57:31Z")

</div>

> [@Kerstin\_Keller](#):
>
> Does the way you described work for you? Also when exporting / installing the targets? Which CMake Version are you using?

Please refer to my more recent posting, [Installing headers the modern way, regurgitated and revisited](https://discourse.cmake.org/t/installing-headers-the-modern-way-regurgitated-and-revisited/3238).

The method described there does work. It is not pretty. I am using CMake 3.19.

---

<div class="post-metadata">

**Author:** ![Kerstin\_Keller](https://discourse.cmake.org/user_avatar/discourse.cmake.org/kerstin_keller/32/180_2.png) [@Kerstin\_Keller](https://discourse.cmake.org/u/Kerstin_Keller)\
**Post date:** [April 30, 2021, 1:02pm UTC](https://discourse.cmake.org/t/installing-headers-the-modern-way/2934/7 "2021-04-30T13:02:32Z")

</div>

Thanks for the quick reply. I totally ended up doing what you described in your second approach. I also feels that this is way to verbose.  
Most of the time I just install folders instead of the header files.
