提问人:Steve Olekszyk 提问时间:11/11/2023 最后编辑:Craig EsteySteve Olekszyk 更新时间:11/11/2023 访问量:36
从 CentOS 7 到 Raspberry Pi 2B 交叉编译 - 无法让 LIBC 和系统包含标头协同工作
Cross compile from CentOS 7 to Raspberry Pi 2B - can't get LIBC and system include headers to work together
问:
我正在尝试将 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 问题,但无法找到该文件。libc.so.6
--sysroot
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 文件位于交叉编译路径中,但我无法确定在不破坏我与 libc 世界的链接的情况下将该路径添加到命令的方法。我试过-I,-isystem,....但是当我这样做时,我得到了原始的 GLIBC 错误gcc
我不是在这里发明轮子,所以我一定错过了什么。我刚刚开始做这个交叉编译的事情,需要帮助来建立我的知识。我阅读了可能的网站,但还没有完全找到答案。
感谢您的帮助。
答:
不是一个完整的解决方案,而是一些解释......
The 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
这些文件是相同的。此外,[再次]它们是为 arm 交叉构建的二进制文件。x86_64
因此,为了能够使用交叉构建,有两种方法:
- 设置变量:。然后,如果我们键入命令,我们使用的不是本机x86_64版本,而是x86_64到布防交叉版本。
PATH
export PATH=/home/redacted/cross-pi-gcc-8.3.0-1/arm-linux-gnueabihf
ld <something>
- 我们可以用 代替 ,而不是 。在这里,在我们的 中,我们会做一些类似的事情:在顶部。如果我们安装交叉编译器,以便将包提取到标准目录(例如
ld
arm-linux-gnueabihf-ld
Makefile
LD = arm-linux-gnueabihf-ld
bin
bin
/usr/local/bin
- 否则,我们需要执行: 并按上述方式进行设置。
export PATH=/home/redacted/cross-pi-gcc-8.3.0-1/bin
LD
无论哪种方式,我们现在都可以交叉构建手臂......有点......
在目录下,我们有文件。这些都是为x86_64而构建的。lib
libcc1*
问题是我们没有库的版本。因此,如果我们这样做:aarch64/arm
arm-linux-gnueabihf-gcc -o hello hello.c
没有(例如)的(arm)版本。aarch64
libc
换句话说,您下载的包只有交叉编译器,但没有目标系统库。
换句话说,我们需要添加到命令中。--sysroot=/path_to_sysroot
gcc
但是,我们没有文件。sysroot
使用 ,我们希望找到:--sysroot
/path_to_sysroot/bin/ls
/path_to_sysroot/lib/libc*
并且,将是二进制文件,并且将编译库代码ls
aarch64/arm
libc
aarch64/arm
因此,为了解决这个问题,我们必须找到并下载合适的包,这些包确实具有预构建的二进制文件,并指向这些二进制文件的顶部目录。aarch64/arm
--sysroot=
回顾一下......该目录应具有目标系统(例如 RPi)从其根目录开始的确切文件层次结构。sysroot
/
同样,您拥有的只是交叉编译器。但是,没有目标库或二进制文件(例如 、 等)ls
vim
您可能需要考虑功能更全面的一站式方法,例如:linaro
评论
--sysroot
-I
.h
/usr/aarch64-linux-gnu
bin
include
lib
-I/usr/aarch64-linux-gnu/include
-I/home/<redacted>/repos/pi-2-compiler/cross-pi-gcc-8.3.0-1/include
find /home/<redacted>/repos/pi-2-compiler/cross-pi-gcc-8.3.0-1 -type f -name include
stdio.h
/usr/local/something
/home/redacted
find
-type d
--sysroot
/
--sysroot=
etc lib sbin usr/bin usr/include usr/lib usr/libexec usr/sbin usr/share
stdio.h
/path_to_my_sysroot/usr/include/stdio.h
sysroot