пятница, 6 мая 2011 г.

Building mc for ARM - сборка mc для ARM

Итак. Для увлекательного процесса сборки нам понадобится немного ингридиентов:
  1. Кросс-компилятор и библиотеки glibc, собранные для ARM'а. Его я взял с диска, который шел с платой AT91SAM9XE512-S3E.
  2. Исходники zlib, glib, ncurses и самого mc. Где качать гуглится влет. Я, лично, качал самые последние версии исходников. Почему ncurses? Потому что кроме mc я сначала собрал редакторы joe и nano, которые требуют ncurses. Ну если есть готовый ncurses, то почему бы не воспользоваться.
Собирал я все статически, ибо при динамической линковке получались какие-то страшные косяки при запуске приложений на ARM. Я забил.

Для начала соберем ncurses. Для этого добавим путь к кросс-компилятору в переменные окружения, чтобы скрипт configure смог найти его:
export PATH=path-to-cross-compiler:$PATH
Далее переходим в папку с исходниками ncurses и делаем configure, в результате чего создастся Makefile с правильным содержимым. Чтобы содержимое было правильным. необходимо передать скрипту configure параметры:
  1. ARCH - архитектура, под которую собираем
  2. CC - кросс-компилятор, в моем случае это arm-none-linux-gnueabi-gcc
  3. CROSS_COMPILE - префикс, который добавляется ко всем кросс-тулзам, например, компилятор называется arm-none-linux-gnueabi-gcc, а линкер arm-none-linux-gnueabi-ld
  4. host - указывает, систему в которой будет работать приложение, в моем случае это arm-none-linux-gnueabi
  5. prefix - куда устанавливаются либы и приложения, когда делаем make install, про него расскажу подробнее: у меня prefix=/mnt/mmcblk0p1 - я сюда монтирую SD-карточку и на писишке и на плате с ARM. В результате не имеем проблем с путями на плате.
  6. enable-static - говорим, чтобы выдавал либы и для статической линковки
Обо всем этом можно узнать, сделав ./configure --help. В итоге получаем:
/configure ARCH=arm CC="arm-none-linux-gnueabi-gcc" CROSS_COMPILE="arm-none-linux-gnueabi-" --host=arm-none-linux-gnueabi CFLAGS=" $_XXFLAGS" --prefix=/mnt/mmcblk0p1 --enable-static=yes
После чего скрипт скажет что все в норме и готово к сборке. Далее делаем: make && make install. В директории /mnt/mmcblk0p1 появятся директории include и lib с соответствующими хидерами и либами. Ncurses готов. Далее нужна библиотека glib, для ее сборки понадобится zlib. Собираем zlib. Небольшая проблема: у zlib скрипт configure не имеет параметров CC, CROSS_COMPILE и прочих, поэтому делаем так:
export CC=arm-none-linux-gnueabi-gcc
export CROSS_COMPILE="arm-none-linux-gnueabi-"
export CC="arm-none-linux-gnueabi-gcc"
./configure --prefix=/mnt/mmvblk0p1
make

make install
Далее собираем glib. Делаем ./configure как в случае с ncurses, если что-то не так, то в помощь ./configure --help. За исключением того, что надо указать дополнительно пути к хидерам и либам для компилятора и линкера:
export CFLAGS="-I/mnt/mmcblk0p1/include -L/mnt/mmcblk0p1/lib"
export LDFLAGS="-L/mnt/mmcblk0p1/lib"

Однако тут configure скорее всего вывалится с ошибкой:
checking for EILSEQ... yes checking for glib-genmarshal... no configure: error: Could not find a glib-genmarshal in your PATH
Необходимо собрать glib у себя на писишке, тогда появятся эти несчастные генмаршалы:
zlib: ./configure --prefix=/opt
make

sudo make install
glib: ./configure --prefix=/opt
make

sudo make install
Далее делаем export PATH=/opt:$PATH, configure со всеми параметрами и опять ошибка:
checking for growing stack
pointer...
configure: error: in
`/home/vit/programs/newArm2/glib-2.24.2':
configure: error: cannot
run test program while cross compiling
See `config.log' for more
details.s

Чтобы вылечиться создаем файл arm-linux.cache с содержимым:
glib_cv_stack_grows=no
glib_cv_uscore=no
ac_cv_func_nonposix_getpwuid_r=yes
ac_cv_func_nonposix_getgrgid_r=yes 
И для configure указываем этот файл при помощи --cache-file=arm-linux.cache. После чего все должно собраться на ура. Не забываем про ключик --enable-shared=yes. Далее сборка mc, тут подводных камней не обнаружилось, кроме того что configure выдает ошибку  undefined reference 'clock_gettime', для победы над которой надо слинковать статически библиотечку librt, а также для статической линковки для configure надо указать ключик --static а не просто -static
export CFLAGS="-I/mnt/mmcblk0p1/include -I/mnt/mmcblk0p1/include/ncurses -L/mnt/mmcblk0p1/lib"
export LDFLAGS="-L/mnt/mmcblk0p1/lib"
export LIBS="-lrt"
./configure ARCH=arm CC="arm-none-linux-gnueabi-gcc" CROSS_COMPILE="arm-none-linux-gnueabi-" --host=arm-none-linux-gnueabi CFLAGS=" --static $_XXFLAGS" --prefix=/mnt/mmcblk0p1 --with-screen=ncurses --with-ncurses-includes=/mnt/mmcblk0p1/include --with-ncurses-libs=/mnt/mmcblk0p1/lib/libncurses.a --without-x GLIB_CFLAGS="-I/mnt/mmcblk0p1/include/glib-2.0 -I/mnt/mmcblk0p1/lib/glib-2.0/include" GLIB_LIBS="/mnt/mmcblk0p1/lib/libglib-2.0.a" GMODULE_CFLAGS="-I/mnt/mmcblk0p1/include/glib-2.0 -I/mnt/mmcblk0p1/lib/glib-2.0/include" GMODULE_LIBS="/mnt/mmcblk0p1/lib/libgmodule-2.0.a" --with-subshell
make

make install
Как-то так. В общем ничего особенного. Man, google и ./configure --help в помощь. За правильность всего не ручаюсь. 

ЗЫ. Редактор постов сегодня по-особенному тупит (

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

  1. Мего полезная вещь!
    Как раз сейчас в процессе изучения процесса компиляции программ под АРМ Линукс

    ОтветитьУдалить
  2. Этот комментарий был удален автором.

    ОтветитьУдалить
  3. Надо попробовать для андроида так собрать, а то голый shell уныл до невозможности.

    (починил)

    ОтветитьУдалить
  4. а как же сборка glib обходится без libffi?

    ОтветитьУдалить
  5. да вот как-то не знаю, собралось так

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