Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux Makefile警告和错误的颜色高亮显示_Linux_Bash_Colors_Sed_Makefile - Fatal编程技术网

Linux 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 提前谢谢 在生成上下文中,以下行的行为与

我已经写了一个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

提前谢谢

在生成上下文中,以下行的行为与它们在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在make解析时只运行echo命令一次,而不是每次使用
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