“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 david@192.168.1.33:~/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

Tente file helloe ldd helloposte a saída.
Goldilocks


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.


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


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.


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.