- Cross-compiling tools package guidelines (Русский)
- Contents
- Важная заметка
- Совместимость версий
- Сборка кросс-компилятора
- Наименование пакета
- Размещение файлов
- пример
- Как и почему
- Почему бы не устанавливать в /opt
- What is that out-of-path executables thing?
- Поиск проблемы
- Что делать, если компиляция не удалась без четкого сообщения?
- Что означает эта ошибка [error message]?
- Почему файлы устанавливаются в неправильных местах?
- Кросс-компиляция под Linux
- Введение
- Binutils
- NewLib
- Сборка Toolchain
- Порядок сборки Toolchain
- Кросс-компиляция в docker. Почему бы и нет?
- Инструменты
- Контейнеризируй это
- Собираем все вместе
- Кастомизация сборки
- CMake и статическая линковка Qt
- В заключении
Cross-compiling tools package guidelines (Русский)
Contents
Важная заметка
На этой странице описан новый принцип работы, основанный на следующих пакетах:
- mingw-w64-gcc и другие пакеты из mingw-w64-* серии
- arm-none-eabi-gcc и другие пакеты из arm-none-eabi-* серии
- другие пакеты из arm-wince-cegcc-* серии
Совместимость версий
Следующая стратегия позволяют выбирать совместимые версии gcc, binutils, ядра и библиотеки C:
- Основные правила:
- существует корреляция между выпусками gcc и binutils, используйте одновременно выпущенные версии;
- лучше использовать последние заголовки ядра для компиляции libc, но использовать переключатель —enable-kernel (специфично для glibc, другие библиотеки C могут использовать другие соглашения) для обеспечения работы на старых ядрах;
- Официальные репозитории: вам, возможно, придется использовать дополнительные исправления и хаки, для версий используемых в Arch Linux (или специфичные ответвления для архитектуры), скорее всего, созданные для совместной работы;
- Документация по программному обеспечению: все программное обеспечение GNU README и NEWS файлы, документирующие такие вещи, как минимально необходимые зависимости;
- Другие дистрибутивы: они тоже делают кросс-компиляцию
- https://clfs.org описывает шаги, необходимые для построения кросс-компилятора, и упоминает несколько актуальных версий зависимостей.
Сборка кросс-компилятора
Общий подход к созданию кросс-компилятора:
- binutils: Создание cross-binutils, которая связывает и обрабатывает для целевой архитектуры
- headers: Установите набор библиотеки C и заголовками ядра для целевой архитектуры
- используйте linux-api-headers в качестве ссылки и передайте ARCH=target-architecture для make
- создать пакет заголовков libc (описан процесс для Glibc here)
- gcc-stage-1: Создайте базовый (этап 1) gcc кросс-компилятор. Будет использоваться для компиляции библиотеки C. Он не сможет построить почти еще ни чего (потому что он не может связываться с библиотекой C, которой у него нет).
- libc: Создайте библиотеку C кросс-компилятора (используя кросс-компилятор этапа 1).
- gcc-stage-2: Сборка полного кросс-компилятора C (этап 2)
Источник заголовков и libc будет отличаться для разных платформ.
Наименование пакета
В имени пакета не должно быть префикса со словом cross- (было предложено ранее, но не было принято в официальных пакетах, возможно, из-за дополнительной длины имен), и должно состоять из имени пакета с префиксом GNU triplet без поля поставщика или со значением «unknown» в поле поставщика; пример: arm-linux-gnueabihf-gcc . Если существует более короткое соглашение об именах (например, mips-gcc ), его можно использовать, но это не рекомендуется.
Размещение файлов
Последние версии gcc и binutils используют не конфликтующие пути для sysroot и библиотек. Исполняемые файлы должны быть помещены в /usr/bin/ , чтобы предотвратить возникновение конфликтов, перед всеми ними необходимо указать префикс имени архитектуры.
Правило, ./configure будет иметь по крайней мере следующие параметры:
где your_target может быть, например, «i686-pc-mingw32».
пример
Это PKGBUILD для binutils для MinGW. Вещи, на которые стоит обратить внимание:
- указание корневого каталога кросс-окружения
- использование переменных $ <_pkgname>, $ <_target>и $ <_sysroot>, чтобы сделать код более читабельным
- удаление дублированных / конфликтующих файлов
Как и почему
Почему бы не устанавливать в /opt
- Во-первых, согласно Стандарту Файловой Иерархии, эти файлы просто принадлежат /usr . И точка!
- Во-вторых, установка в /opt является последней мерой, когда другой опции нет.
What is that out-of-path executables thing?
Эта статья или раздел нуждается в переводе
This weird thing allows easier cross-compiling. Sometimes, project Makefiles do not use CC & co. variables and instead use gcc directly. If you just want to try to cross-compile such project, editing the Makefile could be a very lengthy operation. However, changing the $PATH to use «our» executables first is a very quick solution. You would then run PATH=/usr/arch/bin/:$PATH make instead of make .
Поиск проблемы
Что делать, если компиляция не удалась без четкого сообщения?
Если ошибка возникла во время выполнения configure , прочитайте $srcdir/pkgname-build/config.log . Для ошибки, произошедшей во время компиляции, прокрутите консоль, войдите в систему или найдите слово «error».
Что означает эта ошибка [error message]?
Скорее всего, вы допустили некоторые неочевидные ошибки:
- Слишком много или слишком мало флагов конфигурации. Попробуйте использовать уже проверенный набор флагов.
- Зависимости повреждены. Например, неуместные или отсутствующие файлы binutils могут привести к загадочной ошибке во время настройки gcc.
- Вы не добавили export CFLAGS=»» в свою функцию build() (см. bug 25672 в GCC Bugzilla).
- Для некоторых комбинаций —prefix / —with-sysroot может потребоваться, чтобы каталоги были доступны для записи (что не очевидно из руководства clfs).
- В sysroot нет ни заголовков ядра или libc.
- Если google не помогает, отмените текущую конфигурацию и попробуйте более стабильную/проверенную.
Почему файлы устанавливаются в неправильных местах?
Различные методы запуска make install приводят к разным результатам. Например, некоторые цели make могут не обеспечивать поддержку DESTDIR , а вместо этого требуют использования install_root . То же самое для tooldir , prefix и других подобных аргументов. Иногда предоставление параметров в качестве аргументов вместо переменных среды, например
и наоборот, может привести к различным результатам (часто вызванным рекурсивным самовывозом configure/make).
Источник
Кросс-компиляция под Linux
Введение
Что же у нас есть для кросс-компиляции? Если не считать коммерческих продуктов и мелких поделок, то для того, чтобы скомпилировать любой проект под любую платформу, понадобится Gnu Compiler Collection, или, кратко, GCC. GCC — это один большой набор исходников, но собирать из него кросс-компилятор на каждую новую целевую платформу придётся отдельно.
Надо сказать, список целевых платформ довольно внушителен.
Вообще, для того, чтобы работать с GGC надо собрать т. н. Toolchain, набор утилит для компиляции. В toolchain входит помимно GCC, ещё Binutils, предназначенные для манипуляций с объектными и бинарными файлами. Для голого железа (если планируется работать не под ОС на целевой платформы, весьма полезной будет также NewLib — сборник стандартных процедур.
Binutils
В Binutils входят:
В составе GCC большой набор разнообразных инструментов, однако, скорее всего иметь дело придётся с frontend, который так и называется, gcc. Он сам определяет тип исходного файла и вызывает соответствующий компилятор, а также, по необходимости, линковщик или библиотекарь.
NewLib
NewLib — специальная подборка стандартных функций для встраиваемых систем. Она включает в себя libc (функци работы со строками, файлами и т. д.), libm (разнообразные математические функции). Также она обладает широкими возможностями конфигурирования под разнообразные требования.
Надо сказать, NewLib далеко не единственный выбор. В принципе, если не пользоваться библиотечными функциями, можно вообще без библиотек обойтись, но этот путь сложен и тернист — стандарт си не требует наличия их в т. н. standalone environment 1) . Вполне возможно, есть другие подходящие варианты
GNU Debugger — стандартное средство отладки программ, и, в принципе, необязательно. Возможно, вы предпочтёте графический отладчик или вовсе пользуетесь исключительно printf-style-debug 2) .
Сборка Toolchain
Также стоит определить путь, куда будет всё установлено. В терминах GCC это называется prefix. По умолчанию этот путь — /usr/local . Однако по ряду различных причин иногда стоит специально указать другой. Первая причина — поставить в собственную домашнюю директорию, например, если нет root-полномочий на машине или просто его поставить только для себя (впрочем, лучше так не делать). Другая причина — бывает нужда с специальных вариантах сборки, и тогда это стоит делать, чтобы не спутать такую сборку с обычной. Стоит отметить, что компиляторы под различные платформы не перепутываются, так как имеют различные имена: gcc для ARM, например, будет именоваться arm-elf-gcc 3) или arm-linux-gcc , и именно его придётся указывать при компиляции (либо указывать target, тогда gcc сам вызовет нужный). Если же оставить путь по-умолчанию, сборка попадёт в стандартный путь поиска исполняемых файлов — /usr/local/bin , и может вызываться без специального указания пути или модификации $path .
Для указания prefix у configure есть соответствующая опция: — -prefix=…
Порядок сборки Toolchain
Сборка тулчейна в описанной конфигурации состоит из следующих этапов:
Источник
Кросс-компиляция в docker. Почему бы и нет?
Что такое кросс-компиляция? Какие есть инструменты для сборки бинарных файлов для Windows в Linux? Как настроить docker-контейнер для всего этого? Вот лишь небольшая часть вопросов, которые будут обсуждаться ниже.
Инструменты
Кросс-компиляция позволяет получить исполняемый код для платформы, отличной от той, на которой запускается этот процесс.
В рамках данной статьи рассмотрим кросс-компиляцию для платформы Windows в Linux.
Примером кросс-компилятора может служить Mingw-w64. По сути он предоствляет лишь инструмент для сборки приложения, но, если Вам необходимы сторонние библиотеки, которые не являются частью STL, придется собирать их и зависимости. Так же можно использовать готовые бинарные файлы, так как это описано в этой статье.
Упростить настройку сборки позволяет проект mxe, который предоставляет не только инструменты, но и библиотеки. С их списком можно ознакомиться на официальном сайте. При установке библиотек используется контроль зависимостей, т.е. будет установлен требуемый пакет и все необходимое для его работы. Инструменты поставляются в пред-настроенной конфигурации, например, для статической сборки 64-битных приложений. Это существенно облегчает сборку.
Среда mxe разворачивается в локальной папке пользователя. Для этого достаточно установить зависимости через пакетный менеджер и клонировать репозиторий. В корне репозитория находится Makefile, который и выполняет установку заданных в целях библиотек, добавляет инструменты для сборки и т.д.
Важно отметить, что среда сборки локализуется в пределах своей папки, это позволяет настроить индивидульную среду под каждое приложение.
Контейнеризируй это
Допустим, что сборка релиза для Windows у нас настроена на локальной машине. Релизы выходят довольно часто, в некоторых версиях добавляются новые библиотеки, а, некоторые, например, удаляются. В один прекрасный день начальник требует скинуть сборку релиза на новичка. Как ему настроить свою среду сборки? Какие библиотеки нужно взять из репозитория mxe, а для каких выполнить сборку из исходников?
На этот случай можно завести bash-скрипт, который будет разворачивать всю среду в заданной папке. И после пытаться поддерживать этот скрипт в актуальном состоянии. Но, как и документация к проекту, в один критически важный момент он может устареть.
Хорошим решением будет изолировать нашу среду для сборки внутри docker-контейнера. Сам docker-файл будет содержать самодостаточный набор инструкций по развертыванию среды, а наличие контейнера позволит избежать захламления домашней системы лишними библиотеками.
Собираем все вместе
Для демонстрации возьмем простой Qt-проект — SimpleQtProject. Этот проект собирается утилитой qmake, и состоит из одной единственной формы. Сделано это, конечно же, для простоты. Так же в папке docker лежит файл для сборки контейнера.
Рассмотрим docker-файл проекта. По сути он состоит из нескольких основных частей:
- установка зависимостей для системы сборки
- установка и настройка системы сборки
- компиляция проекта и копирование артефактов на хост-систему
Ниже рассмотрены лишь основные команды из файла, для полного ознакомления рекомендуется обратиться к репозиторию.
Пропустим первый пункт и перейдем непосредственно к установке mxe.
Клонируем репозиторий:
На момент написания статьи последним релизом был build-2019-06-02. Здесь не используется ветка мастер по простой причине: необходима повторяемость сборки. В противном случае, при добавлении новых коммитов в мастер сборка может сломаться.
Далее настраиваем систему сборки:
Данная команда добавит инструменты (экземпляры cmake и Mingw-w64 и пр.) для статической сборки проекта под 64-битную архитектуру, а после соберет с их помощью Qt.
Следующим шагом добавим в PATH путь к исполняемым файлам mxe:
После того, как среда сборки настроена, можно перейти непосредственно к последнему пункту:
Здесь следует пояснить несколько моментов. Предполагается, что при запуске контейнера, в папку /app/src/ будет смонтирована папка с исходниками, содержащая *.pro файл, а в директории /app/res/ смонтировано место, куда следует сложить результаты сборки.
Ниже приведен пример команды для создания docker-image, ее необходимо запускать в папке docker рассматриваемого проекта:
Сборка же запускается там же:
Перед выполнение команды необходимо создать папку result в директории docker для копирования результатов.
Кастомизация сборки
По умолчанию mxe предоставляет MinGW версии 5.5.0 (по крайней мере это справедливо для сборки build-2019-06-02).
Если в проекте используются новые фичи С++ 17, то такая версия компилятора неудовлетворительна. К счастью, среда сборки предоставляет более новые версии в виде отдельных плагинов. Для решения нашей задачи, необходимо в команду сборки библиотек добавить инструкцию по использованию соответствующего плагина:
Данная команда создаст комплект для статической сборки 64-битных приложений с использованием компилятора седьмой версии (7.4.0). Если такой комплект уже существует, то он изменен не будет.
Со списком всех доступных плагинов можно ознакомиться на странице.
В директории mxe/src содержатся *.mk файлы, которые описывают параметры сборки того или иного пакета. При необходимости можно внести требуемые коррективы в уже существующий пакет или добавить свой собственный. Структура файлов описана вот тут — https://github.com/mxe/mxe/wiki/Add-a-New-Package:-Full-Version.
Для копирования pзависимостей проект mxe предоставляет утилиту copydlldeps.sh. Но это не единственный полезный инструмент, с их олным списокм можно ознакомиться на странице.
CMake и статическая линковка Qt
Так сложилось, что в своем проекте я использовал Qt и систему сборки CMake. Когда было принято решение о сборке проекта для Windows, отличным решением выглядело собрать все используя статическую линковку, чтобы пользователям предоставлять один бинарь, без каких-либо зависимостей.
Разбирая целую гору ошибок линковщика, удалось выяснить, что такая сборка из коробки не работает, вообще нигде. Дело в том, что qmake при использовании статической линковки генерирует *.cpp-файл, в котором находятся инструкции по импортированию плагинов, примерно такого вида:
Так же добавляются флаги и библиотеки для этапа линковки в Makefile.
Можно попробовать поэкспериментировать вот с такой конструкцией в CMakeLists.txt:
А дальше добавить в target_link_libraries использование plugin_libs . Но для меня такой подход не принес никаких результатов.
В конце концов, я пришел к решению динамически линковать (по возможности) все внешние библиотеки и копировать вместе с исполняемым файлом еще и необходимые dll с помощью copydlldeps.sh. Более подробно про разворачивание под Qt под Windows описано в статье.
В заключении
Выше было показано, как за несколько простых шагов можно настроить среду для кросс-компиляции проекта. Но, к сожалению, в реальных условиях все не так радужно.
Хоть проект mxe предоставляет внушительный список библиотек, но все равно он может не включать тех, которые нужны именно Вам, или включать слишком новые версии. Да, есть возможность самому создать пакет или, на худой конец, собрать библиотеку из исходников. Но не все можно сбилдить кросс-компилятором, так мне не удалось сделать это с проектом cpprestsdk, потому что ему нужен установленный vcpkg.
Многие проблемы, которые могут появиться при сборке проекта кросс-компилятором, характерны для кросс-платформенной разработки вообще. Например, у меня была странная ошибка из-за элемента перечисления ERROR . Оказалось, что в одном из заголовочных файлов Windows имеется макрос с таким же именем. Его подстановка и ломала весь код.
Это дело каждого — использовать кросс-компиляцию или нет. Мне это принесло неплохой профит. Я настроил сборку под несколько дистрибутивов Linux и Windows в отдельных docker-контейнерах для своего проекта SecureDialogues, добавил один make-файл для запуска процесса поочередно для каждого контейнера. Далее запускаю make и через некоторое время получаю бинарные файлы для требуемых ОС в локальной папке.
Источник