gcc在哪里查找C和c++头文件?

在Unix系统中,gcc在哪里查找头文件?

今天早上我花了一点时间寻找一些系统头文件,所以我认为这将是很好的信息。

139947 次浏览

GCC手册CPP节表示头文件可能位于以下目录中。在搜索路径页中:

GCC在几个不同的地方寻找头文件。在一个普通的Unix系统中,如果你没有指示它,它将在#include中查找请求的头文件:

 /usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include

对于c++程序,它也会首先查找/usr/include/g++-v3。

此外,gcc将查找-I选项后指定的目录

您可以创建一个试图包含伪系统头的文件。 如果在这样的源上以详细模式运行gcc,它将在查找伪标头时列出所有系统包含位置

$ echo "#include <bogus.h>" > t.c; gcc -v t.c; rm t.c


[..]


#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc/i686-apple-darwin9/4.0.1/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.


[..]


t.c:1:32: error: bogus.h: No such file or directory
`gcc -print-prog-name=cc1plus` -v

这个命令会问gcc它正在使用哪个c++预处理器,然后问这个预处理器在哪里查找include。

对于特定的设置,您将得到一个可靠的答案。

同样,对于C预处理器:

`gcc -print-prog-name=cpp` -v

你可以通过查看以下命令查看bash中C程序的(额外的)include路径:

echo $C_INCLUDE_PATH

如果这是空的,它可以被修改为添加默认的包含位置,通过:

export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include

为了让GCC打印出它将在其中查找系统头文件的完整目录集,像这样调用它:

$ LC_ALL=C gcc -v -E -xc - < /dev/null 2>&1 |
LC_ALL=C sed -ne '/starts here/,/End of/p'

哪个将产生表单的输出

#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.

如果你在命令行上有-I-family选项,它们将影响打印出来的内容。

(sed命令是为了摆脱调用打印的所有其他垃圾,而LC_ALL=C是为了确保sed命令有效——“从这里开始”和“搜索列表结束”短语翻译的IIRC。)

g++ -print-search-dirs
gcc -print-search-dirs

编译器查找头文件的路径集可以通过以下命令检查:-

< em > cpp - v < / em >

如果声明< em > # include " < / em >,编译器首先在源文件的当前目录中搜索,如果没有找到,则继续在上述检索到的目录中搜索。

如果你声明< em > #包括& lt; > < / em >,编译器直接搜索从上面的命令获得的目录。

来源:http://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art026

这些是gcc在默认情况下查找指定头文件的目录(假设头文件包含在chevrons <>中); 1. /usr/local/include/——用于第三方头文件。 2. /usr/include/——用于系统头文件 如果你决定把你的自定义头文件放在上面提到的目录以外的地方,你可以像下面这样包括它们: 1. 在文件路径中使用引号("./custom_header_files/foo.h"),而不是include语句中的v号。 2. 在编译代码时使用-I开关。 -I /home/user/custom_headers/ -c foo.c -p foo.o 基本上,-I开关告诉编译器首先查找用-I开关指定的目录(在检查标准目录之前)。当使用-I开关时,头文件可以使用v符号包含

我的系统默认有gcc9,我已经从源代码构建了一个gcc12,我认为接受的答案是不正确的,即gcc -print-prog-name=cc1plus -v没有给出真正的包含搜索路径。

我的构建配置是

Configured with: /home/tian/playground/gcc_build_play/objdir/../gcc-12.1.0/configure --prefix=/home/tian/GCC-12.1.0 --disable-multilib

并且无论我mv gcc12在我的机器中的位置。它总是可以正确地包含自己的c++头文件。


如果我在原始安装目录中键入./gcc -print-prog-name=cc1plus -v,它会给出:

tian@tian-B250M-Wind:~/GCC-12.1.0/bin$ `./gcc -print-prog-name=cc1plus` -v
ignoring nonexistent directory "/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/x86_64-pc-linux-gnu
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/backward
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include
/usr/local/include
/home/tian/GCC-12.1.0/include
/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed
/usr/include
End of search list.

mv my gcc12 to ~/Desktop/,再次运行,得到:

tian@tian-B250M-Wind:~/Desktop/GCC-12.1.0/bin$ `./gcc -print-prog-name=cc1plus` -v
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include/c++/12.1.0"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include/c++/12.1.0/x86_64-pc-linux-gnu"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include/c++/12.1.0/backward"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/include"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed"
ignoring nonexistent directory "/home/tian/GCC-12.1.0/x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/include
End of search list.

如果这是真的,那么我用./g++编译一个程序,它应该使用/usr/include/usr/local/include中的c++头文件。但事实并非如此。

这里省略实验。您可以尝试使用mv重命名测试程序使用的gcc12的任何头文件,或在头文件中添加一些垃圾代码。然后你会看到gcc12 ./g++抱怨gcc12 c++头文件,而不是我的系统gcc9的c++头文件在/usr/include/usr/local/include

所以在这两个地方./g++都可以正确地找到它的gcc12 c++头文件。


所以我猜gccg++是在相对目录中查找头,相对于/path_to_gcc12/bin/gcc

Try./g++ -g -Wall --verbose -o test test.cpp给出了真正的包含路径:

tian@tian-B250M-Wind:~/Desktop/GCC-12.1.0/bin$ ./g++ -g -Wall --verbose -o test test.cpp
Using built-in specs.
COLLECT_GCC=./g++
COLLECT_LTO_WRAPPER=/home/tian/Desktop/GCC-12.1.0/bin/../libexec/gcc/x86_64-pc-linux-gnu/12.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /home/tian/playground/gcc_build_play/objdir/../gcc-12.1.0/configure --prefix=/home/tian/GCC-12.1.0 --disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 12.1.0 (GCC)
COLLECT_GCC_OPTIONS='-g' '-Wall' '-v' '-o' 'test' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/home/tian/Desktop/GCC-12.1.0/bin/../libexec/gcc/x86_64-pc-linux-gnu/12.1.0/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -iprefix /home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/ -D_GNU_SOURCE test.cpp -quiet -dumpbase test.cpp -dumpbase-ext .cpp -mtune=generic -march=x86-64 -g -Wall -version -o /tmp/ccrg0qhG.s
GNU C++17 (GCC) version 12.1.0 (x86_64-pc-linux-gnu)
compiled by GNU C version 12.1.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP


GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../x86_64-pc-linux-gnu/include"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/x86_64-pc-linux-gnu"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/backward"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring duplicate directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed"
ignoring nonexistent directory "/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../x86_64-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/x86_64-pc-linux-gnu
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../include/c++/12.1.0/backward
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0/include-fixed
/usr/local/include
/home/tian/Desktop/GCC-12.1.0/bin/../lib/gcc/../../include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.


所以我想我的猜测是正确的。