我有这个C++项目,使用Makefile编译,有时当(我猜)有一些缺失的包含文件,我得到一个神秘的 "错误2 "信息,并且make进程停止。我怀疑是缺少了一些包含文件,因为这已经是我第三次在包含一个不存在的头文件时发生这种情况了。
它看起来像这样。
---- Build tmp/foo.o ----
---- Build tmp/bar.o ----
---- Build tmp/toto.o ----
---- Build tmp/tata.o ----
make: *** [build_Project] Error 2
这让我抓狂,因为即使是使用啰嗦的命令(每次g++调用都会显示),我也看不到任何东西。我希望这家伙能抛出一些错误的信息,比如"找不到头部X"或"未定义对Y的引用",但什么都没有。
我对gcc的编译选项是 -O0 -Wall -Werror -Wno-write-strings -fno-rtti -fno-exceptions
,如果这有帮助的话。
啊,我们使用Makefile的技巧,包括依赖关系。
ifneq ($(strip $(DEPENDS)),)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPENDS)
endif
endif
虽然这是有记录的东西,但我怀疑我的问题与这个依赖关系的包含有关。
如果你已经偶然发现了这个问题,欢迎评论这个问题......
先谢谢你。
编辑。好吧,经过一番玩耍,抑制掉了 -
在...面前 -include $(DEPENDS)
给了我一些更多的信息(makefile中的 是否 停止在缺少的包含文件上)。)
make[1]: *** No rule to make target « foo.h », necessary for « tmp/bar.d ». Stop.
现在的缺点是,当我启动 make
第一次,我得到 missing bar.d file
信息(这也是为什么我们把每一个应该被包含的依赖文件的 -
).有什么解决办法吗?
好吧,我的编辑解决了这个问题:把一个破折号放在了 "我 "的后面。-
在...面前 include
隐藏来自依赖生成的错误信息。
以后注意:不要试图智取Make。
这是一个定制的Makefile,可能是通过一些工具,比如CMake,它隐藏了类似于这样的编译器输出。
gcc -o a.out a.c 2>&1 > /dev/null
如果你不知道发生了什么事,听起来是个好主意,重新审视一下编译系统,试着重新开始。
devnull 2>&1条语句分成几部分。
第1部分:>>输出重定向这是用来重定向程序的输出,并将输出附加在文件的最后。更多...
第2部分:devnull特殊文件这是一个伪设备特殊文件。
ls -l devnull
会给你这个文件的详细信息。
Crw-rw-rw-. 1 root root 1, 3 Mar 20 18:37 devnull
你观察到CRW了吗?这意味着它是一个伪设备文件,它是字符特殊文件类型,提供串行访问。devnull接受和丢弃所有输入;不产生输出(读取时总是返回一个文件结束的指示)。参考文献。维基百科
第3部分:2>&1个文件描述符。
每当执行一个程序的时候,操作系统总会打开三个文件,标准输入、标准输出和标准错误,因为我们知道每当打开一个文件,操作系统(从内核)就会返回一个非负的整数,叫做文件描述符。这些文件的文件描述符分别是0、1和2.所以2>&1简单的说就是将标准错误重定向到标准输出.&意思是无论后面的是什么都是文件描述符,而不是文件名.简而言之,使用这个命令就是告诉你的程序在执行的时候不要喊话.使用2>&1的重要性是什么呢?如果你不想产生任何输出,即使是在终端产生一些错误的情况下。为了更清楚地解释,让我们考虑下面的例子。
$ ls -l > devnull.
对于上面的命令,终端中没有打印出任何输出,但是如果这个命令产生错误怎么办。
$ ls -l file_doesnot_exists > devnull.
ls: 无法访问file_doesnot_exists。没有这样的文件或目录
尽管我将输出重定向到devnull,但在终端中还是打印出来了。这是因为我们没有将错误输出重定向到devnull,所以为了将错误输出也重定向,需要添加2>&1。
$ ls -l file_doesnot_exists > devnull 2>&1。