接上篇centos6.10 编译gcc11.5 x64到aarch64交叉工具链 -CSDN博客
PATH_MAX找不到,不仅在编译gcc的过程中遇到,而且临时改gcc源码添加#define PATH_MAX 4096 宏定义后勉强通过gcc全量编译。这个新的gcc编译使用了PATH_MAX宏的代码还是会找不到。这个问题看来不弄清楚不行。
PATH_MAX在哪定义的
进入到交叉gcc的include目录查找PATH_MAX,发现是在linux/limits.h这个头文件定义的,这是内核头文件,同时我在用我的交叉gcc编译protobuf时,查看报错PATH_MAX找不到的文件,protobuf提示包含#include <limits.h>是为了提供PATH_MAX。那么说明glibc最终会引用linux/limits.h。顺藤摸瓜验证了这一猜想。
分析
于是我写了个测试代码,用我的gcc编译,报错。然后尝试各种宏定义,也不行。
#include <stdio.h>
//#define _GNU_SOURCE 1
//##define _GCC_LIMITS_H_
//#define _POSIX_C_SOURCE 200809L
//#define _LIMITS_H___#include <limits.h>int main()
{char buf[PATH_MAX]={0};printf("hello");
}
尝试预处理阶段宏展开aarch64-linux-gnu-gcc -E hello.c | less,发现他用是下面这个limites.h
另外构建的一个本地gcc11.5.0是正常的,宏展开是这样的,看样子是这个incude-fixed搞得鬼
研究了半天,查找fixincludes
的文档这么说
当 fixincludes
由 GCC 的 Makefile 运行时,这个 README
文件会被复制到仅包含 GCC 头文件的目录中。
此目录中的许多文件是通过 fixincludes
过程从标准系统头文件自动编辑而来的。它们是特定于系统的,无法在其他类型的系统上使用。它们也不是 GCC 的一部分。我们之所以需要这样做,是因为 GCC 需要符合 ANSI C 标准的头文件,而许多供应商提供的头文件与 ANSI 不兼容。
由于这是一个自动化过程,有时一些严格来说不需要“修复”的头文件也会被“修复”。只要这个过程没有破坏任何东西,这只是一个不幸的附带不便。如果“不太麻烦”,我们希望能够纠正这种情况。
总之这个东西就是为了解决gcc与使用glibc头不兼容,自动自行修正include头文件的,那么是不是我编译的gcc配置错误,导致修正不对。
尝试对比能用的和不能用的incude-fixed/limits.h,差别不大,前后包了一层宏定义,替换一下能用的这个头,他妈的果然行了。但是还没找到是什么导致这个差异
尝试在源码目录查找_GCC_LIMITS_H_ 找到了limitx.h 和limity.h 这两个文件的内容就是前后包的代码段
继续找limitx.h文件名,能用和不能用的limits.h 区别在一个条件判断,关键在于LIMITS_H_TEST这个变量
这个LIMITS_H_TEST的值取决于SYSTEM_HEAD_DIR
到构建目录找最后的Makefile,这是变量展开后的内容,$(gcc_tooldir)/sys-include。到安装目录下去找,确实没有这个目录,gcc_tooldir是上层传入的变量,
libsubdir = $(libdir)/gcc/$(target_noncanonical)/$(version)
gcc_tooldir='$(libsubdir)/$(libsubdir_to_prefix)$(target_noncanonical)'
libsubdir_to_prefix这个东西的意思是把libsubdir转换成prefix需要的../..这种。那么其实libsubdir是啥不重要,gcc_tooldir 就是$(prefix)/$(target_noncanonical)
在我这里应该是安装目录的aarch64-linux-gnu/sys-include目录 没有这个目录。
解决
配置编译gcc时产生这个目录,用--with-headers,会把你的glibc头copy过去产生,或者你自己把glibc头安装到这个目录。原来官方文档说了,fixinclude会在这些文件上运行,产生兼容gcc的glibc头,答案早就在这里啊,只是不经历这么一遭根本理解不了