<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
  "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
  <!ENTITY % general-entities SYSTEM "../general.ent">
  %general-entities;
]>

<sect1 id="ch-system-adjusting">
  <?dbhtml filename="adjusting.html"?>

  <title>调整工具链</title>

  <!--para>Now that the final C libraries have been installed, it is time to adjust
  the toolchain so that it will link any
  newly compiled program against these new libraries.</para-->
  <para>现在最终的 C 运行库已经安装好了，这时就要调整工具链，
	  以便将新编译的任何程序都链接到新的 C 运行库。</para>

  <!--para>First, backup the <filename class="directory">/tools</filename> linker,
  and replace it with the adjusted linker we made in chapter 5. We'll also create
  a link to its counterpart in
  <filename class="directory">/tools/$(uname -m)-pc-linux-gnu/bin</filename>:</para-->
  <para>首先，备份 <filename class="directory">/tools</filename>
	  中的链接器，把它替换成第 5 章准备的调整好的链接器。
	  我们也会把
	  <filename class="directory">/tools/$(uname -m)-pc-linux-gnu/bin</filename>
	  中对应的链接器替换成一个符号链接：</para>

<screen><userinput>mv -v /tools/bin/{ld,ld-old}
mv -v /tools/$(uname -m)-pc-linux-gnu/bin/{ld,ld-old}
mv -v /tools/bin/{ld-new,ld}
ln -sv /tools/bin/ld /tools/$(uname -m)-pc-linux-gnu/bin/ld</userinput></screen>

  <!--para>Next, amend the GCC specs file so that it points to the new
  dynamic linker. Simply deleting all instances of <quote>/tools</quote> should
  leave us with the correct path to the dynamic linker. Also adjust the specs file
  so that GCC knows where to find the correct headers and Glibc start files.
  A <command>sed</command> command accomplishes this:</para-->
  <para>下面修改 GCC 的 specs 文件，使其指向新的动态链接器。
	  把所有的 <quote>/tools</quote> 删除掉就会留下正确的路径。
	  另外，调整 specs 文件，使得 GCC 知道去哪里寻找正确的头文件和
	  Glibc 启动文件。一个 <command>sed</command> 命令即可完成以上工作：
  </para>

<screen><userinput>gcc -dumpspecs | sed -e 's@/tools@@g'                   \
    -e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' \
    -e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' &gt;      \
    `dirname $(gcc --print-libgcc-file-name)`/specs</userinput></screen>

  <!--para>It is a good idea to visually inspect the specs file to verify the
  intended change was actually made.</para-->
  <para>这时最好浏览一下生成的 specs 文件，以确认确实进行了我们期望的修改。
  </para>

  <!--para>It is imperative at this point to ensure that the basic
  functions (compiling and linking) of the adjusted toolchain are working
  as expected. To do this, perform the following sanity checks:</para-->
  <para>现在的当务之急是保证调整过的工具链的基本功能（编译和链接）
	  能够像我们期望的那样工作。为此，进行下列完整性检查：</para>

<screen os="a"><userinput>echo 'int main(){}' &gt; dummy.c
cc dummy.c -v -Wl,--verbose &amp;&gt; dummy.log
readelf -l a.out | grep ': /lib'</userinput></screen>

  <!--para os="b">There should be no errors,
  and the output of the last command will be (allowing for
  platform-specific differences in dynamic linker name):</para-->
  <para os="b">上述命令不应该出现错误，最后一行命令输出的结果应该
	  （不同平台的动态链接器名称可能不同）是：</para>

<screen os="c"><computeroutput>[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]</computeroutput></screen>

  <!--para>Note that on 64-bit systems <filename class="directory">/lib</filename> is
  the location of our dynamic linker, but is accessed via a symbolic link
  in /lib64.</para-->
  <para>注意在 64 位系统上 <filename class="directory">/lib</filename>
	  是动态链接器的位置，但通过 /lib64 中的符号链接访问。</para>
  <note><title>译注</title>
	  <para>虽然可以把编译器查找动态链接器的位置修改到 /lib 中，
		  使得构建出的 LFS 系统完全不需要 /lib64 目录，
		  但动态链接器的位置是硬编码在 ELF 文件中的。
		  因此，为了运行其他机器编译出来的二进制文件
		  （例如 BLFS 中安装 JDK 时），
		  必须创建该符号链接以符合通用惯例。</para>
  </note>

  <note><para>在 32 位系统上，解释器是 /lib/ld-linux.so.2 。</para></note>

  <para os="d">下面确认我们的设定能够使用正确的启动文件：</para>

<screen os="e"><userinput>grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log</userinput></screen>

  <para os="f">以上命令应该输出：</para>

<screen><computeroutput>/usr/lib/../lib/crt1.o succeeded
/usr/lib/../lib/crti.o succeeded
/usr/lib/../lib/crtn.o succeeded</computeroutput></screen>

  <para os="g">确认编译器能正确查找头文件：</para>

<screen><userinput>grep -B1 '^ /usr/include' dummy.log</userinput></screen>

  <para os="h">该命令应当输出：</para>

<screen><computeroutput>#include &lt;...&gt; search starts here:
 /usr/include</computeroutput></screen>

  <para os="i">下一步确认新的链接器使用了正确的搜索路径：</para>

<screen os="j"><userinput>grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'</userinput></screen>

	<para os="k">那些包含 '-linux-gnu' 的路径应该忽略，
		除此之外，以上命令应该输出：</para>

<screen><computeroutput>SEARCH_DIR("/usr/lib")
SEARCH_DIR("/lib")</computeroutput></screen>

  <para os="l">之后确认我们使用了正确的 libc：</para>

<screen os="m"><userinput>grep "/lib.*/libc.so.6 " dummy.log</userinput></screen>

  <para os="n">以上命令应该输出：</para>

<screen os="o"><computeroutput>attempt to open /lib/libc.so.6 succeeded</computeroutput></screen>

  <para os="p">最后，确认 GCC 使用了正确的动态链接器：</para>

<screen os="q"><userinput>grep found dummy.log</userinput></screen>

  <para os="r">以上命令应该输出（不同平台的动态链接器名称可能不同）:</para>

<screen os="s"><computeroutput>found ld-linux-x86-64.so.2 at /lib/ld-linux-x86-64.so.2</computeroutput></screen>

  <!--para os="t">If the output does not appear as shown above or is not received
  at all, then something is seriously wrong. Investigate and retrace the
  steps to find out where the problem is and correct it. The most likely
  reason is that something went wrong with the specs file adjustment. Any
  issues will need to be resolved before continuing with the process.</para-->
  <para os="t">如果输出和以上描述不符，或者根本没有输出，
	  那么必然有什么地方出了严重错误。检查并重新跟踪以上步骤，
	  找到问题的原因，并修复它。
	  最可能的原因是修改 specs 文件的时候出了错误。
	  这里出现的任何问题在继续构建前都必须解决。</para>

  <para os="u">在确认一切工作良好后，删除测试文件：</para>

<screen os="v"><userinput>rm -v dummy.c a.out dummy.log</userinput></screen>

</sect1>
