From 2203e654b389586650d553251b04544a34f189bf Mon Sep 17 00:00:00 2001 From: Sn4il Date: Mon, 2 Sep 2024 15:54:35 +0300 Subject: LFS 12.2 --- lfs-12.2-sysv/partintro/toolchaintechnotes.html | 738 ++++++++++++++++++++++++ 1 file changed, 738 insertions(+) create mode 100644 lfs-12.2-sysv/partintro/toolchaintechnotes.html (limited to 'lfs-12.2-sysv/partintro/toolchaintechnotes.html') diff --git a/lfs-12.2-sysv/partintro/toolchaintechnotes.html b/lfs-12.2-sysv/partintro/toolchaintechnotes.html new file mode 100644 index 0000000..a94c80e --- /dev/null +++ b/lfs-12.2-sysv/partintro/toolchaintechnotes.html @@ -0,0 +1,738 @@ + + + + + + Технические примечания по сборочным инструментам + + + + + + + + +

+ ii. Технические примечания по + сборочным инструментам +

+
+

+ В этом разделе объясняются причины и некоторые технические детали, + лежащие в основе сборки пакетов. Не обязательно сразу понимать все, + что содержится в этом разделе. Большая часть этой информации станет + более понятной после выполнения фактической сборки. Возвращайтесь и + перечитывайте этот раздел в любое время по ходу сборки. +

+

+ Основная задача Глава 5 и Глава 6 + состоит в том, чтобы создать временную область, содержащую заведомо + исправный набор инструментов, которые можно изолировать от + хост-системы. Использовании команды chroot в последующих главах, + обеспечит чистую и безотказную сборку целевой системы LFS. Процесс + сборки разработан таким образом, чтобы свести к минимуму риски для + новых читателей и в то же время обеспечить наибольшую образовательную + ценность. +

+

+ Сборка инструментария основана на процессе кросс-компиляции. Кросс-компиляция обычно + используется для сборки компилятора и его инструментов для машины, + отличной от той, которая используется для сборки. Строго говоря, это + не требуется для LFS, так как машина, на которой будет работать новая + система, та же, что и используемая для сборки. Но у кросс-компиляции + есть большое преимущество, заключающееся в том, что все, что + подвергается кросс-компиляции, не будет зависеть от окружения хоста. +

+
+

+ О кросс-компиляции +

+
+ [Примечание] +

+ Примечание +

+

+ Книга LFS не является руководством и не содержит общего + руководства по созданию кросс (или собственного) тулчейна. Не + используйте команды из книги для кросс-тулчейна, который + планируете использовать для каких-либо других целей, кроме + создания LFS, если у вас нет полного понимания, что вы делаете. +

+
+

+ Кросс-компиляция включает в себя некоторые концепции, которые сами + по себе заслуживают отдельного раздела. Хотя этот раздел можно + пропустить при первом чтении, возвращение к нему позже будет + полезно для полного понимания процесса. +

+

+ Давайте определим некоторые термины, используемые в этом контексте. +

+
+
+
+ сборщик +
+
+

+ это машина, на которой мы собираем программы. Обратите + внимание, что этот компьютер упоминается как «хост» в других + разделах. +

+
+
+ хост +
+
+

+ это машина/система, на которой будут выполняться встроенные + программы. Обратите внимание, что используемое здесь значение + слова «хост» отличается от того, которое + применяется в других разделах. +

+
+
+ цель +
+
+

+ используется только для компиляторов. Это машина, для которой + компилятор создает код. Он может отличаться как от + «сборщика», так и от «хоста». +

+
+
+
+

+ В качестве примера представим следующий сценарий (иногда называемый + «канадским + крестом»): у нас есть компилятор на медленной машине, + назовем ее машиной A и компилятор ccA. У нас также есть быстрая + машина (B), но без компилятора, и мы хотим создать код для другой + медленной машины (C). Чтобы собрать компилятор для машины C, у нас + будет три этапа: +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Этап + + Сборщик + + Хост + + Цель + + Действие +
+ 1 + + A + + A + + B + + Сборка кросс-компилятора cc1 с использованием ccA на машине + A +
+ 2 + + A + + B + + C + + Сборка кросс-компилятора cc2 с использованием cc1 на машине + A +
+ 3 + + B + + C + + C + + Сборка компилятора ccC с использованием cc2 на машине B +
+
+

+ Затем все другие программы, необходимые для машины C, могут быть + скомпилированы с помощью cc2 на быстрой машине B. Обратите + внимание, что до тех пор, пока B не может запускать программы, + собранные для C, нет способа протестировать программы, пока не + будет запущена сама машина C. Например, чтобы запустить набор + тестов на ccC мы можем добавить четвертый этап: +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Этап + + Сборщик + + Хост + + Цель + + Действие +
+ 4 + + C + + C + + C + + Пересобрать и протестировать ccC, используя ccC на машине C +
+
+

+ В приведенном выше примере только cc1 и cc2 являются + кросс-компиляторами, то есть они создают код для машины, отличной + от той, на которой они выполняются. Компиляторы ccA и ccC создают + код для машины, на которой они выполняются. Такие компиляторы + называются нативными + компиляторами. +

+
+
+

+ Реализация кросс-компиляции + для LFS +

+
+ [Примечание] +

+ Примечание +

+

+ Все кросс-компилируемые пакеты в этой книге используют систему + сборки на основе autoconf. Система сборки на основе autoconf + принимает типы систем вида cpu-vendor-kernel-os, называемые + системным триплетом. Поскольку поле vendor часто не содержит + значения, autoconf позволяет вам опустить его. +

+

+ Проницательный читатель может задаться вопросом, почему название + «триплет» + применяется к имени из четырех компонентов. Поле kernel и поле os + ранее применялись как единый элемент: «system». Такая форма с + тремя полями все еще актуальна для некоторых систем, например, + x86_64-unknown-freebsd. Но две + системы могут использовать одно и то же ядро и все же быть + слишком разными, чтобы использовать одинаковый триплет для их + описания. Например, Android, работающий на мобильном телефоне + полностью отличается от Ubuntu, работающей на ARM64 сервере, хотя + они оба работают на одном и том же типе процессора (ARM64) и с + одним ядром (Linux). +

+

+ Без слоя эмуляции вы не сможете запустить исполняемый файл c + сервера на мобильном телефоне и наоборот. Итак, поле «system» было разделено + на поля kernel и os, чтобы однозначно их интерпретировать. В + нашем примере Android обозначается как aarch64-unknown-linux-android, а Ubuntu + aarch64-unknown-linux-gnu. +

+

+ Слово «триплет» сохранилось в лексиконе. Простой + способ определить триплет вашей машины — запустить скрипт + config.guess, + который входит в исходный код многих пакетов. Распакуйте + исходники binutils и запустите скрипт: ./config.guess, обратите + внимание на вывод. Например, для 32-разрядного процессора Intel + вывод будет i686-pc-linux-gnu. В 64-битной системе + это будет x86_64-pc-linux-gnu. В большинстве + систем Linux используют еще более простую команду gcc -dumpmachine, которая + предоставит вам аналогичную информацию. +

+

+ Вы также должны знать имя динамического компоновщика платформы, + часто называемого динамическим загрузчиком (не путать со + стандартным компоновщиком ld, который является частью + binutils). Динамический компоновщик, предоставляемый glibc, + находит и загружает общие библиотеки, необходимые программе, + подготавливает программу к запуску, а затем запускает ее. Имя + динамического компоновщика для 32-разрядной машины Intel — + ld-linux.so.2, а для 64-разрядных + систем — ld-linux-x86-64.so.2. + Надежный способ определить имя динамического компоновщика — + проверить случайный двоичный файл из хост-системы, выполнив + следующую команду: readelf -l + <имя исполняемого файла> | grep interpreter + и зафиксировать результат. Официальный источник, охватывающий все + платформы, находится на вики-странице + Glibc. +

+
+

+ Чтобы сымитировать кросс-компиляцию в LFS, имя триплета хоста + немного подкорректировали, изменив поле "vendor" в переменной + LFS_TGT таким образом, чтобы оно + указывало "lfs". Мы также используем параметр --with-sysroot при сборке + кросс-компоновщика и кросс-компилятора, чтобы сообщить им, где + найти необходимые файлы хоста. Это гарантирует, что ни одна из + программ, входящих в Глава 6, + не сможет ссылаться на библиотеки на машине сборки. Для корректной + работы, обязательны всего два этапа, еще один рекомендуется для + тестирования: +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Этап + + Сборщик + + Хост + + Цель + + Действие +
+ 1 + + ПК + + ПК + + LFS + + Сборка кросс-компилятора cc1 с использованием cc-pc на ПК +
+ 2 + + ПК + + LFS + + LFS + + Сборка компилятора cc-lfs с использованием cc1 на ПК +
+ 3 + + LFS + + LFS + + LFS + + Пересборка и тестирование cc-lfs, используя cc-lfs в lfs +
+
+

