How-to`s — Linux From Scratch. Part2. Сборка временной системы
Первая часть Linux From Scratch. Part1. Подготовка к установке
Во второй части мы соберём временную систему, где будут все необходимые инструменты для сборки LFS. Файлы, которые у нас скомпилируются на этом шаге, будут помещены в папку $LFS/tools для того, чтобы обособить их от основной системы. Сразу предупреждаю, под катом очень много букв, поэтому инструкции для каждого компонента лежит под спойлером. Третья статья будет ещё больше.
Сначала нужно узнать имя рабочей платформы. Самое простое — выполнить скрипт ./config.guess из архива binutils (он идёт почти с любыми исходниками). У меня это i686-pc-linux-gnu.
Затем нужно узнать имя динамического линкера (не путать с ld из binutils). Динамический линкер идёт вместе с glibc и автоматически подгружает необходимые библиотеки для программы. Это можно сделать при помощи следующей конструкции.
readelf -l <name of binary> | grep interpreter
Например, я выполнил
readelf -l /bin/bash | grep interpreter
и у меня получилось следующее
[Requesting program interpreter: /lib/ld-linux.so.2]
Важные примечания.
- После установки пакета, удаляйте его. Это поможет избежать проблем в будущем при новой установке данного пакета и сэкономит место.
- Используется bash
- До использования инструкций, для каждой программы нужно распаковать архивы под пользователем lfs и перейти в соответствующий каталог
Binutils. Часть 1.
Binutils предоставляет линкер, ассемблер и другие инструменты для работы с объектными файлами. Важно его ставить в первую очередь, так как gcc смотрит, какие инструменты доступны и по результатам конфигурируется . Рекомендуется осуществлять сборку в отдельном каталоге.
1 2 3 4 5 6 7 8 |
|
--target=$LFS_TGT — нужно, так как значение того, что выведет config.guess, отличается от того, что должно быть на новой системе
--prefix=/tools — устанавливаем всё в /tools
--disable-nls — интернационализация нам не нужна
--disable-werror — не нужно останавливаться, если возникнут Warnings
Если используется 64х битная архитектура, то нужно сделать следующее
1 2 3 4 5 |
|
Теперь компилируем и устанавливаем
1 2 3 4 |
|
GCC-4.4.3. Часть 1.
GCC для сборки требует пакеты gmp и mpfr.
1 2 3 4 |
tar -jxf ../mpfr-2.4.2.tar.bz2 |
Рекомендуется собирать gcc во внешнем каталоге
1 2 3 |
|
Подготавливаем к компияции
1 2 3 4 5 6 7 |
|
--disable-shared — линкуем внутренние библиотеки статически, чтобы избежать влияние системы-хоста
--disable-multilib — на x86_64 LFS не поддерживает multilib
--disable-decimal-float --disable-threads --disable-libmudflap --disable-libssp --disable-libgomp — эти опции отключают поддержку всех указанных функций, которые не нужны для сборки временной системы.
--enable-languages=c — собираем поддержку только C, другие языки сейчас не нужны
1 2 3 4 |
|
Использование опции --disable-shared означает, что файл libgcc_eh.a file не создаётся и не устанавливается, а Glibc зависит от этой библиотеки. Для этого создаём симлинк на libgcc.a, в котором есть все необходимые объекты.
1 2 3 4 |
|
Linux API Headers
Удостоверяемся, что нету никаких следов предыдущих сборок
1 2 |
|
Затем проверяем и извлекаем хедеры
1 2 3 4 5 |
|
Glibc-2.11.1
Рекомендуется собирать glibc во внешнем каталоге
1 2 |
mkdir -v ../glibc-build |
Так как Glibc больше не поддерживает i386, для компиляции 32х битной системы нужно использовать флаг -march=i486. Есть несколько способов осуществления этого, но тестирование показывает, что флаги помещаются в переменную CFLAGS. Также нужен флаг -mtune=native, что необходимо для того, чтобы сбросить значение, которое может измениться при изменении -march.
1 2 3 4 |
case `uname -m` in |
Теперь настройки
1 2 3 4 5 6 7 |
|
--host=$LFS_TGT, --build=$(../glibc-2.11.1/scripts/config.guess) — собираем, используя линкер и компилятор из /tools
--disable-profile — профиль для временных инструментов не нужен
--enable-add-ons — используем аддон NPTL как инструмент для работы с потоками
--enable-kernel=2.6.18 — поддержка ядра 2.6.18 и более поздних, более старые поддерживать не нужно.
--with-headers=/tools/include — где лежат хедеры
libc_cv_forced_unwind=yes — говорим, что есть поддержка force-unwind без запуска тестов.
libc_cv_c_cleanup=yes — аналогично указываем, что есть поддержка C cleanup handling.
Теперь ставим
1 2 3 4 |
|
Настройка toolchain
Когда установлены временные библиотеки C, все остальные инструменты из этой части должны быть линкованы с этими библиотеками. Для этого нужно, настроить файлы specs, чтобы указывался динамический линкер из /tools. Для этого делаем дамп specs компилятора в место, которое он смотрит по-умолчанию. Для этого воспользуемся заменой при помощи sed.
1 2 3 4 5 6 7 8 |
|
Теперь проверим, что у нас всё работает правильно
1 2 3 4 5 |
|
В результате должно получиться
[Requesting program interpreter: /tools/lib/ld-linux.so.2]
Потом удаляем тестовые файлы
rm -v dummy.c a.out
Binutils. Часть 2
Если сейчас binutils не собирутся, значит на каком-то из предыдущих шагов (Binutils, GCC, или Glibc) были проблемы!
1 2 3 4 5 6 7 8 9 |
|
CC="$LFS_TGT-gcc -B/tools/lib/" AR=$LFS_TGT-ar RANLIB=$LFS_TGT-ranlib — Это сделано для того, чтобы использовались именно собранные нами ранее инструменты
--with-lib-path=/tools/lib — библиотеки ищем только в /tools/lib. Это делается для того, чтобы избежать использования библиотек из хоста.
1 2 3 4 |
|
Готовим к следующей фазе
1 2 3 4 5 |
|
-C ld clean — удаляем все скомпилированные файлы в директории ld
-C ld LIB_PATH=п/usr/lib:/lib — пересобираем все в папке ld. Значение переменной указывает путь для того, чтобы переписать значение библиотек по-умолчанию.
GCC. Часть 2
Версии gcc, вышедшие после 4.3, не ищут стартовые файлы в месте, указанном в —prefix. Поэтому применим патч, который частично возвращает старое поведение.
patch -Np1 -i ../gcc-4.4.3-startfiles_fix-1.patch
Обычно, для того, чтобы исправить потенциально повреждённые хедеры, запускается скрипт fixincludes. Так как GCC-4.4.3 и Glibc-2.11.1 уже установлены и известно, что повреждений нету, скрипт не нужен. Фактически, fixincludes может загрязнить окружение для сборки, устанавливая исправленные файлы из хоста. Поэтому отключим это.
1 2 3 4 |
|
Теперь принудительно заставим использовать флаг -fomit-frame-pointer
1 2 3 4 5 |
|
Теперь заставим использовать динамический линкер из /tools
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Если используется архитектура x86_64, отключение поддержки multilib подразумевает, что gcc не пудет подключить библиотеки с хоста
1 2 3 4 5 6 7 8 9 10 |
|
Затем распаковываем mpfr, gmp, и готовимся к компиляции.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
--enable-clocale=gnu — принудительно указываем корректную модель локали для C++. Это нужно для того, чтобы собрались ABI-совместимые библиотеки.
--enable-threads=posix — Разрешает обработку пногопоточности.
--enable-__cxa_atexit — позволяет использовать __cxa_atexit для регистрации деструкторов для локальных статичких и динамических объектов.
--enable-languages=c,c++ — собираем компиляторов C и C++
--disable-libstdcxx-pch — не собираем pre-compiled header (PCH) для libstdc++. Это требует много места, да и не нужно это нам.
--disable-bootstrap — для нативных сборок gcc по-умолчанию делается "bootstrap" билд. Это заставляет компилировать несколько раз для корректности сборки. Но способ сборки LFS предоставляет достаточную надёжность, чтобы не собирать gcc несколько раз.
Собираем и устанавливаем
1 2 3 4 |
|
Затем создаём ссылку для совместимости с теми программами, которые вызывают cc вместо gcc
ln -vs gcc /tools/bin/cc
1 2 3 4 5 |
|
В результате должно получиться
[Requesting program interpreter: /tools/lib/ld-linux.so.2]
Потом удаляем тестовые файлы
rm -v dummy.c a.out
Tcl-8.5.8
Эта программа и следующие две (Expect и DejaGNU) устанавливаются для поддержки тестов для GCC и Binutils.
1 2 3 4 5 6 |
|
Делаем возможность записи, чтобы позднее удалить отладочную информацию
chmod -v u+w /tools/lib/libtcl8.5.so
ствим хедеры
make install-private-headers
и делаем необходимые ссылки
ln -sv tclsh8.5 /tools/bin/tclsh
Expect-5.43.0
Патчим, чтобы не было фальшивых фэйлов при во время запуска тестовых инструментов gcc и для того, чтобы не было бага из-за недавних изменений tcl.
1 2 3 4 |
|
Заставим принудительно использовать /bin/stty вместо /usr/local/bin/stty, которые могут быть найдены на системе-хосте.
1 2 3 4 |
|
Теперь конфигурируем
1 2 3 4 |
|
--with-tcl=/tools/lib — принудительно указываем, где у нас установлен tcl
--with-tclinclude=/tools/include — хедеры от tcl
--with-x=no — запрещаем искать Tk или библиотеки X Window
Теперь собираем и ставим
1 2 3 4 |
|
SCRIPTS="" — указывается для того, чтобы не ставились дополнительные скрипты
DejaGNU-1.4.4
1 2 3 4 5 |
|
Последней командой мы выполнили проверку результатов
Ncurses-5.7
1 2 3 |
|
--without-ada — не нужна нам поддерка языка Ада.
--enable-overwrite — ставим хедеры в /tools/include, вместо /tools/include/ncurses, чтобы все остальные программы корректно нашли их
1 2 3 4 |
|
Bash-4.1
./configure --prefix=/tools --without-bash-malloc
--without-bash-malloc — выключаем функцию разпределения памяти баша (malloc), которая может вызвать сегфолт
1 2 3 4 5 6 |
|
Bzip2-1.0.5
1 2 3 4 |
|
Coreutils-8.4
Утилиты для просмотра и изменения базовых характеристик системы
./configure --prefix=/tools --enable-install-program=hostname
--enable-install-program=hostname
— разрешение на сборку и установку бинарника hostname, который требуется перловыми инструментами для тестирования.
1 2 3 4 |
|
Так как su у нас не установится, так как нельзя сделать setuid root непривилегированным ползователем, поэтому делаем следующее.
cp -v src/su /tools/bin/su-tools
Diffutils-2.9
Утилиты для сравнение файлов и каталогов
1 2 3 4 5 |
|
Findutils-4.4.2
Утилиты для поиска файлов
1 2 3 4 5 |
|
Gawk-3.1.7
Средства манипулирования текстовыми файлами
1 2 3 4 5 |
|
Gettext-0.17
Утилиты для интернационализации и локализации
1 2 3 4 5 6 7 |
|
--disable-shared — не нужно ставить и собирать библиотеки
Grep-2.6.1
1 2 3 4 5 6 |
|
--disable-perl-regexp — убираем поддержку перловских регулярных выражений
Gzip-1.4
1 2 3 4 5 |
|
M4-1.4.14
Ставим макропроцессор
1 2 3 4 5 |
|
Make-3.81
1 2 3 4 5 |
|
Patch-2.6.1
1 2 3 4 5 |
|
Perl-5.10.1
Сначала патчим для адаптации некоторых жёстких путей к библиотекам C
patch -Np1 -i ../perl-5.10.1-libc-1.patch
Теперь конфигугируем
1 2 3 4 |
|
-Dstatic_ext='Data/Dumper Fcntl IO POSIX' — собираем только минимальный набор расширений, которые нужны для тестирования coreutils и glibc
1 2 3 4 5 6 |
|
Sed-4.2.1
1 2 3 4 5 |
|
Tar-1.23
Сначала нужно исправить баг, появившийся в последних релизах.
1 2 3 |
|
1 2 3 4 5 |
|
Texinfo-4.13a
1 2 3 4 5 |
|
А теперь получаем несколько свободного места, убирая отладочную информацию.
1 2 3 4 5 |
|
И напоследок с правами рута делаем следующее. Ведь сейчас мы залогинены под пользователем, который существует только на системе-хосте.
chown -R root:root $LFS/tools
Теперь мы готовы к следующему этапу.