我正在尝试将 CentOS 7 64 位机器上的 hello world C 程序交叉编译到 Raspberry Pi 2B 32 位目标机器。
我下载了buster交叉编译器
cross-gcc-8.3.0-pi_2-3.tar.gz
我的 hello world C 文件是我们都使用的标准 hello world 程序。
当我首先尝试编译时
arm-linux-gnueabihf-gcc -o helloworld.exe helloworld.c
给我:
/home/<redacted>/repos/pi-2-compiler/cross-pi-gcc-8.3.0-1/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by /home/<redacted>/repos/pi-2-compiler/cross-pi-gcc-8.3.0-1/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld)
collect2: error: ld returned 1 exit status
我的 CentOS 机器上的 libc 版本与目标不同。
libc.so.6
文件位于交叉编译路径中,因此当我使用 --sysroot
选项时,我克服了 libc 问题,但无法找到 stdio.h
文件。
arm-linux-gnueabihf-gcc -o helloworld.exe helloworld.c --sysroot=/home/<redacted>/repos/pi-2-compiler/cross-pi-gcc-8.3.0-1/arm-linux-gnueabihf/libc/lib
helloworld.c:1:10: fatal error: stdio.h: No such file or directory
#include <stdio.h>
^~~~~~~~~
compilation terminated.
stdio.h 文件位于交叉编译路径中,但我无法确定将该路径添加到
gcc
命令而不破坏我与 libc 世界的链接的方法。我尝试了 -I、-isystem,...但是当我这样做时,我得到了原始的 GLIBC 错误
我不是在这里发明轮子,所以一定是我遗漏了一些东西。我刚刚开始交叉编译,需要帮助来积累我的知识。我读了很多网站,但还没有找到答案。
感谢您的帮助。
不是完整的解决方案,而是一些解释......
TL;DR:不幸的是,我们没有所需的所有文件。
我从您提供的链接下载并提取了 tar 文件。
它创建一个子目录:
cross-pi-gcc-8.3.0-1
在该目录下,我们有子目录。值得注意的[一些]是:
arm-linux-gnueabihf
bin
lib
要使用给定的交叉开发实用程序(例如
ld
,但与 gcc
、ar
等类似),它们位于:
./bin/arm-linux-gnueabihf-ld
./arm-linux-gnueabihf/bin/ld
这些文件是相同的。另外,[再次]他们是
x86_64
为arm构建cross的二进制文件。
因此,为了能够使用交叉构建,有两种方法:
PATH
变量:export PATH=/home/redacted/cross-pi-gcc-8.3.0-1/arm-linux-gnueabihf
。然后,如果我们输入命令ld <something>
,我们不是使用本机x86_64版本,而是x86_64 to arm cross版本。ld
,而不是使用 arm-linux-gnueabihf-ld
。在这里,在我们的Makefile
中,我们会做类似的事情:LD = arm-linux-gnueabihf-ld
在顶部无论哪种方式,我们现在都可以为arm进行交叉构建......有点......
在
lib
目录下,我们有libcc1*
文件。这些是为 x86_64 构建的。
问题是我们没有有一个
aarch64/arm
版本的库。所以,如果我们这样做:
arm-linux-gnueabihf-gcc -o hello hello.c
有没有
aarch64
(手臂)版本(例如)libc
。
换句话说,您下载的软件包[仅]有交叉编译器,但没有target系统库。
换句话说,我们需要将
--sysroot=/path_to_sysroot
添加到 gcc
命令中。
但是,我们没有有
sysroot
文件。
通过
--sysroot
,我们期望找到:
/path_to_sysroot/bin/ls
/path_to_sysroot/lib/libc*
并且,
ls
将是 aarch64/arm
二进制文件,而 libc
将为 aarch64/arm
编译库代码
因此,为了解决这个问题,我们必须找到并下载合适的软件包,do已经预先构建了
aarch64/arm
二进制文件,并且让--sysroot=
指向这些文件的顶级目录。
简单回顾一下...
sysroot
目录应该具有与 target 系统(例如 RPi)从其根 /
目录开始的确切文件层次结构。
再次强调,您所拥有的只是交叉编译器。但是,没有目标库或二进制文件(例如ls
、
vim
等)您可能需要考虑功能更齐全的一站式方法,例如
linaro
: