# Struggling with generated headers

**URL:** https://discourse.cmake.org/t/struggling-with-generated-headers/10437
**Category:** Usage
**Created:** [March 21, 2024, 7:01pm UTC](https://discourse.cmake.org/t/struggling-with-generated-headers/10437 "2024-03-21T19:01:10Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Ecologist0045](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/e/2acd7d/32.png) [@Ecologist0045](https://discourse.cmake.org/u/Ecologist0045)
#### Post date: [March 21, 2024, 7:01pm UTC](https://discourse.cmake.org/t/struggling-with-generated-headers/10437/1 "2024-03-21T19:01:10Z")

</div>

I’m using [SBE](https://github.com/real-logic/simple-binary-encoding), which generates headers based on a schema (à la something like protobuf).

I can run it by hand like:

```auto
$ mkdir build/generated
$ java -Dsbe.target.language=CPP -Dsbe.output.dir=build/generated -jar ../simple-binary-encoding/sbe-all/build/libs/sbe-all-1.31.0-SNAPSHOT.jar config/schema.xml

```

Which gives me:

```auto
$ ls -R build/generated/
build/generated/:
test

build/generated/test:
MessageHeader.h Thing.h

```

I can then write a tiny CMake file pointing explicitly at this directory, which builds fine:

```auto
add_executable(Test src/test.cpp)
target_include_directories(Test PUBLIC build/generated)

```

What I want is to automate fetching the code generation tool, building it, and generating the headers for inclusion.  
I’ve been fumbling around and come up with the below, which seems to fetch the repo OK but then not do anything (and, naturally, I get a build error about missing headers):

```auto
include(FetchContent)
FetchContent_Declare(
  sbe
  GIT_REPOSITORY https://github.com/real-logic/simple-binary-encoding.git
  GIT_TAG 1.30.0
  )
FetchContent_MakeAvailable(sbe)

set(GENERATED_FILES ${CMAKE_BINARY_DIR}/generated)
set(LADDER_TEMPLATE config/schema.xml)
add_custom_command(
  OUTPUT ${GENERATED_FILES}
  COMMAND java ARGS -Dsbe.target.language=CPP -Dsbe.output.dir=${GENERATED_FILES} -jar sbe::sbe-jar ${LADDER_TEMPLATE}
  COMMENT "Generating SBE headers"
  DEPENDS ${LADDER_TEMPLATE}
  )

add_executable(Test src/test.cpp)
target_include_directories(Test PUBLIC ${GENERATED_FILES})

```

Bit new to CMake, so apologies if this is rudimentary. Any help very much appreciated.

---

<div class="post-metadata">

### Author: ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)
#### Post date: [March 28, 2024, 3:27pm UTC](https://discourse.cmake.org/t/struggling-with-generated-headers/10437/2 "2024-03-28T15:27:35Z")

</div>

You cannot list a directory as the `OUTPUT` of a custom command. You should instead list the individual files produced by the run, and then add those files into the target you’re building. So effectively something like this:

```auto
set(GENERATED_FILE_DIR ${CMAKE_BINARY_DIR}/generated)
set(GENERATED_FILES
  ${GENERATED_FILE_DIR}/test/MessageHeader.h
  ${GENERATED_FILE_DIR}/test/Thing.h
)
add_custom_command(
  OUTPUT ${GENERATED_FILES}
  COMMAND java ARGS -Dsbe.target.language=CPP -Dsbe.output.dir=${GENERATED_FILES} -jar sbe::sbe-jar ${LADDER_TEMPLATE}
  COMMENT "Generating SBE headers"
  DEPENDS ${LADDER_TEMPLATE}
  )

add_executable(Test src/test.cpp ${GENERATED_FILES})
target_include_directories(Test PUBLIC ${GENERATED_FILE_DIR})

```

---

<div class="post-metadata">

### Author: ![Ecologist0045](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/e/2acd7d/32.png) [@Ecologist0045](https://discourse.cmake.org/u/Ecologist0045)
#### Post date: [March 28, 2024, 8:40pm UTC](https://discourse.cmake.org/t/struggling-with-generated-headers/10437/3 "2024-03-28T20:40:15Z")

</div>

Thanks very much for the help, that’s got me most of the way. I’ve now got a file that looks like:

```auto
set(SBE_VER 1.30.0)

include(FetchContent)
FetchContent_Declare(
  sbe
  GIT_REPOSITORY https://github.com/real-logic/simple-binary-encoding.git
  GIT_TAG ${SBE_VER}
  )
FetchContent_MakeAvailable(sbe)

set(GENERATED_FILE_DIR ${CMAKE_BINARY_DIR}/generated)
set(GENERATED_FILES
  ${GENERATED_FILE_DIR}/priceladder/MessageHeader.h
  ${GENERATED_FILE_DIR}/priceladder/Thing.h
)
set(LADDER_TEMPLATE config/schema.xml)
add_custom_command(
  OUTPUT ${GENERATED_FILES}
  COMMAND java ARGS 
    -Dsbe.target.language=CPP 
    -Dsbe.output.dir=${GENERATED_FILE_DIR} 
    -jar ${sbe_SOURCE_DIR}/sbe-all/build/libs/sbe-all-${SBE_VER}.jar 
    ${LADDER_TEMPLATE}
  COMMENT "Generating SBE headers"
  DEPENDS ${LADDER_TEMPLATE}
  )

add_executable(Test src/test.cpp)
target_include_directories(Test PUBLIC ${GENERATED_FILE_DIR})
target_link_libraries(Test PUBLIC sbe)

```

That sucessully builds my code but I was hoping not to have to explicitly list the path to it in the custom command.  
I’m probably misunderstanding something but I thought I might be able to access it via the target [here](https://github.com/real-logic/simple-binary-encoding/blob/master/CMakeLists.txt#L162). I tried passing it to the command like this but it complains:

```auto
-jar sbe::sbe-jar

```

Is there something I can add to the third-party CMake file to let me do this?

---

<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: [January 1, 2025, 9:05pm UTC](https://discourse.cmake.org/t/struggling-with-generated-headers/10437/4 "2025-01-01T21:05:05Z")

</div>

You might want to try `$<TARGET_FILE:sbe::sbe-jar>`.
