我尝试为基于 ARM 的嵌入式(自定义)Linux 系统编译一些 C 代码。我设置了一个带有名为arm-linux-gnueabi-gcc-4.4 的交叉编译器的Ubuntu VM,因为它看起来像我所需要的。现在,当我使用 gcc 编译代码时,它会生成如下二进制文件:
$ file test1
test1: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked
(uses shared libs), for GNU/Linux 2.6.31,
BuildID[sha1]=0x51b8d560584735be87adbfb60008d33b11fe5f07, not stripped
当我尝试在嵌入式 Linux 上运行这个二进制文件时,我得到了
$ ./test1
-sh: ./test1: not found
权限足够。我只能想象二进制格式有问题,所以我查看了一些工作二进制文件作为引用:
$ file referenceBinary
referenceBinary: ELF 32-bit LSB executable, ARM, version 1, dynamically linked
(uses shared libs), stripped
我发现存在一些差异,但我不具备知识来得出我到底需要修复什么以及如何修复它。有人可以解释哪个差异是关键的吗?
我查看的另一件事是依赖项:
$ ldd test1
libc.so.6 => not found (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)
(有趣的是,尽管它无法执行二进制文件,但它可以在目标系统上运行。)嵌入式系统只有一个 libc.so.0
可用。我想我需要告诉编译器我想要链接的 libc 版本,但据我了解,gcc 只是链接到它附带的版本,这是正确的吗?我能做什么呢?
编辑:这是我使用的 Makefile:
CC=/usr/bin/arm-linux-gnueabi-gcc-4.4
STRIP=/usr/bin/arm-linux-gnueabi-strip
CFLAGS=-I/usr/arm-linux-gnueabi/include
LDFLAGS=-nostdlib
LDLIBS=../libc.so.0
SRCS=test1.c
OBJS=$(subst .c,.o,$(SRCS))
all: test1
test1: $(OBJS)
$(CC) $(LDFLAGS) -o main $(OBJS) $(LDLIBS)
$(STRIP) main
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^>>./.depend;
clean:
rm -f $(OBJS)
include .depend
最佳答案
您可能应该做的是在嵌入式系统上安装libc6
。阅读 this thread关于类似的问题。帖子 #5 中的解决方案是安装:
libc6_2.3.6.ds1-13etch9_arm.deb
linux-kernel-headers_2.6.18-7_arm.deb
libc6-dev_2.3.6.ds1-13etch9_arm.deb
您的另一个选择是将 libc
从嵌入式系统获取到您的虚拟机,然后将其传递给 gcc
链接器并使用 -static
选项。
上面的帖子中也提到了这个解决方案。了解有关静态链接的更多信息 here .
其他要尝试的事情:
在 this thread如果您使用的是 -mabi=apcs-gnu
标志,他们建议从您的 makefile 中删除该标志。
This article如果您从命令行编译,建议给 gcc 添加 -nostdlib
标志。
关于gcc - 基于ARM的嵌入式Linux系统的交叉编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12512101/