交叉編譯實踐-交叉編譯原理與簡單應用
阿新 • • 發佈:2019-02-07
/****************************************************************************************/
/* 獲取更多乾貨技能,點選 [這裡-小編文章列表] 主頁左側掃碼關注公眾號 */
/***************************************************************************************/
首先說說交叉編譯的事:一個簡單的Hello World程式,在x86_64的機器上編譯通過後,將其生成的可執行程式拷貝到aarch64的機器上去執行,肯定是執行不通過的,
但是為了滿足對機器最大程度的利用,對於開發人員來說,又不想每種架構的指令集都搞一臺機器放到身邊,而是想讓不同架構的機器最好在一臺機器上就可以將其編譯生成可執行程式,然後將執行程式交給客戶(可能客戶用的是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應用程式交叉編譯】。