为什么/usr/include中有多个头文件副本?

我一直在浏览我的/usr/include文件夹,试图熟悉布局,我注意到有多个头文件副本(至少通过名称,我实际上并没有将它们区分开以查看它们是否准确在/usr/include的几个子目录中找到的副本).对于标准C和C头文件以及POSIX / LSB标准头文件尤其如此.

一些例子包括(注意./指/usr/include):

./asm-generic/unistd.h
./linux/unistd.h
./unistd.h
./x86_64-linux-gnu/sys/unistd.h
./x86_64-linux-gnu/bits/unistd.h
./x86_64-linux-gnu/asm/unistd.h

./stdlib.h
./x86_64-linux-gnu/bits/stdlib.h
./c++/7/stdlib.h
./c++/7/tr1/stdlib.h

./c++/7/cmath
./c++/7/ext/cmath
./c++/7/tr1/cmath

./asm-generic/termios.h
./linux/termios.h
./x86_64-linux-gnu/sys/termios.h
./x86_64-linux-gnu/bits/termios.h
./x86_64-linux-gnu/asm/termios.h
./termios.h

./linux/time.h
./time.h
./x86_64-linux-gnu/sys/time.h
./x86_64-linux-gnu/bits/time.h

为什么是这样?为什么有些C标准标题出现在C位置?

我只安装了一个编译器(GCC 7).

最佳答案
不,它们不是精确的副本.

如果您想进行调查,您会发现顶级/usr/include中的文件通常会有很多#ifdefs或其他条件,并且它们只会定义与架构无关的部分,并且#include其他内容来自层次结构内更深层次的体系结构特定目录由于某些体系结构特定的部分可能依赖于某些与体系结构无关的部分,因此可能存在多个包含在彼此之上的层.

同样,/usr/include / c下的文件将具有仅对C有意义的附加声明,并且适当时包含相应C包含文件的#includes.

游戏的名称是重复数据删除的可维护性:目标是当一个glibc开发人员需要添加一些只影响应用程序和glibc之间的ABI并且没有特定于体系结构的部分的新东西时,理想情况下需要只添加一个包含文件树中的位置,它将对使用glibc的所有硬件体系结构生效.或者说,例如,当一个新的系统调用被添加到Linux内核时,就会有一个地方可以添加它而不会干扰* BSD或GNU Hurd系统调用定义.或者,如果您将glibc移植到另一个硬件/内核架构,您将找到可以插入必要的内核ABI定义的地方,而不会干扰与架构无关的内容,这绝对是必要的.

是的,这很复杂.

我没有任何简单的参考资料,因为整个/usr/include布局是ISO C和POSIX标准要求的总和,以及GCC和glibc项目的选择.

我建议你记下你的架构三元组(在你的情况下是x86_64-linux-gnu;可以在GCC支持的任何架构上用gcc -dumpmachine获得),然后研究编译器的默认#include< ...>文件搜索路径.

您可以看到搜索路径:

> cpp -v / dev / null -o / dev / null for plain C
> c的cpp -x c -v / dev / null -o / dev / null

我这里没有GCC 7的系统,但对于GCC 6,包含路径的列表对于C来说是这样的:

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

……和C一样:

...
#include <...> search starts here:
 /usr/include/c++/6
 /usr/include/x86_64-linux-gnu/c++/6
 /usr/include/c++/6/backward
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
...

如果/usr/local/include /< architecture triplet>目录存在,它将被添加到列表中,就在/usr/local/include之前.

因此,对于您自己的项目,如果您需要包含文件的体系结构特定版本,您可以将它们放在/usr/[local /] include /< architecture triplet> /和常规体系结构下-notnostic包括/usr/[local /] include /的文件.我不会触及任何包含目录名称包含编译器主版本号的包含目录而没有很好的理由.

如果您打算修改glibc,并且在glibc开发人员文档中找不到所需内容,那么最好在glibc开发邮件列表中寻求建议; glibc非常复杂,因为它也可以在使用GCC之外的编译器的架构上使用,因此可能没有标准的架构三元组约定.

转载注明原文:为什么/usr/include中有多个头文件副本? - 代码日志