Перед сборкой тулчейна стоит предварительно поискать патчи для целевой архитектуры в других дистрибутивах — gcc и другие инструменты часто бывают весьма недружелюбны к сборщикам кросс-тулчейнов. Также стоит просмотреть патчи, пролетающие в списке рассылки slind-devel@ — некоторые из них могут быть ещё не интегрированы в upstream.
GNU тулчейн собирается с помощью длительной и мучительной процедуры бутстрапа, в которой последовательно собираются следующие инструменты/библиотеки:
В разных дистрибутивах для автоматизации этого процесса используются различные утилиты (например, известный crosstool).
В Slind тулчейн собирается с помощью утилиты mktpkg(1) из пакета toolchain-package. Она имеет два режима работы:
Сборка из source-пакетов привязана к версиям пакетов из apt-репозитория Slind и поэтому неудобна при экспериментах с новой архитектурой. Проще воспользоваться вторым вариантом. Для его включения надо (как очевидно) удалить директорию /var/lib/slind-maint. Если простой запуск mktpkg <your-arch> проходит успешно, и в результате его работы в системе оказывается your-gnu-triple-cc и прочие кросс-инструменты, то можно радоваться и дальше не читать.
Для сборки тулчейна в /usr/src устанавливаются следующие пакеты: binutils-source, glibc-source, linux-kernel-headers-source, gcc-source. Они представляют из себя обычные source Debian-пакеты, распакованные на файловой системе.
В качестве примерного списка работы можно привести бутстрап архитектуры armel.
Slind хранит исходники в git и предоставляет утилиту grasp(1) для работы с репозиториями на git.slind.org. Для отправки патча достаточно вытащить исходники с помощью команды grasp getpkg <pkgname>, наложить изменения, закоммитить и отправить в список рассылки с помощью git-format-patch(1) и git-send-email(1).
Для кросс-сборки в Slind используется обычный Debian-овый инструмент dpkg-buildpackage, слегка дополненный необходимыми для кросскомпиляции вещами (установка верного CC, вызов нужного strip(1) и так далее). Для кросс-сборки достаточно создать source-пакет (grasp build <pkgname> для пакетов с git.slind.org или dpkg-source -b <dir> для пакетов, распакованных на файловой системе) и запустить сборку с помощью dpkg-buildpackage -us -uc -rfakeroot -a<yourarch>.
Начиная с этой части, я полагаю, что читатель прочитал пользовательскую документацию на Slind и немножко поигрался с уже имеющимися тулчейнами.
Две части Debian architecture (“linux” и “i386” в “linux-i386”, сокращаемом до “i386”) будут называться Debian system name и Debian CPU name соответственно.
Debian-овские инструменты используют Debian architecture для определения архитектуры, утилиты из GNU toolchain — GNU triple. Поэтому мы начнём с объяснения dpkg того, что существует новая архитектура и она соответствует определённой GNU triple.
Для определения и преобразования архитектур в dpkg существует утилита dpkg-architecture. Список известных ей архитектур она берёт из файла /usr/share/dpkg/archtable, состоящего из двух колонок: GNU triple и Debian architecture.
К сожалению, первая колонка в этом файле тупо игнорируется, так что вписываем в неё ту GNU triple, которую мы хотим получить (для сохранения единообразия вида файла), во вторую — Debian architecture, на которую мы портируем, и займёмся получением GNU triple из архитектуры другим путём :)
Контролировать достижение этой цели мы будем запуском dpkg-architecture -a<arch> -qDEB_HOST_GNU_TYPE.
В файле /usr/share/dpkg/cputable описано соответствие Debian architecture -> GNU CPU name. Добавьте туда свою архитектуру и GNU CPU name, если их там ещё нет.
Если в файле /usr/share/dpkg/ostable выбранной Debian system name соответствует правильный GNU name (например, “linux” -> “*-linux-gnu”), то его трогать не надо. Если же Debian system name отсутствует, то его надо туда добавить, с соответствующим суффиком GNU triple.
В сложных случаях Debian system name может оказаться недостаточно для генерации двух последних частей GNU triple — например, для архитектуры armel необходимо получить GNU triple arm-linux-gnueabi, хотя для этой архитектуры Debian system name — “linux”. Для решения этой проблемы с armel мне пришлось написать патч на dpkg, добавляющий новый файл /usr/share/dpkg/oscputable, в который и вписываются Debian system name, Debian CPU name и целевая GNU triple.
К этому моменту dpkg-architecture -a<arch> -qDEB_HOST_GNU_TYPE должен выдавать нужный GNU triple. Также стоит проверить, что dpkg-architecture -a<arch> не сломался — для переменных DEB_BUILD_* выдаются Debian architecture и GNU triple хоста, а для DEB_HOST_* — искомые architecture/triple target-машины.
dpkg-cross — инструмент для кросс-сборки (обёртка вокруг dpkg-buildpackage) и конверсии пакетов из собранных для target-платформы в кросс-пакеты для host-платформы (foo-dev_1.0_armel.deb -> foo-cross-armel-dev_1.0_i386.deb). Ему тоже нужно объяснить о существовании новой архитектуры.
dpkg-cross необходимо решать следующие задачи: распознавать архитектуру бинарных файлов (для этого используются регекспы, матчащие вывод file(1)) и находить кросс-инструмент для сборки. Кросс-инструменты в тулчейне GNU отличаются от нативных наличием префикса (например, “arm-linux-gnueabi-ld”).
Знание обо всём этом у dpkg-cross сосредоточено в /usr/share/perl5/dpkg-cross.pl. В нём необходимо обновить хэш-таблицы %archtable (debian architecture -> GNU triple), %archdetecttable (debian architecture -> регэксп распознавания файла с помощью file(1)), crossprefixtable (debian architecture -> префикс(ы) GNU-инструментов).
Если вас не интересует embedded и кросс-компиляция — можете смело пропускать весь цикл :)
Я недавно собрал тулчейн для ARM EABI для Slind. По просьбам будущих портеров начинаю документировать раскопанные вещи и набитые в данном процессе шишки.
Каждой комбинации архитектуры компьютера, ABI и операционной системы в Debian присваивается “debian architecture” — строка вида “<os>-<cpu/abi>”. Например, “linux-armel”, “linux-arm” или “kfreebsd-i386”. “linux-” разрешается опускать, и поэтому архитектуры для linux часто записывают в виде “hppa”, “arm” или “armel”.
Сочетание CPU/ABI — вещь интересная. Для ARM существует два несовместимых ABI: OABI и EABI, поэтому необходимо различать пакеты, собранные одним или другим способом. В Debian решили добавлять признак ABI к имени CPU: “arm” означает little-endian ARM CPU и OABI, “armel” — little-endian ARM CPU и EABI. Существовавший когда-то big-endian ARM CPU OABI порт назывался “armeb”, а какое название выберут для big-endian ARM CPU EABI, если такой появится — пока непонятно.
GNU autotools используют другой способ задания архитектуры: тройку <cpu>-<kernel>-<os>.
В терминологии GNU triple ABI относится к операционной системе. Таким образом, Debian architecture “linux-arm” (или просто “arm”) соответствует тройка “arm-linux-gnu”, “armel” — “arm-linux-gnueabi”, “armeb” — “armeb-linux-gnu”, “kfreebsd-i386” — “i486-kfreebsd-gnu” (GNU использует i486 для обозначения CPU, там, где Debian использует i386).