LINUX.ORG.RU

Нужна помощь в построении cross-compilation toolchain


0

0

Мучался три дня, зашел в тупик (кончились идеи). Очень много позаимствовано из CLFS, но у них немного другая цель и поход. Итак,

Дано - i686-Athlon64 с LFS на борту, i586-Pentium-200 без ничего.

Хочется - Научиться технике кросс-компиляции, в качестве побочного эффекта сделать шуструю роутерообразную машину из Pentium-200.

План - Скомпилировать систему для i586 по кусочкам на A64, вставить жесткий диск от P-200, ну и дальше по порядку (an easy part): разбить на разделы, отформатировать, создать дерево каталогов, записать основные конфиги, скопировать скомпилированное ПО (в бинарниках), записать загрузчик. Загвоздка собственно состоит в первой части (кросс-компиляции). По результатам гугления сложилось определенное понимание того как это нужно делать, но на практике я это воплотить так и не смог, возможно из-за мелких просчетов, возможно дело в неправильно понятом концепте в целом. Я попытаюсь внятно изложить процесс как я его понимаю, от All прошу его прокомментировать и/или кинуть полезной ссылкой.

---

Компилятор (в моем случае gcc) создает байткод только для той архитектуры, для которой он был собран - опцией --target. Для сборки софта также необходимо иметь binutils, standart c library (glibc) + заголовочные файлы. Таким образом, если у меня получится соединить эти компоненты (gcc+binutils+glibc+headers), запускающиеся на --host=i686 и собирающие код для --target=i386 (знающие о формате исполняемых файлов и библотек на i386) я получу желаемый toolchain. Затем, при сборке софта, нужно будет либо задавать переменную окружения CC=i386-pc-linux-gnu (для использования соответствующего компилятора), либо передавать configure ключ --host=i386-pc-linux-gnu (как показатель того что собираемая софтина будет запускаться на i386).

Теперь мои действия:

anonymous

1) Toolchain будет находиться в /opt/cross-i386.

2) Linux-headers. Слышал, что многие не рекомендуют использовать "сырые" хэдеры из ванильного ядра. Насколько это верно? Насколько критична разница в версиях между ними и работающим ядром? Anyways, я беру sanitized-kernel-headers-2.6.17 от проекта CLFS. Располагаю часть из них так: /opt/cross-i386/i386-pc-linux-gnu/include/{asm,asm-generic,linux}. asm берется из linux-headers/include/asm-i386 как соответствуюший целевой архитектуре.

3) Binutils-2.17. Должны установиться в /opt/cross-i386 с поддержкой i386, configure такой: configure --prefix=/opt/cross-i386 --target=i386-pc-linux-gnu --enable-shared. Не уверен нужен ли последний ключ.

4) GCC-4.1.1. Устанавливаются в два шага - первый раз - когда не установлено glibc, второй - когда установлено (и собрано gcc, скомпилированным в первый раз, далее). Ставится в /opt/cross-i386, компилируется для сборки кода для i386. Пока без хэдеров, с единственным языком "С" (быстрее), без threads (нет glibc), без shared (не понимают почему, не хочет собираться). Итого: configure --prefix=/opt/cross-i386 --target=i386-pc-linux-gnu --disable-shared --disable-threads --enable-languges=c --without-headers

5) Glibc-2.4. Самая непонятная часть. Итак, есть gcc+binutils+headers, собирающие код для целевой архитектуры, ими собирается glibc. AFAIU, glibc не принимает опции --target, однако это и не требуется, т.к. configure передается CC=i386-pc-linux-gnu, с помощью чего и компилируется нужный код. Glibc также нужно передать путь к нашим кернел-хедерам (/opt/cross-i386/i386-pc-linux-gnu/include). Glibc также отказывается собираться, если в config.cache не будет следующих строк (спасибо clfs): libc_cv_forced_unwind=yes и libc_cv_c_cleanup=yes. Все вместе - CC=i386-pc-linux-gnu-gcc ../glibc-2.4/configure --prefix=/opt/cross-i386 --with-headers=/opt/cross-i386/i386-pc-linux-gnu/include --enable-add-ons --cache-file=config.cache --with-tls --with-__thread. Значение двух последних опций тоже туманно, очевидно они нужны чтобы была поддержка nptl :) (опять же, копипаст из clfs). Glibc не собиралось, пока не была отучена от линковки с libgcc_eh. Устанавливается так - make install_root=/opt/cross-i386/i386-pc-linux-gnu prefix="" install (это правильно?)

