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

时间:2015-08-10 21:01:23

标签: c++ c arm cross-compiling beagleboneblack

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

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

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

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

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的结果是:

$ 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。我猜测特定的尝试只是一次糟糕的转移或其他事情。

3 个答案:

答案 0 :(得分:16)

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

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

可以使用以下命令找到.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使用特定浮点寄存器和EABI的硬浮点版本(armhf),但原始EABI(armel)使用整数寄存器用于传递浮点数。因此,armel程序将在armhf上运行(前提是动态链接器设置为正确的路径!),但反之亦然。

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

答案 1 :(得分:3)

我遇到了同样的问题。我使用apt-get从Ubuntu存储库下载并安装了gcc-arm-linuc-gnueabihf包到我的Ubuntu PC。然后我编译了一个helloworld测试程序并使用sftp将其下载到我的BeagleBone。

尝试在BBB上运行程序时出现错误:"没有这样的文件或目录"

使用objdump我发现ELF可执行文件中的.interp字段是/lib/ld_linux_armhf.so.3。我的BBB有动态链接器/lib/ld-linux.so.3

我在BBB上创建了一个符号链接:

ln -s /lib/ld-linux.so.3 /lib-linux-armhf.so.3

现在交叉编译的应用程序适用于BBB。 BBB正在运行原始的Angstrom发行版。

这不是理想的修复方法。现在我需要在Ubuntu中配置工具链以向应用程序添加正确的动态链接器名称,或者更新BBB以在工具链中指定动态链接器。

我认为错误消息是由于未找到动态链接器文件,而不是应用程序不存在。

答案 2 :(得分:0)

如何识别问题?

AVChapter **

包含类似:

的内容
file cross_compiled_executable

问题是目标上不存在该文件。

如何解决问题?

使用适当的编译器:

  • 创建磁盘映像的人必须为您提供交叉编译器或告诉您如何构建它,例如与crosstool-ng。 BeagleBone问:Toolchain to crosscompile Applications for BBB
  • 编译您自己的图像和交叉编译器,例如与Buildroot。这是a generic QEMU example。 Buildroot has BeagleBone support
  • 在目标上使用本机编译器。但通常目标比主机慢得多,且空间有限,所以你可能不想这样做。

    您也可以使用QEMU等功能仿真器进行构建,然后只在较慢的平台上运行程序,例如:宝石5或慢板。

仅仅攻击interpreter /lib/ld-uClibc.so.0 可能还不够,特别是你必须确保程序与目标libc或程序和内核接口(系统调用,interpreter等)之间的二进制兼容性,如果您尝试使用/proc(目标内核可能太旧而且不包含所需的接口)。唯一可靠的解决方案是使用正确的工具链。