[英]Permanently and reliably set gcc include path globally
系統:LMDE4, 64bit, gcc-8.3.0, VS Code
目標文件: https://github.com/opencv/opencv/blob/master/samples/cpp/videocapture_camera.cpp
現在正如標題所說,這開始讓我生氣。 沒有什么可以解決這樣一個簡單的問題。 不,我不想總是使用“-I”來告訴編譯器很明顯的事情。 這是我到目前為止所做的。
在 VS 代碼的 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 仍然是盲人? 我怎樣才能真正擺脫這個?
這是您在 Ubuntu 20.04 上的問題的最小重現。
$ 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
根據GCC 手冊:3.21 影響 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.
從而重現了錯誤。
-isystem
選項記錄在GCC 手冊:3.16 目錄搜索選項中
您的問題的一般解決方案是:不要以任何方式g++
g++... -isystem /usr/include...
您可以避免以這種方式運行g++
命令,因為選項-isystem /usr/include
是不必要的。 /usr/include
是預處理器的默認搜索目錄。 您無需告訴它在那里尋找系統 header 文件 - 通過環境設置、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
不是標准指令,它是 GCC 擴展,記錄在GCC 手冊中:2.7 Wrapper Headers
而#include <stdlib.h>
意味着:
包括在<...>
搜索順序中發現的第一個名為stdlib.h
的文件,從頭開始
#include_next <stdlib.h>
表示:
包括在<...>
搜索順序中發現的下一個名為stdlib.h
的文件,從現在正在處理的文件之后的目錄開始。
<...>
搜索順序中唯一包含stdlib.h
的目錄是/usr/include
。 因此,如果預處理器在<...>
搜索順序中的任何目錄dir
中的任何文件中遇到#include_next <stdlib.h>
,而/usr/include
在<...>
搜索順序中是第一個,則不能是比<...>
搜索順序中的dir
晚的目錄,其中<stdlib.h>
將被找到。 所以錯誤。
#include_next <foobar.h>
只有在<...>
搜索順序將包含<foobar.h>
的目錄放在包含該指令的文件的目錄之后才能工作。 根據經驗,不要弄亂<...>
搜索順序。
剛剛討論的問題是針對 GCC 6.0 提出的回歸錯誤報告的主題。 如您所見,分辨率為WONTFIX
。
.bashrc
導出都是糟糕的做法。
沒有必要按照默認搜索順序告訴預處理器任何搜索目錄。 你只能把事情弄錯。
默認情況下不會找到的目錄應由命令行上指定的-I dir
選項指定(通常通過構建配置的參數注入),以便這些非默認選項在構建日志中可見以進行故障排除。 在構建系統中應盡量避免使用“看不見的手”。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.