gcc查找头文件的规则

来源:互联网 发布:手机网络怎么重置系统 编辑:程序博客网 时间:2024/05/21 07:54

见:http://gcc.gnu.org/onlinedocs/cpp/Search-Path.html


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

libdir是{prefix}/lib,target是arch=vendor-os,version就是GCC的版本,在Fedora上做实验:


ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.4.6/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include
 /usr/include
End of search list.


这里prefix=/usr。第一个include-fixed文档没有提到。第二是/usr/target/include,第三个是/usr/local/include,第四个是libdir/gcc/target/version/include/,第五个是/usr/include.


看GCC编译帮助文档,用--with-local-prefix能覆盖/usr/local/include。这个目录其实没什么重要的头文件。我更关心的是交叉编译时,如果不指定--with-local-prefix,交叉编译器会搜索主机上的/usr/local/include吗?实验结果是不会。这应该是理所当然的。


--with-native-system-header-dir能覆盖/usr/include,文档上说当它和--with-sysroot一起用时,用在with-sysroot的参数目录下搜索前者指定的目录。根据我对文档的理解,单独使用--with-native-system-header-dir,把参数设为绝对路径(与with-sysroot一起用时一定要用相对路径?),即可覆盖/usr/include。我仍然只关心交叉编译器的行为。交叉编译器搜索主机的/usr/include显然不合理。实验证明,即使什么参数也不加,编出来的交叉编译器不会去找/usr/include。郁闷的是,交叉编译器居然不会去找{prefix}/include。/usr/include看起来就像当prefix=/usr的情况。不知道编译本机编译器而prefix不为/usr时,编出来的编译器是否会还会找/usr/include,即/usr/include是否是硬编码的路径。


文档中说的四个路径,/usr/local/include与/usr/include不会被查找。/usr/target/include会被查找,但这个目录不存在。

prefix/lib/gcc/target/version/{include,include-fixed,sys-include}会被查找。其中sys-include不存在,include-fixed里包含limit相关的两个头文件,include则包含由编译器提供的底层头文件,如stdarg.h, cpuid.h(编译某个C库时曾遇到因找不到编译器提供的cpuid.c而报错)。所以,文件档中所提的,只有/usr/target/include与prefix/lib/gcc/target/version/include被查找了,而且仅后者起(有限的)实际作用。


这里最大的缺失就是/usr/include的替代物。原生编译器可以在这里找到原生系统glibc的头文件,但编译glibc并与gcc共享prefix,glibc的头文件其实上安装在prefix/include。看来/usr/include是个硬编码的值而不能作prefix/include解。所以,编译交叉编译器时要用--with-native-system-header-dir来指定/usr/include的替代值,也就是为目标机器准备的glibc的头文件所在地,如果用相同的prefix,那就应该是prefix/include。


结果令人失望,单独指定--with-native-system-header-dir不起任何作用。指定--with-sysroot=${prefix}的话,会抱怨应该包含系统头文件的目录不存在--它恐怕想找${prefix}/usr/include。我建了这个目录果然就编译通过了。其实文档里说过了,指定--with-sysroot相应于把--sysroot作为一个输入gcc的默认选项,注意是交叉编译器的选项,man gcc可以看到详细解释。这对LFS来说是个好选项。所以,查找规则跟原生gcc无异,只是根目录不作原解。


原来还以为要用--with-sysroot与--with-native-system-header-dir来指定头文件目录。现在看起来,应该把glibc的prefix设为gcc_prefix/usr,再指定--with-sysroot,就不需要做其它事了。但是交叉编译的ld要加上--with-sysroot,这个选项居然在configure的帮助里没有出现(只有一个指定build sysroot的选项),但是man文档里有说明。


最后,编译glibc时居然碰到__waitpid_nocancel未定义的引用。起初还以为nptl不支持ppc64,因为看了一下相应目录,没有找到nocancel的文件。最后发现不知为何,ppc64下的这个文件被删了!!原始解压出来是有的。可能之前用同一个源码树做了不同的配置,虽然在源码树外编译,还是会改变源码树的文件。

原创粉丝点击