LFS CLFS 工具鏈解析

2021-04-19 07:53:18 字數 2805 閱讀 9632

lfs/clfs工具鏈解析

lfs/clfs工具鏈是一套用於從c/c++源**生成可執行檔案的軟體元件適當地組合在一起形成的系統。它包括4大部分,缺一不可:

1、一套標頭檔案,包含了這些源**所需要訪問的系統介面。

2、binutils,包含一些處理二進位制可執行檔案所需的工具,如彙編器、聯結器等等。

3、gcc,包含了編譯c/c++源**所需的工具,並且還能自動呼叫相關的binutils工具來完成生成源**的工具

4、glibc,包含了系統介面的具體實現。

在上面的定義中,請注意這些軟體必須適當地組合,才能形成完整的工具鏈。那麼怎麼才算適當組合呢?當然,這個工具鏈必須能夠發揮作用,也就是確實能夠編譯出目標**,然後才能算適當組合。

那麼,乙個適當組合的工具鏈應當具有什麼特點呢?一般我們把工具鏈執行的機器稱為host,所產生的**稱為target。那麼對於工具鏈的要求便是:它必須要能在host上執行,所產生的**必須能在target上執行。再進一步分析:

1、標頭檔案:必須是針對target的,因為使用這個工具鏈編譯的源**需要訪問的系統介面是trget上的。

2、binutils:必須能在host上執行,然而產生target的**。

3、gcc:和binutils一樣。不過這裡要注意的是,gcc自身帶有乙個庫,稱為libgcc,它必須是target上的**。

4、glibc:必須是target上的**。

有了這些基本認識,讓我們來看一看一些實際的工具鏈構造過程。

lfs工具鏈構造順序:binutils p1->gcc p1->標頭檔案->glibc->adjust->gcc p2->binutils p2

正如youbest指出的,第一遍的binutils和gcc存在的意義,僅僅是為了能編譯出glibc。而glibc的編譯需要工具鏈所有其它內容,包括binutils,gcc和標頭檔案。

lfs不使用交叉編譯,因此host和target永遠是一樣的。在編譯引數中,我們永遠看不到--host和--target的身影。但是,由於工具鏈的引用路徑需要反覆變化,因此我們需要通過修改specs來更改。這點是lfs比較容易出錯的地方。

clfs顧名思義,是要採用交叉編譯的。其構造順序如下:

標頭檔案->cross binutils->cross-gcc c->glibc->gcc final (c/c++)

我們首先看到標頭檔案被放在了開頭。這不是必須的,它完全可以放在glibc之前。cross-gcc只能編譯出c編譯器,因為這時候工具鏈還不全,glibc還不存在,不可能編譯出c++編譯器。然後構建glibc。之後,我們才能編譯出c++編譯器,完成我們的工具鏈。

clfs-sysroot的工具鏈稍有不同,順序如下:

標頭檔案->cross-binutils->glibc標頭檔案->cross-gcc c->gibc->gcc-final (c/c++)

我們看到這裡多了乙個glibc標頭檔案的安裝。事實上,這是由於這裡編譯的gcc是要用sysroot的緣故。在gcc/configure裡面有一段代 碼,大家在vi裡面輸入/inhibit_libc=false就可以發現,在交叉編譯,而沒有sysroot的情況下,inhibit_libc的值會 成為true,而要是sysroot了,就false了。

這個變數的作用,如同有關的注釋所述,是用來關閉gcc對glibc標頭檔案的依賴。因此,在sysroot下我們才會需要這樣乙個安裝glibc標頭檔案的步驟。

我想在sysroot下消除這個步驟,之前測試過這個補丁可行:

使用這個sed命令打個補丁即可:

cp gcc/configure

sed -e 's/inhibit_libc=false/inhibit_libc=true/g' gcc/configure.orig > gcc/configure

不過最近發現有更簡單的方法:在configure的時候加個引數--with-newlib即可。建議採用這個方法,因為不需要打任何補丁。

在此再說一句,工具鏈構建過程中,編譯指令碼對於是否交叉編譯的判斷非常簡單,只要host!=target,就會被認為正在交叉編譯。這也就是為什麼 clfs中使用的$clfs_host通常都是i686-cross-linux-gnu這樣的形式。原因很簡單,因為要確保$clfs_host與$ clfs_target不同。這樣,你完全可以在i686上"交叉編譯"i686的**。

這點非常重要,這意味著我們不需要打任何補丁,即可利用clfs和clfs-sysroot代替lfs來完成系統。對於想做multilib的朋友,這也是乙個福音。畢竟,clfs-sysroot比起clfs和lfs來,節省了大量的編譯過程。

最後,我們來理解一下如何作cclfs工具鏈。這意味著我們要在乙個平台上構建在第二個平台上執行、生成第三個平台上**的工具鏈。我們用build表示 構建工具鏈的機器,host表示工具鏈要執行的機器,target表示工具鏈生成的**所在機器。而在工具鏈元件上,host-target binutils表示該binutils在host上執行,要生成target的**。

步驟如下:

host 標頭檔案->build-host binutils->build-host gcc c->host glibc->target 標頭檔案->build-target binutils->build-target gcc c->target glibc->host-target binutils->host-target gcc final (c/c++)

注意事項如下。首先,標頭檔案必須在相應的glibc之前安裝。其次,build-target的binutils和gcc在這裡的目的是生成target glibc。而build-host binutils 還會被構建host-target binutils和gcc的過程使用到。最後,前兩次的gcc都可以只生成c編譯器,因為他們的目的都只是生成glibc。只有最後一次gcc需要完整生 成。

啥是工具鏈和GNU工具鏈

在軟體工程中,工具鏈 英語 toolchain 是一系列用於製作軟體的工具。這些工具一般乙個接乙個地運用,一件工具的輸出輸入至下一件工具,但廣義上可以單單是指多個相關的工具。工具鏈一般包括用來編輯源 的文字編輯器 生成可執行檔案的編譯器及鏈結器 連線作業系統的庫 以及偵錯程式。例子有gnu tool...

交叉工具鏈

理,但由於嵌入式軟體的執行平台不是本地,所以要做一些特殊處理,讓編譯環境信賴的類庫脫離本地信 賴,使用嵌入式平台的類庫來進行鏈結,處理這一過程就叫作交叉編譯工具鏈。機是執行嵌入式軟體的硬體平台。o 只啟用預處理,編譯,和彙編,也就是他只把程式做成obj檔案 wall 指定產生全部的警告資訊 o2 編...

工具鏈簡述

工具鏈軟體包括binutils gcc glibc gdb等。gcc gnu compiler collection,編譯器,對於c c 語言的完整支援,需要支援glibc庫。glibc 是應用程式程式設計的函式庫軟體包,可以編譯生成靜態庫和共享庫。完整的gcc需要支援glibc。gdb 除錯工具,...