# 【軟體開發】Cross Compile 交叉編譯筆記 ## 概念 交叉編譯 ( Cross Compilation ) 是指**在一台電腦上編譯可以在另一種電腦上執行的程式**,舉個例子 : 你用 Windows 系統的電腦,寫了一個程式是給 Raspberry Pi (樹莓派,使用 ARM 架構) 跑的,在編譯時候正常來說編譯出的執行檔案只能在 Windows 上執行,如果要移植到樹梅派上就無法執行,因為在編譯過後的二進制檔案會受到系統與 CPU 架構影響 ## 確認目標平台 - CPU 架構 ARM、x86 - 作業系統 Linux、Android、Windows - 交叉編譯器 GCC、Android NDK、Yocto Project ## 動態連結 v.s. 靜態連結 ### 靜態連結 Static Link 在使用連結器的時候,將其他檔案也一起包裝起來,讓使用者一併載下來,這樣目標對象就算沒有那個環境也能夠執行,但缺點就是體積比較大,以空間換取時間,在 Linux 上為 `.a` 檔案 ### 動態連接 Dynamic Link 動態連接解決了靜態函數庫的缺點,另外也解決不需要調用函式庫占用記憶體的時間,以時間換取空間,在 Linux 上為 `.so` 檔案,則在 Window 上為 `.dll` ## 實際案例 ### 1. 確認目標作業系統與 CPU 架構 在工作實際案例上,我需要將 Raspberry Pi 開發的程式碼編譯到一台虛擬機器上,首先我們要先透過指令來確認 CPU 架構以及作業系統 ```bash uname -a ``` 可以輸出當前電腦的系統資訊 ```bash! Linux raspberrypi 6.6.31+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.6.31-1+rpt1 (2024-05-29) aarch64 GNU/Linux ``` - Kernel Name `Linux` - Hostname `raspberrypi` - Kernel Version `6.6.31+rpt-rpi-2712` - Build info `#1 SMP PREEMPT Debian 1:6.6.31-1+rpt1 (2024-05-29)` - CPU ARC `aarch64` - Operating System `GNU/Linux` 接著我們需要確認對方電腦資訊 ```bash! Linux (none) 5.10.144 #1 SMP Thu Apr 10 12:45:39 CST 2025 armv7l GNU/Linux ``` 在這邊要注意對方 CPU 架構為 `armv7l`,作業系統為 `GUN/Linux` ### 2. 安裝交叉編譯器 ```bash sudo apt install g++-arm-linux-gnueabihf ``` ### 3. 設定 MakeFile 由於專案是由透過 CMakeTool 進行建置與安裝的,首先先創建 `armv7-toolchain.cmake` ```cmake! # armv7-toolchain.cmake SET(CMAKE_SYSTEM_NAME Linux) SET(CMAKE_SYSTEM_PROCESSOR arm) # Cross-Compile SET(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) SET(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++) # Option : static SET(CMAKE_EXE_LINKER_FLAGS "-static") ``` ### 4. 執行 CMake 指令 ```bash! cmake -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_CXX_FLAGS="-static-libgcc -static-libstdc++" \ -DCMAKE_EXE_LINKER_FLAGS="-static -pthread" \ -DCMAKE_TOOLCHAIN_FILE=../armv7-toolchain.cmake .. ``` - `-pthread` : 確保線程相關程式碼能夠運作正確 - `-static-libgcc -static-libstdc++` : 增強可移植性,靜態鏈接 C++ 標準函式庫,靜態鏈接 GCC 的 Runtime library,這樣目標電腦就不需要安裝這些函示庫跟 Library,但會造成靜態檔案變大