Кросс-компиляция в OS X под Linux, с использованием инструментария crosstool-ng

от автора

В данной заметке речь пойдёт о замечательном средстве автоматизации сборки кросс-тулчейнов crosstool-ng, практически незаменимого инструмента для любого уважающего себя embedded-разработчика. Если вам приходилось по-серьёзному собирать софт из x86-linux под arm-linux, то вы наверняка слышали о нём.

В данном руководстве рассматривается не столько кросс-компиляция по архитектуре, сколько кросс-компиляция по системе — сборка под Linux в Darwin.

Disclaimer

В интернете есть несколько статей по сборке crosstool-ng под OS X, например на benmont.com и в официальном руководстве. Тем не менее, в некоторых статьях встречается множество ошибок и устаревших сведений, а в других описываются лишь общие черты. Здесь будет описан мой путь, по которому я успешно собрал toolchain в июле 2013.

Подготовка

Эта часть зависит от того, какой пакетный менеджер вы используете в OS X — MacPorts или Homebrew. Я для себя давно выбрал ports-way, так что буду писать исходя из этого.

1. Регистрозависимая файловая система

Тут всё просто, в OS X есть утилита Disk Utility, воспользуемся ей для создания нового раздела. Потребуется 5+ Гб.

2. Инструменты

Предполагается, что у вас установлен MacPorts. Установим следующие пакеты:

ncurses lzma libtool binutils gsed gawk grep gcc48 

Проверим, какие версии gcc есть в системе: sudo port select —list gcc. Нам нужна mp-gcc48 — выбираем по-умолчанию командой sudo port select —set gcc mp-gcc48.

3.Установка crosstool-ng

Собирать сам инструментарий достаточно просто, воспользуемся официальной инструкцией:

hg clone http://crosstool-ng.org/hg/crosstool-ng cd crosstool-ng ./bootstrap 

Вынужден прервать официальную инструкцию: в файле kconfig/zconf.hash.c не хватает строчки

#include <stddef.h> 

./configure \ --with-objcopy=/opt/local/bin/gobjcopy \ --with-objdump=/opt/local/bin/gobjdump \ --with-readelf=/opt/local/bin/greadelf \ --with-sed=/opt/local/bin/gsed \ --with-libtool=/opt/local/bin/glibtool \ --with-grep=/opt/local/bin/grep \ --with-install=/opt/local/bin/ginstall make sudo make install 

Это установит ct-ng в /usr/local/bin. Домашняя директория ct-ng: /usr/local/lib/ct-ng.hg+default-2685dfa9de14 в зависимости от ревизии. В этой директории отредактируем файл scripts/functions, заменив строчку для Darwin строчкой от Linux:

--- scripts/functions.orig  2013-07-09 22:15:12.000000000 +0400 +++ scripts/functions   2013-07-06 04:28:41.000000000 +0400 @@ -460,7 +460,7 @@                  mode="$(stat -c '%a' "$(dirname "${dir}")")"                  ;;              Darwin|*BSD) -                mode="$(stat -f '%Lp' "$(dirname "${dir}")")" +                mode="$(stat -c '%a' "$(dirname "${dir}")")"                  ;;              *)                  CT_Abort "Unhandled host OS $CT_SYS_OS" 

Это потому, что ct-ng случайно хавает версию gstat из GNU-набора, вместо оригинального stat из OS X. Полюбуйтесь красотой и изящностью здешнего кода и закройте файл.

Можете также скопировать скрипт ct-ng.comp для bash-completion, работает хорошо.
Теперь нужно выбрать временную папку, в которой будут коваться наш замечательный cross-toolchain и его sysroot. У меня это /Volumes/Unixen/ct-config, перейдите в вашу папку и начнём настройку.

Настройка crosstool-ng

Прежде чем начать настройку, унаследуем конфигурацию от шаблона. Нас интересует x86_64-unknown-linux-gnu:

cd /Volumes/Unixen/ct-config ct-ng x86_64-unknown-linux-gnu ct-ng menuconfig 

После этого вы видите меню, в котором мы будем настраивать наш инструментарий.

1. Paths and misc options

