# BitBake & Yocto Project
---
## 1. Yocto Project Overview
* **Yocto Project** 是一個 Linux 基金會主導的開源計畫,旨在提供一套可重複、可客製化且跨架構的嵌入式 Linux 開發工具鏈
* **核心組件**:
* **BitBake**:核心 Build Engine
* **OpenEmbedded-Core (OE-Core)**:基礎 Metadata 集合,包含 recipes, classes 與 configs
* **Poky**:Yocto 的 Reference System,集成了 BitBake、OE-Core 與範例 Metadata,是開發者的起手點
---
## 2. Core Concepts & Components
### 2.1 BitBake (Build Engine)
* 基於 Python 開發的任務排程工具。雖然功能類似 `GNU Make`,但專為大規模嵌入式系統設計
* **主要特性**:
* 解析 Metadata(`.bb` 檔案),計算 Task Dependency(如 fetch → compile)
* 支援跨平台並行處理 (Parallel Execution)
* **與 GNU Make 的差異**:
* 具備 **Class 繼承機制** (`.bbclass`)。
* 任務腳本可混用 Python 與 Shell Script。
* 引入 **Shared State Cache (sstate-cache)** 機制,大幅優化重複建構的速度。
### 2.2 Recipes (.bb files)
* 描述單一軟體套件如何建構的「藍圖」
* **重要變數 (Key Variables)**:
* `PN` / `PV`:Package Name 與 Version
* `LICENSE` & `LIC_FILES_CHKSUM`:定義授權並透過 md5/sha256 校驗碼確保授權文件的完整性
* `SRC_URI`:Source code 來源路徑(支援 Git, HTTP, local files 等)
* `DEPENDS`:Build-time dependencies(編譯時期的相依性)
* `RDEPENDS`:Runtime dependencies(執行時期的相依性)
### 2.3 Classes (.bbclass files)
* 封裝可重用的建構邏輯(例如 `cmake`, `autotools`)
* **關鍵語法**:
* `inherit`:讓 Recipe 直接繼承類別定義好的功能
* `addtask`:定義任務的執行順序
* `EXPORT_FUNCTIONS`:允許 Recipe 覆寫 (override) 或擴充 Class 裡的 function
### 2.4 Configuration Files (.conf)
* `local.conf`:開發者的本地設定(例如 `MACHINE` 型號、`DL_DIR` 下載路徑)
* `layer.conf`:定義 Layer 的搜尋路徑與優先權 (`BBFILE_PRIORITY`)
* `bitbake.conf`:系統全域設定(例如 `${bindir}`, `${libdir}` 等路徑定義與編譯器參數)
---
## 3. GNU Make vs. BitBake
| 項目 | GNU Make | BitBake |
| --- | --- | --- |
| **建構規則** | Makefile | Recipe (`.bb`) |
| **規則擴充** | 手動加入 Makefile | Recipe Append (`.bbappend`) |
| **設定檔** | Makefile 或 環境變數 | Configuration (`.conf`) |
| **繼承機制** | 無 | Class (`.bbclass`) |
| **腳本語言** | Shell | Shell + Python |
---
## 4. Build Workflow & Tasks
### 4.1 Standard Task Order
BitBake 會依照以下順序執行預設任務:
1. **do_fetch**:抓取 Source code
2. **do_unpack**:解壓縮檔案到工作目錄
3. **do_patch**:套用 `.patch` 檔案
4. **do_compile**:執行編譯流程(如 `make` 或 `gcc`)
5. **do_install**:將產物安裝到臨時目錄(`${D}`)
6. **do_package**:將檔案切分成各個 Packages (如 debug, doc, main)。
7. **do_build**:完成所有流程
### 4.2 Cache Mechanism
* **sstate-cache**:BitBake 會紀錄每個 Task 的輸入(Checksum),若輸入未變動,則直接從 Cache 抓取結果,避免重複編譯消耗時間
---
## 5. Components Summary Table
| Component | Format | Role | Key Features |
| --- | --- | --- | --- |
| **BitBake** | Engine | Build Task Scheduler | Parallel execution, Dependency handling |
| **Recipes** | `.bb` | Build Blueprints | Define `SRC_URI`, `DEPENDS`, etc. |
| **Append Files** | `.bbappend` | Customization | **Override or extend existing recipes** |
| **Classes** | `.bbclass` | Reusable Logic | Use `inherit` to simplify recipes |
| **Configuration** | `.conf` | Settings | Machine type, Layer priority, Paths |
| **Layers** | Folder | Modular Container | Organize Metadata; Priority based |
---
## 6. Example: Hello World
### 6.1 下載 BitBake repository
```bash
git clone https://git.openembedded.org/bitbake
```

BitBake 核心資料夾結構和功能說明:
* bin/:執行檔工具,包含核心的bitbake 指令
* classes/:共用建構邏輯,存放 .bbclass 檔案
* conf/:預設設定檔,例如核心的 bitbake.conf
* contrib/:輔助腳本,額外的工具與幫助程式碼
* doc/:說明文件,BitBake 的技術手冊
* lib/:核心函式庫,BitBake 運作所需的 Python 核心程式碼
### 6.2 File structure:
```text
project/
├── classes/
│ └── base.bbclass # 定義基礎 Tasks (fetch, compile...)
├── conf/
│ └── bitbake.conf # 定義全域變數 (Compiler, Paths)
├── recipes/
│ └── hello/
│ ├── files/
│ │ ├── hello.c # Source code
│ │ └── LICENSE # License file
│ └── hello_1.0.bb # Recipe description
```
#### bitbake.conf

#### base.bbclass

* 利用 addtask 指令定義 Task 順序:fetch → unpack → compile → install
#### hello_1.0.bb

* Metadata & Compliance:
* LICENSE 與 LIC_FILES_CHKSUM:強制定義軟體授權並進行 MD5/SHA256 校驗
* Source Tracking:透過 SRC_URI 指定本地或遠端資源路徑
* 任務自定義:
* do_compile:明確定義編譯行為,利用全域變數執行交叉編譯
* do_install:定義產物分發邏輯,將 Binary 搬移至預計的映像檔根目錄下對應的路徑
#### hello.c
```bash
#include <stdio.h>
int main(void){
printf("Hello, world from Bitbake!\n");
return 0;
}
```
### 6.3 compile
```bash
bitbake hello
```
---
## 7. Common Commands
開發中常用的 BitBake 指令:
* **Debug 環境變數**:
```bash
bitbake <recipe> -e
```
* **Verbose Mode**:
```bash
bitbake <recipe> -v
```
* **分析相依性圖表**:
```bash
bitbake <recipe> -g
```
* **查詢 Layers**:
```bash
bitbake-layers show-layers
```
---
## 8. Troubleshooting
在 BitBake 開發過程中,遇到報錯可以先檢查以下幾點:
* **Python 版本不相容**:

* **原因**:BitBake 核心是基於 Python 3 運作,若系統預設 Python 版本過舊或使用的 Python 3 版本低於該 Yocto 版本的要求,解析 Metadata 時會報錯
* **對策**:
1. **版本檢查**:執行 `python3 --version` 確認版本。
2. **環境初始化**:確保有執行 `source oe-init-build-env`,這會自動設定正確的 `PATH`
3. **使用 Pyenv**:建立獨立的 Python 虛擬環境或使用 `pyenv` 切換版本,避免污染全域環境
```bash
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="/build_2/charlie/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
pyenv install -v 3.9.0
pyenv global 3.9.0
```

* **LIC_FILES_CHKSUM 不符合**:
* **現象**:`do_populate_lic` 報錯
* **原因**:授權檔案內容變動或 md5 填錯
* **對策**:使用 `md5sum <file>` 重新計算並更新 Recipe
* **SRC_URI 找不到檔案**:
* **現象**:`do_fetch` 失敗
* **原因**:檔案沒放在 `files/` 子目錄下,或檔名大小寫不一
* **對策**:確認檔案路徑,或檢查 `FILESPATH` 變數
* **清除快取重新建構**:
```bash
bitbake <recipe> -c cleanall # 刪除所有產物與下載的 sourc
```