Making Generated Header Files Available to Other Targets in the Same Base Project

Given some package which generates code including header files (typically associated with a library).
Is there a recommended way of making generated headers available to other targets?

I have an approach which works but it seems clumsy to me.
I have the following structure (this example uses ProtoBuf but it could be anything).

base

  • CMakeLists.txt
  • generated
    • CMakeLists.txt
    • foo.pro
  • consume
    • CMakeLists.txt
    • main.cpp

base/CMakeLists.txt

...
add_subdirectory(generated)
add_subdirectory(consume)
...

base/generate/CMakeLists.txt

...
find_package(Protobuf CONFIG REQUIRED)
set(PROTO_SOURCES foo.proto)
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_SOURCES})
get_filename_component(FOO_PROTO_HDR_DIR ${PROTO_HDRS} DIRECTORY)
set(FOO_PROTO_HDRS ${FOO_PROTO_HDR_DIR} PARENT_SCOPE)
...

base/consume/CMakeLists.txt

...
target_include_directories(FooConsumer PRIVATE
        ${CMAKE_CURRENT_BINARY_DIR}
        ${FOO_PROTO_HDRS}
        ${Protobuf_INCLUDE_DIRS}
...

Approaches I considered:

  • return an include directory from the sub-project using PARENT_SCOPE (this is demonstrated above)
  • write the header files into a well known (base level) directory (where would that be?)

Instead, add the path as a PUBLIC usage requirement on the target “providing” the header. Something like:

target_include_directories(tgt PUBLIC
  "$<BUILD_INTERFACE:${FOO_PROTO_HDR_DIR}>")

The $<BUILD_INTERFACE> genex is used since this path won’t be valid for an installation.