Search code examples
linuxbashcolorssedmakefile

Color highlighting of Makefile warnings and errors


I have written a Makefile which works fine; I am just posting the part of it under investigation:

BUILD_PRINT = @echo -e "\e[1;34mBuilding $<\e[0m"
COMPILE_cpp = $(CXX) $(CFLAGS) -o $@ -c $< $(MAKEDEP) $(INCLUDES)
%.o : %.cpp
    $(BUILD_PRINT)
    $(COMPILE_cpp)
.SUFFIXES: .o .cpp

I would like to highlight the warnings and errors given by the compiler without using external tools (such as colorgcc or CMake); I thought that a good way to hack it was via "bash script tricks". Looking at the solution posted in How Can I highlight the warning and error lines in the make output? I have tried the following:

pathpat="(/[^/]*)+:[0-9]+"
ccred=$(echo -e "\033[0;31m")
ccyellow=$(echo -e "\033[0;33m")
ccend=$(echo -e "\033[0m")

BUILD_PRINT = @echo -e "\e[1;34mBuilding $<\e[0m"
COMPILE_cpp = $(CXX) $(CFLAGS) -o $@ -c $< $(MAKEDEP) $(INCLUDES)
%.o : %.cpp
    $(BUILD_PRINT)
    $(COMPILE_cpp) 2>&1 | sed -e "/[Ee]rror[: ]/ s%$pathpat%$ccred&$ccend%g" -e "/[Ww]arning[: ]/ s%$pathpat%$ccyellow&$ccend%g" echo "${PIPESTATUS[0]}"
.SUFFIXES: .o .cpp

but it is not working. I get the following output

Building main.cpp
g++ -o main.o -c main.cpp  2>&1 | sed -e "/[Ee]rror[: ]/ s%athpat%cred&cend%g" -e "/[Ww]arning[: ]/ s%athpat%cyellow&cend%g" echo ""
sed: can't read echo: No such file or directory
sed: can't read : No such file or directory

Thanks in advance!


Solution

  • Got it working.

    First of all thanks @EtanReisner and @rici. Here's the code:

    BUILD_PRINT = \e[1;34mBuilding $<\e[0m
    
    COMPILE_cpp = $(CXX) $(CFLAGS) -o $@ -c $< $(MAKEDEP) $(INCLUDES)
    COMPILE_cpp_OUT=$$($(COMPILE_cpp) 2>&1 | sed -e 's/error/\\\e[1;31merror\\\e[0m/g' -e s/warning/\\\e[1;33mwarning\\\e[0m/g')
    
    %.o : %.cpp
        @echo -e "$(BUILD_PRINT)\n$(COMPILE_cpp)\n$(COMPILE_cpp_OUT)"
    .SUFFIXES: .o .cpp
    

    All the commands are invoked by only one echo because I want all the outputs (command string and warnings/errors) coherently grouped for each file built when I launch a parallel build with make -j.

    $(BUILD_PRINT) just prints out the path of the file currently being built.

    $(COMPILE_cpp) prints out the string of the compiler, so that I can see the command with all the flags/dependencies/etc...

    $(COMPILE_cpp_OUT) stores the output of the compiler and change some relevant word colour via sed command.