27 мая 2010 г.

Собираем свой кросскомпилятор для ARM.

Для задачи портирования маленькой RT оси на SDK2.0, внутри которого какой-то ARM7, нужно собрать компилятор, который будет собирать исполняемые файлы под архитектуру ARM, работая при этом на машине с x86_64 процессором. К сожалению, в интернете практически отсутствуют руководства по сборке своего кросскомпилятора - в основном, рекомендуется использовать какие-то монстры наподобие Buildroot или crosstool-ng, которые помимо кросскомпилятора собирают еще кучу софта, мне ненужного.
Методом "научного тыка" я похоже набрел на последовательность действий, которая позволила мне наконец-то собрать для себя кросскомпилятор.

Для сборки нужны:
  • binutils - утилиты типа ar, nm и т.п.
  • gcc - он будет нашим кросскомпилятором
  • newlib - библиотека языка C, оптимизированная для использования во встраиваемых системах
Для сборки рекомендую выделить отдельный каталог, например ~/toolchain-arm, и проводить все последующие действия внутри него.
    Для начала скачиваем последнюю версию binutils отсюда. Распаковываем архив и конфигурируем исходники командой:
    ./configure --prefix=/usr/local/arm-linux/ --target=arm-elf --enable-interwork --enable-multilib --with-float=soft --disable-werror
    Затем, как обычно собираем и устанавливаем binutils. Установка будет произведена в каталог /usr/local/arm-linux. К сожалению, у меня возникли проблемы с правами доступа к подкаталогам каталога arm-linux; но они решаются запуском следующей команды в каталоге arm-linux.
    sudo find . -type d -exec chmod go+rx '{}' \;
    Исполняемые файлы будут расположены в /usr/local/arm-linux/bin. Поместим этот каталог в $PATH, чтобы иметь доступ к утилитам при сборке других программ (желательно поместить нижеследующую строку в ~/.profile и выполнить команду
    . ~/.profile):
    PATH=$PATH":/usr/local/arm-linux/bin" && export PATH
    Теперь мы можем обращаться к новым утилитам, используя префикс arm-elf: arm-elf-ar, arm-elf-nm и т.п.
    Затем, приступим к сборке кросскомпилятора и библиотеки языка C. Скачаем gcc отсюда и newlib отсюда и распакуем их. Также скачаем обновленный командой GNUARM файл t-arm-elf отсюда и заменим им файл [gcc-source-dir]/gcc/config/arm/t-arm-elf.
    Перед сборкой newlib нужно собрать урезанную версию gcc для arm, при помощи которой мы скомпилируем newlib. Затем, уже имея собранную newlib, мы скомпилируем полную версию gcc с newlib.
    Сборку gcc следует проводить в отдельном каталоге [gcc-build-dir], который не должен быть расположен внутри каталога [gcc-source-dir], иначе мы получим ошибку:
    ./gcc/libgcc.mvars: Нет такого файла или каталога
    Перейдем в [gcc-build-dir] и выполним команду:
    sudo ../[gcc-source-dir]/configure --target=arm-elf --prefix=/usr/local/arm-linux/ --enable-interwork --enable-multilib --with-float=soft --enable-languages="c,c++" --with-newlib  --with-headers=../[newlib-source-dir]/newlib/libc/include/ && sudo make && sudo make install
    Все, мы получили урезанную версию кросскомпилятора gcc для arm. Нужно перейти в каталог /usr/local/arm-linux/ и вновь (как на стадии с binutils) исправить права доступа на подкаталоги иначе на следующем шаге мы получим ошибку:
    arm-elf-gcc: error trying to exec 'cc1': execvp: Нет такого файла или каталога
    Теперь приступим к сборке newlib. Перейдем в [newlib-source-dir] и выполним команду:
    ./configure --target=arm-elf --prefix=/usr/local/arm-linux/ --enable-interwork --enable-multilib --with-float=soft
    Далее, как обычно, make и make install.
    Имея собранную newlib приступим к сборке полной версии кросскомпилятора. Перейдем в [gcc-build-dir] и выполним:
    sudo make && sudo make install
    Осталось только вновь исправить права доступа на  подкаталоги в каталоге /usr/local/arm-linux.
    Теперь все - у нас есть свой кросскомпилятор для архитектуры ARM!

    UPD (03.08.2010):
    При сборке простого хелловорлда, у меня внезапно выскочила ошибка:
    arm-elf-gcc -c -Wall -Wstrict-prototypes -Wno-trigraphs -O0 -pipe -g -mcpu=arm7tdmi main.c
    /usr/local/arm-linux/libexec/gcc/arm-elf/4.5.0/cc1: error while loading shared libraries: libmpfr.so.1: cannot open shared object file: No such file or directory
    make: *** [main.o] Ошибка 1
    Оказывается, libmpfr нужно обязательно ставить вместе с gcc. Лично я проделал это так:
    • Качаем MPFR отсюда. Распаковываем и собираем командой:
      ./configure --target=arm-elf --prefix=/usr/local/arm-linux/ && make && sudo make install
      Теперь libmpfr установлена в /usr/local/arm-linux/lib/
    • Переходим в [gcc-build-dir], удаляем оттуда все файлы и каталоги и заново конфигурируем и собираем gcc заново командой:
      sudo ../[gcc-source-dir]/configure --target=arm-elf --prefix=/usr/local/arm-linux/ --enable-interwork --enable-multilib --with-float=soft --enable-languages="c,c++" --with-newlib  --with-headers=../[newlib-source-dir]/newlib/libc/include/ --with-mpfr=/usr/local/arm-linux/lib/ --without-ppl && sudo make && sudo make install

    UPD (16.11.2011):
    Все что описано выше является ужаснейшими костылями. Есть способ проще - http://www.gnuarm.com/support.html, готовые бинарники и исходники в секции "Files".
    Если не собирается binutis и версия gcc >= 4.3, то добавить опцию --disable-werror для скрипта configure.
    Если при сборке ругается на отсутствие makeinfo, а makeinfo в системе есть - подправить переменную MAKEINFO в Makefile на /usr/bin/makeinfo.
    Для сборки insight-gdb нужен установленный bison/yacc.

    9 комментариев:

    1. . ~/.profile - напиши по-нормальному, убил 5 минут чтобы понять что за хрень)

      ОтветитьУдалить
    2. http://gnuarm.org/t-arm-elf - ссылка не работает...

      ОтветитьУдалить
    3. блин, убил 6 часов на установку тулчейна, так и не установил, то понос, то золотуха
      можешь помочь по ssh установить?

      ОтветитьУдалить
    4. Честно говоря, я даже и не подозревал, что найдется какой-нибудь маньяк, помимо меня конечно, кто рискнет сам собирать тулчейн)
      Есть более простой способ - поставить уже готовый армовский тулчейн. Например CodeSourcery G++ Lite Edition. В бесплатной версии есть все необходимые консольные утилиты - binutils, компилятор, линковщик и набор библиотек вместе с отладчиком. Скачать можно тут - http://www.codesourcery.com/sgpp/lite/arm/portal/release1592 , только нужно сначала зарегистрироваться на их сайте.

      ОтветитьУдалить
    5. блин! спасибо тебе!
      правда герои не ищут легких путей...

      ОтветитьУдалить
    6. Владимир Кисиль4 янв. 2013 г., 14:17:00

      попытался собрать gcc по вашему ману.. binutils собрлись. а вот gcc.. нет. (gcc-4.7.2 binutils-2.23 newlib-1.20.0) сначала configure затребовал gmp, mpc & mpfr. Скачал исходники, скрипт выдал make файл. sudo make и выдает ошибку. без описания, просто ошибка 1, ошибка 2. с чем может быть связано ?

      ОтветитьУдалить
    7. Данный мануал стоит воспринимать как музейную редкость. В настоящий момент по нему уже мало что соберешь - прогресс не стоит на месте.
      Рекомендую воспользоваться уже готовым кросскомпилятором CodeSourcery (которых успешно купила Mentor Graphics, оставив тулчейн бесплатным). Ну или же самостоятельно ковыряться в зависимостях gcc и выдаваемых при его сборке ошибках, в поисках своего пути...

      ОтветитьУдалить