Как стать автором
Обновить

Комментарии 27

Я тут недавно тоже вплотную озадачился кросскомпиляцией под ARM, так как оказалось, что под мой Toshiba AC100 ни одного нормального (современного) бинарного дистрибутива нет. И в итоге оказалось, что в Gentoo Linux с этим все не просто хорошо, а замечательно:
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.
А можно уточнить в чем смысл эмуляции embedded процессоров на x86, если основные задачи, для которых их используют, обычно связаны с обменом данными через i2c, spi, дрыгание gpio и прочие спец фичи контроллеров? Разве можно проэмулировать это под линукс на обычном ПК?
Ну для меня смысл в том, что тот же GCC не получится собрать на ARM'овой железке которая у меня есть потому, что у нее не хватает памяти. Кросс-компиляция тоже не всегда работает, так как тот же GCC хочет бутстрапа, т.е. скомпилировать самого себя пару-тройку раз (пока процесс не сойдется). Потому и остается эмуляция.

Crosstool-NG ?

Нене, мне не нужен кросскомпилятор, для этого у меня есть sys-devel/crossdev. Но некоторые пакеты кросскомпиляцией не собрать (Ну или может собрать в итоге и получится, но перед этим долго мучиться и понимать, что с ним не так), потому на помощь приходит виртуализация.
тот же 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 на свой Toshiba AC-100.
За ссылку спасибо =)
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 и опять таки не заморачиваться.

Пользоваться этим и далее не понимать, как оно «вертится внутри».
До того, как познакомился с DS-5, кросс-компиляция под ARM была головной болью. Сейчас же это всё происходит без каких-либо проблем.

Поддерживается как сборка под linux, так и под голый ARM. Можно отлаживаться через gdb или JTAG, в т. ч. и производить трассировку инструкций при условии поддержки этого как аппаратной платформой, так и отладчиком.

P. S. Никак не связан с производителем, просто дейстивительно приятно использовать этот инструмент в работе. Если есть какие-то вопросы, отвечу на них
Инструмент хорош, пока вам не нужен JTAG или baremetal. А как только они становятся нужны, то появляется проблема — DS-5 стоит весьма прилично. Есть конечно всякие DS-5 [CPU Vendor] Edition, но и они тоже стоят денег.
П.С. Сам живу на Altera edition оного, после допиливания (ага, там первые версии шли с корявейшими скриптами сборки и заливки через JTAG) оный становится очень вкусным.
DS-5 стоит прилично для одинокого радиолюбителя, для компании же эти затраты окупаются вмиг.
Собственно, вот такая она, эта кросскомпиляция.

Собственно, это была вовсе и не кросскомпиляция.
В Википедии, по вашему, ошибаются?
В этом месте википедии всё нормально написано. Тем не менее, начиная с заголовка HOW2 в вашей статье описывается не кросс-компиляция, а нативная компиляция внутри эмулятора.

Ещё один вопрос: если у вас есть gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabihf, зачем танцы с ARM в QEMU?
Прошу прощения, нет больше вопросов. Вот что значит с утра не выпить кофе.
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)
Обычно этого достаточно, чтобы компилятор начал сборку проекта

Этого достаточно, если Makefile проекта написан так, чтобы использовать переменную окружения CROSS_COMPILE. Вот как, например, Makefile ядра или U-Boot. С произвольным проектом это не работает.

Можно ли на Windows10 собирать образы и UserSpace приложения для Linux SBC?

WSL + Docker - да. Но лучше на W11.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории