从 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

提问人:Steve Olekszyk 提问时间:11/11/2023 最后编辑:Craig EsteySteve Olekszyk 更新时间:11/11/2023 访问量:36

问:

我正在尝试将 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--sysrootstdio.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

我不是在这里发明轮子,所以我一定错过了什么。我刚刚开始做这个交叉编译的事情,需要帮助来建立我的知识。我阅读了可能的网站,但还没有完全找到答案。

感谢您的帮助。

C Raspberry-Pi CentOS 交叉编译

评论

0赞 Craig Estey 11/11/2023
是的,您需要 .但是,您可能需要一个用于文件的 arm 版本。在我的 arm (ubuntu) 交叉开发系统上,我有一个目录,其中包含 、 和 的子目录 所以,对我来说 [已经有一段时间了],我想我需要 .你的路径有点复杂,但我会从 .你总是可以做:或类似的事情。在它找到的目录中,查找--sysroot-I.h/usr/aarch64-linux-gnubinincludelib-I/usr/aarch64-linux-gnu/include-I/home/<redacted>/repos/pi-2-compiler/cross-pi-gcc-8.3.0-1/includefind /home/<redacted>/repos/pi-2-compiler/cross-pi-gcc-8.3.0-1 -type f -name includestdio.h
0赞 Craig Estey 11/11/2023
如果您对系统具有 root/admin 访问权限,则可以安装编译器等。它们可能会出现在 .然后,您的构建 makefile/scripts 可以简化并摆脱依赖关系。结果将可由其他[未编辑]用户重复使用。对命令的更正:(哎呀)。/usr/local/something/home/redactedfind-type d
0赞 Steve Olekszyk 11/11/2023
感谢您的快速回复。我躲在一堵墙后面,不允许我安装任何东西,尽管我确实拥有 CentOS 盒子的管理员权限。当我使用 --sysroot 访问 libc.so.6 文件时,如果我使用 -I 开关指向具有 stdio.h 文件的 include 目录,它将被覆盖。我不知道如何操作“ld”程序查找 libc.so.6 的位置,因此我可以将 -I 用于 include 标头。
0赞 Craig Estey 11/11/2023
我的记忆仍然朦胧;-)但是,我刚刚开始在我的跨开发系统上查看脚本/配置。无论您指向什么,它都应该是最终的层次结构(即从目标系统上)。所以,在 my 的 [one of] 下,我有 subdirs: 并且,(例如)是 那么,你的顶级目录是什么样子的?--sysroot/--sysroot=etc lib sbin usr/bin usr/include usr/lib usr/libexec usr/sbin usr/sharestdio.h/path_to_my_sysroot/usr/include/stdio.hsysroot
0赞 Steve Olekszyk 11/11/2023
以下是位的位置;$ 找到 .-name “libc.so.6” ./cross-pi-gcc-8.3.0-1/arm-linux-gnueabihf/libc/lib/libc.so.6 $ find .-name “stdio.h” ./cross-pi-gcc-8.3.0-1/lib/gcc/arm-linux-gnueabihf/8.3.0/include/ssp/stdio.h ./cross-pi-gcc-8.3.0-1/arm-linux-gnueabihf/include/c++/8.3.0/tr1/stdio.h ./cross-pi-gcc-8.3.0-1/arm-linux-gnueabihf/libc/usr/include/stdio.h ./cross-pi-gcc-8.3.0-1/arm-linux-gnueabihf/libc/usr/include/bits/stdio.h 为了让 libc 工作,我必须使用一个 sysroot 去 ...\libc\lib 这使我超越了 stdio.h 文件所在的 ...\libc\usr\include

答:

0赞 Craig Estey 11/11/2023 #1

不是一个完整的解决方案,而是一些解释......

The TL;DR:很遗憾,我们没有我们需要的所有文件。


我从您提供的链接下载并提取了 tar 文件。

它创建一个子目录:cross-pi-gcc-8.3.0-1

在该目录下,我们有子目录。值得注意的是:

arm-linux-gnueabihf
bin
lib

使用给定的交叉开发实用程序(例如 但与 、 等类似)他们位于:ldgccar

./bin/arm-linux-gnueabihf-ld
./arm-linux-gnueabihf/bin/ld

这些文件是相同的。此外,[再次]它们是为 arm 交叉构建的二进制文件。x86_64

因此,为了能够使用交叉构建,有两种方法:

  1. 设置变量:。然后,如果我们键入命令,我们使用的不是本机x86_64版本,而是x86_64到布防交叉版本。PATHexport PATH=/home/redacted/cross-pi-gcc-8.3.0-1/arm-linux-gnueabihfld <something>
  2. 我们可以用 代替 ,而不是 。在这里,在我们的 中,我们会做一些类似的事情:在顶部。如果我们安装交叉编译器,以便将包提取到标准目录(例如ldarm-linux-gnueabihf-ldMakefileLD = arm-linux-gnueabihf-ldbinbin/usr/local/bin
  3. 否则,我们需要执行: 并按上述方式进行设置。export PATH=/home/redacted/cross-pi-gcc-8.3.0-1/binLD

无论哪种方式,我们现在都可以交叉构建手臂......有点......

在目录下,我们有文件。这些都是为x86_64而构建的。liblibcc1*


问题是我们没有库的版本。因此,如果我们这样做:aarch64/arm

arm-linux-gnueabihf-gcc -o hello hello.c

没有(例如)的(arm)版本。aarch64libc

换句话说,您下载的包只有交叉编译器,但没有目标系统库。

换句话说,我们需要添加到命令中。--sysroot=/path_to_sysrootgcc

但是,我们没有文件sysroot

使用 ,我们希望找到:--sysroot

/path_to_sysroot/bin/ls
/path_to_sysroot/lib/libc*

并且,将是二进制文件,并且将编译库代码lsaarch64/armlibcaarch64/arm


因此,为了解决这个问题,我们必须找到并下载合适的包,这些包确实具有预构建的二进制文件,并指向这些二进制文件的顶部目录。aarch64/arm--sysroot=

回顾一下......该目录应具有目标系统(例如 RPi)从其根目录开始的确切文件层次结构。sysroot/


同样,您拥有的只是交叉编译器。但是,没有目标库或二进制文件(例如 、 等)lsvim

您可能需要考虑功能更全面的一站式方法,例如:linaro

评论

0赞 Steve Olekszyk 11/11/2023
感谢您的辛勤工作。请参阅我关于进入 10 的笔记......来自网站的版本,有了那个,不需要--sysroot或任何东西。我会接受这个答案,这样你就会得到信任。再次感谢。