# GeneratorExpression: \`TARGET\_FILE\` for \`add\_custom\_target\`

**URL:** https://discourse.cmake.org/t/generatorexpression-target-file-for-add-custom-target/7690
**Category:** Code
**Created:** [March 16, 2023, 10:49am UTC](https://discourse.cmake.org/t/generatorexpression-target-file-for-add-custom-target/7690 "2023-03-16T10:49:21Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Lecris](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lecris/32/3193_2.png) [@Lecris](https://discourse.cmake.org/u/Lecris)
#### Post date: [March 16, 2023, 10:49am UTC](https://discourse.cmake.org/t/generatorexpression-target-file-for-add-custom-target/7690/1 "2023-03-16T10:49:21Z")

</div>

Assuming `add_custom_taget` generates only 1 file, it would be sometimes useful to expose what is the name/location of that file, e.g.:

```cmake
add_custom_target(CustomTarget
	COMMAND compute_version.sh
	COMMAND ${CMAKE_COMMAND} -E copy_if_different _computed_version _final_version
	OUTPUT_FILE _generated_version)
set_source_files_properties(version.cpp.in PROPERTIES
	OBJECT_DEPENDS $<TARGET_FILE:CustomTarget>)

```

In this example `version.cpp` is always regenerated if the `_final_version` file changes, e.g. a git commit, while `_computed_version` is always re-created. This could be useful if we define the version in a variable that is always computed from `_computed_version` for example, and then it is used in `configure_file()`.

Adding the interface for `TARGET_FILE` will make it easier to integrate, without hard-coding a path standard.

---

<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: [March 16, 2023, 6:11pm UTC](https://discourse.cmake.org/t/generatorexpression-target-file-for-add-custom-target/7690/2 "2023-03-16T18:11:40Z")

</div>

You usually want to use `add_custom_command(OUTPUT)` rather than `add_custom_target(OUTPUT)` as it behaves a lot more sensibly. Something like this might work:

```cmake
add_custom_command(
  OUTPUT _computed_version
                  no_exist # make this run all the time
  COMMAND compute_version.sh)
add_custom_command(
  OUTPUT _generated_version
  DEPENDS _computed_version
  COMMAND ${CMAKE_COMMAND} -E copy_if_different _computed_version _generated_version)
add_custom_target(version DEPENDS _computed_version)

```

---

<div class="post-metadata">

### Author: ![Lecris](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lecris/32/3193_2.png) [@Lecris](https://discourse.cmake.org/u/Lecris)
#### Post date: [March 16, 2023, 6:25pm UTC](https://discourse.cmake.org/t/generatorexpression-target-file-for-add-custom-target/7690/3 "2023-03-16T18:25:01Z")

</div>

Indeed, but the interface of `TARGET_FILE` would still be useful here so that we can make `set_source_files_properties` more flexible.

I have been considering the `add_custom_command` approach as I’ve seen it floating around, but does it actually behave differently from `add_custom_target`. Because the custom\_target is always out-of-date, so why add the `add_custom_command` wit a `no_exist` file? The `custom_command` will not be running if a file does not depend on `_generated_version` in this case, or if the build target does not depend on `custom_target` `version`.

---

<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: [March 16, 2023, 6:41pm UTC](https://discourse.cmake.org/t/generatorexpression-target-file-for-add-custom-target/7690/4 "2023-03-16T18:41:00Z")

</div>

I found some behavior differences in make and ninja around it. I don’t remember the details though, sorry.
