“Nenhum tal arquivo ou diretório” ao executar um programa cross-compilado em um Raspberry Pi

7

Eu comprei recentemente um Raspberry Pi. Eu já o configurei e instalei um compilador cruzado para arm em meu desktop (amd64). Eu compilei um simples programa "hello world" e copiei-o do meu desktop para o meu Pi com scp ./hello [email protected]:~/hello . Após o login no meu Pi eu corro ls -l hello e obtenho 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
    
por David Martínez 16.11.2013 / 18:18

4 respostas

5

Se ldd disser que não é um executável dinâmico, ele foi compilado para o destino errado.

Obviamente, você fez a compilação cruzada, pois file é um executável ARM de 32 bits. No entanto, há mais de uma arquitetura "ARM", então, possivelmente, sua cadeia de ferramentas foi configurada incorretamente.

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

O IMO fazendo com que um toolchain cross-compiler funcione pode ser entediante e frustrante, mas, presumindo que o host não é um fator significativo (não deveria ser), neste caso, isso pode ser feito. O Crosstool-ng usa um configurador TLI, portanto, se você tiver que tentar várias compilações, anote suas escolhas a cada vez para saber o que funcionou.

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

    
por 16.11.2013 / 18:36
1

primeiro compile seu programa com a opção --static e teste-o. se funciona como estática, em seguida, em framboesa pi

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

depois, verifique todas as libs se elas estiverem lá

Eu resolvi assim. Eu tenho /lib/ld-linux-armhf-so.3 mas não /lib/ld-linux.so.3 então faça um ln -s entre trabalhou para mim

    
por 03.02.2015 / 23:54
0

As bibliotecas no sistema de destino diferem daquelas do sistema host no qual seu executável foi compilado on / against.

Você deve incluir a opção --static em seus CFLAGS e LDGLAGS se estiver usando o make. Se você estiver usando o gcc direto, use a opção --static desta forma o executável é portátil.

    
por 25.01.2016 / 22:47
0

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 de disco deve fornecer-lhe o compilador cruzado ou informá-lo exatamente como criá-lo, por exemplo, com crosstool-ng . Como obtê-lo para o RPI foi perguntado aqui .
  • compile sua própria imagem e compilação cruzada, por exemplo com Buildroot . Aqui está um exemplo genérico do QEMU . O Buildroot tem suporte RPI .
  • use um compilador nativo no destino. Mas geralmente os alvos são muito mais lentos que o seu host e o espaço é restrito, então você provavelmente não quer fazer isso.

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

Apenas hackear o interpreter é potencialmente insuficiente, especialmente você precisa garantir compatibilidade binária entre o programa e o alvo libc, ou interfaces de programa e kernel (syscalls, /proc , etc.) se você tentar usar -static (o kernel de destino pode ser muito antigo e não conter as interfaces necessárias). A única solução robusta é usar o toolchain correto.

    
por 24.04.2018 / 05:59