How is `CMAKE_NINJA_OUTPUT_PATH_PREFIX` supposed to work?

Attempting to integrate two CMake-generated Ninja projects that use CMAKE_NINJA_OUTPUT_PATH_PREFIX with subninja directives fails. See the following interaction:

alex@alex-ubuntu:~/Development/subninja-demo$ tree
.
├── A
│   └── CMakeLists.txt
├── B
│   └── CMakeLists.txt
└── build.sh

2 directories, 3 files
alex@alex-ubuntu:~/Development/subninja-demo$ cat A/CMakeLists.txt 
cmake_minimum_required(VERSION 3.21)
project(A LANGUAGES NONE)
alex@alex-ubuntu:~/Development/subninja-demo$ cat B/CMakeLists.txt 
cmake_minimum_required(VERSION 3.21)
project(B LANGUAGES NONE)
alex@alex-ubuntu:~/Development/subninja-demo$ cat build.sh 
#!/bin/bash

cmake -G Ninja -S A -B build/A -DCMAKE_BUILD_TYPE=Release -DCMAKE_NINJA_OUTPUT_PATH_PREFIX=A
cmake -G Ninja -S B -B build/B -DCMAKE_BUILD_TYPE=Release -DCMAKE_NINJA_OUTPUT_PATH_PREFIX=B

cat >build/build.ninja <<HERE
subninja A/build.ninja
subninja B/build.ninja
HERE

(cd build && ninja -v)

$ ./build.sh 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/Development/subninja-demo/build/A
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/Development/subninja-demo/build/B
ninja: error: B/build.ninja:94: multiple rules generate /usr/share/cmake-3.21/Modules/CMakeDetermineSystem.cmake [-w dupbuild=err]

alex@alex-ubuntu:~/Development/subninja-demo$ cmake --version
cmake version 3.21.3

CMake suite maintained and supported by Kitware (kitware.com/cmake).

I’m seeing the same error in a different context, when trying to generate a build using clang from within VS2019.

I’m using the very nice feature whereby you give VS2019 a CMakeLists.txt file, rather than a pre-generated project file, and it allows you to add clang as a compiler and automatically generates a ninja project file.

In my case, though, there is a custom target that uses Bison to generate a .cpp file from a .y file.

    configure_file(${UTILITIES_DIRECTORY}/bisonparse.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/GENERATED/bisonparse.cmake @ONLY)
    add_custom_target(bisonparse ALL
                      COMMAND ${CMAKE_COMMAND} "-DFLAG_NAMES=${PROJECT_FB_FLAG_NAMES}"
                                               "-DFLAGS=${PROJECT_FB_FLAGS}"
                                               -P ${CMAKE_CURRENT_BINARY_DIR}/GENERATED/bisonparse.cmake
                      VERBATIM
                      BYPRODUCTS ${GENERATED_BISON_SOURCE_FILES} ${GENERATED_WINONLY_BISON_SOURCE_FILES} ${GENERATED_LINONLY_BISON_SOURCE_FILES}
                                 ${GENERATED_BISON_HEADER_FILES} ${GENERATED_WINONLY_BISON_HEADER_FILES} ${GENERATED_LINONLY_BISON_HEADER_FILES})

My bisonparse.cmake.in file (and consequently the genarated bisonparse.cmake file) contains a message(“…”) statement each time it is invoked by the custom target, so I can verify that this does indeed happen only once during project generation.

Nevertheless, the configuration fails with the message:

'<path>/ninja.exe' '-C' <CMAKE_CURRENT_BINARY_DIR>/x64-Clang-Debug' '-t' 'recompact'

failed with:

ninja: error: build.ninja:9351: multiple rules generate GENERATE/<path>/MyParser.cpp [-w dupbuild=err].

If I then dig out build.ninja and look up line 9351, I find it’s in a section headed

#############################################
# Custom command for CMakeFiles\bisonparse

…which is similar but by no means identical to another section earlier in the file headed

#############################################
# Utility command for bisonparse

I’ve no idea what’s going on, but I thought I might at least be able to work around it by specifying

-w dupbuild=warn

to get a warning instead of an error, but I found a bug report here stating that there isn’t any way that I can pass the option ‘-w dupbuild=warn’ to the ‘recompact’ function, which is where the failure occurs.

So I’m stumped on this, and for the time being I’ve moved over to Linux in the hope that it will let me generate a GNU Makefile there using clang.