«Aucun fichier ou répertoire de ce type» lors de l'exécution d'un programme compilé de manière croisée sur un Raspberry Pi


8

J'ai récemment acheté un Raspberry Pi. Je l'ai déjà configuré et j'installe un compilateur croisé pour arm sur mon bureau (amd64). J'ai compilé un simple programme "hello world" puis je le copie de mon bureau vers mon Pi avec scp ./hello david@192.168.1.33:~/hello. Après la connexion à mon Pi, je cours ls -l helloet j'obtiens une réponse normale:

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

Mais lorsque j'essaie de l'exécuter, j'obtiens ce qui suit:

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

Essayez file helloet ldd helloet après la sortie.
goldilocks


Vous avez choisi le mauvais compilateur croisé. Vous considérez simplement travailler sur le Pi lui-même?
Thorbjørn Ravn Andersen

Réponses:


5

Si ldddit que ce n'est pas un exécutable dynamique, alors il a été compilé pour la mauvaise cible.

Évidemment, vous l'avez compilé de manière croisée, comme le filedit un exécutable ARM 32 bits. Cependant, il y a plus d'une architecture "ARM", donc votre chaîne d'outils a peut-être été mal configurée.

Si vous utilisez crosstool-NG, jetez un œil à .configla valeur de CT_ARCH_ARCH. Pour le Raspberry Pi, ce devrait être "armv6j" 1 - ou du moins, c'est ce qui fonctionne pour moi. Il y a d'autres détails, mais je pense que cela devrait suffire. Malheureusement, si c'est faux, vous devez maintenant reconstruire.

IMO faire fonctionner une chaîne d'outils de compilateur croisé peut être fastidieux et frustrant, mais, en supposant que l'hôte n'est pas un facteur important (il ne devrait pas l'être), dans ce cas, cela peut être fait. Crosstool-ng utilise un configurateur TLI, donc si vous devez essayer plusieurs versions, notez vos choix à chaque fois pour savoir ce qui a fonctionné.

1 Je crois qu'armv7 est un arc beaucoup plus courant (beaucoup de téléphones et autres), donc si vous utilisez simplement quelque chose que vous croyez être un compilateur croisé ARM générique, c'est probablement le problème. Ces chiffres prêtent à confusion car, par exemple, le processeur du pi est un ARM11 , mais (selon cette page), la famille de processeurs ARM11 utilise l'architecture ARMv6 - c.-à-d. ARM11 est une implémentation d'ARMM6.


1

compilez d'abord votre programme avec --staticoption, puis testez-le. si cela fonctionne comme statique, alors sur framboise pi

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

puis vérifiez toutes les bibliothèques si elles sont là

J'ai résolu comme ça. Je n'ai , /lib/ld-linux-armhf-so.3mais pas /lib/ld-linux.so.3 alors faire un ln -sentre ensuite travaillé pour moi


1

Comment identifier le problème?

file cross_compiled_executable

Contient quelque chose comme:

interpreter /lib/ld-uClibc.so.0

et le problème est que ce fichier n'existe pas sur la cible.

Comment résoudre le problème?

Utilisez un compilateur approprié, soit:

  • la personne qui a créé l'image disque doit vous fournir le compilateur croisé ou vous dire exactement comment le construire, par exemple avec crosstool-ng . Comment l'obtenir pour RPI a été demandé ici .
  • compilez votre propre image et compilateur croisé, par exemple avec Buildroot . Voici un exemple générique de QEMU . Buildroot a un support RPI .
  • utiliser un compilateur natif sur la cible. Mais généralement, les cibles sont beaucoup plus lentes que votre hôte et l'espace est limité, vous ne voudrez donc probablement pas le faire.

    Vous pouvez également être en mesure d'utiliser un émulateur fonctionnel tel que QEMU pour créer, puis d'exécuter uniquement les programmes sur une plate-forme plus lente, par exemple gem5 ou une carte lente.

Il interpreterne suffit pas de pirater le , notamment vous devez assurer la compatibilité binaire entre le programme et la libc cible, ou les interfaces du programme et du noyau (syscalls /proc, etc.) si vous essayez d'utiliser -static(le noyau cible peut être trop ancien et ne contient pas les interfaces requises). La seule solution robuste consiste à utiliser la chaîne d'outils appropriée.


0

Les bibliothèques du système cible diffèrent de celles du système hôte sur lequel votre exécutable a été compilé.

Vous devez inclure l'option --static dans vos CFLAGS et LDGLAGS si vous utilisez make. Si vous utilisez directement gcc, utilisez l'option --static de cette façon, l'exécutable est portable.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.