我正在尝试为一个嵌入式(自定义)基于ARM的Linux系统编译一些C代码。我使用一个名为arm-linux-gnueabi-gcc-4.4的交叉编译器在Ubuntu虚拟机中进行设置,因为它看起来就是我需要的。现在当我用这个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
uClibc
可以替代glibc
。但是你需要构建使用uClibc
的gcc编译器。获得一个工作正常的工具链(包括gcc,uClibc(或glibc)和其他软件包),并从源代码构建Linux内核,Busybox和其他软件包的一个相对容易的方法是使用BuildRoot
。使用良好的编译器+ libc组合,您可以将您的应用程序静态链接,并独立于目标库。 - sawdust