# Custom command not re-run when dependencies change

**URL:** <https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596>\
**Category:** Code\
**Created:** [September 6, 2024, 9:31am UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596 "2024-09-06T09:31:33Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hannes\_Hauswedell](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/b5ac83/32.png) [@Hannes\_Hauswedell](https://discourse.cmake.org/u/Hannes_Hauswedell)\
**Post date:** [September 6, 2024, 9:31am UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/1 "2024-09-06T09:31:33Z")

</div>

Hi,  
I have been trying to make this work for hours now, but I can’t find the  
problem. I have a command that generates a coverage report. Naturally, I  
want this report to be re-generated when the unit tests are updated. But  
it just won’t work.

Here’s the code:

```auto
add_custom_target (all_unit_tests COMMENT "Meta-Target for all unit tests.")

add_custom_command (OUTPUT ${PROJECT_BINARY_DIR}/html/index.html
                     # Run tests.
                     COMMAND ${CMAKE_CTEST_COMMAND} -j 
${PEPR_COVERAGE_PARALLEL_LEVEL} --output-on-failure
                     # Create output directory.
                     COMMAND ${CMAKE_COMMAND} -E make_directory 
${PROJECT_BINARY_DIR}/html/
                     # Run gcovr and create HTML report.
                     COMMAND ${GCOVR_COMMAND} ${PEPR_GCOVR_ARGUMENTS} 
--html-details --print-summary --output
                             ${PROJECT_BINARY_DIR}/html/index.html
                     WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
                     DEPENDS all_unit_tests
                     COMMENT "Processing code coverage counters and 
generating HTML report."
                     COMMAND_EXPAND_LISTS)

add_custom_target (coverage_html
                    DEPENDS ${PROJECT_BINARY_DIR}/html/index.html
                    COMMENT "Generate coverage report.")

macro (pepr_test unit_test_cpp)
     file (RELATIVE_PATH unit_test "${CMAKE_SOURCE_DIR}/../unit" 
"${CMAKE_CURRENT_LIST_DIR}/${unit_test_cpp}")
     pepr_test_component (target "${unit_test}" TARGET_NAME)
     pepr_test_component (test_name "${unit_test}" TEST_NAME)

     add_executable (${target} ${unit_test_cpp})
     target_link_libraries (${target} pepr::test::coverage)
     add_test (NAME "${test_name}" COMMAND ${target})

     add_dependencies(all_unit_tests "${target}")

     unset (unit_test)
     unset (target)
     unset (test_name)
endmacro ()

```

Subsequently, the pepr\_test macro is invoked a couple of times. The unit  
tests are correctly recognised as dependencies of `coverage_html`, so  
when I `ninja coverage_html`, the unit tests are rebuilt after source  
code changes. However, the html is never updated.  
What am I missing?

Thanks,  
Hannes

---

<div class="post-metadata">

**Author:** ![hsattler](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/59ef9b/32.png) [@hsattler](https://discourse.cmake.org/u/hsattler)\
**Post date:** [September 6, 2024, 6:30pm UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/2 "2024-09-06T18:30:36Z")

</div>

> [@Hannes\_Hauswedell](#):
>
> `DEPENDS all_unit_tests`

This is not a file level dependency. What shall Ninja compare against to decide that index.html needs to be updated?

---

<div class="post-metadata">

**Author:** ![h-2](https://discourse.cmake.org/user_avatar/discourse.cmake.org/h-2/32/4914_2.png) [@h-2](https://discourse.cmake.org/u/h-2)\
**Post date:** [September 10, 2024, 9:51am UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/3 "2024-09-10T09:51:18Z")

</div>

I don’t know? Why does it not just check all dependencies recursively?

Does this mean that the top-level target needs file-level dependencies on all lowest-level targets’ files? This is super inconvenient, or do you see a nice way to adapt my example code?

---

<div class="post-metadata">

**Author:** ![hsattler](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/59ef9b/32.png) [@hsattler](https://discourse.cmake.org/u/hsattler)\
**Post date:** [September 10, 2024, 11:52am UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/4 "2024-09-10T11:52:50Z")

</div>

Assuming that the test output is stable, depending on the test binaries might be sufficient (they change when the source files changed)

You could also attach a post build command to each test case target that touches a common file that you can depend on (touch, so that the time stamp changes).

---

<div class="post-metadata">

**Author:** ![h-2](https://discourse.cmake.org/user_avatar/discourse.cmake.org/h-2/32/4914_2.png) [@h-2](https://discourse.cmake.org/u/h-2)\
**Post date:** [September 10, 2024, 12:01pm UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/5 "2024-09-10T12:01:02Z")

</div>

> [@hsattler](#):
>
> Assuming that the test output is stable, depending on the test binaries might be sufficient (they change when the source files changed)

Yeah, I think that would be enough. How would I do that? I tried using a TARGET\_FILE generator, but couldn’t make it work…

---

<div class="post-metadata">

**Author:** ![h-2](https://discourse.cmake.org/user_avatar/discourse.cmake.org/h-2/32/4914_2.png) [@h-2](https://discourse.cmake.org/u/h-2)\
**Post date:** [September 12, 2024, 3:50pm UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/6 "2024-09-12T15:50:17Z")

</div>

In particular, I tried adding

```auto
add_dependencies(coverage_html $<TARGET_FILE:${target}>)

```

below, `add_dependencies(all_unit_tests "${target}")`.

But it says that the dependency target

```auto
CMake Error at CMakeLists.txt:104 (add_dependencies):
  The dependency target "$<TARGET_FILE:ConstexprFlatMap>" of target
  "coverage_html" does not exist.

```

---

<div class="post-metadata">

**Author:** ![hsattler](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/59ef9b/32.png) [@hsattler](https://discourse.cmake.org/u/hsattler)\
**Post date:** [September 12, 2024, 4:47pm UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/7 "2024-09-12T16:47:04Z")

</div>

You still try adding dependencies to the target but you need a proper file dependency for the custom command.

---

<div class="post-metadata">

**Author:** ![h-2](https://discourse.cmake.org/user_avatar/discourse.cmake.org/h-2/32/4914_2.png) [@h-2](https://discourse.cmake.org/u/h-2)\
**Post date:** [September 13, 2024, 8:14am UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/8 "2024-09-13T08:14:21Z")

</div>

I still don’t understand why none of this is transitive. I thought that the build system would do exactly this for me 🙁

In any case, how do I add “a proper file dependency for the custom command” after it’s been defined?

---

<div class="post-metadata">

**Author:** ![h-2](https://discourse.cmake.org/user_avatar/discourse.cmake.org/h-2/32/4914_2.png) [@h-2](https://discourse.cmake.org/u/h-2)\
**Post date:** [September 18, 2024, 2:56pm UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/9 "2024-09-18T14:56:52Z")

</div>

> [@h-2](#):
>
> In any case, how do I add “a proper file dependency for the custom command” after it’s been defined?

Could anyone help me with this? 🙏

---

<div class="post-metadata">

**Author:** ![jtxa](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jtxa/32/1535_2.png) [@jtxa](https://discourse.cmake.org/u/jtxa)\
**Post date:** [September 20, 2024, 12:24am UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/10 "2024-09-20T00:24:18Z")

</div>

Collect the executables in a property of your target. Use a GenEx to depend on the content of that property.

Something like:

```auto
...
  DEPENDS $<TARGET_PROPERTY:all_unit_tests,TEST_EXECUTABLES>
...

set_property(
  TARGET all_unit_tests
  APPEND
  PROPERTY TEST_EXECUTABLES "$<TARGET_FILE:${target}>"
)

```

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [September 20, 2024, 11:26pm UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/11 "2024-09-20T23:26:15Z")

</div>

> [@jtxa](#):
>
> `DEPENDS $<TARGET_PROPERTY:all_unit_tests,TEST_EXECUTABLES>`

You may need to wrap that with `$<GENEX_EVAL:...>` since you’re allowing the `TEST_EXECUTABLES` target property to contain generator expressions too.

---

<div class="post-metadata">

**Author:** ![h-2](https://discourse.cmake.org/user_avatar/discourse.cmake.org/h-2/32/4914_2.png) [@h-2](https://discourse.cmake.org/u/h-2)\
**Post date:** [September 23, 2024, 1:18pm UTC](https://discourse.cmake.org/t/custom-command-not-re-run-when-dependencies-change/11596/12 "2024-09-23T13:18:24Z")

</div>

Thank you! Combining these two things, solved the problem for me.
