交叉編譯器簡介
首先和大家分享的是嵌入式系統(tǒng)移植中交叉編譯工具集题造,具體如下圖:
如圖坐求,第一個問題是為什么要有交叉編譯?
眾所周知我們的CPU它工作方式非常簡單晌梨,就是根據(jù)不同的高低電平去干不同的事情。如下圖:
如圖须妻,比如說CPU要做加法仔蝌,那么很顯然x86可以這樣認為“add 1010”如果說看到這樣一個組合我就認為CPU要做加法了。那么自然而然我們程序員只要寫成高低的一個標(biāo)示給CPU荒吏,CPU基本就能做加法敛惊。所以這個跟我們前面學(xué)習(xí)匯編的思想很像,但是我們現(xiàn)在不一樣了因為我們的PC一般來說是x86的绰更,但是如果說我們現(xiàn)在的CPU換一款換成ARM同樣后面是1010瞧挤,那么1010對于ARM來說因為它是兩家不同的公司,那么它對這樣的指定級的編碼和譯碼的時候是不是會有不同的結(jié)果儡湾。比如說在arm中的1010就可能不是加法了而可能是mov這一數(shù)據(jù)的搬移指令特恬。那么大家就可以發(fā)現(xiàn)如果我們在x86上編譯的一個二進制集合包或者是二進制程序集合,我們不做任何的修改直接放到arm板子上運行那么就一定會出現(xiàn)一個新的問題徐钠,就是我們的arm是不認識這樣的集合的癌刽,也就是說跟你本身想做加法的邏輯是不一致的。
所以這樣我們就迫切想要去在x86上去編譯一個arm也能理解的邏輯尝丐。也就是這個情況就變成了如下圖:
如圖显拜,我們x86下也就是我們的主機和目標(biāo)機,就是我們原來最開始學(xué)習(xí)應(yīng)用開發(fā)的時候我們的主機就是x86爹袁,然后我們的目標(biāo)機也是x86远荠,因為我們運行也是在x86上運行起來進程或網(wǎng)絡(luò)編程的概念。但是我們現(xiàn)在嵌入式開發(fā)不一樣失息,我們的主機沒有變還是x86但是我們的目標(biāo)機現(xiàn)在已經(jīng)變成了ARM CPU譬淳。
所以這樣來看档址,我們原本正常情況下主機跟目標(biāo)機是統(tǒng)一品牌的。但是到現(xiàn)在我們就變成了主機是一個平臺目標(biāo)機是另外一個平臺瘦赫,那這種情況我們就稱為交叉辰晕。
也就是說,這種情況下我們就需要一個交叉編譯器來完成從一個結(jié)構(gòu)編譯另外一個結(jié)構(gòu)的編譯器确虱。如果目標(biāo)機跟主機是同一平臺的我們就稱為同一編譯器含友,比如說我們最典型的gcc,以上就是我們第一個為什么要有交叉編譯器的概念校辩,那么在這個概念中我們要引入一個命令叫file命令窘问,通過這個命令我們來加深一下為什么我們在以后編譯開發(fā)過程中可能遇到的新的問題,也就是我們都知道Linux系統(tǒng)中一個可執(zhí)行程序并沒有后綴名宜咒,也就是我們不會像Windows一樣寫成ese或者.xx讓大家來區(qū)分惠赫,很有可能我們最終可執(zhí)行程序都叫build,那么這種情況下就會經(jīng)常出現(xiàn)如果我不小心在實際開發(fā)中把x86下編譯的build燒寫到了arm板上故黑,結(jié)果跑了半天都跑不出來儿咱,甚至整個程序運行的邏輯都是混亂的。
這個原有就在于有時候我們粗心馬虎把x86的程序放在了arm板上了场晶,那么我們應(yīng)該怎么去避免這樣一個情況了混埠?
如圖我們還是用一個1.c用一個非常簡單的hello world做一個例子,然后我們用gcc -o build 1.c生成一個build程序诗轻,然后點擊ls查看會發(fā)現(xiàn)這個build一沒有后綴名二沒有其他的標(biāo)識钳宪,我怎么知道它是在x86下運行還是在arm下運行,或者換句話來說把這個程序放到我的板子上能不能運行起來呢扳炬?然后我們就來看第一個命令叫做file build吏颖,然后點擊回車鍵大家就可以發(fā)現(xiàn)它上面有一堆東西,這一堆東西一般情況下我們不用全部關(guān)心但是我們唯一需要關(guān)心的就是“x86-64”因為我這個機器是64位的恨樟,所以說你會發(fā)現(xiàn)看build真正屬性的第二個選項中它會告訴我們build工作的平臺是x86認識的半醉,這就是從file中去讀它文件頭的一個信息。
以上就是file非常重要的一個概念厌杜。
交叉編譯結(jié)果
下面我們來看如果有了交叉編譯器后奉呛,交叉編譯的結(jié)果又會變成什么樣子。在之前我們講交叉編譯器也說過一般有兩種方法:第一就是直接用編譯好的夯尽,第二就是自己手動編譯瞧壮。我們今天還是采用芯片廠商已經(jīng)編譯好的。
在Linux系統(tǒng)安裝軟件其實比較簡單匙握,不是雙擊的形式咆槽,其實就是個解包的過程,它主要是把工具集解壓到一個目錄上然后我們直接使用它就可以圈纺。
然后我們來看看安裝交叉編譯器的方法:
安裝交叉編譯器其實非常簡單就是一個解壓縮的過程秦忿。解壓縮的過程麦射,解壓到linux標(biāo)準(zhǔn)目錄,在安裝過程中我們就直接在Windows目錄下把交叉編譯器拷到你們的共享目錄就可以了灯谣。
如圖潜秋,安裝命令就是“tar-zxvf arm-linux-qcc-4.5.1-vfp-20120301.tgz ”注意在上面的那行命令中的tgz,它實際上是個縮寫胎许,所以使用的就是zcvf峻呛,然后記住千萬不用把這個包解完就直接回車了,因為我們知道這個包是默認Windows的共享目錄辜窑,所以一旦回車就可能導(dǎo)致編譯器中有些工具是用不了的钩述,最典型的工具就是軟鏈接因為在Windows里是沒有軟鏈接的概念的,所以說如果這個包里面有軟鏈接的文件那很有可能就是解壓出來它就支持不了穆碎,最后就可能報錯或者占用的數(shù)據(jù)量比較大牙勘。所以我們建議大家盡量不要安裝在Windows的共享目錄盡量安裝在Linux本身的虛擬機的硬盤目錄。所以我們在切換到另一個目錄需要“-C”一般來說交叉編譯器在制作的時候就把整個目錄都給你打包好了所禀,所以有寫時候我們就習(xí)慣直接解壓的根(/)上方面,通過根就相當(dāng)于把解壓的權(quán)限直接交給交叉編譯器,然后點擊回車鍵:
如圖色徘,大家會發(fā)現(xiàn)這個地方出現(xiàn)了一些問題葡幸,“文件已存在”這個原因是因為我剛才在敲命令的時候沒有使用超級用戶,所以我們要早命令“tar-zxvf arm-linux-qcc-4.5.1-vfp-20120301.tgz -C /”前加上一個sudo在去輸入就沒有錯了贺氓。然后我們把它進行解壓,在解壓過程中床蜘,一般來說是沒有太大問題的辙培,大家可以小心點看它有沒有報什么錯誤,如果沒有報錯誤就可以了邢锯。
解壓完成后:
如圖扬蕊,我們進入opt目錄后,因為opt中本身就有個目錄丹擎,但是我們可以一級一級的進去尾抑。最后進入4.5.1目錄后會發(fā)現(xiàn)這個目錄下的選項其實就是交叉編譯器中總括的安裝包,其中有寫目錄對我們來說是有幫助的蒂培。
比如說“bin”這個目錄就相當(dāng)于交叉編譯器中的命令集合再愈,也就是說我們的命令基本上應(yīng)該在bin里去找。而“l(fā)ib”它有兩種形式护戳,第一種形式就是我們交叉編譯器在運行的時候它有一個庫翎冲。第二種就是我們最終要交叉編譯器雖然在x86中運行但是最終要編譯成arm,所以說我們在編譯過程中就涉及到兩種庫媳荒,一種是x86的庫一種就是arm的庫抗悍。
也就是說我們交叉編譯器本身是個軟件驹饺,它在運行需要x86的一個平臺,所以這個時候它肯定是要有一個x86的庫為它運行時準(zhǔn)備的缴渊,但是它最終生成的目標(biāo)要依賴arm體系赏壹。所以它鏈接的時候需要arm庫的提供。
如圖衔沼,我們先進入bin里面看一下蝌借,這個地方大家會發(fā)現(xiàn)文件比較多,當(dāng)然文件雖多大家可以發(fā)現(xiàn)都有一個統(tǒng)一的規(guī)則俐巴。當(dāng)然這個地方先來提成一個思想也就是說我們安裝的叫交叉編譯集合或者叫交叉編譯鏈一個整塊骨望,也就是說我們不僅僅要用到它叫g(shù)cc的東西,同時還可以看到gcc的外面還有很多其他的命令欣舵,這些命令其實就是我們在后面會給大家介紹叫做工具集的功能擎鸠,所以說我們實際上安裝交叉編譯器就是安裝一套工具,不光是gcc缘圈。然后輸入如圖上命令劣光,它其實就是個l文件,l文件軟鏈接到本地目錄下的文件糟把,所以這個命名規(guī)則跟我們之前講的交叉編譯器的規(guī)則也很像“arm-none-linux-gnueabi-gcc”也就是在Linux下新的標(biāo)準(zhǔn)接口的一個gcc工具绢涡。一般來說這個名字太長懶得去寫,我們就可以用軟鏈接的方式去把它鏈在這里遣疯,直接敲“arm-linux-gcc”就可以了雄可,所以這就是我們比較常用的方式。
那么我們安裝的一般步驟來說第一步就是把它解壓缠犀,一般來說要把它解壓到linux標(biāo)準(zhǔn)目錄下一步就是我們的兩種使用方法数苫。
使用
1.使用簡單方法(就是我直接在shear中敲)
#arm-linux-gcc -o build 1.c(這樣就可以直接用它了,跟我們的gcc命令一樣辨液,只是調(diào)用命令不在調(diào)用gcc了而是“arm-linux”這個命令)
簡單方法的優(yōu)缺點:敲很少的字符就可以工作了虐急,但是它的缺點也很多,就比如說你的系統(tǒng)不僅僅開發(fā)的這一個品牌滔迈,還有其他別的品牌止吁,那在這種情況下就很可能不知道用這種快捷方式是找的哪一個,所以很有可能導(dǎo)致我們在編譯中出現(xiàn)一些稀奇古怪的問題燎悍。因為你編譯器用錯了敬惦,很有可能你新編譯器不知道或者老編譯器又不支持,所以這種方法使用起來一定要小心谈山,也就是你系統(tǒng)里不能有多個編譯器仁热。
2.使用絕對路徑方法(最好的辦法)
#/opt/FriendlyARM/toolschain/4.5.1/bin/arm-linux-gcc -o build 1.c
絕對路徑的優(yōu)缺點:它的缺點就是跟簡單路徑相反太復(fù)雜,但是我個人還是比較喜歡用絕對路徑雖然麻煩點但是它不用每次都輸入,而且這種方法絕對能保證你用的編譯器是正確的抗蠢。