我正在try 在CentOS 7 64位机器上交叉编译Hello world C程序,并将其与Raspberry PI 2B 32位目标机器交叉编译.

我下载了巴斯特交叉编译器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.

H文件位于交叉编译路径中,但我无法确定如何在不 destruct 与libc世界的链接的情况下将该路径添加到gcc命令中.我试过了-我,-系统,...但当我这样做时,我得到了原始的GLIBC错误

我不是在发明轮子,所以我肯定遗漏了什么.我刚刚开始做这个交叉编译的工作,需要帮助来增加我的知识.我看了五月的网站,但还没有完全找到答案.

谢谢你的帮助.

推荐答案

不是一个完全的解决方案,但有一些解释.

不幸的是,我们没有我们需要的所有文件.


我从您提供的链接下载并解压了tar文件.

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

在该目录下,我们有子目录.值得注意的[一些]是:

arm-linux-gnueabihf
bin
lib

要使用给定的交叉开发实用程序(例如,ld,但类似于gccar等),它们位于:

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

这些文件是identical.同样,他们也是x86_64岁. cross为ARM构建的二进制文件.

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

  1. 设置PATH变量:export PATH=/home/redacted/cross-pi-gcc-8.3.0-1/arm-linux-gnueabihf.然后,如果我们键入命令ld <something>,我们使用的是本机x86_64版本,而不是x86_64到ARM交叉版本.
  2. 我们可以用arm-linux-gnueabihf-ld代替ld.在这里,在我们的Makefile中,我们会做一些类似的事情:LD = arm-linux-gnueabihf-ld在顶部.这工作if我们安装交叉编译器,使得包bin被解压缩到标准bin目录(例如/usr/local/bin
  3. 否则,我们需要执行:export PATH=/home/redacted/cross-pi-gcc-8.3.0-1/bin并设置LD,如上所述.

不管怎样,我们现在可以为ARM交叉构建...有点...

lib目录下,我们有libcc1*个文件.这些是为x86_64构建的.


问题是,我们not确实有一个aarch64/arm版本的库.所以,如果我们这么做了:

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

no-aarch64(ARM)版本的(例如)libc.

换句话说,您下载的包只有交叉编译器,但没有target个系统库.

换句话说,我们需要在gcc命令的基础上加上--sysroot=/path_to_sysroot.

但是,我们not有这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)从其根/目录开始的确切文件层次 struct .


同样,您拥有的是交叉编译器just.但是,no个目标库或二进制文件(例如,lsvim等)

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

C++相关问答推荐

librsvg rsvg_handle_get_dimensions获取像素大小与浏览器中的渲染大小没有不同

为什么这个select()会阻止?

理解没有返回语句的递归C函数的行为

C:gcc返回多个错误定义,但msvc—不""'

如何将字符串argv[]赋给C中的整型数组?

C:fopen是如何实现二进制模式和文本模式的?

为什么C语言允许你使用var =(struct NAME){

在一个小型玩具项目中实现终端历史记录功能

在编译时参数化类型定义

如何将长字符串转换为较小的缩写,该缩写由第一个字符、最后一个字符和中间的字符数组成?

在移动数组元素时获得意外输出

如何按顺序将所有CSV文件数据读入 struct 数组?

#定义SSL_CONNECTION_NO_CONST

';\n&39;和';\r&39;中的';\n&39;之间有什么关系?

赋值两侧的后置增量,字符指针

无算术运算符和循环的二进制乘法

为什么GCC 13没有显示正确的二进制表示法?

为什么GCC不能在 struct 初始值设定项中以sizeof作为条件的三进制中处理复合文字的编译时求值?

将size_t分配给off_t会产生符号转换错误

Linux memcpy 限制关键字语法