系统:LMDE4、64位,gcc-8.3.0,VS代码
目标文件:https://github.com/opencv/opencv/blob/master/samples/cpp/videocapture_camera.cpp
现在,正如标题所述,这开始激怒我。解决这种简单问题没有任何工作。不,我不想一直使用“ -I”向编译器讲述很明显的事情。这是我到目前为止所做的。
在VS Code的c_cpp_properties.json中:
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/include/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "gnu++14",
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include/"
]
}
}
],
"version": 4
}
在.bashrc中:
#C Include
export C_INCLUDE_PATH="/usr/include"
export C_INCLUDE_PATH=$C_INCLUDE_PATH:"/usr/include/opencv2"
#C++ Include
export CPLUS_INCLUDE_PATH="/usr/include"
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:"/usr/include/c++/8/"
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:"/usr/include/opencv2"
#C/C++ Include
export CPATH="/usr/include"
我很确定所有.bashrc导出都已经是一个肮脏的解决方法,并且仍然在编译时收到以下消息:
In file included from /usr/include/c++/8/bits/stl_algo.h:59,
from /usr/include/c++/8/algorithm:62,
from /usr/include/opencv2/core/base.hpp:55,
from /usr/include/opencv2/core.hpp:54,
from ~/LearnDummy/helloworld.cpp:1:
/usr/include/c++/8/cstdlib:75:15: fatal error: stdlib.h: Datei oder Verzeichnis nicht gefunden
#include_next <stdlib.h>
^~~~~~~~~~
compilation terminated.
很好... stdlib.h是未知的(耶稣!)... find /usr -name stdlib.h
给了我
/usr/include/stdlib.h
/usr/include/c++/8/stdlib.h
/usr/include/c++/8/tr1/stdlib.h
/usr/include/x86_64-linux-gnu/bits/stdlib.h
/usr/include/i386-linux-gnu/bits/stdlib.h
此外,VS Code已经知道(!),一旦单击“转到定义”,文件仍然在哪里,而gcc仍然是盲目的。我该如何摆脱呢?
答案 0 :(得分:0)
这是您在Ubuntu 20.04上遇到的问题的minimal repro。
$ g++ --version
g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0
...
$ cat main.cpp
#include <cstdlib>
int main ()
{
return EXIT_SUCCESS;
}
$ export CPLUS_INCLUDE_PATH="/usr/include"; g++ -c main.cpp
In file included from main.cpp:1:
/usr/include/c++/9/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
75 | #include_next <stdlib.h>
| ^~~~~~~~~~
compilation terminated.
请注意,export CPLUS_INCLUDE_PATH="/usr/include"
与您的
.bashrc
中的相同设置。
如果我们删除该环境设置,则不会发生错误:
$ export CPLUS_INCLUDE_PATH=; g++ -c main.cpp; echo Done
Done
根据the GCC Manual: 3.21 Environment Variables Affecting GCC,该环境设置的效果 等同于:
$ g++ -isystem /usr/include -c main.cpp
In file included from main.cpp:1:
/usr/include/c++/9/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
75 | #include_next <stdlib.h>
| ^~~~~~~~~~
compilation terminated.
相应地会重现错误。
the GCC Manual: 3.16 Options for Directory Search中记录了-isystem
选项
您的问题的一般解决方案是:请勿以任何方式运行g++
编译
效果 g++ ... -isystem /usr/include ...
您可以避免以这种方式运行g++
命令,因为该选项
-isystem /usr/include
是不必要的。 /usr/include
是默认的搜索目录
用于预处理器。您无需告诉它在那里查找系统头文件-
通过环境设置或VS Code配置或其他任何方式。
请参阅预处理程序对C ++的默认搜索顺序:-
$ echo | g++ -x c++ -E -Wp,-v -
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/9"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/9
/usr/include/x86_64-linux-gnu/c++/9
/usr/include/c++/9/backward
/usr/lib/gcc/x86_64-linux-gnu/9/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include ### <- There it is ###
End of search list.
...
所以您的评论:
我很确定所有.bashrc导出都已经是一个肮脏的解决方法
在钱上 1 。但是更糟糕的是,.bashrc
设置:
export CPLUS_INCLUDE_PATH="/usr/include"
将问题转变为 bash个人资料的持久功能。
错误如何发生?
-isystem /usr/include
与预处理程序的搜索顺序之间的差异
可以在这里看到:
$ echo | g++ -x c++ -isystem /usr/include -E -Wp,-v -
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/9"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/../../../../x86_64-linux-gnu/include"
ignoring duplicate directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include ### <- Was previously last, now is first ###
/usr/include/c++/9
/usr/include/x86_64-linux-gnu/c++/9
/usr/include/c++/9/backward
/usr/lib/gcc/x86_64-linux-gnu/9/include
/usr/local/include
/usr/include/x86_64-linux-gnu
End of search list.
...
如您所见,/usr/include
现在在<...>
搜索中被检测为重复目录
订购;第二次出现-以前是 last -被删除,第一次出现是
保留,在搜索顺序中排在第一位。
现在召回诊断:
/usr/include/c++/9/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
75 | #include_next <stdlib.h>
| ^~~~~~~~~~
预处理器指令#include_next
不是标准指令,它是
在the GCC manual: 2.7 Wrapper Headers
#include <stdlib.h>
的意思是:
从头开始,包含在stdlib.h
搜索顺序中发现的第一个名为<...>
的文件
#include_next <stdlib.h>
的意思是:
包括从stdlib.h
搜索顺序中发现的名为<...>
的下一个文件。
目录,紧随正在处理的文件之后。
在<...>
搜索顺序中唯一包含stdlib.h
的目录是/usr/include
。所以,
如果预处理器在#include_next <stdlib.h>
中任何目录dir
中的任何文件中遇到<...>
搜索顺序,虽然/usr/include
在<...>
搜索顺序中排在第一位,但是没有目录
在dir
搜索顺序中晚于<...>
的位置,将找到<stdlib.h>
。还有错误。
#include_next <foobar.h>
仅在<...>
搜索顺序将包含以下内容的目录
在包含该指令的文件所在的文件之后的<foobar.h>
。根据经验,
只是不要弄乱<...>
的搜索顺序。
刚才讨论的问题是a regression bug-report raised against GCC 6.0的主题。
如您所见,分辨率为WONTFIX
。
.bashrc
出口都是不当行为。
没有必要告诉预处理器中的任何搜索目录 其默认搜索顺序。你只能把事情弄错。
默认情况下将 找不到的目录应由
在命令行上指定的-I dir
选项(通常通过参数注入)
的构建配置),以便这些非默认选项在构建日志中可见
解决问题。在构建系统中应避免“看不见的手”
最大程度的实践。