Installing headers the modern way, regurgitated and revisited

Some weeks ago, under Installing headers the modern way, I posed a question regarding the relationship (or lack thereof) between target_sources(mylib PUBLIC ...) and install(TARGETS mylib PUBLIC_HEADER ...). This is a part of CMake’s current design/evolution that just doesn’t seem especially cohesive.

Well, I recently undertook writing/generating my first CMake package config file. And while I’m at it, hey, let’s make this thing relocatable, too.

Oh, boy.

So, let’s say we have:

target_sources(
  mylib
  PUBLIC
    myfirstpublicheader.h
    mysecondpublicheader.h
)

Well, that just won’t do. To satisfy relocatability requirements, the $<INSTALL_INTERFACE:> generator expression must be used. For each header.

target_sources(
  mylib
  PUBLIC
    $<INSTALL_INTERFACE:myfirstpublicheader.h>
    $<INSTALL_INTERFACE:mysecondpublicheader.h>
)

Um, ew. But okay.

Oh, wait… that little bit of code I used to copy the INTERFACE_SOURCES property to the PUBLIC_HEADER property?

get_target_property(MYLIB_PUBLIC_HEADERS mylib INTERFACE_SOURCES)
set_target_properties(
  mylib
  PROPERTIES
    PUBLIC_HEADER "${MYLIB_PUBLIC_HEADERS}"
)

Well, after decorating things with $<INSTALL_INTERFACE:>, my headers aren’t getting installed anymore.

Hm. Okay. Well, it seems that has a perfectly trivial solution: just use the $<BUILD_INTERFACE:> generator expression:

target_sources(
  mylib
  PUBLIC
    $<INSTALL_INTERFACE:myfirstpublicheader.h>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/myfirstpublicheader.h>
    $<INSTALL_INTERFACE:mysecondpublicheader.h>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/mysecondpublicheader.h>
)

And now my headers install! Yay!

Oh, dear. What have I done? See, I don’t have just a couple of public headers like this contrived example code; I have tens of them, like many, many other moderately-sized C++ projects. And this thing has just exploded.

I am hoping that someone will tell me that I’ve missed a trick here. But failing that, I respectfully suggest that something has gone off the rails with this design.