# \`add\_custom\_command\` and Generated Header Dependencies

**URL:** https://discourse.cmake.org/t/add-custom-command-and-generated-header-dependencies/7393
**Category:** Usage
**Tags:** gen:ninja
**Created:** [February 2, 2023, 9:57pm UTC](https://discourse.cmake.org/t/add-custom-command-and-generated-header-dependencies/7393 "2023-02-02T21:57:31Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![marstaik](https://discourse.cmake.org/user_avatar/discourse.cmake.org/marstaik/32/2230_2.png) [@marstaik](https://discourse.cmake.org/u/marstaik)
#### Post date: [February 2, 2023, 9:57pm UTC](https://discourse.cmake.org/t/add-custom-command-and-generated-header-dependencies/7393/1 "2023-02-02T21:57:31Z")

</div>

Context:

I have been struggling with this for a while, and it was working when I happened to be generating “.cpp” files, but now with c++17 and the ability to move everything generated to static inline, I no longer require generating cpp fragments, only headers.

I have developed a pre-compiler system that parses _ANY_ source/header files, and generates a header file. (It actually generates two, but that’s an implementation detail)

You declare a target, add your SOURCES AND HEADERS as target\_sources, and then pass the target to a function.

_Sidenote_ - The precompiler is written itself with llvm’s libtooling, and understands msvc and gcc style arguments. If there is some other way to register a precompiler that I do not know, please inform me.

Finally, after setting up your target, you invoke `pre_compile_target(my_target)` which goes through all the source files added (headers and sources), and generates a custom command that looks like this:

```auto
add_custom_command(
      OUTPUT ${output_refl_in} ${output_rb_refl_in}
      COMMAND
        reflector -i ${source_dir} -o ${output_dir} -f ${relpath} #
        --driver-mode ${refl_driver_mode} #
        ${rt_flag} ${ct_flag} # generation flags
        ${ct_static_init_args} ${rt_static_init_args} #
        "$<$<BOOL:${id}>:-I$<SEMICOLON>$<JOIN:${id},$<SEMICOLON>-I$<SEMICOLON>>>" #
        "$<$<BOOL:${iid}>:-I$<SEMICOLON>$<JOIN:${iid},$<SEMICOLON>-I$<SEMICOLON>>>" #
        "$<$<BOOL:${co}>:-O$<SEMICOLON>\"$<JOIN:${co},\"$<SEMICOLON>-O$<SEMICOLON>\">\">" #
        "$<$<BOOL:${ico}>:-O$<SEMICOLON>\"$<JOIN:${ico},\"$<SEMICOLON>-O$<SEMICOLON>\">\">" #
        "$<$<BOOL:${cd}>:-D$<SEMICOLON>$<JOIN:${cd},$<SEMICOLON>-D$<SEMICOLON>>>" #
        "$<$<BOOL:${icd}>:-D$<SEMICOLON>$<JOIN:${icd},$<SEMICOLON>-D$<SEMICOLON>>>" #
      DEPENDS reflector ${abspath}
      VERBATIM COMMAND_EXPAND_LISTS)

    target_is_interface(is_interface ${target})
    if(is_interface)
      set(link_type INTERFACE)
      set(static_link_type PUBLIC)
    else()
      set(link_type PUBLIC)
      set(static_link_type PRIVATE)
    endif()

    target_sources(${target} ${link_type} ${output_refl_in}
                             ${output_rb_refl_in})

```

The generated files end in `.refl.in`, the dependent file is either a c++ source file, or header file.

Note that if `a.cpp` requires `a.h`, and `a.h` → `a.h.refl.in`, that `a.h.refl.in` must be generated before any source compilation command runs.

Despite adding the `a.h.refl.in` as a target\_source, cmake simply ignores the dependency and never generates the file.

As far as I know cmake uses implicit dependency scanning (assuming it uses ninja in this case) to find out that `a.cpp` depends on `a.h`, so why cant I tell cmake that `a.h` depends on `a.h.refl.in` which is dependent on `a.h` itself?

---

<div class="post-metadata">

### Author: ![marstaik](https://discourse.cmake.org/user_avatar/discourse.cmake.org/marstaik/32/2230_2.png) [@marstaik](https://discourse.cmake.org/u/marstaik)
#### Post date: [February 2, 2023, 11:25pm UTC](https://discourse.cmake.org/t/add-custom-command-and-generated-header-dependencies/7393/2 "2023-02-02T23:25:00Z")

</div>

Solution:

Following this post with the new File sets: [How to install an interface library with generated source in build folder - #2 by ben.boeckel](https://discourse.cmake.org/t/how-to-install-an-interface-library-with-generated-source-in-build-folder/5449/2)

I was able to get around this by creating an interface library with a generated name “${target}\_gen\_lib”, and then put the generated files into the fileset of the interface library.

adding `target_link_libraries(${target} ${target}_gen_lib)` then allows everything to work, since the gen\_lib target must be completed before ${target} is run.
