«Нет такого файла или каталога» при выполнении кросс-скомпилированной программы на Raspberry Pi

8

Я недавно купил Raspberry Pi. Я уже настроил его, и я установил кросс-компилятор для arm на моем рабочем столе (amd64). Я скомпилировал простую программу «hello world», а затем скопировал ее со своего рабочего стола на свой Pi с помощью scp ./hello david@192.168.1.33:~/hello. После входа в мой Pi я запускаю ls -l helloи получаю нормальный ответ:

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

Но когда я пытаюсь выполнить это, я получаю следующее:

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
Дэвид Мартинес
источник
Попробуйте file helloи ldd helloопубликовать вывод.
Златовласка
Это та же проблема, что «Нет такого файла или каталога» лежит в установленных двоичных файлах Optware - неправильный ABI.
Жиль "ТАК - перестань быть злым"
Вы выбрали неправильный кросс-компилятор. Рассматривается просто работа над самим Пи?
Торбьерн Равн Андерсен

Ответы:

5

Если lddговорится, что это не динамический исполняемый файл, то он был скомпилирован для неправильной цели.

Очевидно, вы сделали кросс-компиляцию, как fileговорит, это исполняемый файл 32-битной ARM. Однако существует более одной архитектуры "ARM", поэтому, возможно, ваш набор инструментов был настроен неправильно.

Если вы используете crosstool-NG, взгляните на .configзначение CT_ARCH_ARCH. Для Raspberry Pi это должно быть «armv6j» 1 - или, по крайней мере, это то, что работает для меня. Есть и другие особенности, но я думаю, что этого должно быть достаточно. К сожалению, если это не так, теперь вам нужно восстановить.

IMO заставить кросс-компиляторный набор инструментов работать может быть утомительным и разочаровывающим, но, предполагая, что хост не является существенным фактором (это не должно быть), в этом случае это может быть сделано. Crosstool-ng использует конфигуратор TLI, поэтому, если вам в итоге придется попробовать несколько сборок, каждый раз записывайте свой выбор, чтобы вы знали, что сработало.

1 Я считаю, что armv7 - это гораздо более распространенная арка (множество телефонов и тому подобное), поэтому, если вы просто используете то, что, по вашему мнению, является универсальным кросс-компилятором ARM, возможно, это проблема. Эти цифры сбивают с толку, поскольку, например, процессор pi является ARM11 , но (согласно этой странице) семейство процессоров ARM11 использует архитектуру ARMv6 - то есть ARM11 является реализацией ARMv6.

лютик золотистый
источник
1

сначала скомпилируйте вашу программу с --staticопцией, а затем протестируйте ее. если он работает как статический, то на Raspberry Pi

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

затем проверьте все библиотеки, если они там

Я решил так. У меня есть, /lib/ld-linux-armhf-so.3но не /lib/ld-linux.so.3 тогда сделать ln -sмежду тем работал на меня

хамза килич
источник
1

Как определить проблему?

file cross_compiled_executable

Содержит что-то вроде:

interpreter /lib/ld-uClibc.so.0

и проблема в том, что этот файл не существует на цели.

Как решить проблему?

Используйте правильный компилятор:

  • человек, создавший образ диска, должен предоставить вам кросс-компилятор или точно сказать, как его создать, например, с помощью crosstool-ng . Как получить его для RPI спросили здесь .
  • скомпилируйте свой собственный образ и кросс-компилятор, например, с помощью Buildroot . Вот общий пример QEMU . Buildroot имеет поддержку RPI .
  • используйте нативный компилятор на цели. Но, как правило, цели гораздо медленнее, чем ваш хост, и из-за ограниченного пространства вам вряд ли захочется этого делать.

    Вы также можете использовать функциональный эмулятор, такой как QEMU, для сборки, а затем запускать программы только на более медленной платформе, например, gem5 или медленной плате.

Простого взлома interpreterпотенциально недостаточно, особенно /procесли вы пытаетесь использовать -static( необходимо использовать двоичную совместимость между программой и целевым libc, или интерфейсами программы и ядра (syscalls и т. Д.) (Целевое ядро ​​может быть слишком старым и не содержат требуемых интерфейсов). Единственное надежное решение - использовать правильный набор инструментов.

Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
источник
0

Библиотеки в целевой системе отличаются от библиотек хост-системы, в которой исполняемый файл был скомпилирован или запрещен.

Вы должны включить опцию --static в ваши CFLAGS и LDGLAGS, если вы используете make. Если вы используете прямой gcc, используйте опцию --static, чтобы исполняемый файл был переносимым.

Кевин Паркер
источник