“Esse arquivo ou diretório não existe” ao executar um programa de compilação cruzada em um Raspberry Pi

8

Eu comprei recentemente um Raspberry Pi. Já o configurei e instalei um compilador cruzado para arm na minha área de trabalho (amd64). Compilei um programa simples "olá mundo" e depois copio-o da minha área de trabalho para o meu Pi scp ./hello [email protected]:~/hello. Após o login no meu Pi, eu corro ls -l helloe recebo uma resposta normal:

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

Mas quando tento executá-lo, recebo o seguinte:

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
David Martínez
fonte
Tente file helloe ldd helloposte a saída.
Goldilocks
É o mesmo problema que “Esse arquivo ou diretório não existe” nos binários instalados da Optware - ABI incorreta.
Gilles 'SO- stop be evil'
Você escolheu o compilador cruzado errado. Considerado apenas trabalhando no próprio Pi?
Thorbjørn Ravn Andersen

Respostas:

5

E se ldd diz que não é um executável dinâmico, foi compilado para o destino errado.

Obviamente, você o compilou de maneira cruzada, como fileé um executável ARM de 32 bits. No entanto, há mais de uma arquitetura "ARM", portanto, possivelmente, sua cadeia de ferramentas foi configurada incorretamente.

Se você estiver usando o crosstool-NG, dê uma olhada no .configvalor de CT_ARCH_ARCH. Para o raspberry pi, deve ser "armv6j" 1 - ou pelo menos, é isso que está funcionando para mim. Existem outras especificidades, mas acho que isso deve ser suficiente. Infelizmente, se estiver errado, você precisa reconstruir agora.

A IMO fazer com que uma cadeia de ferramentas de compilador cruzado funcione pode ser entediante e frustrante, mas, presumindo que o host não seja um fator significativo (não deveria ser), nesse caso, pode ser feito. O Crosstool-ng usa um configurador TLI; portanto, se você precisar tentar várias compilações, anote suas opções a cada vez para saber o que funcionou.

1 Eu acredito que o armv7 é um arco muito mais comum (muitos telefones e outros); portanto, se você está apenas usando algo que acredita ser um cross-compiler genérico para ARM, provavelmente esse é o problema. Esses números são confusos, pois, por exemplo, o processador do pi é um ARM11 , mas (conforme essa página), a família de processadores ARM11 usa a arquitetura ARMv6 - ou seja, o ARM11 é uma implementação do ARMv6.

Cachinhos Dourados
fonte
1

primeiro compile seu programa com a --staticopção e teste-o. se funcionar como estático, então no raspberry pi

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

verifique todas as bibliotecas, se houver

Eu resolvi assim. Eu tenho, /lib/ld-linux-armhf-so.3mas não /lib/ld-linux.so.3 então fazer um ln -sentre então trabalhou para mim

hamza kılıç
fonte
1

Como identificar o problema?

file cross_compiled_executable

Contém algo como:

interpreter /lib/ld-uClibc.so.0

e o problema é que esse arquivo não existe no destino.

Como resolver o problema?

Use um compilador adequado:

  • a pessoa que criou a imagem do disco deve fornecer o compilador cruzado ou dizer exatamente como construí-lo, por exemplo, com crosstool-ng . Como obtê-lo para o RPI foi solicitado aqui .
  • Compile sua própria imagem e compilador cruzado, por exemplo, com o Buildroot . Aqui está um exemplo genérico de QEMU . O Buildroot tem suporte para RPI .
  • use um compilador nativo no destino. Mas geralmente os alvos são muito mais lentos que o seu host e o espaço é limitado, portanto você provavelmente não quer fazer isso.

    Você também pode usar um emulador funcional como o QEMU para criar e executar os programas apenas em uma plataforma mais lenta, por exemplo, gem5 ou uma placa lenta.

Apenas hackear o interpreterpotencial não é o suficiente, principalmente para garantir a compatibilidade binária entre o programa e a libc de destino, ou as interfaces de programa e do kernel (syscalls /proc, etc.) se você tentar usar -static(o kernel de destino pode ser muito antigo e não contém as interfaces necessárias). A única solução robusta é usar a cadeia de ferramentas correta.

Ciro Santilli adicionou uma nova foto
fonte
0

As bibliotecas no sistema de destino diferem das do sistema host em que o executável foi compilado / contra.

Você deve incluir a opção --static no seu CFLAGS e LDGLAGS se estiver usando o make. Se você estiver usando o straight gcc, use a opção --static para que o executável seja portátil.

Kevin Parker
fonte