No rule to make target

I am attempting to set dependencies with generator expression, but it is not correctly expanded.

add_custom_target(test1 ALL
  DEPENDS           ${CMAKE_CURRENT_BINARY_DIR}/foobar
  SOURCES foo.bar
)

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foobar
  COMMAND           echo dummyfoobargenerator
  DEPENDS           $<TARGET_PROPERTY:test1,SOURCES>
)

this results in error:

-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/test/build
gmake[2]: *** No rule to make target 'foobar.rule', needed by 'foobar'. Stop.
gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/test1.dir/all] Error 2
gmake: *** [Makefile:101: all] Error 2

This is a bit unexpected. foobar is not part of target properties sources, it was not my intention to use it as such. Do i have to filter them out or is there a better way?

I suspect that the current directory is not well-defined and that’s why this isn’t happy in the end. I think that the Makefiles generators add some “sources” for their internal bookkeeping (such as the .rule files). Filtering could help, but I suspect that the genex doesn’t work well for out-of-source builds since the paths don’t seem to be normalized at all. Does it work with the Ninja generator?

@brad.king?

using Ninja results in cyclic dependency error. I used relative paths for conciseness. The behaviour is the same with absolute paths.

Normalizing paths with genex is a challenge, though. I tried other things but always hit the rule not found error.

here is a simplified version of the problem:

cmake_minimum_required(VERSION 3.20)

project(MyProj LANGUAGES NONE)

add_custom_target(test1 ALL
	COMMAND ${CMAKE_COMMAND} -E echo "this line:$<TARGET_PROPERTY:test1,SOURCES>"
	SOURCES foo.bar
	COMMAND_EXPAND_LISTS
)
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/test/build
this line:foo.bar /tmp/test/build/CMakeFiles/test1 /tmp/test/build/CMakeFiles/test1.rule
Built target test1
[Finished in 0.1s]

this version builds successfully.
it makes me think that CMake might have created a target-level dependency for target_property, even so this should only happen for TARGET_xxx_FILE, etc.

these restrictions might to also apply to add_custom_command.

Thanks, that looks like a small enough example for tracking down the cause at least. Could you please file it as an issue? I’m not sure that the solution is trivial however. Thanks.

another thing i observed is that the output for get_target_property(mysrcs test1 SOURCES) is different from $<TARGET_PROPERTY:test1,SOURCES>: the former does not show the internal files. Are target_properties always read before generator expressions? Should i mention this in the same gitlab issue?

get_target_property works at configure time, so it may have out-of-date information (e.g., if a target_sources is performed after the initial query). The generator seems to add additional sources before the generator expression is evaluated.

1 Like