如何将linux编译过程中的警告及错误信息输出到文件中

作为一个完美主义者,我在windows系统下编写和调试程序时,都会小心翼翼的搞定每一个warning,使得程序最终编译出来的输出结果非常干净,简简单单的一个success,让人看的神清气爽!

然而在linux下,事情往往不如我所愿,特别是在编译一些大型的开源项目,比如u-boot、linux内核、qt等程序的源码时,一方面本身这些代码的规模就极其庞大,就算所有模块全部没有警告,仅仅是编译输出的其他各类信息(比如过程信息、配置信息、路径信息等),就已经是频繁刷屏,让人应接不暇了。这时候,若再加上一些warning信息的话,则更让人头大【注1】。而最痛苦的是,如果此时出现了一些错误,则会出现错误信息被夹杂在海量的警告信息和其他信息中,导致很难察觉和追溯,给程序的编译和调试带来极大的麻烦。此处最典型的实例就是我昨天自己亲身经历的一个事情。

注1:在实际情况中(特别是编译像u-boot、内核、qt等大型项目源码时),这些warning可以说是非常的多,非常的多,也不知道怎么会有这么多。我一直想不明白,就是各位大神在编写和调试这些项目的源码时,为什么不把代码写干净一点,非得要留下这么多的warning呢,希望有朝一日有大神能帮我解答这个问题?

昨天在编译一份I.MX6的嵌入式程序时,由于编译过程涉及到u-boot、kernel、rootfs、app、UI等多个部件,因此我们当时自己写了一个脚本进行自动化编译。而对于kernel的编译过程,是先编译出image,然后再使用lzop工具进行压缩生成zImage。那么,问题就来了,我的系统中忘了安装lzop,导致生成了image之后,没有生成配套的zImage。但是,当时我们的脚本也写的不够严谨,当出现这个问题后,脚本并没有自动停止,而是继续运行下去了。所以,当我一看到最后脚本提示说运行成功了(当然,这里的成功其实只是一个最终的提示信息,并不代表全部过程都成功),也就没有去详细分析其中的过程(因为shell中的输出信息可谓是海量,正常情况下我想应该是没有人会去翻阅的),于是就以为所有程序都编译OK了,于是就直接一股脑下载到目标板上去了。结果无需多说,自然是出了问题。当时也是排查了很久,最后才发现问题所在。

于是,为了解决这个问题(就是编译程序时各类提示信息频繁刷屏,导致实际有用的信息被淹没在海量信息里,很难查阅),或者说,为了预防类似的问题再次出现,我就在想有没有什么比较好的招数呢?自然,大多数人都会想的到,最常用的一招就是,编译时使用静默输出的配置,即:

make -s

这样会关闭所有的其他输出信息,只保留编译过程中的警告和错误信息。显然,这种情况下,肯定比之前要好多了。但是,这里的-s也只是关闭了常规提示信息,编译警告信息则会照常输出。可是,如上所述,很多大型开源项目中,警告信息那可也不是一般的多,分分钟就给你刷屏刷到千里之外。所以,经过我自己的亲身实践,这个办法也收效甚微,只能继续思考。

终于,经过一番检索和验证,最终发现通过引入“输出文件”的思路,能够比较有效的解决这个问题。具体来说就是,将输出在屏幕上的各类信息同步输出到一个指定的文件中去,一旦有什么情况,翻阅和查询那个文件,总比在shell中回滚要方便的多。

不过,在开始介绍具体的方法之前,要先对linux中的输出设备进行一下介绍。大家都知道,linux系统中默认有3个输出设备,分别为stdin、stdout、sdterr,分别表示标准输入设备、标准输出设备和标准错误设备。那么你可知道这3类设备在系统中的,都各自有一个指定的代号吗?见下表:

设备名称 标准叫法 代号
标准输入设备 stdin = standard input 0
标准输出设备 stdout = standard output 1
标准错误设备 stderr = standard error 2

有了他们各自的代号,我们就可以进行分流,将你不太关注的信息输出到文件里去,有空再慢慢查阅。而将你关注的信息输出到屏幕上,实时获取。具体有以下几种组合方式:

1、将所有信息全部输出到屏幕

这个就不用多说了,直接一个make命令下去就好

make xxx				# 输出所有的提示信息到屏幕上
make xxx -s				# 仅输出警告及错误信息到屏幕上

2、将所有信息全部输出到文件

可以实现将所有信息全部输出到同一个文件,也可以分开输出到不同的文件。

make xxx 1>info.log 2>warn.log		# 1表示常规提示信息,2表示警告及错误信息
make xxx > all.log 2>&1			# 其中的2>&1表示错误信息输出到&1中,而&1指的是all.log

3、将常规提示信息输出到屏幕,而将警告错误信息输出到文件

就是说,无关紧要的提示信息刷屏刷掉没关系,但是错误及警告信息全部输出到日志文件了,事后可以去慢慢查阅。适用于那些警告错误信息会非常多,可以一个个慢慢处理的场合。

make xxx 2> info.log			# 警告及错误信息分流到log文件中去

4、将常规提示信息输出到文件,而将警告错误信息输出到屏幕

就是说,海量的常规提示信息全部分流到文件中去了,屏幕上只剩下一些很关键的警告及错误信息,易于提取和处理。适用于那些警告及错误信息不太多,又必须现场逐个处理的场合。

make xxx 1> warn.log			# 常规提示信息分流到log文件中去
make xxx > warn.log			# 1不写也可以,因为系统默认就是1

注意:上面所有的1/2等数字,后面紧跟着大于号’>’ ,中间不能有空格!大于号">"与输出文件名中间,则可以紧跟,也可以加一个空格。

你可能感兴趣的:(linux)