cmake

How to make colorized message() with CMake?


I want to have message function in CMakeLists.txt which output colorized text. Maybe an escape sequence.

For example:

message("\x1b[31m;This text must be in red")

It don't work. I got:

Syntax error in cmake code at

/home/taurus/cmakecolor/CMakeLists.txt:1

when parsing string

\x1b[31m;This text must be in red

Invalid escape sequence \x

Solution

  • To extend @grim's correct answer, you can make things a bit more convenient by setting up variables to handle the various colours:

    if(NOT WIN32)
      string(ASCII 27 Esc)
      set(ColourReset "${Esc}[m")
      set(ColourBold  "${Esc}[1m")
      set(Red         "${Esc}[31m")
      set(Green       "${Esc}[32m")
      set(Yellow      "${Esc}[33m")
      set(Blue        "${Esc}[34m")
      set(Magenta     "${Esc}[35m")
      set(Cyan        "${Esc}[36m")
      set(White       "${Esc}[37m")
      set(BoldRed     "${Esc}[1;31m")
      set(BoldGreen   "${Esc}[1;32m")
      set(BoldYellow  "${Esc}[1;33m")
      set(BoldBlue    "${Esc}[1;34m")
      set(BoldMagenta "${Esc}[1;35m")
      set(BoldCyan    "${Esc}[1;36m")
      set(BoldWhite   "${Esc}[1;37m")
    endif()
    
    message("This is normal")
    message("${Red}This is Red${ColourReset}")
    message("${Green}This is Green${ColourReset}")
    message("${Yellow}This is Yellow${ColourReset}")
    message("${Blue}This is Blue${ColourReset}")
    message("${Magenta}This is Magenta${ColourReset}")
    message("${Cyan}This is Cyan${ColourReset}")
    message("${White}This is White${ColourReset}")
    message("${BoldRed}This is BoldRed${ColourReset}")
    message("${BoldGreen}This is BoldGreen${ColourReset}")
    message("${BoldYellow}This is BoldYellow${ColourReset}")
    message("${BoldBlue}This is BoldBlue${ColourReset}")
    message("${BoldMagenta}This is BoldMagenta${ColourReset}")
    message("${BoldCyan}This is BoldCyan${ColourReset}")
    message("${BoldWhite}This is BoldWhite\n\n${ColourReset}")
    

    If you really fancy pushing the boat out, you can replace the built-in message function with your own which colourises the output depending on the message type:

    function(message)
      list(GET ARGV 0 MessageType)
      if(MessageType STREQUAL FATAL_ERROR OR MessageType STREQUAL SEND_ERROR)
        list(REMOVE_AT ARGV 0)
        _message(${MessageType} "${BoldRed}${ARGV}${ColourReset}")
      elseif(MessageType STREQUAL WARNING)
        list(REMOVE_AT ARGV 0)
        _message(${MessageType} "${BoldYellow}${ARGV}${ColourReset}")
      elseif(MessageType STREQUAL AUTHOR_WARNING)
        list(REMOVE_AT ARGV 0)
        _message(${MessageType} "${BoldCyan}${ARGV}${ColourReset}")
      elseif(MessageType STREQUAL STATUS)
        list(REMOVE_AT ARGV 0)
        _message(${MessageType} "${Green}${ARGV}${ColourReset}")
      else()
        _message("${ARGV}")
      endif()
    endfunction()
    
    message("No colour at all.")
    message(STATUS "\"Colour\" is spelled correctly.")
    message(AUTHOR_WARNING "\"Color\" is misspelled.")
    message(WARNING "Final warning: spell \"color\" correctly.")
    message(SEND_ERROR "Game over.  It's \"colour\", not \"color\".")
    message(FATAL_ERROR "And there's no \"z\" in \"colourise\" either.")
    

    I can't say that I recommend overriding the built-in message function in this way, but having said that, I've not found any major problems with doing this either.