Why does TARGET_FILE_DIR create a dependency on the target

I’m trying to create some rules to copy files to a targets library directory. I’ve pretty much solved it but my current solution had some issues that it would only really work for sure if all targets would be build of the project. Now that doesn’t really need to happen so I was figuring out an alternative.

I came pretty close until I noticed that using generator expression of TARGET_FILE_DIR immediately adds a dependency on the target. Afterward I add the dependency the other way around and I get a inter-target dependency graph error.

Basically what I had was:
add_custom_target(${CustomLibCopyCommandName}

                            COMMAND ${CMAKE_COMMAND} -E echo Running ${CustomLibCopyCommandName}

                            COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${MainTarget}>/${LINKLIBRARY_PATH}

                            COMMAND ${CMAKE_COMMAND} -E copy_if_different ${TargetBIN} $<TARGET_FILE_DIR:${MainTarget}>/${LINKLIBRARY_PATH}

                            )

and then adding
add_dependencies(${MainTarget} ${CustomLibCopyCommandName})

As soon as I change TARGET_FILE_DIR to some other like TARGET_FILE_BASE_NAME it works. In the docs it also mentions that TARGET_FILE_BASE_NAME doesn’t add the dependency on tgt but I don’t understand why the depencency needs to be there for the other cases and if there is a good alternative that works with Ninja, Visual Studio and Xcode to get the correct paths for a target.

This behavior is a side effect of the current implementation. This genex shares the implementation with $<TARGET_FILE:...> which, with reason, add a dependency on the target.

The dependency is also added for $<TARGET_FILE_NAME:...>. For these two genex, I agree with you, It seems a bit curious. But adding a dependency ensure, for your example, that the directory exist when your command is executed.

Yes. Nothing in CMake guarantees that directories for targets exist before the target itself is done.