Linux Makefile警告和错误的颜色高亮显示
我已经写了一个Makefile,它工作得很好;我只是发布了正在调查的部分:Linux Makefile警告和错误的颜色高亮显示,linux,bash,colors,sed,makefile,Linux,Bash,Colors,Sed,Makefile,我已经写了一个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 提前谢谢 在生成上下文中,以下行的行为与
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
提前谢谢 在生成上下文中,以下行的行为与它们在shell中的行为不同:
ccred=$(echo -e "\033[0;31m")
ccyellow=$(echo -e "\033[0;33m")
ccend=$(echo -e "\033[0m")
在shell中,这些将把回声输出放入这些变量中。在make中,它尝试运行echo
命令,但该命令不存在,并最终创建空变量
这些线路应该是
通过shell运行命令并存储输出,然后在主体中用作ccred=$(shell echo-e“\033[0;31m”)
$(ccred)
将字符串存储在变量中,然后在正文中用作ccred=\033[0;31m
$$(echo-e'$(ccred)
将命令存储在变量中,然后在主体中用作ccred=echo-e“\033[0;31m”
$$($(ccred)
ccred
)
make和shell变量共享一个前缀sigil$。因此,要在make上下文中使用shell变量,需要将shell上下文中的$加倍为$$,从而对其进行转义。因此,s%$pathpat%$ccred&$ccend%g
需要是s%$$pathpat%$$ccred&$$ccend%g
,等等
make规则主体的每一行都作为不同的shell命令执行,因此这些命令不能相互交互。为了有意义地使用像echo“${PIPESTATUS[0]}”这样的构造,因此要求它们在make中位于同一命令行上。因此,该模式规则中的编译行必须是$(编译cpp)2>&1 | sed…;echo“${PIPESTATUS[0]}”
但是,即使这样也不能满足您的需要,因为您不需要从需要退出的编译中回显退出状态,因此您可能需要;在那里退出“${PIPESTATUS[0]}”
。让它工作起来了
首先感谢@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
BUILD\u PRINT=\e[1;34mBuilding$&1|sed-e's/error/\\\e[1;31merror\\\e[0m/g'-e s/warning/\\\e[1;33mwarning\\\\e[0m/g')
%.o:%.cpp
@echo-e“$(生成\u打印)\n$(编译\u cpp)\n$(编译\u cpp\u输出)”
.后缀:.o.cpp
所有命令仅由一个echo
调用,因为我希望在使用make-j
启动并行构建时,为每个构建的文件将所有输出(命令字符串和警告/错误)连贯地分组
$(BUILD\u PRINT)
只打印当前正在生成的文件的路径
$(COMPILE\u cpp)
打印出编译器的字符串,这样我就可以看到包含所有标志/依赖项等的命令
$(COMPILE\u cpp\u OUT)
存储编译器的输出,并通过sed
命令更改一些相关单词的颜色。什么是(或不是)这个makefile到底发生了什么?快速浏览一下,您可能只需要避开body规则中的$
,因此s%$pathpat%$ccred&$ccend%g
需要是s%$$pathpat%$$ccred&$$ccend%g
,等等。此外,pipestatus echo不会像在同一命令行那样在自己的行上工作作为编译行,以您想要的方式工作。我编辑了这篇文章,但出现了一个错误。您的命令行基本上说,sed-e“…1”-e“…2”echo”
。它告诉sed
对名为echo
的文件和空字符串执行sed命令..1
和..2
。因此,错误消息是合乎逻辑的。此外,在makefile中,设置make
变量的命令不能使用bash语法。因此ccred=$(echo-e“\033[0;31m”)
的作用与您认为的不同。最后,正如Etan指出的那样,在将命令行传递给bash之前,会处理makefiles中的$
替换,因此您需要为bash替换转义$
,或者将()
围绕make变量的名称。您需要在echo
前面加一个分号,将其分隔成第二个命令,而不仅仅是将其附加到sed命令。我会误读$(echo-e“\033[0;31m”)
最初,您可能想从该行中删除$()
,然后使用$$(echo“$$ccred”)
在规则体中,或使用$(shell echo…)
获取命令的输出。顺便说一句,除了学习更多关于bash
和make
的价值外,我不认为避免使用诸如colorgc
或colormake
之类的简单工具的理由。但最好的解决方案可能是使用clang
编译,它将错误消息着色d警告本身。Etan Reisner和rici,谢谢您的详细解释。我对这个主题很陌生,我知道我犯了一些小错误。现在我已经按照您的提示修改了我的Makefile文件:$(COMPILE\u cpp)2>&1|sed-e s/error/“\\\e[1;31merror\\\\e[0m”/g
但是,结果是,调用make目标时,我得到的整个编译器输出不是用红色粗体写的错误
字,而是用替换的\e[1;31merror\e[0m
纯文本。我哪里错了?@helmet\u 23您需要使用echo(或类似)评估这些转义字符。不仅仅是将它们发送到输出。请注意,在我的变体中,echo总是存在于某个地方。如果您想要更具可读性的内容,可以使用ccred=$(shell tput setaf 001)
,并使用来选择颜色。这在debian jessie上对我不起作用。我必须包含echo的完整路径(例如@/bin/echo)以避免使用shell内置命令。
ccred=$(echo -e "\033[0;31m")
ccyellow=$(echo -e "\033[0;33m")
ccend=$(echo -e "\033[0m")
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