How to tell execute_process to preserve ansi colors in its output?

Sample project

cmake_minimum_required(VERSION 3.16)

if(NOT CMAKE_SCRIPT_MODE_FILE)
    project(proj LANGUAGES NONE)
endif()

message(WARNING "This is a warning")

if(NOT NESTED_CALL)
    execute_process(
        COMMAND
            "${CMAKE_COMMAND}"
            -DNESTED_CALL=1
            -P
            "${CMAKE_CURRENT_LIST_FILE}"
    )
endif()

When I configure the sample project with a recent cmake (v4.1) on macOS in the iTerm2 terminal, I get

CMake Warning at CMakeLists.txt:7 (message):
  This is a warning <--------------------- this shows as yellow text


CMake Warning at /Users/alex/Dev/projects/cmake/general/nested_cmake_ansi_colors/CMakeLists.txt:7 (message):
  This is a warning <--------------------- this shows as white text

So the second message gets its color lost.

I can force the color to show if I set the export CLICOLOR_FORCE=1 env variable before the execute_process call, but I can’t do this universally because I don’t know if the outer cmake call is connected to a terminal / tty and whether the terminal supports colors.

Is this a bug or a missing feature in execute_process?

Shouldn’t execute_process treat the stdout as just another piped output to the cmake’s stdout, because it doesn’t have the OUTPUT_FILE / ERROR_FILE options set to redirect to a different file?

execute_process by default captures the output so that it can be printed wherever CMake’s output is going, which might be cmake-gui or ccmake display buffers instead of a real terminal. One could add an option to pass through the real pipes, at least when called from a command-line tool like cmake.

I came here after I tried to implement colors in Zephyr’s sysbuild. Zephyr’s sysbuild does run CMake inside a CMake execute_process. See Zephyr Bug 106182 for details. I tried a workaround with setting OUTPUT_FILE and ERROR_FILE to /dev/stdout and /dev/stderr, respectively. But that only works on Unix and has other issues.

@brad.king your answer explains the reason for that implementation detail, thanks. CMake would have to open a pseudoterminal for the process started by execute_process, in order to make it believe it runs in a terminal and for CMake still being able to capture the output.

Are there simpler solutions to implement CMake printing colors when started by CMake, but only when the outer CMake is run in a terminal?