Здесь важно указать опции Local tarballs directory (/Volumes/Unixen/src) и Prefix directory (/Volumes/Unixen/${CT_TARGET}), не забудьте создать /Volumes/Unixen/src.

2. C compiler

Здесь я отключил поддержку Java и Fortran, потому что не знаю, как поведёт себя GCC при сборке с включёнными фичами. Обязательно отключаем [ ] Link libstdc++ statically into the gcc binary, иначе будет ошибка

collect2: error: ld returned 1 exit status ld: library not found for -lcrt0.o  

3. Debug facilities

Здесь придётся отключить поддержку dmalloc и ltrace, так как иначе будут нерешаемые проблемы. В разделе gdb следует отключить [ ] Native gdb и, если нет необходимости, отключить [*] Enable python scripting (проблема с python, но решение будет ниже). Я использую версию gdb version (7.3.1).

4. Companion libraries

Здесь строго следующие версии библиотек, иначе будут ошибки компиляции и autotools, эти версии подбирал методом тыка, зачастую помогал выбор более свежей.

      * GMP version (5.0.2)       * MPFR version (3.1.2)       * PPL version (0.11.2)       * CLooG version (0.15.11)       * MPC version (1.0.1) 

Сборка toolchain

Практически всё готово. В процессе сборки может возникнуть следующая ошибка (версия ядра указана моя):

[ERROR]    /Volumes/Unixen/ct-config/.build/src/linux-3.8.11/arch/x86/tools/relocs.c:8:17: fatal error: elf.h: No such file or directory 

Поэтому заранее позаботимся об этом, взяв elf.h из доверенного источника. Если под рукой нет, возьмите мой elf.h. Класть нужно в /usr/include.

Ещё нужно подправить лимит открытых файлов (RE: Libc iconvdata compilation problem):

ulimit -n 1024 

Если во время сборки у вас возникнет ошибка в gdb, если вы не отключили [*] Enable python scripting раньше:

configure: error: python is missing or unusable 

то отредактируйте файл .build/gdb-*/gdb/python/python-config.py, закомментировав строки

#            if getvar('LINKFORSHARED') is not None: #                libs.extend(getvar('LINKFORSHARED').split()) 

Кажется, всё готово.

ct-ng build 

На Macbook Air с i5 сборка идёт порядка 68 минут, причём у вас скорее всего в середине всплывут какие-нибудь ошибки. Так что отойти далеко от компьютера не получится.

Заключение

/Volumes/Unixen $ du -csh ct-config/

4,0G    ct-config/ 4,0G    итого 

/Volumes/Unixen $ x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-gcc -v

Using built-in specs. COLLECT_GCC=x86_64-unknown-linux-gnu/bin/x86_64-unknown-linux-gnu-gcc COLLECT_LTO_WRAPPER=/Volumes/Unixen/x86_64-unknown-linux-gnu/libexec/gcc/x86_64-unknown-linux-gnu/4.7.3/lto-wrapper Configured with: /Volumes/Unixen/ct-config/.build/src/gcc-4.7.3/configure --build=x86_64-build_apple-darwin12.4.0 --host=x86_64-build_apple-darwin12.4.0 --target=x86_64-unknown-linux-gnu --prefix=/Volumes/Unixen/x86_64-unknown-linux-gnu --with-sysroot=/Volumes/Unixen/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot --enable-languages=c,c++ ..... Target: x86_64-unknown-linux-gnu Thread model: posix gcc version 4.7.3 (crosstool-NG hg+default-2685dfa9de14)  

Можно попробовать что-нибудь собрать:

cd linux-source-3.9 export PATH=$PATH:/Volumes/Unixen/x86_64-unknown-linux-gnu/bin export C_INCLUDE_PATH=/usr/include:/opt/local/include:/Volumes/Unixen/x86_64-unknown-linux-gnu/x86_64-unknown-linux-gnu/sysroot/usr/include make ARCH=x86_64 CROSS_COMPILE=x86_64-unknown-linux-gnu- all -j4 

Успехов,
Xlab was there.

ссылка на оригинал статьи http://habrahabr.ru/post/186124/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *