"No existe tal archivo o directorio" cuando se ejecuta un programa compilado en una Raspberry Pi


8

Recientemente compré una Raspberry Pi. Ya lo configuré e instalo un compilador cruzado para armar en mi escritorio (amd64). Compilé un programa simple "hello world" y luego lo copié desde mi escritorio a mi Pi con scp ./hello david@192.168.1.33:~/hello. Después de iniciar sesión en mi Pi, ejecuto ls -l helloy obtengo una respuesta normal:

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

Pero cuando trato de ejecutarlo, obtengo lo siguiente:

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

Intenta file helloy ldd hellopublica la salida.
Ricitos de oro


Has elegido el compilador cruzado incorrecto. ¿Considerado solo trabajar en el Pi mismo?
Thorbjørn Ravn Andersen

Respuestas:


5

Si ldddice que no es un ejecutable dinámico, se compiló para el destino incorrecto.

Obviamente lo compiló de forma cruzada, como se filedice es un ejecutable ARM de 32 bits. Sin embargo, hay más de una arquitectura "ARM", por lo que posiblemente su cadena de herramientas se configuró incorrectamente.

Si está utilizando crosstool-NG, observe .configel valor de CT_ARCH_ARCH. Para la frambuesa pi, debería ser "armv6j" 1 , o al menos eso es lo que me funciona. Hay otros detalles, pero creo que debería ser suficiente. Desafortunadamente, si está mal, ahora tienes que reconstruir.

La OMI para que funcione una cadena de herramientas de compilación cruzada puede ser tediosa y frustrante, pero, suponiendo que el host no sea un factor significativo (no debería serlo), en este caso se puede hacer. Crosstool-ng usa un configurador TLI, por lo que si termina teniendo que probar varias compilaciones, escriba sus elecciones cada vez para saber qué funcionó.

1 Creo que armv7 es un arco mucho más común (muchos teléfonos y demás), así que si solo estás usando algo que crees que es un compilador cruzado ARM genérico, ese es probablemente el problema. Estos números son confusos ya que, por ejemplo, el procesador del pi es un ARM11 , pero (según esa página), la familia de procesadores ARM11 usa la arquitectura ARMv6, es decir, ARM11 es una implementación de ARMv6.


1

primero compile su programa con la --staticopción, luego pruébelo. si funciona como estático, entonces en frambuesa pi

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

luego verifique todas las bibliotecas si están allí

He resuelto así. Tengo /lib/ld-linux-armhf-so.3pero no hice /lib/ld-linux.so.3 un ln -sintermedio y luego trabajé para mí


1

¿Cómo identificar el problema?

file cross_compiled_executable

Contiene algo como:

interpreter /lib/ld-uClibc.so.0

y el problema es que ese archivo no existe en el destino.

¿Como resolver el problema?

Use un compilador adecuado, ya sea:

  • la persona que creó la imagen del disco debe proporcionarle el compilador cruzado o decirle exactamente cómo construirlo, por ejemplo, con crosstool-ng . Aquí se preguntó cómo obtenerlo para RPI .
  • compile su propia imagen y compilador cruzado, por ejemplo, con Buildroot . Aquí hay un ejemplo genérico de QEMU . Buildroot tiene soporte RPI .
  • use un compilador nativo en el destino. Pero, en general, los objetivos son mucho más lentos que su host y tienen poco espacio, por lo que es probable que no quiera hacer esto.

    También puede usar un emulador funcional como QEMU para compilar y luego ejecutar los programas en una plataforma más lenta, por ejemplo, gem5 o una placa lenta.

Simplemente hackear el interpreterpotencialmente no es suficiente, en particular, debe garantizar la compatibilidad binaria entre el programa y la libc de destino, o las interfaces del programa y del núcleo (syscalls /proc, etc.) si intenta usarlo -static(el núcleo de destino puede ser demasiado viejo y no contiene las interfaces requeridas). La única solución sólida es usar la cadena de herramientas correcta.


0

Las bibliotecas en el sistema de destino difieren de las del sistema host en el que se compiló su ejecutable.

Debe incluir la opción estática en sus CFLAGS y LDGLAGS si está usando make. Si está utilizando gcc directo, use la opción --static de esta manera, el ejecutable es portátil.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.