---
# System prepended metadata

title: 【軟體開發】Cross Compile 交叉編譯筆記
tags: [Software Development]

---

# 【軟體開發】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，但會造成靜態檔案變大