6) Завершающая стадия, и здесь я обламываюсь - нормальный gcc, слинкованный с правильными glibc. Все то же что и в 4), только с большим количеством фич: configure --prefix=/opt/cross-i386 --target=i386-pc-linux-gnu --enable-shared --enable-languages=c,c++ --enable-__cxa_atexit --enable-c99 --enable-long-long --enable-threads=posix. Облом такой: /opt/cross-i386/bin/i386-pc-linux-gnu-ld: cannot find /lib/libc_nonshared.a. Дальше я не знаю что делать, т.к. предыдущие шаги вроде бы верные, и на этом шаге нет никаких экзотических флагов... Не знаю в каком направлении двигаться дальше, нужна поддержка.

anonymous
()
Ответ на: комментарий от welkam

io [~] $ host operwrt.org Host operwrt.org not found: 3(NXDOMAIN)

anonymous
()
Ответ на: комментарий от welkam

Кароче, неправильный адрес :) Может openwrt.org? По-моему это немного не то, см. праймари гоал - "Научиться технике кросс-компиляции"

anonymous
()
Ответ на: комментарий от MKuznetsov

> http://www.scratchbox.org/

ОК, почитаю, но, все-равно, мне больше нравится подход ребят из CLFS - решать задачу, используя стандартные компоненты, стандартным же образом. Топик все-равно в силе :)

anonymous
()

Я бы на твоём месте пошёл по пути CLFS, тщательно аргументируя отклонения от неё, особенно здесь, на начальном этапе. К сожалению, особо помочь не могу, так как сам плаваю в этих вопросах, но думаю, что проблему можно исправить так:

1. На шаге 3 следует добавить ключ --with-lib-path=/opt/cross-i386/lib - тогда новые программы будут стараться линковаться в эту директорию. Не забудь выставить окружение как указано тут: http://cross-lfs.org/view/svn/x86/final-preps/settingenvironment.html (особенно `set +h' и $PATH).

2. Перед сборкой второго gcc (на 6м шаге) с той же целью, что и в п.1 следует исправить spec-файлы gcc так, как это описано тут: http://www.linuxfromscratch.org/lfs/view/development/chapter05/adjusting.html (ищи команду, начинающуюся на gcc -dumpspecs) и тут: http://cross-lfs.org/view/svn/x86/cross-tools/gcc-final.html (здесь это первый накладываемый патч). Только учти, что у тебя другой путь к библиотекам.

3. После сборки тулчейна не забудь вернуть всё на место: http://cross-lfs.org/view/svn/x86/final-system/adjusting.html.

И ещё, ты уверен, что на пятом шаге ключи --host и --build, предложенные в CLFS тут: http://cross-lfs.org/view/svn/x86/cross-tools/glibc.html, не нужны?

Jini ★★
()
Ответ на: комментарий от Jini

Здорово, спасибо, про lib-path и spec похоже на правду. Я думаю именно поэтому не собирался второй gcc.

> И ещё, ты уверен, что на пятом шаге ключи --host и --build, предложенные в CLFS тут: http://cross-lfs.org/view/svn/x86/cross-tools/glibc.html, не нужны?

Точно, спасибо за наводку. У glibc нет --target, но программы, собирающиеся для целевой платформы должны линковаться на хосте с библиотекой корректного формата (сильно сомневаюсь что правильно говорю, но точно правильно передавать --host=$TARGET)

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()

Раньше тоже собирал тулчейны руками, потом стал генту юзать, а там есть скрипт crossdev, сейчас только им собираю. Конечно, лучше сначала разобраться, руками пособирать. Можешь посмотреть этот скрипт, он небольшой.

Zmacs
()

Поставь генту и crossdev и нееби моск себе и людям. Нафи нужен тебе этот гемор?

imp ★★
()
Ответ на: комментарий от anonymous

Посмотрю, спасибо. Только дело в том что я уже собрал :) Правильно или нет - узнаю когда соберу систему для первого пня. Сейчас в наличие свободного времени пытаюсь собрать glibc, пока не очень успешно в аспекте финального расположения откомпиленных файлов + hard-coded pathes неверные (если интересно - недавний топик в General). Если все получится - отпишусь, возможно напишу мини-статью, пока же помолчу :)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.