在一種計算機環(huán)境中運行的編譯程序,能編譯出在另外一種環(huán)境下運行的代碼,我們就稱這種編譯器支持交叉編譯。這個編譯過程就叫交叉編譯。簡單地說,就是在一個平臺上生成另一個平臺上的可執(zhí)行代碼。這里需要注意的是所謂平臺,實際上包含兩個概念:體系結(jié)構(gòu)(Architecture)、操作系統(tǒng)(Operating System)。同一個體系結(jié)構(gòu)可以運行不同的操作系統(tǒng);同樣,同一個操作系統(tǒng)也可以在不同的體系結(jié)構(gòu)上運行。舉例來說,我們常說的x86 Linux平臺實際上是Intel x86體系結(jié)構(gòu)和Linux for x86操作系統(tǒng)的統(tǒng)稱;而x86 WinNT平臺實際上是Intel x86體系結(jié)構(gòu)和Windows NT for x86操作系統(tǒng)的簡稱。
有時是因為目的平臺上不允許或不能夠安裝我們所需要的編譯器,而我們又需要這個編譯器的某些特征;有時是因為目的平臺上的資源貧乏,無法運行我們所需要編譯器;有時又是因為目的平臺還沒有建立,連操作系統(tǒng)都沒有,根本談不上運行什么編譯器。
交叉編譯這個概念的出現(xiàn)和流行是和嵌入式系統(tǒng)的廣泛發(fā)展同步的。我們常用的計算機軟件,都需要通過編譯的方式,把使用計算機語言編寫的代碼(比如C代碼)編譯(compile)成計算機可以識別和執(zhí)行的二進制代碼。比如,我們在Windows平臺上,可使用Visual C++開發(fā)環(huán)境,編寫程序并編譯成可執(zhí)行程序。這種方式下,我們使用PC平臺上的Windows工具開發(fā)針對Windows本身的可執(zhí)行程序,這種編譯過程稱為native compilation,中文可理解為本機編譯。然而,在進行嵌入式系統(tǒng)的開發(fā)時,運行程序的目標平臺通常具有有限的存儲空間和運算能力,比如常見的 ARM 平臺,其一般的靜態(tài)存儲空間大概是16到32MB,而CPU的主頻大概在100MHz到500MHz之間。這種情況下,在ARM平臺上進行本機編譯就不太可能了,這是因為一般的編譯工具鏈(compilation tool chain)需要很大的存儲空間,并需要很強的CPU運算能力。為了解決這個問題,交叉編譯工具就應運而生了。通過交叉編譯工具,我們就可以在CPU能力很強、存儲控件足夠的主機平臺上(比如PC上)編譯出針對其他平臺的可執(zhí)行程序。
1.交叉編譯的基礎知識
在做實際工作之前,我想我們應該先掌握一些關(guān)于交叉編譯的基本知識,其實說白了也就是理解一些我們經(jīng)常會碰到的英文單詞;
host 主機平臺。
target 目的平臺。
perfix 交叉編譯器的安裝位置。
xxx-xxxx-xxxxx 平臺描述。
我們在主機平臺上開發(fā)程序,并在這個平臺上運行交叉編譯器,編譯我們的程序;而由交叉編譯器生成的程序?qū)⒃谀康钠脚_上運行。這里值得說明得是平臺描述,象arm-linux、i386-pc-linux2.4.3這樣的字符串我們經(jīng)常會看到,其實它是用來描述平臺的,它有完整格式、縮減格式和別名之分。完整格式是:CPU-制造廠商-操作系統(tǒng),如sparc-sun-sunos4.1.4,說明平臺所使用的CPU是sparc,制造廠商是sun,上面運行的操作系統(tǒng)是SunOS,版本是4.1.4。當然,我們都不愿記這么長的東西,因此可以使用短格式,短格式中有選擇地去處了制造廠商、軟件版本等信息,因此我們同樣可以用sparc-sunos或sparc-sunos-sunos4來描述這個平臺。如果覺得這個還是太麻煩,那就可以使用別名,sun4m就可以很簡單地描述這個平臺。需要注意的是,并不是所有的平臺都有別名,也不是所有的短格式都可以正確地描述平臺。
2.我需要準備些什么
先得準備好主機平臺,建議采用x86 Linux做主機平臺,因為這樣需要的設置工作少。當然你也可以使用你所喜歡的平臺或你所能得到的平臺,其中的區(qū)別在于你可能必須做更多的設置工作,當然也有這種可能,就是你所選擇的主機平臺根本不能生成適用于目標平臺的正確的交叉編譯器。
對于交叉編譯器,可以自己生成,也可以從網(wǎng)上下載。區(qū)別在于從網(wǎng)上下載非常簡單方便,但也許你找不到適合你所選擇的平臺的。而自己生成交叉編譯器,有時會遇到很多挫折,但這的確是個有趣的值得懷念的經(jīng)歷。
如果你想自己生成交叉編譯器,那你必須先準備下面這些東西
1、磁盤空間。至少要500M左右的空間,如果想一氣呵成的話,那就要900M-1G的空間。
2、各種源代碼。你至少要準備binutils-2.11.2、gcc-2.95.3、linux-2.4.6、newlib-1.8.2或glibc-2.2.2的源代碼。
如果你所使用的主機平臺不是運行的linux,那你還必須注意以下這些問題
1、GNU bash必須是默認shell,所以你也許得把/bin/sh改成bash。
2、你要確認已經(jīng)安裝了GNU bison,因為這些軟經(jīng)同樣使用了bison擴展。
3、GNU gmake是系統(tǒng)默認得make,因為這些軟件都使用了gmake擴展,如果不是,在需要make時,記得使用gmake。
4、如果你想生成交叉glibc,則GNU gsed必須是默認sed,因為glibc會用到gsed的擴展。
5、如果你想生成交叉glibc,那還必須準備glibc-linuxthreads-2.2.2的源代碼。
6、確認正確的路徑搜索順序,讓GNU軟件首先被執(zhí)行。
3.怎樣生成交叉編譯器
要進行交叉編譯,我們需要在主機平臺上安裝對應的交叉編譯工具鏈(cross compilation tool chain),然后用這個交叉編譯工具鏈編譯我們的源代碼,終生成可在目標平臺上運行的代碼。常見的交叉編譯例子如下:
1、在Windows PC上,利用ADS(ARM 開發(fā)環(huán)境),使用armcc編譯器,則可編譯出針對ARM CPU的可執(zhí)行代碼。
2、在Linux PC上,利用arm-linux-gcc編譯器,可編譯出針對Linux ARM平臺的可執(zhí)行代碼。
3、在Windows PC上,利用cygwin環(huán)境,運行arm-elf-gcc編譯器,可編譯出針對ARM CPU的可執(zhí)行代碼。