2014-07-07 14 views
5

Natrafiłem na najdziwniejszy problem, jaki kiedykolwiek spotkałem. Łączę kompilację aplikacji dla procesora ARM z systemem Linux na pokładzie. Używam buildroot i wszystko idzie dobrze, dopóki próbuję uruchomić aplikację na celu: otrzymuję -sh: ./hw: not found. Np .:"sh: ./ <file> nie znaleziono" błąd podczas próby wykonania pliku

$ cat /tmp/test.cpp 
#include <cstdio> 
#include <vector> 

int main(int argc, char** argv){ 
     printf("Hello Kitty!\n"); 
     return 0; 
} 
$ ./arm-linux-g++ -march=armv7-a /tmp/test.cpp -o /tftpboot/hw 

załaduj plik wykonywalny do miejsca docelowego; następnie wydawanie na tarczy:

# ./hw 
-sh: ./hw: Permission denied 
# chmod +x ./hw 
# ./hw 
-sh: ./hw: not found 
# ls -l ./hw 
-rwxr-xr-x 1 root  root   6103 Jan 1 03:40 ./hw 

Jest więcej do niego: na budowę z distro kompilatora, jak arm-linux-gnueabi-g++ -march=armv7-a /tmp/test.cpp -o /tftpboot/hw, aplikacja działa poprawnie!

Porównywałem pliki wykonywalne przez readelf -a -W /tftpboot/hw, ale nie zauważyłem znacznej różnicy. I pasted both outputs here. Jedyne, co zauważyłem, to linie Version5 EABI, soft-float ABI i Version5 EABI. Próbowałem usunąć różnicę, przekazując jedną z -mfloat-abi=softfp i -mfloat-abi=soft, ale wydaje się, że kompilator ją ignoruje. Przypuszczam jednak, że to nie ma znaczenia, ponieważ kompilator nawet nie ostrzega.

Pomyślałem również, być może sh wyprowadza ten błąd, jeśli plik wykonywalny jest niekompatybilny w jakiś sposób. Ale na moim głównym komputerze widzę kolejny błąd w tym przypadku, np .:

$ sh /tftpboot/hw 
/tftpboot/hw: 1: /tftpboot/hw: Syntax error: word unexpected (expecting ")") 
+0

podobny http://stackoverflow.com/questions/14535897/buildroot-file-system-cross-compiling-dynamically-linked-application-fails-bu –

Odpowiedz

7

sh drukuje ten dziwny błąd, ponieważ stara się uruchomić program jako skrypt powłoki!

Twój błąd ./hw: not found jest prawdopodobnie spowodowany przez linker dynamiczny (interpreter AKA ELF), który nie został znaleziony. Spróbuj skompilować go jako program statyczny z -static lub uruchom go za pomocą dynamicznego programu ładującego: # /lib/ld-linux.so.2 ./hw lub coś w tym stylu.

Jeśli problem jest to, że ładowarka jest dynamiczny nazwany inaczej narzędzie łańcucha i w środowisku wykonawczym można go naprawić:

  • w środowisku wykonawczym: z dowiązania symbolicznego.
  • w narzędziu łańcucha: użyj -Wl,--dynamic-linker=/lib/ld-linux.so.2
+2

Tak , opcja '-static' zrobiła lewę! Dziękuję Ci bardzo! Po prostu ciekawy - jeśli wiesz, proszę, powiedz mi: jaka biblioteka powinna tam być połączona i dlaczego plik był traktowany jak skrypt, dopóki nie połączyłem statycznie? Czy system nie widzi sygnatury "ELF" w pliku? –

+2

@YagamyLight: Problem nie dotyczy biblioteki, ale dynamicznego linkera, czyli programu ładującego dynamiczne pliki wykonywalne. W Linuksie jest to zwykle '/ lib/ld-linux *'. Możesz zobaczyć, co to jest z 'objdump -s -j/bin/ls', będąc'/bin/ls' dynamicznym plikiem wykonywalnym, który działa. – rodrigo

+2

@YagamyLight: Plik traktowany jest jak skrypt, ponieważ właśnie tak robi 'sh' z jego pierwszym argumentem: traktuj go jak skrypt. Aby traktować to jako polecenie (i możliwy program) użyj 'sh -c./Hw'. Ale wtedy możesz po prostu napisać './Hw'. – rodrigo

Powiązane problemy