CJx*_*JxD 10 c c++ arm cross-compiling beagleboneblack
我陷入了不那么阳光明媚的交叉编译世界.
我正在尝试为我的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
Run Code Online (Sandbox Code Playgroud)
我通过SCP将文件传输到BeagleBone,并设置了可执行权限 chmod +x hello_world
在运行它(./hello_world)时,我唯一的回答是:
-bash: ./hello_world: No such file or directory
Run Code Online (Sandbox Code Playgroud)
正如我所期望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
Run Code Online (Sandbox Code Playgroud)
结果ldd是:
$ ldd hello_world
not a dynamic executable
Run Code Online (Sandbox Code Playgroud)
我尝试添加合适的平台和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
Run Code Online (Sandbox Code Playgroud)
这最初开始给我一个新的错误:Text file busy但是我已经无法再次收到该错误,因为它现在返回No such file or directory.我猜这个特定的尝试只是一个糟糕的转移或其他东西.
CJx*_*JxD 18
由于评论中没有人发布答案,我想我很高兴;)
No such file or directory来自内核尝试调用ELF可执行文件.interp字段指定的动态链接器,但不存在此类文件.
.interp可以使用以下命令找到该字段:
objdump -j .interp -s ./hello_world
Run Code Online (Sandbox Code Playgroud)
在此示例的情况下,可执行文件的.interp字段是/lib/ld-linux.so.3,但BeagleBone Black上的动态链接器的名称是/lib/ld-linux-armhf.so.3.
之所以发生这种情况,是因为程序编译的工具链与平台所需的工具链略有不同.它应该是arm-linux-gnueabihf-*而不是arm-linux-gnueabi-*.
两者之间的区别在于Cortex-A8使用特定的浮点寄存器和armhfEABI 的hard-float版本(),但原始的EABI(armel)使用整数寄存器来传递浮点数.因此,armel程序将运行armhf(假设动态链接器设置为正确的路径!),但反之亦然.
简单地添加符号链接ln -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3就足以解决此问题,但正确的解决方法是在首先编译程序时使用正确的工具链.