簡體   English   中英

永久可靠地設置 gcc 包括全局路徑

[英]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


[1] 正如您所懷疑的那樣,您發布的所有.bashrc導出都是糟糕的做法。

  • 沒有必要按照默認搜索順序告訴預處理器任何搜索目錄。 你只能把事情弄錯。

  • 默認情況下不會找到的目錄應由命令行上指定的-I dir選項指定(通常通過構建配置的參數注入),以便這些非默認選項在構建日志中可見以進行故障排除。 在構建系統中應盡量避免使用“看不見的手”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM