mirror of
https://github.com/LCTT/LFS-BOOK-7.7-systemd.git
synced 2026-01-14 00:49:09 +00:00
155 lines
12 KiB
HTML
155 lines
12 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content=
|
||
"application/xhtml+xml; charset=utf-8" />
|
||
<title>
|
||
5.2. Toolchain Technical Notes
|
||
</title>
|
||
<link rel="stylesheet" type="text/css" href="../stylesheets/lfs.css" />
|
||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1" />
|
||
<link rel="stylesheet" href="../stylesheets/lfs-print.css" type="text/css"
|
||
media="print" />
|
||
</head>
|
||
<body class="lfs" id="lfs-7.7-systemd">
|
||
<div class="navheader">
|
||
<h4>
|
||
Linux From Scratch - Version 7.7-systemd
|
||
</h4>
|
||
<h3>
|
||
第五章 构建临时系统
|
||
</h3>
|
||
<ul>
|
||
<li class="prev">
|
||
<a accesskey="p" href="introduction.html" title=
|
||
"简介">前一页</a>
|
||
<p>
|
||
简介
|
||
</p>
|
||
</li>
|
||
<li class="next">
|
||
<a accesskey="n" href="generalinstructions.html" title=
|
||
"通用编译指南">下一页</a>
|
||
<p>
|
||
通用编译指南
|
||
</p>
|
||
</li>
|
||
<li class="up">
|
||
<a accesskey="u" href="chapter05.html" title=
|
||
"第五章 构建临时系统">向上</a>
|
||
</li>
|
||
<li class="home">
|
||
<a accesskey="h" href="../index.html" title=
|
||
"Linux From Scratch - Version 7.7-systemd">主页</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="sect1" lang="en" xml:lang="en">
|
||
<h1 class="sect1">
|
||
<a id="ch-tools-toolchaintechnotes" name="ch-tools-toolchaintechnotes"></a>5.2 工具链技术备注</h1>
|
||
<p>
|
||
本节解释总体构建方法之中的某些基本原理和技术细节。并不需要立即理解本节中的所有问题。在进行实际构建的过程中,绝大部分的信息将会变得愈加清晰。在该过程中可随时查阅本小节的内容。
|
||
</p>
|
||
<p>
|
||
<a class="xref" href="chapter05.html" title="第五章 构建临时系统">第五章</a> 的总体目标是生成一个临时的系统,它包含一个已知的较好工具集,该工具集可与宿主系统分离。通过使用 <span class="command"><strong>chroot</strong></span>,其余各章中的命令将被包含在此环境中,以保证目标 LFS 系统能够洁净且无故障地生成。构建过程的设计就是为了使得新读者有最少的风险,同时还能有最好的指导价值。
|
||
</p>
|
||
<div class="admon note">
|
||
<img alt="[Note]" src="../images/note.png" />
|
||
<h3>
|
||
注意
|
||
</h3>
|
||
<p>
|
||
在继续之前,请留意工作平台的名称,目标系统三段式名称可通过运行脚本 <span class="command"><strong>config.guess</strong></span> 获得,许多软件的源码包都附带有该脚本[LCTT 译注:目标系统三段式名称描述了代码运行的平台,是GNU 构建系统中的一个核心概念,形如i686-pc-gnu-linux。它包含三个字段:CPU家族/型号的名称(如i686)、供应商(pc)和操作系统名称(如gnu-linux)。更详细的信息请参阅 http://wiki.osdev.org/Target_Triplet]。解开 Binutils 源码包并执行脚本:<strong class="userinput"><code>./config.guess</code></strong>,查看其输出。例如,对于一个现代的 32 位英特尔处理器,其输出很可能为 <span class="emphasis"><em>i686-pc-linux-gnu</em></span>。
|
||
</p>
|
||
<p>
|
||
还请留意平台的动态链接器的名称,它通常被称为动态加载器(为了不与标准链接器 <span class="command"><strong>ld</strong></span> 发生混淆,后者包含中在 Binutils 中)。该动态链接器由 Glibc 提供,它寻找并加载程序所需的共享库,为程序运行作准备,并运行它。对于 32-位英特尔的机器,动态链接器的名称为 <code class="filename">ld-linux.so.2</code>。判断动态链接器的一个可靠方法是检查宿主系统中的任意一个二进制文件,执行:<strong class="userinput"><code>readelf -l <二进制文件名> | grep interpreter</code></strong> 且查看其输出。可在 Glibc 源码树根目录下的文件 <code class="filename">shlib-versions</code> 中找到所有平台的权威参考。
|
||
</p>
|
||
</div>
|
||
<p>
|
||
下面是 <a class="xref" href="chapter05.html" title="第五章 构建临时系统">第五章</a>构建方法的几个关键技术点:
|
||
</p>
|
||
<div class="itemizedlist">
|
||
<ul>
|
||
<li class="listitem">
|
||
<p>
|
||
使用 <code class="envar">LFS_TGT</code> 变量改变目标系统三段式的“vendor”字段,从而稍微调整工作平台的名称,以保证第一遍构建 Binutils 和 GCC 时能够生成兼容的交叉链接器和交叉编译器。此处的交叉链接器和交叉编译器生成的二进制文件与当前的硬件兼容,而不是用于其它的硬件架构。
|
||
</p>
|
||
</li>
|
||
<li class="listitem">
|
||
<p>
|
||
临时库经交叉编译获得。由于交叉编译原本就不应该依赖于宿主系统,因此,通过降低宿主系统的头文件或库进入新工具的可能性,该方法可去除目标系统的可能污染。交叉编译的方式,还可以在 64-位硬件平台上同时构建出 32-位和 64-位库。
|
||
</p>
|
||
</li>
|
||
<li class="listitem">
|
||
<p>
|
||
谨慎操作 GCC 源码,以告诉编译器将使用哪个目标系统动态链接器。
|
||
</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<p>
|
||
Binutils 是首个安装的包,这是因为执行 GCC 和 Glibc 的 <span class="command"><strong>configure</strong></span> 时都将进行有关汇编器和链接器的多项特性测试,以判断允许或禁用哪些软件特性。其重要性可能更甚于最初的意识。对 GCC 或 Glibc 的错误配置可能导致工具链出现难以捉摸的问题,可能直到整个构建过程接近尾声时才会显现出这些问题。通常情况下,一次测试套件失败可在进行太多其它工作前突出该错误。
|
||
</p>
|
||
<p>
|
||
Binutils 将其汇编器和链接器安装在两个地方,即 <code class="filename">/tools/bin</code> 和 <code class="filename">/tools/$LFS_TGT/bin</code>。一个地方的工具是另一个地方工具的硬链接。链接器的一个重要方面是它的库搜索顺序。可给 <span class="command"><strong>ld</strong></span> 传递参数 <em class="parameter"><code>--verbose</code></em> 获得详细信息。如,<strong class="userinput"><code>ld --verbose | grep SEARCH</code></strong> 可得到当前的搜索路径及其顺序。通过编译一个模拟程序并向链接器传递 <em class="parameter"><code>--verbose</code></em> 开关,可显示 <span class= "command"><strong>ld</strong></span> 都链接了哪些文件。例如,<strong class="userinput"><code>gcc dummy.c -Wl,--verbose 2>&1 | grep succeeded</code></strong> 将显示链接过程中成功打开的所有文件。
|
||
</p>
|
||
<p>
|
||
下一个安装的包是 GCC。下面是运行 GCC 的 <span class="command"><strong>configure</strong></span> 的输出的一个例子:
|
||
</p>
|
||
<pre class="screen">
|
||
<code class=
|
||
"computeroutput">checking what assembler to use... /tools/i686-lfs-linux-gnu/bin/as
|
||
checking what linker to use... /tools/i686-lfs-linux-gnu/bin/ld</code>
|
||
</pre>
|
||
<p>
|
||
基于前述原因,这很重要。它还说明了 GCC 的配置脚本并不会搜索 PATH 目录来寻找使用什么工具。不过,在 <span class="command"><strong>gcc</strong></span> 自身的实际运行中,并不需要使用同样的搜索路径。运行:<strong class= "userinput"><code>gcc -print-prog-name=ld</code></strong> 可获知 <span class="command"><strong>gcc</strong></span> 使用是何种标准链接器(译者注:<strong class= "userinput"><code>gcc -print-prog-name</code></strong> 这个命令是为了显示 gcc 使用的某些内部工具的绝对路径,但事实上,<span class="command"><strong>ld</strong></span> 并不是 GCC 的内部工具,因此这条命令实际上没什么用)。
|
||
</p>
|
||
<p>
|
||
在编译模拟程序时,向 <span class="command"><strong>gcc</strong></span> 传递命令行选项 <em class="parameter"><code>-v</code></em> 可获得详细信息。例如,<strong class="userinput"><code>gcc -v dummy.c</code></strong> 将显示预处理器、编译和汇编阶段的详细信息,包括 <span class="command"><strong>gcc</strong></span> 的 include 搜索路径及其顺序。
|
||
</p>
|
||
<p>
|
||
下一个安装的包是经过净化的 Linux API 头文件。这些头文件可使得标准 C 库(Glibc)与 Linux 内核提供的特性进行交行交互。
|
||
</p>
|
||
<p>
|
||
下一个安装的包是 Glibc。构建 Glibc 时,最重要的考量是编译器、二进制工具和内核头文件。由于 Glibc 总是使用传递给它的配置脚本的 <em class="parameter"><code>--host</code></em> 参数有关的编译器,如,在我们这个场景中是 <span class="command"><strong>i686-lfs-linux-gnu-gcc</strong></span>,因此编译器通常不是一个问题。二进制工具和内核头文件可能会更复杂一些。因此,请谨慎行事并利用可用的配置开关以强制使用正确的选择。<span class= "command"><strong>configure</strong></span> 运行完毕,目录 <code class="filename">glibc-build</code> 下的文件 <code class="filename">config.make</code> 包含有所有的重要详细。需要注意的是,<em class="parameter"><code>CC="i686-lfs-gnu-gcc"</code></em> 用来控制使用哪个二进制工具,<em class= "parameter"><code>-nostdinc</code></em> 和 <em class="parameter"><code>-isystem</code></em> 标志用来控制编译器的 include 搜索路径。这些条目强调了 Glibc 包的一个重要方面,即其构建机制是非常自给自足的,通常并不依赖默工具链的默认设置。
|
||
</p>
|
||
<p>
|
||
在第二遍编译 Binutils 过程中,我们能够利用配置开关 <em class="parameter"><code>--with-lib-path</code></em> 来控制 <span class="command"><strong>ld</strong></span> 的库搜索路径。
|
||
</p>
|
||
<p>
|
||
第二遍编译 GCC 时,也需要修改其源代码以告诉 GCC 使用新的动态链接器。如果不加修改,将会导致 GCC 自身的程序嵌入来自宿主系统目录 <code class="filename">/lib</code> 的动态链接器名称,这将破坏远离宿主系统的目标。正是基于前面的这个出发点,核心工具链是自包含和自托管的。<a class="xref" href="chapter05.html" title="第五章 构建临时系统"">第五章</a>其它的软件包都将在 <code class="filename">/tools</code> 中的新 Glibc 的基础上进行构建。
|
||
</p>
|
||
<p>
|
||
在进入<a class="xref" href="../chapter06/chapter06.html" title="第六章 安装基本的系统软件">第六章</a>中的 chroot 环境前,将安装的首个主要的软件包是 Glibc,这是因为它天生具有前面提及的自给自足特点。一旦将 Glibc 安装到 <code class="filename">/usr</code> 中,我们将快速改变工具链的默认设置,然后继续构建目标 LFS 系统的其余部分。
|
||
</p>
|
||
</div>
|
||
<div class="navfooter">
|
||
<ul>
|
||
<li class="prev">
|
||
<a accesskey="p" href="introduction.html" title=
|
||
"简介">前一页</a>
|
||
<p>
|
||
简介
|
||
</p>
|
||
</li>
|
||
<li class="next">
|
||
<a accesskey="n" href="generalinstructions.html" title=
|
||
"通用编译指南">下一页</a>
|
||
<p>
|
||
通用编译指南
|
||
</p>
|
||
</li>
|
||
<li class="up">
|
||
<a accesskey="u" href="chapter05.html" title=
|
||
"第五章 构建临时系统">向上</a>
|
||
</li>
|
||
<li class="home">
|
||
<a accesskey="h" href="../index.html" title=
|
||
"Linux From Scratch - Version 7.7-systemd">主页</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</body>
|
||
</html>
|