在 Mac 上为 Raspberry Pi 交叉编译 ARM ASM

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 / 赠书活动

目前, 星球 内第2个项目《仿小红书(微服务架构)》正在更新中。第1个项目:全栈前后端分离博客项目已经完结,演示地址:http://116.62.199.48/。采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 276 小节,累计 43w+ 字,讲解图:1917 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 1500+ 小伙伴加入,欢迎点击围观

最近发布了 我学习一些 ARM 程序集的经验,特别是尝试开发一个简单的排序算法。最初,我只是在我的 Mac 上使用 Atom 和 TextMate 编辑器,然后通过 ftp 将源代码传输到 Pi 上进行编译和运行,但我已经意识到这不会削减它的工作任何稍大的东西,所以我开始考虑让 Eclipse C++ 与交叉编译器工具链一起工作( 交叉编译 允许您在一种硬件架构类型上编译代码以在另一种硬件架构类型上运行)

几个月前 ,我实际上考虑过让它在 Windows 上运行,但我没有使用它或进一步追求它,所以我没有试图回溯我的步骤,而是从头开始(我也想让它在我的Mac 而不是 Windows)。

第一次尝试——在 Mac 上用 Eclipse C++ 编译

跳过几个步骤以了解更有趣的细节,假设已经下载并安装了适用于 C++ 的 Eclipse 以及适用于 ARM 的 GNU 工具链 ,这是我第一次构建项目时得到的:


 11:54:51 **** Build of configuration arm cross compile for project ASMCrossCompile ****
make all
Building file: ../test.S
Invoking: Cross GCC Assembler
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-as-o "test.o" "../test.S"
Finished building: ../test.S
Building target: ASMCrossCompile
Invoking: Cross GCC Linker
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-gcc-L/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib -o "ASMCrossCompile" ./test.o
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [ASMCrossCompile] Error 1

此 SO 帖子中描述了此错误“undefined reference to `_exit'”:
http://stackoverflow.com/questions/19419782/exit-c-text0x18-undefined-reference-to-exit-when-using-arm-none-eabi-gcc

这个问题显然与不同硬件架构上的交叉编译直接相关,解决方案是在加载器配置中添加 –specs=nosys.specs 选项。我在 Eclipse 的项目属性、C/C++ Build/Settings/Cross GCC Linker 中添加了这个,并添加到专家设置命令行模式中,这解决了这个问题。

将可执行文件传输到 Pi

在 Eclipse C++ 中,在运行配置设置中,您可以选择“新建连接”并配置与 Pi 的 ssh 连接。您还需要在 Pi 上设置一个完整路径,用于放置文件的位置。

此时我收到此错误:“上传时出错:文件系统输入或输出错误”。在 Pi 本身上执行文件时出现段错误。

四处搜索,一般建议似乎对可执行文件运行“文件”以检查它是否已编译并链接到正确的体系结构。

对于我新的交叉编译文件,我得到了这个:


 11:54:51 **** Build of configuration arm cross compile for project ASMCrossCompile ****
make all
Building file: ../test.S
Invoking: Cross GCC Assembler
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-as-o "test.o" "../test.S"
Finished building: ../test.S
Building target: ASMCrossCompile
Invoking: Cross GCC Linker
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-gcc-L/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib -o "ASMCrossCompile" ./test.o
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [ASMCrossCompile] Error 1

对于在 Pi 上正确运行的可执行文件,我得到了这个:


 11:54:51 **** Build of configuration arm cross compile for project ASMCrossCompile ****
make all
Building file: ../test.S
Invoking: Cross GCC Assembler
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-as-o "test.o" "../test.S"
Finished building: ../test.S
Building target: ASMCrossCompile
Invoking: Cross GCC Linker
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-gcc-L/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib -o "ASMCrossCompile" ./test.o
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [ASMCrossCompile] Error 1

好的,很明显我很接近但还没有。

从像 这篇 文章(这篇文章中的一些关键截图似乎丢失了)和 这篇文章来看 ,使用 github 可用的 RaspberryPi 项目的现成编译器交叉链似乎更容易和更直接(而不仅仅是一个更通用的 ARM 处理器工具链,但不是专门针对 Pi 和/或 Raspbian 的)。这是为 Linux 编译的,所以按照前两篇文章中的提示,这是我的下一次尝试。

第二次尝试:Eclipse C++ 加上 Raspberry Pi Tools 工具链……在 Ubuntu 上……在 VirtualBox 上……在 Mac 上

从上面的 github 项目 url 克隆 Tools.git 项目。

创建 C 项目

创建一个新的 C 项目,根据此屏幕截图选择默认值:

接下来进入此对话框 - 指向您克隆 Raspberry Pi 工具源的位置:

  • 设置编译器前缀为:arm-linux-gnueabihf-
  • 设置路径为/rpi_tools_download_dir/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin

要构建项目,请选择构建和全部构建。

完毕。

您应该会在 Project Explorer 树视图中看到一个 Binaries 条目。

要将代码部署到 Pi,我们可以设置运行配置,再次选择远程应用程序选项,使用 ssh 并将其指向您的 Pi。

现在我仍然遇到与以前相同的一般输入/输出错误,所以我通过 ssh 到 Pi 上查看出现在那里的新文件,并注意到它不可执行,所以在远程执行步骤中,您仍然需要对其执行 chmod +x。

尽管在其上创建一个文件显示的设置与我在 Pi 上编译和链接的可执行文件的设置相同,所以现在我们看起来不错:


 11:54:51 **** Build of configuration arm cross compile for project ASMCrossCompile ****
make all
Building file: ../test.S
Invoking: Cross GCC Assembler
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-as-o "test.o" "../test.S"
Finished building: ../test.S
Building target: ASMCrossCompile
Invoking: Cross GCC Linker
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-gcc-L/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib -o "ASMCrossCompile" ./test.o
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [ASMCrossCompile] Error 1

现在我们到了某个地方!

一个快速的 hello world 调用 syscall 4 来写入控制台:


 11:54:51 **** Build of configuration arm cross compile for project ASMCrossCompile ****
make all
Building file: ../test.S
Invoking: Cross GCC Assembler
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-as-o "test.o" "../test.S"
Finished building: ../test.S
Building target: ASMCrossCompile
Invoking: Cross GCC Linker
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-gcc-L/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib -o "ASMCrossCompile" ./test.o
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [ASMCrossCompile] Error 1

添加 chmod 似乎让我们在 Pi 端获得了一个可执行文件,但仍然出现 i/o 错误。

然而!通过 ssh 连接到 Pi 并执行新传输的文件:


 11:54:51 **** Build of configuration arm cross compile for project ASMCrossCompile ****
make all
Building file: ../test.S
Invoking: Cross GCC Assembler
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-as-o "test.o" "../test.S"
Finished building: ../test.S
Building target: ASMCrossCompile
Invoking: Cross GCC Linker
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/bin/arm-none-eabi-gcc-L/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib -o "ASMCrossCompile" ./test.o
/Applications/EclipseIDEs/gcc-arm-none-eabi-4_9-2015q2/arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'
collect2: error: ld returned 1 exit status
make: *** [ASMCrossCompile] Error 1

成功!我现在可以在我的 Mac 上使用 Eclipse 为 Pi 开发 asm! (虽然必须在 Mac 上的 VirtualBox 上的 Ubuntu 上运行它,但我可以接受