Enabling ANSI escape color code will result in unexpected results

At [QTCREATORBUG-30147] ERROR_VARIABLE from execute_process is not working as expected - Qt Bug Tracker we can see the following code:

cmake_minimum_required(VERSION 3.14)
project(QtCreatoCmakeBug)

unset(generated_files)
execute_process(COMMAND ${CMAKE_COMMAND}
           -P ${CMAKE_CURRENT_SOURCE_DIR}/myScript.cmake
           ERROR_VARIABLE error_output) # CMake writes messages to standard error.

string(STRIP "${error_output}" error_output)
list(LENGTH error_output error_output_len)
message("error_output list ${error_output} length: ${error_output_len}")

# Same list variable
set(my_file_list "myFile1.h;myFile1.cpp")
list(LENGTH my_file_list my_file_list_len)
message("my_file_list list ${my_file_list} length: ${my_file_list_len}")

with myScript.cmake as:

cmake_minimum_required(VERSION 3.16)
message("myFile1.h;myFile1.cpp")

The length is reported as 2 and 2 with Qt Creator 11, and 1 and 2 for Qt Creator 12.

This is due to the fact that Qt Creator 12 sets CLICOLOR_FORCE to 1 which causes the CMake run via execute_process to inject escape codes.

The output is actually:

e[0mmyFile1.h;myFile1.cppe[0m

The fix would be either use:

string(ASCII 27 Esc)
string(REPLACE "${Esc}[0m" "" error_output "${error_output}")

or set CLICOLOR_FORCE to 0 for the CMake project in Qt Creator.

But what about fixing this at CMake level? I can think of two fixes:

  1. string(STRIP "${error_output}" error_output) would also strip the escape codes
  2. list(LENGTH error_output error_output_len) would ignore the escape codes
  3. Ignore issue and fix it via documentation

Any thoughts?

Either of these would need to be a policy change. I don’t think we could reliably do that without changing behavior silently. A string(STRIP_ANSI) command sounds fine though.

I think the issue is that using CLICOLOR_FORCE=1 is the wrong thing to do as not everything is expecting this. Better would be if we had something like cmake --color=<auto|on|off> Including, ironically, Qt Creator choking on my NINJA_STATUS with oodles of color settings when I last tried it (years ago).

If your execute_process() call might change its output depending on whether certain environment variables are set, and your project is sensitive to those changes, then the project should be ensuring those environment variables are controlled as part of the call. In other words, explicitly set CLICOLOR_FORCE=0 as part of the command. There could be a range of environment variables that might matter to a project, CLICOLOR_FORCE is just one example. I don’t think CMake should manage these with dedicated options, there are already fairly straightforward ways for a project to do this without them.