Installing headers the modern way

I find myself doing this:

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?

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.

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?

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

@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

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

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)

Please refer to my more recent posting, Installing headers the modern way, regurgitated and revisited.

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

1 Like

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.