C++ make/gcc 神秘错误2:如何获得更多信息?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5390081/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:03:26  来源:igfitidea点击:

Make / gcc cryptic error 2: how to have more information?

c++gccdependenciesmakefile

提问by Gui13

I have this C++ project which compiles using a Makefile, and sometimes when (my guess) there are some missing includes, I get a cryptic "error 2" message and the make process stops.
I suspect the missing includes because this is the third times it happens when I included a non-existent header file.

我有一个使用 Makefile 编译的 C++ 项目,有时(我的猜测)缺少一些包含时,我会收到一条神秘的“错误 2”消息并且 make 过程停止。
我怀疑缺少包含,因为这是我包含不存在的头文件时第三次发生这种情况。

It looks like this:

它看起来像这样:

---- Build tmp/foo.o ----
---- Build tmp/bar.o ----
---- Build tmp/toto.o ----
---- Build tmp/tata.o ----
make: *** [build_Project] Error 2

This is driving me nuts, because even using verbose commands (where each g++ invocation is showed), I can't see anything.
I expected the guy to throw up some erroneous messages like "can't find header X" or "undefined reference to Y", but there's nothing.

这让我发疯,因为即使使用冗长的命令(显示每个 g++ 调用),我也看不到任何东西。
我预计这家伙会抛出一些错误消息,例如“找不到标题 X”或“未定义对 Y 的引用”,但什么也没有。

My compiling options for gcc are -O0 -Wall -Werror -Wno-write-strings -fno-rtti -fno-exceptions, if this helps.

我的 gcc 编译选项是-O0 -Wall -Werror -Wno-write-strings -fno-rtti -fno-exceptions,如果这有帮助的话。

Ah, and we use the Makefile trick of including dependencies:

啊,我们使用包含依赖项的 Makefile 技巧:

ifneq ($(strip $(DEPENDS)),)
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPENDS)
endif
endif

( see hereand herefor more information )

(有关更多信息,请参见此处此处

Although this is documented stuff, I suspect my problem has something to do with this dependencies inclusion.

尽管这是记录在案的内容,但我怀疑我的问题与此依赖项包含有关。

If you already stumbled on this issue, feel free to comment on this...

如果您已经偶然发现了这个问题,请随时对此发表评论...

Thanks in advance.

提前致谢。

edit:Okay, after a bit of playing, suppressing the -in front of -include $(DEPENDS)gives me some more info (the makefile doesstop on the missing included file).

编辑:好的,在玩了一会儿之后,抑制-前面的-include $(DEPENDS)给了我更多信息(makefile确实停止在丢失的包含文件上)。

make[1]: *** No rule to make target ? foo.h ?, necessary for ? tmp/bar.d ?. Stop.

Now the drawback is that when I launch makefor the first time, I get a missing bar.d filemessage for each dependency file that should be included (which was why we put the -in the first place). Any solution?

现在的缺点是,当我make第一次启动时,我会收到missing bar.d file每个应该包含的依赖文件的消息(这就是我们将-放在首位的原因)。有什么解决办法吗?

采纳答案by Gui13

Ok my edit solved the problem: placing a dash -in front of includehides the error messages coming from the dependency generation.

好的,我的编辑解决了这个问题:-在前面放置一个破折号include隐藏来自依赖项生成的错误消息。

Note for later: don't try to outsmart Make.

以后注意:不要试图智胜Make。

回答by Steve-o

It's a bespoke Makefile, possibly via some tool like CMake that is hiding the compiler output similar to this:

这是一个定制的 Makefile,可能是通过像 CMake 这样的工具隐藏了类似于以下的编译器输出:

gcc -o a.out a.c 2>&1 > /dev/null

If you don't know what is happening it sounds like a good idea to revisit the build system completely, try starting anew.

如果您不知道发生了什么,完全重新访问构建系统听起来是个好主意,请尝试重新开始。

回答by startergo

/dev/null 2>&1 statement into parts:

/dev/null 2>&1 语句分成几部分:

Part 1: >> output redirection This is used to redirect the program output and append the output at the end of the file. More...

第 1 部分:>> 输出重定向 这用于重定向程序输出并将输出附加到文件末尾。更多...

Part 2: /dev/null special file This is a Pseudo-devices special file. Command

第 2 部分:/dev/null 特殊文件 这是一个伪设备特殊文件。命令

ls -l /dev/null

ls -l /dev/null

will give you details of this file:

将为您提供此文件的详细信息:

crw-rw-rw-. 1 root root 1, 3 Mar 20 18:37 /dev/null

crw-rw-rw-。1 根根 1, 3 Mar 20 18:37 /dev/null

Did you observe crw? Which means it is a pseudo-device file which is of character-special-file type that provides serial access. /dev/null accepts and discards all input; produces no output (always returns an end-of-file indication on a read). Reference: Wikipedia

你观察cw了吗?这意味着它是一个提供串行访问的字符特殊文件类型的伪设备文件。/dev/null 接受并丢弃所有输入;不产生任何输出(读取时总是返回文件结束指示)。参考:维基百科

Part 3: 2>&1 file descriptor

第 3 部分:2>&1 文件描述符

Whenever you execute a program, the operating system always opens three files, standard input, standard output, and standard error as we know whenever a file is opened, the operating system (from kernel) returns a non-negative integer called a file descriptor. The file descriptor for these files are 0, 1, and 2, respectively. So 2>&1 simply says redirect standard error to standard output. & means whatever follows is a file descriptor, not a filename. In short, by using this command you are telling your program not to shout while executing. What is the importance of using 2>&1? If you don't want to produce any output, even in case of some error produced in the terminal. To explain more clearly, let's consider the following example:

每当您执行程序时,操作系统总是打开三个文件,标准输入、标准输出和标准错误,正如我们所知,每当打开文件时,操作系统(来自内核)返回一个称为文件描述符的非负整数。这些文件的文件描述符分别为 0、1 和 2。所以 2>&1 只是说将标准错误重定向到标准输出。& 表示后面的内容是文件描述符,而不是文件名。简而言之,通过使用这个命令,你告诉你的程序在执行时不要喊叫。使用 2>&1 的重要性是什么?如果您不想产生任何输出,即使在终端中产生某些错误的情况下。为了更清楚地解释,让我们考虑以下示例:

$ ls -l > /dev/null

$ ls -l > /dev/null

For the above command, no output was printed in the terminal, but what if this command produces an error:

对于上面的命令,终端没有打印输出,但是如果这个命令产生错误怎么办:

$ ls -l file_doesnot_exists > /dev/null

$ ls -l file_doesnot_exists > /dev/null

ls: cannot access file_doesnot_exists: No such file or directory

ls: 无法访问 file_doesnot_exists: 没有那个文件或目录

Despite I'm redirecting output to /dev/null, it is printed in the terminal. It is because we are not redirecting error output to /dev/null, so in order to redirect error output as well, it is required to add 2>&1:

尽管我将输出重定向到 /dev/null,但它还是打印在终端中。因为我们没有将错误输出重定向到/dev/null,所以为了同样重定向错误输出,需要添加2>&1:

$ ls -l file_doesnot_exists > /dev/null 2>&1

$ ls -l file_doesnot_exists > /dev/null 2>&1