+ В приведенной выше таблице «ПК» означает, что команды выполняются на + компьютере с использованием уже установленного дистрибутива. + «В lfs» + означает, что команды выполняются в chroot-окружении. +

+

+ Это еще не конец истории. Язык С - это не просто компилятор; также + он определяет стандартную библиотеку. В этой книге используется + библиотека GNU C под названием glibc (есть альтернативный вариант - + "musl"). Эта библиотека должна быть скомпилирована для машины lfs, + то есть с использованием кросс-компилятора cc1. Но сам компилятор + использует внутреннюю библиотеку, реализующую сложные инструкции, + недоступные в наборе инструкций ассемблера. Эта внутренняя + библиотека называется libgcc, и для полноценной работы ее + необходимо связать с библиотекой glibc! Кроме того, стандартная + библиотека для C++ (libstdc++) также должна быть связана с glibc. + Решение этой проблемы курицы и яйца состоит в том, чтобы сначала + собрать деградированную libgcc на основе cc1, в которой отсутствуют + некоторые функциональные возможности, такие как потоки и обработка + исключений, затем собрать glibc с использованием этого + деградированного компилятора (сама glibc не деградирована), а затем + собрать libstdc++. В этой последней библиотеке будет не хватать + некоторых функциональных возможностей libgcc. +

+

+ Выводом из предыдущего абзаца является то, что cc1 не может собрать + полнофункциональную libstdc++ с деградированной libgcc, но это + единственный компилятор, доступный для сборки библиотек C/C++ на + этапе 2. Есть две причины, по которым мы не используем сразу + компилятор cc-lfs, собранный на этапе 2, для сборки этих библиотек. +

+
+
    +
  • +

    + Вообще говоря, cc-lfs не может работать на ПК (хост-системе). + Хотя триплеты для ПК и LFS совместимы друг с другом, + исполняемый файл для lfs должен зависеть от glibc-2.40; + хост-дистрибутив может использовать либо другую реализацию + libc (например, musl), либо предыдущий выпуск glibc + (например, glibc-2.13). +

    +
  • +
  • +

    + Даже если cc-lfs может работать на ПК, его использование на + ПК сопряжено с риском привязки к библиотекам ПК, так как + cc-lfs является родным компилятором. +

    +
  • +
+
+

+ Поэтому, когда мы собираем gcc этап 2, мы даем указание системе + сборки пересобрать libgcc и libstdc++ с помощью cc1, но мы + связываем libstdc++ с новой пересобранной libgcc вместо старой, + деградированной. Это делает пересобранную библиотеку libstdc++ + полностью функциональной. +

+

+ В Глава 8 + (или «этап + 3») собраны все пакеты, необходимые для системы LFS. + Даже если пакет уже был установлен в системе LFS в предыдущей + главе, мы все равно пересобираем пакет. Основная причина пересборки + этих пакетов состоит в том, чтобы сделать их стабильными: если мы + переустанавливаем пакет LFS в готовой системе LFS, содержимое + пакета должно совпадать с содержимым того же пакета при первой + установке в Глава 8. + Временные пакеты, установленные в Глава 6 + или + Глава 7 не могут удовлетворять этому требованию, потому + что некоторые из них собраны без необязательных зависимостей и + autoconf не может выполнить некоторые проверки функций в Глава 6 + из-за кросс-компиляции, в результате чего во временных пакетах + отсутствуют дополнительные функции или используются не оптимальные + процедуры кода. Кроме того, второстепенной причиной для пересборки + пакетов является выполнение тестов. +

+
+
+

+ Другие детали + процесса +

+

+ Кросс-компилятор будет установлен в отдельный каталог $LFS/tools, так как он не будет частью конечной + системы. +

+

+ Сначала устанавливается Binutils, потому что во время выполнения + команды configure gcc + и glibc выполняются различные тесты функций на ассемблере и + компоновщике, чтобы определить, какие программные функции следует + включить или отключить. Это важнее, чем может показаться на первый + взгляд. Неправильно настроенный gcc или glibc может привести к + незначительной поломке сборочных инструментов, где последствия + такой поломки могут проявиться ближе к концу сборки всего + дистрибутива. Сбой тестов обычно выявляет эту ошибку до того, как + будет выполнено много дополнительной работы. +

