天天看點

《Linux From Scratch》第二部分:準備建構 第五章:建構臨時檔案系統- 5.2 工具鍊技術備注

         本節解釋總體建構方法之中的某些基本原理和技術細節。并不需要立即了解本節中的所有問題。在進行實際建構的過程中,絕大部分的資訊将會變得愈加清晰。在該過程中可随時查閱本小節的内容。

《Linux From Scratch》第二部分:準備建構 第五章:建構臨時檔案系統- 5.2 工具鍊技術備注

在繼續之前,請留意工作平台的名稱,它通常稱作目标系統三段式名稱。目标系統三段式名稱可通過運作腳本 config.guess

簡單獲得,許多軟體的源碼包都附帶有該腳本(譯者注:目标系統三段式名稱描述了代碼運作的平台,是GNU 建構系統中的一個核心概念,形如

i686-pc-gnu-linux。它包含三個字段:CPU家族/型号的名稱(如 i686)、供應商(pc)和作業系統名稱(如

gnu-linux)。更詳細的資訊請參閱 http://wiki.osdev.org/Target_Triplet)。解壓 Binutils

源碼包,執行其中的腳本:<code>./config.guess</code> 并檢視其輸出。例如,對于一個現代的 32 位英特爾處理器,其輸出很可能為 i686-pc-linux-gnu。

還請留意平台的動态連結器的名稱,它通常被稱為動态加載器(不要與 Binutils 中的标準連結器 ld 混淆)。該動态連結器由 Glibc 提供,它尋找并加載程式所需的共享庫,為程式運作作準備,并運作它。對于 32 位英特爾的機器,動态連結器的名稱為 <code>ld-linux.so.2</code>。判斷動态連結器的一個可靠方法是檢查宿主系統中的任意一個二進制檔案,執行:<code>readelf -l &lt;二進制檔案名&gt; | grep interpreter</code> 且檢視其輸出。可在 Glibc 源碼樹的根目錄下的 <code>shlib-versions</code> 檔案中找到所有平台的權威參考。

通過改變 <code>LFS_TGT</code> 變量的目标系統三段式中的 “供應商” 字段,進而稍微調整工作平台的名稱,以保證第一遍建構 Binutils 和 GCC 時能夠生成相容的交叉連結器和交叉編譯器。此處的交叉連結器和交叉編譯器生成的二進制檔案與目前的硬體相容,而不是用于其它的硬體架構。

臨時庫經交叉編譯獲得。由于交叉編譯原本就不應該依賴于宿主系統,是以,通過降低宿主系統的頭檔案或庫進入新工具的可能性,該方法可去除目标系統的可能污染。交叉編譯的方式,還可以在 64 位硬體平台上同時建構出 32 位和 64 位庫。

謹慎操作 GCC 源碼,以告訴編譯器将使用哪個目标系統動态連結器。

Binutils 是首個安裝的包,這是因為執行 GCC 和 Glibc 的 configure

時都将進行有關彙編器和連結器的多項特性測試,以判斷允許或禁用哪些軟體特性。其重要性可能更甚于最初的意識。對 GCC 或 Glibc

的錯誤配置可能導緻工具鍊出現難以捉摸的問題,可能直到整個建構過程接近尾聲時才會顯現出這些問題。通常情況下,一次測試套件失敗可在你進行太多其它工作前暴露出該錯誤。

Binutils 将其彙編器和連結器安裝在兩個位置,即 <code>/tools/bin</code> 和 <code>/tools/$LFS_TGT/bin</code>。一個位置的工具是硬連結到另一個位置的。連結器的一個重要方面是它的庫搜尋順序。可給 ld 傳遞參數 <code>--verbose</code> 獲得詳細資訊。如,<code>ld --verbose | grep SEARCH</code> 可得到目前的搜尋路徑及其順序。通過編譯一個模拟程式并向連結器傳遞 <code>--verbose</code> 開關,可顯示 ld 都連結了哪些檔案。例如,<code>gcc dummy.c -Wl,--verbose 2&gt;&amp;1 | grep succeeded</code> 将顯示連結過程中成功打開的所有檔案。

下一個安裝的包是 GCC。下面是運作 GCC 的 configure 的輸出的一個例子:

基于前述原因,這很重要。它還說明了 GCC 的配置腳本并不會搜尋 PATH 目錄來尋找使用什麼工具。不過,在 gcc 自身的實際運作中,并不需要使用同樣的搜尋路徑。運作:<code>gcc -print-prog-name=ld</code> 可獲知 gcc 使用是何種标準連結器(LCTT 譯注:<code>gcc -print-prog-name</code> 這個指令是為了顯示 gcc 使用的某些内部工具的絕對路徑,但事實上,ld 并不是 GCC 的内部工具,是以這條指令實際上沒什麼用)。

在編譯模拟程式時,向 gcc 傳遞指令行選項 <code>-v</code> 可獲得詳細資訊。例如,<code>gcc -v dummy.c</code> 将顯示預處理器、編譯和彙編階段的詳細資訊,包括 gcc 的 include 搜尋路徑及其順序。

下一個安裝的包是經過淨化的 Linux API 頭檔案。這些頭檔案可使得标準 C 庫(Glibc)與 Linux 核心提供的特性進行交行互動。

下一個安裝的包是 Glibc。建構 Glibc 時,最重要的考量是編譯器、二進制工具和核心頭檔案。由于 Glibc 總是使用傳遞給它的配置腳本的 <code>--host</code> 參數有關的編譯器,如,在我們這個場景中是 i686-lfs-linux-gnu-gcc,是以編譯器通常不是一個問題。二進制工具和核心頭檔案可能會更複雜一些。是以,請謹慎行事并利用可用的配置開關以強制使用正确的選擇。configure 運作完畢,目錄 <code>glibc-build</code> 下的檔案 <code>config.make</code> 包含有所有的重要細節。需要注意的是,<code>CC="i686-lfs-gnu-gcc"</code> 用來控制使用哪個二進制工具,<code>-nostdinc</code> 和 <code>-isystem</code> 标志用來控制編譯器的 include 搜尋路徑。這些條目強調了 Glibc 包的一個重要方面,即其建構機制是非常自給自足的,通常并不依賴默工具鍊的預設設定。

在第二遍編譯 Binutils 過程中,我們能夠利用配置開關 <code>--with-lib-path</code> 來控制 ld 的庫搜尋路徑。

建立者:Gerard Beekmans

編輯者:Matthew Burgess 和 Armin K.

翻譯團隊:LCTT

譯者/校對:Yuking-net,wxy

繼續閱讀