gcc 如何找到以下头文件?

use*_*132 10 linux gcc

我已经包含sys/ptrace.h在我的 C 程序中。

的输出/usr/lib/gcc/x86_64-linux-gnu/4.8/cc1 -v给出了以下路径,其中 gcc 查找头文件

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
 /usr/include
End of search list.
Run Code Online (Sandbox Code Playgroud)

gcc -M我的程序的输出给出了以下头文件位置

    pt.o: pt.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \
 /usr/include/x86_64-linux-gnu/bits/wordsize.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs.h \
 /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h \
 /usr/include/x86_64-linux-gnu/bits/types.h \
 /usr/include/x86_64-linux-gnu/bits/typesizes.h /usr/include/libio.h \
 /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdarg.h \
 /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \
 /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \
 /usr/include/x86_64-linux-gnu/sys/ptrace.h
Run Code Online (Sandbox Code Playgroud)

由于/usr/include/x86_64-linux-gnu/未包含在第一个输出中,gcc 如何查找sys/ptrace.h

编辑:

echo '#include <sys/ptrace.h>' | gcc -fsyntax-only -xc -v -H -结果的输出

Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) 
Run Code Online (Sandbox Code Playgroud)

Gia*_*968 12

简短的回答。

您的问题是关于 , 的输出cc1 -v,但这并不影响 CPP(C 预处理器),它的包含混合到整个编译链中。如果您cpp -v在您的系统上运行,您应该看到,混合的包含看起来与 的输出相似,cc1 -v但至少在其中/usr/include/x86_64-linux-gnu添加了路径。

更长的答案。

由于/usr/include/x86_64-linux-gnu/未包含在第一个输出中,gcc 如何查找sys/ptrace.h

从技术上讲,/usr/include/x86_64-linux-gnu/没有在第一个输出中明确设置,但/usr/include/肯定是。这是官方 GNU GCC 文档中解释的默认搜索路径:

GCC 在几个不同的地方寻找标题。在一个普通的 Unix 系统上,如果你不另外指示它,它会寻找用#include <file>in请求的标头:

  • /usr/local/include
  • libdir/gcc/target/version/include
  • /usr/目标/包括
  • /usr/包括

并在此处进一步解释:

GCC#include "file"首先在包含当前文件的目录中查找请求的头文件,然后在-iquote选项指定的目录中查找,然后在相同的位置查找使用尖括号请求的头文件。例如,如果 /usr/include/sys/stat.h包含 # include "types.h",GCCtypes.h先在 in 中查找 /usr/include/sys,然后在其通常的搜索路径中查找。

所以这意味着x86_64-linux-gnu/路径只是/usr/include/*/sys/像这样插入:

/usr/include/x86_64-linux-gnu/sys/ptrace.h
Run Code Online (Sandbox Code Playgroud)

至少这是我在这个问题的早期版本中最初的想法。但是在查看了这个站点之后,对正在发生的事情的解释会更详细一些,并且该站点对与我上面发布的内容等效的内容的直接响应在下面重新发布;大胆的强调是我的:

但这有点像一个空洞的答案(而且也不完整)。肯定有办法让 GCC 告诉你它最终会在哪里寻找它的头文件?好吧,尽管将 GCC 视为接收源代码文件并输出工作程序的单个整体应用程序很方便,但从技术上讲,它是其他程序的集合,这些程序链接在一起以生成最终编译的目标文件。第一个是 CPP,C Pre-Processor 的缩写,它的工作是寻找编译器指令, #include并按照它们指定的方式修改源代码;在包含的情况下,通过将另一个文件的内容复制到当前文件中。您可以通过将 -v 标志传递给它来查看它在何处查找这些文件:

知道 CPP(C 预处理器)是编译器过程的第一步,让我们看看cpp -v我的 Ubuntu 12.04.5 测试系统上的“include”输出:

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
Run Code Online (Sandbox Code Playgroud)

在那里你可以清楚地看到/usr/include/x86_64-linux-gnu。为了比较,这里是/usr/lib/gcc/x86_64-linux-gnu/4.6/cc1 -v在同一个 Ubuntu 12.04.5 测试系统上类似的“包含”输出:

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.6/include-fixed
 /usr/include
Run Code Online (Sandbox Code Playgroud)

请注意/usr/include/x86_64-linux-gnu初始 CPP(C 预处理器)操作如何清楚地插入到混音中。该网站上的帖子进一步解释了这些路径的来源;再次大胆强调是我的:

这个路径实际上是在编译时内置到 CPP(它是 GCC 的一部分)中的;如果出于某种原因您最终删除了这些目录之一,则仍会在每次编译时对其进行检查。每个目录都按照此处列出的顺序进行搜索;如果在 中找到文件/usr/local/include,则不会检查接下来的三个目录。

所以这一切都归结为 CPP(C 预处理器)被称为 C 编译链的第一部分。