В данной заметке речь пойдёт о замечательном средстве автоматизации сборки кросс-тулчейнов 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.
Автор: Xlab