Provo a compilare un codice C per un sistema Linux embedded (personalizzato) basato su ARM. Ho creato una macchina virtuale Ubuntu con un cross-compilatore chiamato arm-linux-gnueabi-gcc-4.4 perché sembrava quello di cui avevo bisogno. Ora, quando ho compilare il mio codice con questo gcc, produce un binario come questo:Compilatura incrociata per un sistema Linux basato su ARM incorporato
$ 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
Quando provo a fare funzionare questo binario su Linux embedded, ottengo
$ ./test1
-sh: ./test1: not found
permessi sono sufficienti. Posso solo immaginare che qualcosa non va con il formato binario, così ho guardato un po 'di binario a lavorare come riferimento:
$ file referenceBinary
referenceBinary: ELF 32-bit LSB executable, ARM, version 1, dynamically linked
(uses shared libs), stripped
vedo che ci sono alcune differenze, ma non ho le conoscenze per ricavare che cosa esattamente mi serve risolvere e come posso risolvere il problema. Qualcuno può spiegare quale differenza è critica?
Un'altra cosa che ho guardato sono le dipendenze:
$ ldd test1
libc.so.6 => not found (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)
(È interessante notare che questo funziona sul sistema di destinazione anche se non può eseguire il binario.) Il sistema embedded ha solo libc.so.0
disponibili. Suppongo di dover dire al compilatore la versione di libc a cui voglio collegarmi, ma a quanto ho capito, gcc solo link con la versione che viene fornita, è corretto? Cosa posso fare a riguardo?
Edit: Ecco il Makefile che uso:
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
Se hai poca memoria, il più piccolo 'uClibc' può sostituire' glibc'. Comunque avresti bisogno di un compilatore * gcc * costruito per usare 'uClibc'. Un metodo (relativamente) facile per ottenere una toolchain funzionante di * gcc *, * uClibc * (o * glibc *) e amici più la compilazione del kernel Linux, Busybox e altri pacchetti tutto da sorgente è usare 'BuildRoot'. Con una buona combinazione di compilatore + libc, puoi collegare la tua app in modo statico ed essere indipendente dalle librerie del bersaglio. – sawdust