尝试在目标设备上运行交叉编译的可执行文件失败,并显示:没有这样的文件或目录

2024-03-01

我陷入了交叉编译的不那么阳光的世界。

我正在尝试为我的 BeagleBone Black(运行 TI Cortex-A8 处理器)编译一个简单的 hello world 应用程序。

首先,我在 x86 上编译并成功运行了 hello world 应用程序gcc

然后我将编译设置更改为以下内容:

arm-linux-gnueabi-gcc -c -O0 -g3 -Wall main.c -o bin/obj/main.o
arm-linux-gnueabi-gcc bin/obj/main.o -o bin/hello_world

我通过 SCP 将文件传输到 BeagleBone,并设置可执行权限chmod +x hello_world

运行后(./hello_world),我唯一的回应是:

-bash: ./hello_world: No such file or directory

的输出file匹配的是/sbin/init正如我所期望的:

$ file hello_world
hello_world: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0x24b659b7a41fe043a6f4649d4ebfb5e692ebf0c7, not stripped
$ file /sbin/init
/sbin/init: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0xd21f6957ec031a27d567b3d5e6aa14b9e0c30c37, stripped

的结果ldd is:

$ ldd hello_world
    not a dynamic executable

我尝试添加合适的平台和 CPU 类型,将编译更改为:

arm-linux-gnueabi-gcc -c -O0 -g3 -Wall -march=armv7-a -mtune=cortex-a8  main.c -o bin/obj/main.o
arm-linux-gnueabi-gcc bin/obj/main.o -o bin/hello_world

这最初给我带来了一个新错误:Text file busy,但此后我无法再次恢复该错误,因为它现在返回了No such file or directory。我猜那个特定的尝试只是一次糟糕的转会或其他什么。


由于评论中没有人发布答案,我想我很高兴;)

No such file or directory来自当内核尝试调用由 ELF 可执行文件指定的动态链接器时.interp字段,但不存在这样的文件。

The .interp可以使用以下命令找到字段:

objdump -j .interp -s ./hello_world

在此示例中,可执行文件的.interp场是/lib/ld-linux.so.3,但是 BeagleBone Black 上的动态链接器的名称是/lib/ld-linux-armhf.so.3.

发生这种情况是因为该程序是使用与平台所需的工具链略有不同的工具链进行编译的。它应该是arm-linux-gnueabihf-*而不是arm-linux-gnueabi-*.

两者之间的区别在于 Cortex-A8 使用特定的浮点寄存器和硬浮点版本(armhf) 的 EABI,但原始 EABI (armel)使用整数寄存器来传递浮点数。因此,armel程序将运行在armhf(前提是动态链接器设置为正确的路径!),但反之则不然。

只需添加一个符号链接ln -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3足以解决这个问题,但正确的解决方法是首先在编译程序时使用正确的工具链。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试在目标设备上运行交叉编译的可执行文件失败,并显示:没有这样的文件或目录 的相关文章

随机推荐