交叉編譯實踐-交叉編譯原理與簡單應用

/****************************************************************************************/

/*           獲取更多乾貨技能,點擊 [這裏-小編文章列表] 主頁左側掃碼關注公衆號             */ 

/***************************************************************************************/

    

        首先說說交叉編譯的事:一個簡單的Hello World程序,在x86_64的機器上編譯通過後,將其生成的可執行程序拷貝到aarch64的機器上去執行,肯定是執行不通過的,

會報文件格式不正確之類的錯誤,這是因爲程序的編譯平臺環境和程序的運行平臺環境不同導致的,x86_64的機器CPU是amd64架構的(複雜指令集),而aarch64機器的CPU是arm架構的(精簡指令集),所以,兩個不同指令集結構的機器,是不能相互解釋執行的,因爲他執行讀取等的尋址方式是不同的。
但是爲了滿足對機器最大程度的利用,對於開發人員來說,又不想每種架構的指令集都搞一臺機器放到身邊,而是想讓不同架構的機器最好在一臺機器上就可以將其編譯生成可執行程序,然後將執行程序交給客戶(可能客戶用的是arm機器,而開發大部分都是x86機器),這樣既節省了資源,有滿足了我們開發人員的需求,兩全其美,何樂而不爲呢!這就是我們本篇所介紹的方法:交叉編譯。
操作系統:Linux
目標機:arm指令集的aarch64機器
宿主機:amd指令集的x86_64機器
目的:在amd的x86_64機器上編譯源碼,生成可執行程序,在arm的aarch64機器上運行
進階:簡單的HelloWorld沒有挑戰性和代表性,我們選擇依賴底層較多的Qt程序去完成交叉編譯

1. 交叉編譯器的安裝
    我們知道,最終需要執行的可執行程序,是通過編譯器生成的,編譯器會通過機器的架構,組織相關的符號,通過編譯鏈接生成最後的可執行程序,所以,必須得有一種編譯器,他自己是可以在x86_64架構升運行的,但是能將源碼編譯鏈接生成在aarch64架構上執行的程序。老一輩程序員們已經編出了這樣一款軟件,其和gcc是一模一樣的,只不過我們的gcc是自己運行的平臺架構和通過gcc生成的可執行程序運行的平臺架構是同一個架構,而aarch64-linux-gnu-gcc是自己運行的平臺爲x86_64,而生成的可執行程序是在aarch64上運行的,對,就是aarch64-linux-gnu-gcc(C++用aarch64-linux-gnu-g++,同g++),就是我們要用的交叉編譯器,可以通過網上直接下載,或直接在線安裝,都是可以的。

2. 設置交叉編譯器
    如果下載安裝的交叉編譯器系統找不到,可以通過設置環境變量PATH將aarch64-linux-gnu-gcc設置到環境變量中,這樣系統就能找到了,一般安裝後,在 /usr/bin中就已經存在了,同時會生成 /usr/aarch64-linux-gnu/目錄,下面有bin、include、lib三個目錄,lib中即爲aarch64機器的基本相關庫,如果編譯的程序有依賴於目標機器的第三方庫,則可以將其放到這個lib目錄下,保證編譯時能夠找到。

3. 用交叉編譯器編譯源文件生成可執行文件
    編譯源文件是,一定要設置用交叉編譯器aarch64-linux-gnu-gcc進行編譯,這樣生成的文件才能在aarch64平臺上運行起來。
選擇編譯器有兩種方式:1. 如果aarch64-linux-gnu-gcc所在的目錄(可以用whereis aarch64-linux-gnu-gcc進行查看)已經設置在環境變量PATH中,則可以直接用aarch64-linux-gnu-gcc main.cpp -o main進行生成。 2. 如果aarch64-linux-gnu-gcc所在目錄沒有環境變量PATH中,可以將其目錄設置到PATH中,然後重啓或用source使其生效,然後同第一步。 3.將系統中的gcc直接軟連接到aarch64-linux-gnu-gcc上,然後就像正常使用gcc編譯器一樣編譯源碼就好了。

通過以上三步,就可以在x86_64平臺上編譯出能在aarch64上運行的程序了。
以下爲簡單的HelloWorld源碼的編譯步驟:
int main(int argc, char* argv[])
{
printf("Hello World!\n");
return ;
}
在終端執行:aarch64-linux-gnu-gcc main.cpp -o main
生成main的可執行文件後,查看文件格式:file main,輸出:
main: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=d933995224ec8ca652d9585e36d0130596af490b, not stripped
顯示文件是ARM aarch64,說明交叉編譯成功,且在該平臺是運行不起來的,報“可執行文件格式錯誤”,必須到aarch64平臺上運行,截圖如下:

以上即爲簡單的交叉編譯,沒有依賴其他第三方的庫,只要有aarch64平臺的libc.so庫即可以了。

由於以上的簡單HelloWorld程序沒有依賴第三方庫,所以其在實際項目中沒有代表性,只能說明交叉編譯的基本原來,更復雜的交叉編譯,是需要依賴很多相關庫的,在下篇中所介紹的Qt應用程序交叉編譯,即使在實際項目中所用的,敬請期待下篇【交叉編譯實踐-Qt應用程序交叉編譯】。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章