GeneratorExpression: `TARGET_FILE` for `add_custom_target`

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.:

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.

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:

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)

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.

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