Makefile警告和错误的颜色突出显示

 ningxiao088_272 发布于 2023-01-10 09:34

我写了一个工作正常的Makefile; 我只是将其中一部分发布到调查中:

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

我想强调编译器给出的警告和错误,而不使用外部工具(如colorgcc或CMake); 我认为破解它的一个好方法是通过" bash脚本技巧 ".查看在" 如何突出显示输出中的警告和错误行"中发布的解决方案?我尝试过以下方法:

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

但它不起作用.我得到以下输出

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

提前致谢!

2 个回答
  • 搞定了.

    首先感谢@EtanReisner和@rici.这是代码:

    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
    

    所有命令仅由一个调用,echo因为我希望所有输出(命令字符串和警告/错误)针对我启动并行构建时构建的每个文件进行相关分组make -j.

    $(BUILD_PRINT) 只打印出当前正在构建的文件的路径.

    $(COMPILE_cpp) 打印出编译器的字符串,这样我就可以看到带有所有flags/dependencies/etc的命令......

    $(COMPILE_cpp_OUT)存储编译器的输出并通过sed命令更改一些相关的字颜色.

    2023-01-10 09:36 回答
  • 在make上下文中,以下行的行为与它们在shell中的行为不同:

    ccred=$(echo -e "\033[0;31m")
    ccyellow=$(echo -e "\033[0;33m")
    ccend=$(echo -e "\033[0m")
    

    在shell中,那些将回显的输出放入那些变量中.在make中尝试运行echo不存在的命令,最终创建空变量.

    这些行应该是

    ccred=$(shell echo -e "\033[0;31m")通过shell运行命令并存储输出,然后$(ccred)在正文中使用

    ccred=\033[0;31m将字符串存储在变量中,然后$$(echo -e '$(ccred)')在主体中使用

    ccred=echo -e "\033[0;31m"将命令存储在变量中,然后$$($(ccred)在主体中使用

    第一个或第二个选项中的任何一个都可能没问题.(:=而不是=在第一个选项中使make只运行一次echo命令,在make parse time,而不是每次ccred都使用.)

    make和shell变量共享前缀sigil $.因此,在make上下文中使用shell变量需要$通过将其加倍来转义in shell上下文$$.因此s%$pathpat%$ccred&$ccend%g需要s%$$pathpat%$$ccred&$$ccend%g等等

    make规则体的每一行都作为不同的shell命令执行,因此这些命令不能相互交互.为了echo "${PIPESTATUS[0]}"有意义地使用构造,因此要求它们在make中位于同一命令行中.因此,该模式规则中的编译行需要$(COMPILE_cpp) 2>&1 | sed ...; echo "${PIPESTATUS[0]}".

    但是,即使这样做也不会做你想要的,因为你不需要从你需要退出的编译中回显退出状态,所以你可能想要; exit "${PIPESTATUS[0]}"那样做.

    2023-01-10 09:36 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有