Comments 27
https://wiki.gentoo.org/wiki/Cross_build_environment
https://wiki.gentoo.org/wiki/Distcc/Cross-Compiling
В Gentoo-вики по Raspberry Pi тоже можно найти много полезного (и далеко не только RPi-специфичного):
https://wiki.gentoo.org/wiki/Raspberry_Pi
Что меня поразило — делать полную виртуалку с ARM-системой совсем не обязательно, современный qemu позволяет (при соответствующей настройке системы, конечно же) на обычном x86_64 компьютере запускать ARM'овые бинарники, что, в соединении с chroot'ом, для меня оказалось гораздо эффективнее и удобнее, чем «настоящая» виртуалка. Ну и не стоит забывать про distcc.
Crosstool-NG ?
тот же GCC хочет бутстрапа,
А если RTFM?
Building a native compiler
For a native build, the default configuration is to perform a 3-stage bootstrap of the compiler when ‘make’ is invoked.
It can be disabled with the --disable-bootstrap parameter to ‘configure'
Building a cross compiler
When building a cross compiler, it is not generally possible to do a 3-stage bootstrap of the compiler.
За ссылку спасибо =)
GCC я привел только как пример, в той же Gentoo есть много пакетов, которые кросскомпиляцией не собрать, Часть вываливаются с:
configure: error: cannot run test program while cross compiling
У части — просто жестко прописаны пути к cc или либам. Понятно, что 99% всего этого я мог бы починить, а заодно заслать патч разработчику, только уж слишком много таких пакетов и слишком мало у меня желания этим заниматься.
Вы путаете процессоры и микроконтроллеры. Cortex-A, про которые идёт речь в этом топике — полноценные general purpose cpu, на них спокойно может крутиться linux и вещи типа дёрганья каких-либо gpio, spi/i2c/i2s/uart осуществляется из ядра ОС, т. е. через драйвер с точки зрения userspace.
А эмулировать можно и такие процессоры, и контроллеры. Естественно, для части вещей придётся описывать эмуляцию периферии. Одним из полезных кейсов, когда вполне может быть модульное тестирование. Другим — интеграционное тестирование с сетью (я как-то писал для этого эмулятор сетевой карты enc28j60).
Toolchain'ы для ARM делятся на несколько типов. Основные это noneabi, eabi и eabihf.
noneabi — это toolchain для компиляции проекта работающего в bare metal.
eabi — это toolchain для компиляции проекта работающего в какой-либо ОС. В моём случае, это Linux.
eabihf — это почти то же самое, что и eabi, с разницей в реализации операций над числами с плавающей точко. hf — расшифровывается как hard float, т.е. аппаратная реализация вычислений с плавающей точкой.
Это триплеты target-архитектур, которые вы, ко всему прочему, ещё и неправильно написали.
Триплет обычно состоит из трёх частей: целевой процессор, vendor и OS, vendor зачастую опускается (и может в этом случае означать pc для x86 и x86_64; или unknown для почти всего остального). OS иногда состоит из двух частей, разделяемых также дефисом (e.g. linux-gnueabi
, linux-androideabi
) и означает API и ABI целевой платформы. В случае bare metal OS, как правило, none-*
, т. е. для bare metal arm это выглядит как arm-unknown-none-eabi
, что, как правило, сокращается до arm-none-eabi
.
eabi
и eabihf
отличаются, собственно, ABI вызова функций с плавающей точкой, а не наличием поддержки hardfloat целевой платформой (т. е. регулирует -mfloat-abi
). Очевидно, что fpu необходим для eabihf
, но никто не запрещает использовать hardfloat, но передавать аргументы функции не используя аппаратные регистры для floating point.
В случае платформ типа raspberrypi с linux'ом на борту необходимо использовать aarch64-linux-gnueabi
/arm-linux-gnueabi
/arm-linux-gnueabihf
в зависимости от того какое abi используется ОС, установленной на rpi.
Стоит также понимать, что написанное выше справедливо для gcc и сделанных на базе (или мимикрирующих под) него тулчейнах. У clang/llvm свои триплеты, которые строятся по схожему принципу, но с несколько иным пониманием того, что такое target cpu. Например, у gcc триплеты arm-*-*
включают очень разнородные cpu: от ARM7 (не путать с ARMv7*) и Cortex-M, которые предназначены для микроконтроллеров, обычно не имеют кэшей (исключение — новые Cortex-M на архитектуре ARMv8-M) до ARM11 и Cortex-A/R, которые являются полноценными процессорами. Выбор процессора, набора команд и других параметров кодогенерации осуществляется ключами типа -mcpu
/-march
/-mtune
, -thumb
и пр.
В случае же llvm часть информации из -mcpu
/-march
/-mtune
переехала в target. Например, вместо TARGET=arm-none-eabi
и -march=cortex-m3
необходимо использовать TARGET=thumbv7m-none-eabi
, если правильно помню.
Дабы не размножать ветки, продолжу здесь.
Просто используется toolchain в роли компилятора.
Компилятор — часть тулчейна. Обычно просто используется нативный тулчейн, для которого HOST и TARGET совпадают.
А стандартные библиотеки поставляются вместе с toolchain'ом.
Это зависит от мейнтейнеров конкретных пакетов, т. е. далеко не всегда так.
Я говорю о toolchain GCC и языках C и C++. Поправьте пожалуйста мой тезис.
Стандартные библиотеки (glibc и libstdc++) всегда поставляются вместе с toolchain. Даже если у вас есть sysroot из target системы и вы указываете его при сборке вашей программы [например так set(CMAKE_SYSROOT путь_к_sysroot)], то toolchain всё равно возьмёт те стандартные библиотеки, с которыми был собран, а не из target системы. А вы скорее вего получите ошибку типа version `GLIBCXX_3.4.20' not found Потому что в реальной жизни toolchain, который вы скачали из интернетов, собирали с одной версией стандартных библиотек, а у вас на target системе конечно же другая версия...
Стандартные библиотеки (glibc и libstdc++) всегда поставляются вместе с toolchain
Это не так. Например, я не вижу в установленном у меня arm-none-eabi-gcc
даже libc
(например crt0.o
, libc.a
, libm.a
и подобных файлов), не говоря уже о тяжеловесной glibc
которая на контроллере с 20k RAM и 64k ROM не взлетит (да и не соберётся под эту платформу в силу отсутствия на ней ОС). Урезанная версия libc
(newlib
, собственно) у меня стоит отдельным опциональным пакетом. Из того что идёт в комплекте -- заголовочные файлы стандартных библиотек C и C++, архитектуро-зависимые заголовочные файлы (bits/*.h
) и объектные файлы (прологи/эпилоги crti.o
/crtn.o
, crtbegin.o
/crtend.o
).
toolchain всё равно возьмёт те стандартные библиотеки, с которыми был собран, а не из target системы
Скорее возьмёт пути поиска заголовочных файлов и библиотек по умолчанию на основе той конфигурации с которой он был собран. При необходимости можно добавить -nostdinc
/-nostdinc++
/-nolibc
/-nostdlib
/-nodefaultlibs
настроить правильные для конкретной системы пути поиска и явно указать какие библиотеки линковать.
Но, в целом, это причина брать сторонний тулчейн только для кросс-компиляции. Кагбэ странно ожидать что сторонний тулчейн будет нормально собирать под произвольный хост используя библиотеки хоста с которыми он может быть не совместим. Особенно когда речь про очень специальные библиотеки типа libgcc
/libc
/libstdc++
. Чтобы оценить насколько эти библиотеки специальные можно глянуть на описание процесса бутстрапа компилятора в LFS
Поэтому лучше собирать на хосте. В моём случае, это i5 с 4ГБ ОЗУ, Fedora 24.
В этот момент статью закончило читать 90% разработчиков.
На самом деле тут статья «из пушки по воробьям».
Eclipse+GNU ARM делают это все «из коробки»
Для поклонников Майкрософта и Вижуал Студио достаточно доставить в свою любимую среду VisualGDB и опять таки не заморачиваться.
В этот момент статью закончило читать 90% разработчиков.
Ну это же хорошо.
На самом деле тут статья «из пушки по воробьям».
Не согласен.
Eclipse+GNU ARM делают это все «из коробки»
Для поклонников Майкрософта и Вижуал Студио достаточно доставить в свою любимую среду VisualGDB и опять таки не заморачиваться.
Пользоваться этим и далее не понимать, как оно «вертится внутри».
Поддерживается как сборка под linux, так и под голый ARM. Можно отлаживаться через gdb или JTAG, в т. ч. и производить трассировку инструкций при условии поддержки этого как аппаратной платформой, так и отладчиком.
P. S. Никак не связан с производителем, просто дейстивительно приятно использовать этот инструмент в работе. Если есть какие-то вопросы, отвечу на них
П.С. Сам живу на Altera edition оного, после допиливания (ага, там первые версии шли с корявейшими скриптами сборки и заливки через JTAG) оный становится очень вкусным.
Собственно, вот такая она, эта кросскомпиляция.
Собственно, это была вовсе и не кросскомпиляция.
make CROSS_COMPILE=/usr/bin/arm-none-linux-gnueabihf- ARCH=arm all
Обычно этого достаточно, чтобы компилятор начал сборку проекта тулчейном, а не нативно (Командоой выше я спокойно собираю ядро для arm-девайса на десктопе. Сам тулчейн — собранный вручную Linaro Crosstools)
С тестированием тож все легко: Собираем образ системы (debootstrap для debian-based систем), в системе ставим qemu-user-static, копируем /usr/bin/qemu-arm-static по томуже пути в чрут и можно туда заходить.
Что примечательно — внутри чрута можно выполнить «Нативную» компиляцию.
Ну или можно схитрить и использовать buildroot для сборки почти всего и настройкой через привычный menuconfig (какой-никакой GUI)
Можно ли на Windows10 собирать образы и UserSpace приложения для Linux SBC?
Кросскомпиляция под ARM