本節書摘來自異步社群《嵌入式linux開發實用教程》一書中的第1章,第1.3節,作者 朱兆祺,李強,袁晉蓉,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
平常我們做的編譯叫本地編譯,也就是在目前平台編譯,編譯得到的程式也是在本地執行。相對而言的交叉編譯指的是在一個平台上生成另一個平台的可執行代碼。
常見的交叉編譯有以下3種。
在windows pc上,利用ads(arm 開發環境),使用armcc編譯器,編譯出針對arm cpu的可執行代碼。
在linux pc上,利用arm-linux-gcc編譯器,編譯出針對linux arm平台的可執行代碼。
在windows pc上,利用cygwin環境,運作arm-elf-gcc編譯器,編譯出針對arm cpu的可執行代碼。
由于一般嵌入式開發系統的存儲大小是有限的,通常都要在性能優越的pc上建立一個用于目标機的交叉編譯工具鍊,用該交叉編譯工具鍊在pc上編譯目标機上要運作的程式,比如在pc平台(x86 cpu)上編譯出能運作在以arm為核心的cpu平台上的程式。要生成在目标機上運作的程式,必須要用交叉編譯工具鍊完成。交叉編譯工具鍊是一個由編譯器、連接配接器和解釋器組成的綜合開發環境,交叉編譯工具鍊主要由binutils、gcc和glibc 3個部分組成。有時出于減小libc 庫大小的考慮,也可以用别的 c 庫來代替 glibc,例如 uclibc、dietlibc 和 newlib。建立交叉編譯工具鍊是一個相當複雜的過程,如果不想自己經曆複雜繁瑣的編譯過程,網上有一些編譯好的可用的交叉編譯工具鍊可以下載下傳,但就以學習為目的來說,讀者有必要學習自己制作一個交叉編譯工具鍊。本節通過具體的執行個體講述基于arm的嵌入式linux交叉編譯工具鍊的制作過程。
制作arm-linux交叉編譯工具鍊的一般通過crosstool工具或者crosstool_ng,前者使用友善,但是制作會受到一些限制,使用crosstool最多隻能編譯gcc 4.1.1、glibc 2.x的版本。crosstool-ng是新的用來建立交叉工具鍊的工具,它是crosstool的替換者,crosstool_ng有更好的定制性,并且一直保持着更新,對新版本的編譯工具鍊的支援比較好,當然也帶來了一些麻煩,它并不是下載下傳下來就可以使用的,必須先配置安裝。我們這裡選用crosstool_ng來制作我們的編譯鍊。
1.安裝crosstool_ng
在crosstool_ng官網上下載下傳最新版本。
擷取源碼操作指令:
下載下傳源碼成功之後解壓源碼:
考慮到後續将要使用到的各種目錄,在這裡先建立好後續所需目錄。
由于ubuntu作業系統的很多開發軟體都沒有安裝,是以要先安裝一些制作交叉編譯鍊必備的軟體。在ubuntu下安裝軟體的指令為:sudo apt-get install*。
配置整個工程并且進行依賴檢測:
在安裝過程中,提示如下錯誤:
輸出錯誤提示缺失bison這個軟體,安裝:
安裝完成之後,再次進行配置:
又一次輸出錯誤:
提示缺失flex這個軟體,進行安裝:
安裝完成之後,再一次進行配置:
又一次提示錯誤:
提示缺失gperf這個軟體,進行安裝:
再一次提示出錯:
缺失makeinfo軟體,進行安裝,如果安裝的是makeinfo,則會有如下提示:
此時應該安裝texinfo軟體:
這次的配置成功,如果讀者操作還會報錯的話,依照上面方法找出其根源進行改正即可。成功配置之後會自動建立我們需要的makefile檔案。
執行makefile檔案:
編譯成功之後進行安裝:
成功安裝之後,可以看到已經安裝到指定的目錄下,最後輸出這麼一句話:
這是在提醒我們不要忘記了配置環境變量,多麼人性化的提示。接下來配置環境變量。
執行使其生效:
使用ct-ng –v指令檢視安裝結果:
ok!ct-ng環境變量添加成功,也就意味着整個crosstool-ng安裝成功。
2.配置交叉編譯鍊
現在需要去做的就是配置要編譯的交叉編譯工具鍊,在crosstool-ng中有很多已經做好的預設配置(位于crosstool-ng- x.y.z(crosstool-ng-1.18.0)/samples目錄下),這裡隻需要進行修改就好了。對于編譯器元件部分的版本最好不要修改,因為那個應該是經過測試後的最高版本了,但核心版本可以修改。
可以看到samples目錄下的一些預設配置,如下所示:
裡面有很多預設配置,有arm、avr32、mips、powerpc等硬體平台,而arm平台有如下幾個:
因為是制作arm-linux交叉編譯鍊,是以選擇arm-unknown-linux-gnueabi進行配置。将arm-unknown-linux-gnueabi檔案夾複制到crosstool-build/目錄下:
将預設配置檔案拷貝到工作目錄(crosstool-build)下并改名為.config,因為預設的配置檔案為.config,完成之後可以加載需要的配置。
執行ct-ng menuconfig進入配置界面進行配置:
進入配置界面,如圖1.1所示。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLyADZiVmYzEzNkFjZ5kDN2E2NlJGNmFTOxgDMwUmNxkTYjJTNyMzYy8CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
下面設定源碼目錄和安裝目錄,這需要讀者依據自己實際設定的情況來進行配置。
第一步,設定源碼包路徑和交叉編譯器的安裝路徑。
配置之後的結構如圖1.2所示。
第二步,修改交叉編譯器針對的構架。
因為本次是針對ok6410制作編譯鍊,那就依據s3c6410的硬體特性來制作。
target options是重點要修改的地方(以下配置均是基于已拷貝過來的配置)。
architecture level()需要進行修改。
通過查找資料,這個應該是指令集的架構,對于s3c6410 arm1176jzf-s核心使用的是armv6zk架構,就選armv6zk。那麼,具體都支援哪些架構呢?可以用man gcc來查詢,搜尋arm,再搜尋-march=就可以找到本gcc支援的處理器核心清單了:
emit assembly for cpu()需要進行修改。
這個對應的是cpu的核心類型。同樣,也和上面的選項一樣,對應一個gcc選項。gcc的描述如下。
這樣看簡單一些了,如果是s3c2410/s3c2440就選arm920t,如果是s3c6410就選arm1176jzf-s。
tune for cpu() ,對應的gcc描述如下:
意思是說這個選項和-mcpu 很類似,這裡是指真實的cpu型号。不過有讀者是編譯2440的工具鍊,這裡選擇的是arm9tdmi,如果不是,那就空着。這裡的作用是如果arm920t處理不了,就用arm9tdmi的方式來編譯。
與floating point()浮點相關的選項s3c6410 有硬體vfp,是以這裡選的是hardware fpu。這個是給有硬浮點的處理器強行選軟浮點用的。
use specific fpu()跟浮點有關,這裡不選任何内容。至于怎麼組合,讀者可以跟據自己的cpu的實際情況進行相應的配置。
當然,如果讀者需要用它來編譯java那就不用去除。
其他選項采用預設設定存盤然後退出,這樣就配置完了。
開始編譯,此編譯過程需要花費大約兩個小時,最終編譯出arm-linux-gcc-4.4.1編譯鍊。
這裡要安裝的交叉編譯鍊版本是arm-linux-gcc 4.4.1(交叉編譯鍊的版本很多,讀者可以自行安裝版本更高的編譯鍊)。采用的linux系統環境是ubuntu10.04.4。具體的操作步驟如下。
1.在/usr/local下面建立一個檔案夾:mkdir arm,将arm-linux-gcc 4.4.1放在arm檔案夾裡面。然後解壓縮,指令根據壓縮包的字尾不同而不同。
2.添加環境變量,vim /etc/profile。
3.在最後一行添加:export path=$path:/usr/local/arm/4.4.1/bin。
4.退出執行指令:source /etc/profile。使其生效。
5.檢測安裝是否成功:arm-linux-gcc -v ;如果成功,輸出最後一行則會提示:gcc version 4.4.1 (sourcery g++ lite 2009q3-67)。描述如下:
筆者建議最好不要在root使用者下進行安裝,否則使用交叉編譯鍊可能會存在權限限制。