Bad dependency management for custom commands with Unix Makefiles generator

When using “Unix Makefile” generator combined with custom commands and custom targets to generate files, CMake make use of sub-make invocation which doesn’t propagate the dependency tree between custom targets.

Give the following use case:

add_custom_command(OUTPUT fileA.cpp
    COMMAND echo "Generate file A"
)
add_custom_command(OUTPUT fileB.cpp
    COMMAND echo "Generate file B"
    DEPENDS fileA.cpp
)
add_custom_command(OUTPUT fileC.cpp
    COMMAND echo "Generate file C"
    DEPENDS fileA.cpp
)

add_custom_target(GenA ALL DEPENDS fileA.cpp)
add_custom_target(GenB ALL DEPENDS fileB.cpp)
add_custom_target(GenC ALL DEPENDS fileC.cpp)

CMake generates, for Unix Makefile, 3 different sub-make invocation for the custom targets.
The result is that, when building with parallelization enabled, “fileA.cpp” is generated concurrently up to 3 times (one by GenA, one by GenA as dependency on GenB and one by GenA as dependency of GenC).
This behavior occurs only under Unix Makefile. Ninja and other generators (Visual Studio) correctly handle the parallel dependencies.

Output with Makefile:

[proc] Executing command: /usr/bin/cmake --build build/make -j20 --
[build] [ 20%] Generating fileA.cpp
[build] [ 40%] Generating fileA.cpp
[build] [ 60%] Generating fileA.cpp
[build] Generate file A
[build] Generate file A
[build] Generate file A
[build] [ 80%] Generating fileB.cpp
[build] Generate file B
[build] [ 80%] Built target GenA
[build] [100%] Generating fileC.cpp
[build] Generate file C
[build] [100%] Built target GenB
[build] [100%] Built target GenC
[driver] Build completed: 00:00:00.057

Output with Ninja:

[proc] Executing command: /usr/bin/cmake --build build/ninja -j20 --
[build] [1/3] Generating fileA.cpp
[build] Generate file A
[build] [2/3] Generating fileC.cpp
[build] Generate file C
[build] [3/3] Generating fileB.cpp
[build] Generate file B
[driver] Build completed: 00:00:00.013

This is not only a considerable waste of resources but it is also the cause of failed build due to the data race on writing and reading “fileA.cpp”.
Is there a proper way to handle this scenario correctly under “Unix Makefile” or is it possible to fix CMake implementation and avoid the use of sub-make invocations for custom_targets with dependencies?

This is documented behaviour, see the docs of add_custom_command():

Do not list the output in more than one independent target that may build in parallel or the instances of the rule may conflict. Instead, use the add_custom_target() command to drive the command and make the other targets depend on that one. See the Example: Generating Files for Multiple Targets below.

Follow the cited link for an example.