"Nessun file o directory" quando si esegue un programma compilato su un Raspberry Pi


8

Di recente ho comprato un Raspberry Pi. L'ho già configurato e installo un compilatore incrociato per arm sul mio desktop (amd64). Ho compilato un semplice programma "ciao mondo" e poi lo copio dal mio desktop al mio Pi con scp ./hello david@192.168.1.33:~/hello. Dopo il login nel mio Pi corro ls -l helloe ottengo una risposta normale:

-rwxr-xr-x 1 david david 6774 Nov 16 18:08 hello

Ma quando provo ad eseguirlo, ottengo quanto segue:

david@raspberry-pi:~$ ./hello
-bash: ./hello: No such file or directory

david@raspberry-pi:~$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.26, BuildID[sha1]=0x6a926b4968b3e1a2118eeb6e656db3d21c73cf10, not stripped
david@raspberry-pi:~$ ldd hello 
    not a dynamic executable

Prova file helloe ldd hellopubblica l'output.
Riccioli d'oro


Hai scelto il compilatore incrociato sbagliato. Considerato solo di lavorare sul Pi stesso?
Thorbjørn Ravn Andersen,

Risposte:


5

Se ldddice che non è un eseguibile dinamico, è stato compilato per la destinazione sbagliata.

Ovviamente l'hai compilato in modo incrociato, come filedice un eseguibile ARM a 32 bit. Tuttavia, esiste più di un'architettura "ARM", quindi probabilmente la tua toolchain è stata configurata in modo errato.

Se stai usando crosstool-NG, dai un'occhiata al .configvalore di CT_ARCH_ARCH. Per il raspberry pi, dovrebbe essere "armv6j" 1 - o almeno, questo è ciò che funziona per me. Ci sono altri dettagli, ma penso che dovrebbe essere sufficiente. Sfortunatamente, se è sbagliato, ora devi ricostruire.

L'IMO che fa funzionare una toolchain tra compilatori può essere noioso e frustrante, ma presumere che l'host non sia un fattore significativo (non dovrebbe esserlo), in questo caso può essere fatto. Crosstool-ng usa un configuratore TLI, quindi se finisci per provare più build, annota ogni volta le tue scelte in modo da sapere cosa ha funzionato.

1 Credo che armv7 sia un arco molto più comune (molti telefoni e simili), quindi se stai usando qualcosa che ritieni sia un cross-compilatore ARM generico, questo è probabilmente il problema. Questi numeri sono confusi come, ad esempio, il processore pi è un ARM11 , ma (come da quella pagina), la famiglia di processori ARM11 utilizza l'architettura ARMv6 - ovvero ARM11 è un'implementazione di ARMv6.


1

prima compila il tuo programma con l' --staticopzione, quindi testalo. se funziona come statico quindi su raspberry pi

cat "programname" | grep "lib*"
/lib/ld-linux.so.3
libc6.so 

quindi controlla tutte le librerie se sono presenti

Ho risolto in questo modo. Ho, /lib/ld-linux-armhf-so.3ma non ho /lib/ld-linux.so.3 fatto un ln -sintermediario, poi ho lavorato per me


1

Come identificare il problema?

file cross_compiled_executable

Contiene qualcosa come:

interpreter /lib/ld-uClibc.so.0

e il problema è che quel file non esiste sulla destinazione.

Come risolvere il problema?

Utilizzare un compilatore appropriato, sia:

  • la persona che ha creato l'immagine del disco deve fornirti il ​​compilatore incrociato o dirti esattamente come costruirlo, ad esempio con crosstool-ng . Qui è stato chiesto come ottenerlo per RPI .
  • compila la tua immagine e cross compilatore, ad esempio con Buildroot . Ecco un esempio QEMU generico . Buildroot ha il supporto RPI .
  • usa un compilatore nativo sulla destinazione. Ma in genere i target sono molto più lenti del tuo host e lo spazio è limitato, quindi probabilmente non vorrai farlo.

    Potresti anche essere in grado di utilizzare un emulatore funzionale come QEMU per costruire, e quindi eseguire i programmi solo su una piattaforma più lenta, ad esempio gem5 o una scheda lenta.

Il solo hacking di questo non interpreterè potenzialmente sufficiente, in particolare è necessario garantire la compatibilità binaria tra il programma e la libc di destinazione o interfacce di programma e kernel (syscalls /proc, ecc.) Se si tenta di utilizzare -static(il kernel di destinazione potrebbe essere troppo vecchio e non contiene le interfacce richieste). L'unica soluzione affidabile è utilizzare la toolchain corretta.


0

Le librerie sul sistema di destinazione differiscono da quelle del sistema host su cui è stato compilato il file eseguibile.

Dovresti includere l'opzione --static nei tuoi CFLAGS e LDGLAGS se stai usando make. Se stai usando straight gcc, usa l'opzione --static in questo modo l'eseguibile è portatile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.