+

+ Binutils устанавливает свой ассемблер и компоновщик в двух местах: + $LFS/tools/bin и $LFS/tools/$LFS_TGT/bin. Инструменты в одном + месте жестко связаны с другими. Важным аспектом компоновщика + является порядок поиска в библиотеке. Подробную информацию можно + получить от ld, + передав ей флаг --verbose. + Например, $LFS_TGT-ld --verbose | + grep SEARCH покажет текущие пути поиска и их + порядок. Он показывает, какие файлы связаны с помощью ld, путем компиляции фиктивной + программы и передачи параметра --verbose компоновщику. Например, + $LFS_TGT-gcc dummy.c -Wl,--verbose + 2>&1 | grep succeeded покажет все файлы, + успешно открытые во время компоновки. +

+

+ Следующий устанавливаемый пакет — gcc. Пример того, что можно + увидеть во время запуска configure: +

+
checking what assembler to use... /mnt/lfs/tools/i686-lfs-linux-gnu/bin/as
+checking what linker to use... /mnt/lfs/tools/i686-lfs-linux-gnu/bin/ld
+

+ Это важно по причинам, упомянутым выше. Также здесь + демонстрируется, что сценарий настройки gcc не просматривает + значения переменной PATH, чтобы найти, какие инструменты + использовать. Однако во время фактической работы самого + gcc не обязательно + используются одни и те же пути поиска. Чтобы узнать, какой + стандартный компоновщик будет использовать gcc, запустите: $LFS_TGT-gcc -print-prog-name=ld. +

+

+ Подробную информацию можно получить из gcc, передав ему параметр + -v при компиляции фиктивной + программы. Например, gcc -v + dummy.c покажет подробную информацию об этапах + препроцессора, компиляции и сборки, включая указанные в + gcc пути поиска и их + порядок. +

+

+ Далее устанавливаются очищенные заголовочные файлы Linux API. Они + позволяют стандартной библиотеке C (Glibc) взаимодействовать с + функциями, предоставляемыми ядром Linux. +

+

+ Следующий устанавливаемый пакет — glibc. Наиболее важными при + сборке glibc являются компилятор, бинарные инструменты и + заголовочные файлы ядра. С компилятором и бинарными инструментами, + как правило, не бывает проблем, поскольку glibc всегда использует + параметры, передаваемые скрипту configure, которые указаны в + --host, например, в нашем + случае компилятором будет $LFS_TGT-gcc, а инструментом + readelf будет + $LFS_TGT-readelf. С + заголовочными файлами ядра может быть немного сложнее. Поэтому мы + не рискуем и используем доступный параметр configure, чтобы + обеспечить правильный выбор. После выполнения команды configure проверьте содержимое + файла config.make в каталоге + build на наличие всех нужных + параметров. Эти элементы подчеркивают важный аспект пакета glibc — + он очень самодостаточен с точки зрения своего механизма сборки и, + как правило, не полагается на значения по умолчанию. +

+

+ Как было сказано выше, затем компилируется стандартная библиотека + C++, а затем в Глава 6 + все остальные программы, которым необходимо разрешить проблему + циклических зависимостей во время сборки. На этапе установки всех + этих пакетов используется переменная DESTDIR, для принудительной + установки в файловую систему LFS. +

+

+ В конце Глава 6 + устанавливается собственный компилятор lfs. Сначала собирается + binutils с той же переменной DESTDIR, + что и другие программы, затем повторно собирается gcc, без сборки + некоторых некритических библиотек. Из-за какой-то странной логики в + сценарии настройки GCC CC_FOR_TARGET + заканчивается как cc, + когда хост совпадает с целью, но отличается от системы сборки. + Поэтому значение CC_FOR_TARGET=$LFS_TGT-gcc явно + указывается в параметрах конфигурации. +

+

+ После входа в среду chroot в + Глава 7 первой задачей является установка libstdc++. Затем + выполняется установка временных программ, необходимых для + правильной работы тулчейна. С этого момента основной набор + инструментов является самодостаточным и автономным. В Глава 8 + собираются, тестируются и устанавливаются окончательные версии всех + пакетов, необходимых для полнофункциональной системы. +

+
+
+ + + -- cgit v1.2.3