Cross-compiling tools package guidelines (Русский) - ArchWiki

Jump to content
From ArchWiki
Состояние перевода: На этой странице представлен перевод статьи Cross-compiling tools package guidelines. Дата последней синхронизации: 5 октября 2023. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Данная статья описывает создание пакетов с инструментами для кросс-компиляции. Другим способом кросс-компиляции является использование distcc на смешанных архитектурах. Смотрите distcc#Cross compiling with distcc.

Совет: В качестве альтернативы для создания кросс-компиляторных пакетов вы можете использовать crosstool-ng и создать свой собственный набор инструментов полностью автоматизированным способом. crosstool-ng доступен в пакете crosstool-ng.

## Важная заметка

На этой странице описан новый принцип работы, основанный на следующих пакетах:

- 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://trac.clfs.org описывает шаги, необходимые для сборки кросс-компилятора, и упоминает несколько актуальных версий зависимостей.

## Сборка кросс-компилятора

Общий подход к созданию кросс-компилятора:

1. binutils: Создание cross-binutils, которая связывает и обрабатывает для целевой архитектуры
2. headers: Установите набор библиотеки C и заголовками ядра для целевой архитектуры
   1. используйте linux-api-headers в качестве образца и передайте `ARCH=target-architecture` для make
   2. создайте пакет заголовков libc (для Glibc процесс описан здесь)
3. gcc-stage-1: Создайте базовый (этап 1) gcc кросс-компилятор. Будет использоваться для компиляции библиотеки C. Он не сможет собирать почти что угодно другое (потому что он не сможет слинковаться с библиотекой C, которой на данном этапе ещё нет).
4. libc: Соберите библиотеку C (используя кросс-компилятор из этапа 1).
5. gcc-stage-2: Сборка полного кросс-компилятора C (этап 2)

Источник заголовков и libc будет отличаться для разных платформ.

Совет: Точная процедура может сильно варьироваться в зависимости от ваших потребностей. Например, если вы хотите создать «клон» системы Arch Linux с теми же версиями ядра и glibc, вы можете пропустить сборку заголовков и передать `--with-build-sysroot=/` в `configure`.

## Наименование пакета

В имени пакета не должно быть префикса со словом `cross-` (было предложено ранее, но не было принято в официальных пакетах, возможно, из-за дополнительной длины имен), и должно состоять из имени пакета с префиксом GNU triplet без поля поставщика или со значением "unknown" в поле поставщика; пример: `arm-linux-gnueabihf-gcc`. Если существует более короткое соглашение об именах (например, `mips-gcc`), его можно использовать, но это не рекомендуется.

## Размещение файлов

Последние версии gcc и binutils используют не конфликтующие пути для sysroot и библиотек. Исполняемые файлы должны быть помещены в `/usr/bin/`, чтобы предотвратить возникновение конфликтов, перед всеми ними необходимо указать префикс имени архитектуры.

Как правило, `./configure` будет иметь по крайней мере следующие параметры:

    _target=your_target
    _sysroot=/usr/lib/${_target}
    ...
    ./configure \
        --prefix=${_sysroot} \
        --sysroot=${_sysroot} \
        --bindir=/usr/bin

где `your_target` может быть, например, "i686-pc-mingw32".

## Пример

Это PKGBUILD для binutils для MinGW. Вещи, на которые стоит обратить внимание:

- указание корневого каталога кросс-окружения
- использование переменных `${_pkgname}` , `${_target}` и `${_sysroot}` , чтобы сделать код более читабельным
- удаление дублированных / конфликтующих файлов

    # Maintainer: Allan McRae <allan@archlinux.org>

    # cross toolchain build order: binutils, headers, gcc (pass 1), w32api, mingwrt, gcc (pass 2)

    _target=i686-pc-mingw32
    _sysroot=/usr/lib/${_target}

    pkgname=${_target}-binutils
    _pkgname=binutils
    pkgver=2.19.1
    pkgrel=1
    pkgdesc="MinGW Windows binutils"
    arch=('i686' 'x86_64')
    url="http://www.gnu.org/software/binutils/"
    license=('GPL')
    depends=('glibc>=2.10.1' 'zlib')
    options=('!libtool' '!distcc' '!ccache')
    source=(http://ftp.gnu.org/gnu/${_pkgname}/${_pkgname}-${pkgver}.tar.bz2)
    md5sums=('09a8c5821a2dfdbb20665bc0bd680791')

    build() {
      cd ${srcdir}/${_pkgname}-${pkgver}
      mkdir binutils-build && cd binutils-build

      ../configure --prefix=${_sysroot} --bindir=/usr/bin \
        --with-sysroot=${_sysroot} \
        --build=$CHOST --host=$CHOST --target=${_target} \
        --with-gcc --with-gnu-as --with-gnu-ld \
        --enable-shared --without-included-gettext \
        --disable-nls --disable-debug --disable-win32-registry
      make
      make DESTDIR=${pkgdir}/ install

      # clean-up cross compiler root
      rm -r ${pkgdir}/${_sysroot}/{info,man}
    }

Примечание: Во время сборки инструментария всегда выполняйте команды `configure` и make в отдельном каталоге (out-of-tree compilation) и удаляйте весь каталог `src` после малейшего изменения в PKGBUILD.

## Как и почему

### Почему бы не устанавливать в /opt

Две причины:

1. Во-первых, согласно File Hierarchy Standard, эти файлы просто должны быть в `/usr`. И точка!
2. Во-вторых, установка в `/opt` является крайней мерой, когда других вариантов нет.

### Что за "out-of-path executables"?

Размещение исполняемых файлов за пределами path — эта такая странная штука, которая облегчает кросс-компиляцию. В некоторых проектах Makefile не использует `CC` и другие подобные переменные, а вместо них напрямую используют gcc. Если вы просто хотите попробовать выполнить кросс-компиляцию такого проекта, то редактирование Makefile может оказаться весьма долгой операцией. Однако изменение `$PATH` на использование в первую очередь «наших» исполняемых файлов — очень быстрое решение. Вместо простого `make` можно запустить что-то вроде `PATH=/usr/архитектура/bin/:$PATH 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.
- Если вдумчивое гугление не помогает, отмените текущую конфигурацию и попробуйте более стабильную/проверенную.

### Почему файлы устанавливаются в неправильных местах?

Различные методы запуска `make install` приводят к разным результатам. Например, некоторые цели make могут не обеспечивать поддержку `DESTDIR`, а вместо этого требуют использования `install_root`. То же самое для `tooldir`, `prefix` и других подобных аргументов. Иногда предоставление параметров в качестве аргументов вместо переменных окружения, например

    ./configure CC=arm-elf-gcc

вместо

    CC=arm-elf-gcc ./configure

и наоборот, может привести к различным результатам (часто вызванным рекурсивным самовывозом configure/make).

## Смотрите также

- https://wiki.osdev.org/GCC_Cross-Compiler

Category:

- Arch package guidelines (Русский)