我正在使用 crosstool-ng 构建跨原生工具链:build=x86_64, host=target=arm。
我需要这个新工具链包含一个与
/
系统中已安装的工具链不同的 glibc。
在主机设备上,新工具链将位于用户目录中$HOST_SYSROOT
,我无法触及系统的其余部分。
我的 ct-ng 配置生成了一个几乎完全可用的工具链,但有一个例外:
[toolchain dir]/[host arch]/sysroot/usr/
中的对象引用 /
而不是 /$HOST_SYSROOT/[...]
。
例如,sysroot/usr/bin
中的二进制文件(例如,locale
)都使用/lib/ld-linux-armhf.so.3
处的链接器而不是$HOST_SYSROOT/lib/ld-linux-armhf.so.3
。
我该如何解决这个问题?
使用
patchelf
将正确的 rpath 和解释器添加到二进制文件中并不能解决问题,因为二进制文件的其他部分引用了更多根目录。就好像有人打算将 sysroot/
目录与 /
合并,但我在我的系统上无法做到这一点。
我相信我的 ct-ng 配置的某些部分一定缺少 autoconf 标志
--prefix=$HOST_SYSROOT
标志,或 CFLAG --sysroot=$HOST_SYSROOT
。
我以为是 glibc
但添加这个前缀会导致构建失败。
根据我使用交叉编译工具链的经验,这是一个常见问题,源于 glibc 在编译过程中如何处理路径配置。
根本原因实际上并不是缺少 --prefix 或 --sysroot 标志 - 而是 glibc 将硬编码路径编译到二进制文件中。您需要修改两个特定的 crosstool-ng 配置:
最后一个设置至关重要 - 它告诉 crosstool-ng 在构建 glibc 组件时使用相对路径而不是绝对路径。如果没有这个,glibc 将始终尝试使用根目录的绝对路径。 您可能还需要添加:
CT_SYSROOT_TYPES_SUFFIX=y
这种组合迫使 glibc 正确地重新定位其相对于 sysroot 的内部路径,而不是使用 / 中的绝对路径。 不要尝试直接修补 glibc 的前缀/sysroot - 正如您所发现的那样,这会带来疯狂。二进制引用在整个代码库中嵌入得太深。
如果进行这些更改后仍然遇到问题,请检查您的 CT_PREFIX_DIR 是否与您的预期安装目录匹配,并从头开始重建工具链(部分重建可能会留下过时的配置)。
这将为您提供一个可正确重定位的工具链,该工具链完全在您的用户目录中工作,无需 root 访问权限或修改系统的 / 目录。