尝试在目标设备上运行交叉编译的可执行文件失败,并显示:没有此类文件或目录 [英] Trying to run a cross-compiled executable on target device fails with: No such file or directory
问题描述
我陷入了一个不太晴朗的交叉编译世界.
I've got caught in the not-so-sunny world of cross-compilation.
我正在尝试为我的BeagleBone Black(运行TI Cortex-A8处理器)编译一个简单的hello world应用程序.
I'm trying to compile a simple hello world application for my BeagleBone Black (which runs a TI Cortex-A8 processor).
首先,我使用gcc
然后,我将编译设置更改为以下内容:
Then I changed my compilation settings to the following:
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
I transferred the file via SCP to the BeagleBone, and set executable permissions with chmod +x hello_world
运行它(./hello_world
)时,我唯一的回答是:
Upon running it (./hello_world
), my only response is:
-bash: ./hello_world: No such file or directory
正如我期望的那样,file
的输出与/sbin/init
的输出匹配:
The output of file
matches that of /sbin/init
as I would expect:
$ 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类型,将编译更改为:
I tried adding a suitable platform and CPU type, changing my compilation to:
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
.我猜测特定尝试只是一次错误的转移或其他.
This initially started giving me a new error: Text file busy
, but I have since been unable to get that error back again as it now returns No such file or directory
. I'm guessing that particular attempt was just a bad transfer or something.
推荐答案
由于评论中没有人发布答案,我想我很高兴;)
Since nobody from the comments posted the answer, I guess I get the pleasure ;)
No such file or directory
来自内核尝试调用由ELF可执行文件的.interp
字段指定的动态链接程序,但不存在此类文件的情况.
No such file or directory
comes from when the kernel tries to invoke the dynamic linker specified by the ELF executable's .interp
field, but no such file exists.
可以使用以下命令找到.interp
字段:
The .interp
field can be found with the following command:
objdump -j .interp -s ./hello_world
在此示例中,可执行文件的.interp
字段为/lib/ld-linux.so.3
,但BeagleBone Black上的动态链接程序的名称为/lib/ld-linux-armhf.so.3
.
In the case of this example, the executable's .interp
field was /lib/ld-linux.so.3
, but the name of the dynamic linker on the BeagleBone Black is /lib/ld-linux-armhf.so.3
.
之所以发生这种情况,是因为该程序的编译工具链与平台所需的工具链略有不同. 应为arm-linux-gnueabihf-*
而不是arm-linux-gnueabi-*
.
This happened because the program was compiled with a slightly different toolchain to the one required for the platform. It should be arm-linux-gnueabihf-*
rather than arm-linux-gnueabi-*
.
两者之间的区别在于,Cortex-A8使用具有EABI硬浮点版本(armhf
)的特定浮点寄存器,但是原始的EABI(armel
)使用整数寄存器来进行浮点传递点号.结果,armel
程序将在armhf
上运行(前提是将动态链接器设置为正确的路径!),反之亦然.
The difference between the two is that the Cortex-A8 uses specific floating point registers with the hard-float version (armhf
) of the EABI, but the original EABI (armel
) uses integer registers for passing around floating point numbers. As a result, armel
programs will run on armhf
(provided the dynamic linker is set to the correct path!), but not vice versa.
只需添加符号链接ln -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3
即可解决此问题,,但正确的解决方法是首先编译程序时使用正确的工具链.
Simply adding a symbolic link ln -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3
is enough to resolve this issue, but the correct fix is to use the right toolchain when compiling the program in the first place.
这篇关于尝试在目标设备上运行交叉编译的可执行文件失败,并显示:没有此类文件或目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!