Try   HackMD

【Work】Cross Compile 交叉編譯筆記

概念

交叉編譯 (Cross Compilation) 是指在一台電腦上編譯可以在另一種電腦上執行的程式
舉個例子: 你用 Windows 系統的電腦,寫了一個程式是給 Raspberry Pi (樹莓派,使用 ARM 架構) 跑的,在編譯時候正常來說編譯出的執行檔案只能在 Windows 上執行,如果要移植到樹梅派上就無法執行,因為編譯需要考量到編譯器以及對應的平台是什麼

確認目標平台

  • CPU 架構
    ARM、x86
  • 作業系統
    Linux、Android、Windows
  • 交叉編譯器
    GCC、Android NDK、Yocto Project

實際案例

在工作實際案例上,我需要將 Raspberry Pi 開發的程式碼編譯到一台虛擬機器上,首先我們要先透過指令來確認 CPU 架構以及作業系統

uname -a

可以輸出當前電腦的系統資訊

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

接著我們需要確認對方電腦資訊

Linux (none) 5.10.144 #1 SMP Thu Apr 10 12:45:39 CST 2025 armv7l GNU/Linux

在這邊要注意對方 CPU 架構為 armv7l,作業系統為 GUN/Linux

步驟

安裝交叉編譯器

sudo apt install g++-arm-linux-gnueabihf

設定 MakeFile

由於專案是由透過 CMakeTool 進行建置與安裝的,首先先創建 armv7-toolchain.cmake

# armv7-toolchain.cmake
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR arm)

# 指定交叉編譯器 需要先行安裝
SET(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)

# 可選:啟用靜態編譯,需要將整個環境都打包過去執行
SET(CMAKE_EXE_LINKER_FLAGS "-static")

執行 CMake 指令

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