msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2020-08-19 23:33+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Translate Toolkit 2.2.5\n" #. type: Content of: msgid "Toolchain Technical Notes" msgstr "工具链技术说明" #. type: Content of: <sect1><para> msgid "" "This section explains some of the rationale and technical details behind the " "overall build method. It is not essential to immediately understand " "everything in this section. Most of this information will be clearer after " "performing an actual build. This section can be referred to at any time " "during the process." msgstr "" "本节综合地解释构建方法中的逻辑和技术细节。您现在并不需要立刻理解本节的所有内" "容,在实际进行构建的过程中,可以更清晰地理解本节的信息。在整个构建过程中,您" "随时可以回来翻阅本节。" #. type: Content of: <sect1><para> msgid "" "The overall goal of <xref linkend=\"chapter-cross-tools\"/> and <xref " "linkend=\"chapter-temporary-tools\"/> is to produce a temporary area that " "contains a known-good set of tools that can be isolated from the host " "system. By using <command>chroot</command>, the commands in the remaining " "chapters will be contained within that environment, ensuring a clean, " "trouble-free build of the target LFS system. The build process has been " "designed to minimize the risks for new readers and to provide the most " "educational value at the same time." msgstr "" "<xref linkend=\"chapter-cross-tools\"/>和<xref linkend=\"chapter-temporary-" "tools\"/>的总目标是构造一个临时环境,它包含一组可靠的,能够与宿主系统完全分离" "的工具。这样,通过使用 <command>chroot</command> 命令,其余各章中执行的命令就" "被限制在这个临时环境中。这确保我们能够干净、顺利地构建 LFS 系统。整个构建过程" "被精心设计,以尽量降低新读者可能面临的风险,同时提供尽可能多的教育价值。" #. type: Content of: <sect1><para> msgid "" "The build process is based on the process of <emphasis>cross-compilation</" "emphasis>. Cross-compilation is normally used for building a compiler and " "its toolchain for a machine different from the one that is used for the " "build. This is not strictly needed for LFS, since the machine where the new " "system will run is the same as the one used for the build. But cross-" "compilation has the great advantage that anything that is cross-compiled " "cannot depend on the host environment." msgstr "" "构建过程是基于<emphasis>交叉编译</emphasis>过程的。交叉编译通常被用于为一台与" "本机完全不同的计算机构建编译器及其工具链。这对于 LFS 并不严格必要,因为新系统" "运行的机器就是构建它时使用的。但是,交叉编译拥有一项重要优势,即任何交叉编译" "产生的程序都不可能依赖于宿主环境。" #. type: Content of: <sect1><sect2><title> msgid "About Cross-Compilation" msgstr "关于交叉编译" #. type: Content of: <sect1><sect2><para> msgid "" "Cross-compilation involves some concepts that deserve a section on their " "own. Although this section may be omitted in a first reading, it is strongly " "suggested to come back to it later in order to get a full grasp of the build " "process." msgstr "" "交叉编译涉及一些概念,值得专门用一节讨论。尽管您可以在初次阅读时跳过本节,但" "强烈建议您之后回头阅读本节,以完全掌握构建过程。" #. type: Content of: <sect1><sect2><para> msgid "Let us first define some terms used in this context:" msgstr "首先我们定义讨论交叉编译时常用的术语:" #. type: Content of: <sect1><sect2><variablelist><varlistentry><term> msgid "build" msgstr "build" #. type: Content of: <sect1><sect2><variablelist><varlistentry><listitem><para> msgid "" "is the machine where we build programs. Note that this machine is referred " "to as the <quote>host</quote> in other sections." msgstr "" "指构建程序时使用的机器。注意在某些其他章节,这台机器被称为<quote>host</" "quote>(宿主)。" #. type: Content of: <sect1><sect2><variablelist><varlistentry><term> msgid "host" msgstr "host" #. type: Content of: <sect1><sect2><variablelist><varlistentry><listitem><para> msgid "" "is the machine/system where the built programs will run. Note that this use " "of <quote>host</quote> is not the same as in other sections." msgstr "" "指将来会运行被构建的程序的机器。注意这里说的<quote>host</quote>与其他章节使用" "的“宿主”(host) 一词不同。" #. type: Content of: <sect1><sect2><variablelist><varlistentry><term> msgid "target" msgstr "target" #. type: Content of: <sect1><sect2><variablelist><varlistentry><listitem><para> msgid "" "is only used for compilers. It is the machine the compiler produces code " "for. It may be different from both build and host." msgstr "" "只有编译器使用这个术语。编译器为这台机器产生代码。它可能和 build 与 host 都不" "同。" #. type: Content of: <sect1><sect2><para> msgid "" "As an example, let us imagine the following scenario (sometimes referred to " "as <quote>Canadian Cross</quote>): we may have a compiler on a slow machine " "only, let's call the machine A, and the compiler ccA. We may have also a " "fast machine (B), but with no compiler, and we may want to produce code for " "another slow machine (C). To build a compiler for machine C, we would have " "three stages:" msgstr "" "例如,我们考虑下列场景 (有时称为<quote>Canadian Cross</quote>):我们仅在一台" "运行缓慢的机器上有编译器,称这台机器为 A,这个编译器为 ccA。我们还有一台运行" "较快的机器 (B),但它没有安装编译器,而我们希望为另一台缓慢的机器 (C) 生成代" "码。如果要为 C 构建编译器,可以通过三个阶段完成:" #. type: Content of: <sect1><sect2><informaltable><tgroup><thead><row><entry> msgid "Stage" msgstr "阶段" #. type: Content of: <sect1><sect2><informaltable><tgroup><thead><row><entry> msgid "Build" msgstr "Build" #. type: Content of: <sect1><sect2><informaltable><tgroup><thead><row><entry> msgid "Host" msgstr "Host" #. type: Content of: <sect1><sect2><informaltable><tgroup><thead><row><entry> msgid "Target" msgstr "Target" #. type: Content of: <sect1><sect2><informaltable><tgroup><thead><row><entry> msgid "Action" msgstr "操作描述" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "1" msgstr "1" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "A" msgstr "A" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "B" msgstr "B" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "build cross-compiler cc1 using ccA on machine A" msgstr "在机器 A 上,使用 ccA 构建交叉编译器 cc1" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "2" msgstr "2" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "C" msgstr "C" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "build cross-compiler cc2 using cc1 on machine A" msgstr "在机器 A 上,使用 cc1 构建交叉编译器 cc2" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "3" msgstr "3" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "build compiler ccC using cc2 on machine B" msgstr "在机器 B 上,使用 cc2 构建交叉编译器 ccC" #. type: Content of: <sect1><sect2><para> msgid "" "Then, all the other programs needed by machine C can be compiled using cc2 " "on the fast machine B. Note that unless B can run programs produced for C, " "there is no way to test the built programs until machine C itself is " "running. For example, for testing ccC, we may want to add a fourth stage:" msgstr "" "这样,我们可以为机器 C 使用 cc2 在快速的机器 B 上构建所有其他程序。注意除非 " "B 能运行为 C 编译的程序,我们无法测试编译得到的程序,直到在 C 上运行它。例" "如,如果要测试 ccC,我们可以增加第四个阶段:" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "4" msgstr "4" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "rebuild and test ccC using itself on machine C" msgstr "在机器 C 上,用 ccC 重新构建它本身,并测试" #. type: Content of: <sect1><sect2><para> msgid "" "In the example above, only cc1 and cc2 are cross-compilers, that is, they " "produce code for a machine different from the one they are run on. The " "other compilers ccA and ccC produce code for the machine they are run on. " "Such compilers are called <emphasis>native</emphasis> compilers." msgstr "" "在上面的例子中,只有 cc1 和 cc2 是交叉编译器,它们为与它们本身运行的机器不同" "的机器产生代码。而另外的编译器 ccA 和 ccC 为它们本身运行的机器产生代码,它们" "称为<emphasis>本地</emphasis>编译器。" #. type: Content of: <sect1><sect2><title> msgid "Implementation of Cross-Compilation for LFS" msgstr "LFS 的交叉编译实现" #. type: Content of: <sect1><sect2><note><para> msgid "" "Almost all the build systems use names of the form cpu-vendor-kernel-os " "referred to as the machine triplet. An astute reader may wonder why a " "<quote>triplet</quote> refers to a four component name. The reason is " "history: initially, three component names were enough to designate " "unambiguously a machine, but with new machines and systems appearing, that " "proved insufficient. The word <quote>triplet</quote> remained. A simple way " "to determine your machine triplet is to run the <command>config.guess</" "command> script that comes with the source for many packages. Unpack the " "binutils sources and run the script: <userinput>./config.guess</userinput> " "and note the output. For example, for a 32-bit Intel processor the output " "will be <emphasis>i686-pc-linux-gnu</emphasis>. On a 64-bit system it will " "be <emphasis>x86_64-pc-linux-gnu</emphasis>." msgstr "" "几乎所有构建系统都使用形如 CPU-供应商-内核-操作系统,称为三元组的名称表示目标" "机器。好奇的读者可能感到奇怪,为什么一个<quote>三元组</quote>却包含四个部分。" "这是历史遗留的:最早,三个部分就足以无歧义地描述一台机器。但是随着新的机器和" "系统不断出现,最终证明三个部分是不够的。然而,<quote>三元组</quote>这个术语保" "留了下来。有一种简单方法可以获得您的机器的三元组,即运行许多软件包附带的 " "<command>config.guess</command> 脚本。解压缩 Binutils 源码,然后运行脚本:" "<userinput>./config.guess</userinput>,观察输出。例如,对于 32 位 Intel 处理" "器,输出应该是 <emphasis>i686-pc-linux-gnu</emphasis>,而对于 64 位系统输出应" "该是 <emphasis>x86_64-pc-linux-gnu</emphasis>。" #. type: Content of: <sect1><sect2><note><para> msgid "" "Also be aware of the name of the platform's dynamic linker, often referred " "to as the dynamic loader (not to be confused with the standard linker " "<command>ld</command> that is part of binutils). The dynamic linker provided " "by Glibc finds and loads the shared libraries needed by a program, prepares " "the program to run, and then runs it. The name of the dynamic linker for a " "32-bit Intel machine will be <filename class=\"libraryfile\">ld-linux.so.2</" "filename> (<filename class=\"libraryfile\">ld-linux-x86-64.so.2</filename> " "for 64-bit systems). A sure-fire way to determine the name of the dynamic " "linker is to inspect a random binary from the host system by running: " "<userinput>readelf -l <name of binary> | grep interpreter</userinput> " "and noting the output. The authoritative reference covering all platforms is " "in the <filename>shlib-versions</filename> file in the root of the Glibc " "source tree." msgstr "" "另外注意平台的动态链接器的名称,它又被称为动态加载器 (不要和 Binutils 中的普" "通链接器 <command>ld</command> 混淆)。动态链接器由 Glibc 提供,它寻找并加载程" "序所需的共享库,为程序运行做好准备,然后运行程序。在 32 位 Intel 机器上动态链" "接器的名称是 <filename class=\"libraryfile\">ld-linux.so.2</filename> (在 64 " "位系统上是 <filename class=\"libraryfile\">ld-linux-x86-64.so.2</filename>)。" "一个确定动态链接器名称的准确方法是从宿主系统找一个二进制可执行文件,然后执" "行:<userinput>readelf -l <二进制文件名> | grep interpreter</" "userinput> 并观察输出。包含所有平台的权威参考可以在 Glibc 源码树根目录的 " "<filename>shlib-versions</filename> 文件中找到。" #. type: Content of: <sect1><sect2><para> msgid "" "In order to fake a cross compilation, the name of the host triplet is " "slightly adjusted by changing the "vendor" field in the " "<envar>LFS_TGT</envar> variable. We also use the <parameter>--with-sysroot</" "parameter> option when building the cross linker and cross compiler to tell " "them where to find the needed host files. This ensures that none of the " "other programs built in <xref linkend=\"chapter-temporary-tools\"/> can link " "to libraries on the build machine. Only two stages are mandatory, and one " "more for tests:" msgstr "" "为了将本机伪装成交叉编译目标机器,我们在 <envar>LFS_TGT</envar> 变量中,对宿" "主系统三元组的 "vendor" 域进行修改。我们还会在构建交叉链接器和交叉" "编译器时使用 <parameter>--with-sysroot</parameter> 选项,指定查找所需的 host " "系统文件的位置。这保证在<xref linkend=\"chapter-temporary-tools\"/>中的其他程" "序在构建时不会链接到宿主 (build) 系统的库。前两个阶段是必要的,第三个阶段可以" "用于测试:" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "pc" msgstr "pc" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "lfs" msgstr "lfs" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "build cross-compiler cc1 using cc-pc on pc" msgstr "在 pc 上使用 cc-pc 构建交叉编译器 cc1" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "build compiler cc-lfs using cc1 on pc" msgstr "在 pc 上使用 cc1 构建 cc-lfs" #. type: Content of: <sect1><sect2><informaltable><tgroup><tbody><row><entry> msgid "rebuild and test cc-lfs using itself on lfs" msgstr "在 lfs 上使用 cc-lfs 重新构建并测试它本身" #. type: Content of: <sect1><sect2><para> msgid "" "In the above table, <quote>on pc</quote> means the commands are run on a " "machine using the already installed distribution. <quote>On lfs</quote> " "means the commands are run in a chrooted environment." msgstr "" "在上表中,<quote>在 pc 上</quote> 意味着命令在已经安装好的发行版中执行。" "<quote>在 lfs 上</quote> 意味着命令在 chroot 环境中执行。" #. type: Content of: <sect1><sect2><para> msgid "" "Now, there is more about cross-compiling: the C language is not just a " "compiler, but also defines a standard library. In this book, the GNU C " "library, named glibc, is used. This library must be compiled for the lfs " "machine, that is, using the cross compiler cc1. But the compiler itself " "uses an internal library implementing complex instructions not available in " "the assembler instruction set. This internal library is named libgcc, and " "must be linked to the glibc library to be fully functional! Furthermore, the " "standard library for C++ (libstdc++) also needs being linked to glibc. The " "solution to this chicken and egg problem is to first build a degraded cc1 " "based libgcc, lacking some functionalities such as threads and exception " "handling, then build glibc using this degraded compiler (glibc itself is not " "degraded), then build libstdc++. But this last library will lack the same " "functionalities as libgcc." msgstr "" "现在,关于交叉编译,还有更多要处理的问题:C 语言并不仅仅由一个编译器实现,它" "还规定了一个标准库。在本书中,我们使用 GNU C 运行库,即 glibc。它必须为 lfs " "目标机器使用交叉编译器 cc1 编译。但是,编译器本身使用一个库,实现汇编指令集并" "不支持的一些复杂指令。这个内部库称为 libgcc,它必须链接到 glibc 库才能实现完" "整功能!另外,C++ 标准库 (libstdc++) 也必须链接到 glibc。为了解决这个”先有鸡" "还是先有蛋“的问题,只能先构建一个降级的 cc1,它的 libgcc 缺失线程和异常等功" "能,再用这个降级的编译器构建 glibc (这不会导致 glibc 缺失功能),再构建 " "libstdc++。但是这种方法构建的 libstdc++ 和 libgcc 一样,会缺失一些功能。" #. type: Content of: <sect1><sect2><para> msgid "" "This is not the end of the story: the conclusion of the preceding paragraph " "is that cc1 is unable to build a fully functional libstdc++, but this is the " "only compiler available for building the C/C++ libraries during stage 2! Of " "course, the compiler built during stage 2, cc-lfs, would be able to build " "those libraries, but (1) the build system of GCC does not know that it is " "usable on pc, and (2) using it on pc would be at risk of linking to the pc " "libraries, since cc-lfs is a native compiler. So we have to build libstdc++ " "later, in chroot." msgstr "" "讨论还没有结束:上面一段的结论是 cc1 无法构建功能完整的 libstdc++,但这是我们" "在阶段 2 构建 C/C++ 库时唯一可用的编译器!当然,在阶段 2 中构建的编译器 cc-" "lfs 将会可以构建这些库,但是 (1) GCC 构建系统不知道这个编译器在 pc 上可以使" "用,而且 (2) 它是一个本地编译器,因此在 pc 上使用它可能产生链接到 pc (宿主系" "统) 库的风险。因此我们必须在进入 chroot 后再次构建 libstdc++。" #. type: Content of: <sect1><sect2><title> msgid "Other procedural details" msgstr "构建过程的其他细节" #. type: Content of: <sect1><sect2><para> msgid "" "The cross-compiler will be installed in a separate <filename class=" "\"directory\">$LFS/tools</filename> directory, since it will not be part of " "the final system." msgstr "" "交叉编译器会被安装在独立的 <filename class=\"directory\">$LFS/tools</" "filename> 目录,因为它不属于最终构建的系统。" #. type: Content of: <sect1><sect2><para> msgid "" "Binutils is installed first because the <command>configure</command> runs of " "both GCC and Glibc perform various feature tests on the assembler and linker " "to determine which software features to enable or disable. This is more " "important than one might first realize. An incorrectly configured GCC or " "Glibc can result in a subtly broken toolchain, where the impact of such " "breakage might not show up until near the end of the build of an entire " "distribution. A test suite failure will usually highlight this error before " "too much additional work is performed." msgstr "" "我们首先安装 Binutils。这是由于 GCC 和 Glibc 的 <command>configure</command> " "脚本首先测试汇编器和链接器的一些特性,以决定启用或禁用一些软件特性。初看起来" "这并不重要,但没有正确配置的 GCC 或者 Glibc 可以导致工具链中潜伏的故障。这些" "故障可能到整个构建过程快要结束时才突然爆发,不过在花费大量无用功之前,测试套" "件的失败可以将这类错误凸显出来。" #. type: Content of: <sect1><sect2><para> msgid "" "Binutils installs its assembler and linker in two locations, <filename class=" "\"directory\">$LFS/tools/bin</filename> and <filename class=\"directory\">" "$LFS/tools/$LFS_TGT/bin</filename>. The tools in one location are hard " "linked to the other. An important facet of the linker is its library search " "order. Detailed information can be obtained from <command>ld</command> by " "passing it the <parameter>--verbose</parameter> flag. For example, <command>" "$LFS_TGT-ld --verbose | grep SEARCH</command> will illustrate the current " "search paths and their order. It shows which files are linked by " "<command>ld</command> by compiling a dummy program and passing the " "<parameter>--verbose</parameter> switch to the linker. For example, <command>" "$LFS_TGT-gcc dummy.c -Wl,--verbose 2>&1 | grep succeeded</command> " "will show all the files successfully opened during the linking." msgstr "" "Binutils 将汇编器和链接器安装在两个位置,一个是 <filename class=\"directory" "\">$LFS/tools/bin</filename>,另一个是 <filename class=\"directory\">$LFS/" "tools/$LFS_TGT/bin</filename>。这两个位置中的工具互为硬链接。链接器的一项重要" "属性是它搜索库的顺序,通过向 <command>ld</command> 命令加入 <parameter>--" "verbose</parameter> 参数,可以得到关于搜索路径的详细信息。例如," "<userinput>ld --verbose | grep SEARCH</userinput> 会输出当前的搜索路径及其顺" "序。此外,通过编译一个样品 (dummy) 程序并向链接器 <command>ld</command> 传递 " "<parameter>--verbose</parameter> 参数,可以知道哪些文件被链接。例如," "<userinput>gcc dummy.c -Wl,--verbose 2>&1 | grep succeeded</" "userinput> 将显示所有在链接过程中被成功打开的文件。" #. type: Content of: <sect1><sect2><para> msgid "" "The next package installed is GCC. An example of what can be seen during its " "run of <command>configure</command> is:" msgstr "" "下一步安装 GCC。在执行它的 <command>configure</command> 脚本时,您会看到类似" "下面这样的输出:" #. type: Content of: <sect1><sect2><screen> #, no-wrap msgid "" "<computeroutput>checking what assembler to use... /mnt/lfs/tools/i686-lfs-linux-gnu/bin/as\n" "checking what linker to use... /mnt/lfs/tools/i686-lfs-linux-gnu/bin/ld</computeroutput>" msgstr "" "<computeroutput>checking what assembler to use... /tools/i686-lfs-linux-gnu/bin/as\n" "checking what linker to use... /mnt/lfs/tools/i686-lfs-linux-gnu/bin/ld</computeroutput>" #. type: Content of: <sect1><sect2><para> msgid "" "This is important for the reasons mentioned above. It also demonstrates that " "GCC's configure script does not search the PATH directories to find which " "tools to use. However, during the actual operation of <command>gcc</command> " "itself, the same search paths are not necessarily used. To find out which " "standard linker <command>gcc</command> will use, run: <command>$LFS_TGT-gcc -" "print-prog-name=ld</command>." msgstr "" "基于我们上面论述的原因,这些输出非常重要。这说明 GCC 的配置脚本没有在 PATH 变" "量指定的目录中搜索工具。然而,在 <command>gcc</command> 的实际运行中,未必会" "使用同样的搜索路径。为了查询 <command>gcc</command> 会使用哪个链接器,需要执" "行以下命令:<userinput>$LFS_TGT-gcc -print-prog-name=ld</userinput>。" #. type: Content of: <sect1><sect2><para> msgid "" "Detailed information can be obtained from <command>gcc</command> by passing " "it the <parameter>-v</parameter> command line option while compiling a dummy " "program. For example, <command>gcc -v dummy.c</command> will show detailed " "information about the preprocessor, compilation, and assembly stages, " "including <command>gcc</command>'s included search paths and their order." msgstr "" "通过向 <command>gcc</command> 传递 <parameter>-v</parameter> 参数,可以知道在" "编译样品程序时发生的细节。例如,<userinput>gcc -v dummy.c</userinput> 会输出" "预处理、编译和汇编阶段中的详细信息,包括 <command>gcc</command> 的包含文件搜" "索路径和顺序。" #. type: Content of: <sect1><sect2><para> msgid "" "Next installed are sanitized Linux API headers. These allow the standard C " "library (Glibc) to interface with features that the Linux kernel will " "provide." msgstr "" "下一步安装“净化的” (sanitized) Linux API 头文件。这允许 C 标准库 (Glibc) 与 " "Linux 内核提供的各种特性交互。" #. type: Content of: <sect1><sect2><para> msgid "" "The next package installed is Glibc. The most important considerations for " "building Glibc are the compiler, binary tools, and kernel headers. The " "compiler is generally not an issue since Glibc will always use the compiler " "relating to the <parameter>--host</parameter> parameter passed to its " "configure script; e.g. in our case, the compiler will be <command>$LFS_TGT-" "gcc</command>. The binary tools and kernel headers can be a bit more " "complicated. Therefore, take no risks and use the available configure " "switches to enforce the correct selections. After the run of " "<command>configure</command>, check the contents of the <filename>config." "make</filename> file in the <filename class=\"directory\">build</filename> " "directory for all important details. Note the use of <parameter>CC=" "\"$LFS_TGT-gcc\"</parameter> (with <envar>$LFS_TGT</envar> expanded) to " "control which binary tools are used and the use of the <parameter>-nostdinc</" "parameter> and <parameter>-isystem</parameter> flags to control the " "compiler's include search path. These items highlight an important aspect of " "the Glibc package—it is very self-sufficient in terms of its build " "machinery and generally does not rely on toolchain defaults." msgstr "" "下一步安装 Glibc。在构建 Glibc 时需要着重考虑是编译器,二进制工具,以及内核头" "文件。编译器一般不成问题,Glibc 总是使用传递给配置脚本的 <parameter>--host</" "parameter> 参数相关的编译器。例如,在我们的例子中,使用的编译器是 <command>" "$LFS_TGT-gcc</command>。但二进制工具和内核头文件的问题比较复杂。安全起见,我" "们使用配置脚本提供的开关,保证正确的选择。在 <command>configure</command> 脚" "本运行完成后,可以检查 <filename>build</filename> 目录中的 <filename>config." "make</filename> 文件,了解全部重要的细节。注意参数 <parameter>CC=\"$LFS_TGT-" "gcc\"</parameter> (其中 <envar>$LFS_TGT</envar> 会被展开) 控制构建系统使用正" "确的二进制工具,而参数 <parameter>-nostdinc</parameter> 和 <parameter>-" "isystem</parameter> 控制编译器的包含文件搜索路径。这些事项凸显了 Glibc 软件包" "的一个重要性质 —— 它的构建机制是相当自给自足的,通常不依赖于工具链默认值。" #. type: Content of: <sect1><sect2><para> msgid "" "As said above, the standard C++ library is compiled next, followed in <xref " "linkend=\"chapter-temporary-tools\"/> by all the programs that need " "themselves to be built. The install step of all those packages uses the " "<envar>DESTDIR</envar> variable to have the programs land into the LFS " "filesystem." msgstr "" "正如前文所述,接下来构建 C++ 标准库,然后是<xref linkend=\"chapter-temporary-" "tools\"/>中那些需要自身才能构建的程序后。在安装这些软件包时使用 " "<envar>DESTDIR</envar> 变量,将它安装到 LFS 文件系统中。" #. type: Content of: <sect1><sect2><para> msgid "" "At the end of <xref linkend=\"chapter-temporary-tools\"/> the native lfs " "compiler is installed. First binutils-pass2 is built, with the same " "<envar>DESTDIR</envar> install as the other programs, then the second pass " "of GCC is constructed, omitting libstdc++ and other non-important " "libraries. Due to some weird logic in GCC's configure script, " "<envar>CC_FOR_TARGET</envar> ends up as <command>cc</command> when the host " "is the same as the target, but is different from the build system. This is " "why <parameter>CC_FOR_TARGET=$LFS_TGT-gcc</parameter> is put explicitly into " "the configure options." msgstr "" "在<xref linkend=\"chapter-temporary-tools\"/>一节的末尾,构建 lfs 本地编译" "器。首先使用和其他程序相同的 <envar>DESTDIR</envar> 第二次构建 binutils,然后" "第二次构建 GCC,构建时忽略 libstdc++ 和其他不重要的库。由于 GCC 配置脚本的一" "些奇怪逻辑,<envar>CC_FOR_TARGET</envar> 变量在 host 系统和 target 相同,但" "与 build 不同时,被设定为 <command>cc</command>。因此我们必须显式地在配置选项" "中指定 <parameter>CC_FOR_TARGET=$LFS_TGT-gcc</parameter>。" #. type: Content of: <sect1><sect2><para> msgid "" "Upon entering the chroot environment in <xref linkend=\"chapter-chroot-" "temporary-tools\"/>, the first task is to install libstdc++. Then temporary " "installations of programs needed for the proper operation of the toolchain " "are performed. Programs needed for testing other programs are also built. " "From this point onwards, the core toolchain is self-contained and self-" "hosted. In <xref linkend=\"chapter-building-system\"/>, final versions of " "all the packages needed for a fully functional system are built, tested and " "installed." msgstr "" "在<xref linkend=\"chapter-chroot-temporary-tools\"/>中,进入 chroot 环境后," "首先安装 libstdc++。之后临时性地安装工具链的正常工作所必须的程序。还要构建测" "试其他程序时必须的程序。此后,核心工具链成为自包含的本地工具链。在<xref " "linkend=\"chapter-building-system\"/>中,构建、测试并最后一次安装所有软件包," "它们组成功能完整的系统。"