BitBake使用攻略--從HelloWorld講起

chegxy發表於2021-12-22


寫在前面

《BitBake使用攻略》系列文章將從今天開始不定時的更新,主要講解BitBake的背景,基本語法,功能及其命令等知識,旨在為即將從事Yocto專案和OpenEmbedded專案的同學做一些預備知識,由於本人能力有限,一些紕漏還望各位指出,話不多說,我們馬上進入正題。


1. 什麼是BitBake

BitBake就是位元燒烤,哈哈,皮一下。BitBake是一個開源的構建工具,通過提供必要的後設資料,其能構建出從bootloader到應用層各種各樣的軟體包,可以將其對標GNU Make工具,而BitBake需要的菜譜檔案就是GNU Make的CMakeList檔案,當然了,也包括各種配置檔案,引用官方的解釋,BitBake的介紹如下:

Fundamentally, BitBake is a generic task execution engine that allows shell and Python tasks to be run efficiently and in parallel while working within complex inter-task dependency constraints. One of BitBake's main users, OpenEmbedded, takes this core and builds embedded Linux software stacks using a task-oriented approach.

BitBake如此強大,為何我們好像基本沒有聽說過呢?這是因為BitBake作為Yocto和OpenEmbedded專案的核心構建工具,主要服務於嵌入式工程的構建過程,上手不是特別簡單,所以在一般領域不是特別出名,但這不代表他的功能遜色,相反,通過通過編寫相應後設資料檔案和配置檔案,你可以構建任何你想要的包。
BitBake有幾個比較突出的特點:

  • BitBake是以任務為單位進行構建的,而這些任務通常是由菜譜檔案(字尾為bb)、配置檔案(字尾conf)以及類檔案(字尾bbclass)所提供。
  • 通過新增一些變數,BitBake可以從本地,甚至是遠端伺服器獲取要用到的原始碼或補丁等檔案。
  • BitBake採用CS架構,這就提供了一種遠端構建的可能。

大致介紹完BitBake後,你可能會覺得這玩意這麼厲害是不是特別難學,其實還好,畢竟是一個工具性的軟體,只要按著規則來基本沒有太大的難度。接下來,我將從一個學習新工具或者新語言必學的專案HelloWorld來為大家介紹BitBake的基本用法。

2. BitBake的安裝

首先,我們先要下載BitBake軟體,大致有三種方式可以供我們獲得BitBake:

  • 直接克隆OpenEmbedded維護的BitBake原始碼包。

  • 從你下載的Yocto或者OpenEmbedded專案程式碼中取出BitBake原始碼包。

  • 直接下載官方打包好的BitBake軟體包,可以執行下面的命令:

    $ wget http://git.openembedded.org/bitbake/snapshot/bitbake-1.17.0.tar.gz
    $ tar zxpvf bitbake-1.17.0.tar.gz
    

我們使用推薦使用第一種方式,因為我們可以得到一個最穩定的版本,執行下面的命令:

git clone git://git.openembedded.org/bitbake

執行完成後,你將獲得BitBake的原始碼目錄:

cxy@ubuntu:~/Repository/BitBake/bitbake$ ls -al 
total 108
drwxrwxr-x  9 cxy cxy  4096 Dec 21 23:12 .
drwxrwxr-x  4 cxy cxy  4096 Dec 21 23:12 ..
-rw-rw-r--  1 cxy cxy   365 Dec 21 23:12 AUTHORS
drwxrwxr-x  2 cxy cxy  4096 Dec 21 23:12 bin
-rw-rw-r--  1 cxy cxy 16501 Dec 21 23:12 ChangeLog
drwxrwxr-x  2 cxy cxy  4096 Dec 21 23:12 classes
drwxrwxr-x  2 cxy cxy  4096 Dec 21 23:12 conf
drwxrwxr-x  4 cxy cxy  4096 Dec 21 23:12 contrib
drwxrwxr-x  6 cxy cxy  4096 Dec 21 23:12 doc
drwxrwxr-x  8 cxy cxy  4096 Dec 21 23:12 .git
-rw-rw-r--  1 cxy cxy    31 Dec 21 23:12 .gitattributes
-rw-rw-r--  1 cxy cxy   392 Dec 21 23:12 .gitignore
drwxrwxr-x 13 cxy cxy  4096 Dec 21 23:24 lib
-rw-rw-r--  1 cxy cxy  1224 Dec 21 23:12 LICENSE
-rw-rw-r--  1 cxy cxy 15394 Dec 21 23:12 LICENSE.GPL-2.0-only
-rw-rw-r--  1 cxy cxy  1286 Dec 21 23:12 LICENSE.MIT
-rw-rw-r--  1 cxy cxy   229 Dec 21 23:12 MANIFEST.in
-rw-rw-r--  1 cxy cxy  1949 Dec 21 23:12 README
-rw-rw-r--  1 cxy cxy    43 Dec 21 23:12 toaster-requirements.txt
-rw-rw-r--  1 cxy cxy  2887 Dec 21 23:12 TODO

為了可以在任意位置使用bitbake的命令,我們需要將bin目錄新增到PATH環境變數中,例如,我可以執行如下命令:

$ export PATH=/home/cxy/Repository/BitBake/bitbake/bin:$PATH

這時,嘗試執行一下你的bitbake,看看是否能正確輸出版本號:

cxy@ubuntu:~/Repository/BitBake/bitbake$ bitbake --version
BitBake Build Tool Core version 1.53.0

到此,你的BitBake環境已經準備好啦!

3. 使用BitBake構建一個HelloWorld工程

我們最後要到達的效果是使用BitBake工具輸出HelloWorld的字樣,你可能會覺得這一部分簡單,實際上是我想使用官網的一個案例帶你去學習BitBake的構建邏輯,同時也提供了一個我們今後學習BitBake使用的工程。
我們先新建一個hello工程,並進入到這個目錄下:

$ mkdir hello
$ cd hello

這時,我們不禁在想,在這一個空空的目錄下怎麼去輸出HelloWorld呢,你不妨現在試著執行一下構建工具看看會發生什麼,執行命令:

$ bitbake

可以發現(有點版本可能不會輸出),輸出資訊裡提示BBPATH變數未設定,這個變數是幹嘛的呢,它是BitBake構建過程中最核心的變數,用於指定bb檔案以及conf檔案的儲存位置,而bb檔案中又定義了構建任務,所以在幹所有事之前我們要先定義BBPATH變數,將其指定為我們的工程目錄,例如:

$ BBPATH="/home/cxy/Repository/BitBake/hello/"
$ export BBPATH

隨後,我們重新使用bitbake命令編譯一下工程,這時你會發現系統提示找不到conf/bitbake.conf,而這個檔案是bitbake執行時第一個要找到檔案,其記錄了許多bitbake很重要的全域性變數,因此我們建立它:

$ mkdir conf
$ cd conf/
$ touch bitbake.conf

並在bitbake.conf中新增如下內容:

TMPDIR  = "${TOPDIR}/tmp"
CACHE   = "${TMPDIR}/cache"
STAMP   = "${TMPDIR}/stamps"
T       = "${TMPDIR}/work"
B       = "${TMPDIR}"

我們對上面的變數分別做一個簡單的介紹:

  • TMPDIR:用於存放構建生成的檔案,類似於輸出目錄,其中TOPDIR由系統自動賦值為工程目錄路徑。
  • CACHE:指定存放快取檔案的地方,通過這些檔案,bitbake可以在重新構建時省去很多工作。
  • STAMP:戳記檔案存放目錄。
  • T:存放臨時檔案,如log檔案。
  • B:bitbake在這個目錄下進行構建工作。

再次執行bitbake命令你會發現這次又提示缺少classes/base.bbclass檔案,這個檔案是一個類檔案。在BitBake中,類檔案會提供菜譜共有的內容,而base.bbclass是所有菜譜檔案(bb檔案)的公共基類,是必須提供的,因此我們建立這個檔案:

$ mkdir classes
$ cd classes/
$ touch base.bbclass

同時,新增如下內容到這個檔案中:

addtask build

這句程式碼表示繼承該類的菜譜必須執行do_build任務,這時候你再執行一下就會發現bitbake沒有報錯,而是提示沒有事情可做,也就是沒有提供任務。因此,接下來我們提供一個菜譜檔案去指定一些可供bitbake執行的任務。另外為了維護目錄的整潔性,我們使用bitbake中層的概念(每個層之間菜譜是獨立的,大的工程中都有好多層,用於分離不同種類的檔案)。我們新建層meta-mylayer,同時每個層需要又一個配置檔案conf/layer.conf

$ mkdir meta-mylayer
$ cd meta-mylayer/
$ mkdir conf
$ cd conf/
$ touch layer.conf

在這個配置檔案中,我們需要為其填充一些配置項,內容如下:

BBPATH .= ":${LAYERDIR}"

BBFILES += "${LAYERDIR}/*.bb"

BBFILE_COLLECTIONS += "mylayer"
BBFILE_PATTERN_mylayer := "^${LAYERDIR}/"

在這個檔案中,我們先設定了BBPATH變數,.=表示的是追加,所以我們將LAYERDIR(這個變數會被自動設定為當前層的根路徑)內容追加到BBPATH中,表示在這個路徑下也可以找到BB檔案。而BBFILES是一個正規表示式,使用這個規則可以匹配到我們的菜譜檔案。另外,最後的兩個變數我們暫時先不說,以後具體講到菜譜檔案再聊,或者你可以參考一下官方的解釋:BBFILE_COLLECTIONS , BBFILE_PATTERN
之後,我們還需要編寫我們的第一個菜譜檔案,去告訴BitBake我們要做些什麼,在meta-mylayer目錄下新建一個菜譜檔案printhello.bb,內容如下:

DESCRIPTION = "Prints Hello World"
PN = 'printhello'
PV = '1'

python do_build() {
    bb.plain("********************");
    bb.plain("*                  *");
    bb.plain("*  Hello, World!   *");
    bb.plain("*                  *");
    bb.plain("********************");
}

在這個檔案中,我們定義了三個變數,分別表示描述資訊,菜譜名稱以及菜譜的版本號。另外我們還定義了一個任務do_build(任務名稱以do_開頭),內容是使用bb.plain函式列印若干字串。由於所有BB檔案都要繼承基類base.bbclass,因此這個BB檔案也就必須要執行do_build任務了(參考上面所講)。
此時,你再次回到根目錄下執行bitbake printhello命令(表示我們要構建printhello.bb菜譜),你會發現BitBake似乎並沒有找到這個菜譜,這是因為我們還需要一個變數去將新建的層包含到我們的工程中,而這個變數需要定義到conf/bblayers.conf檔案中,我們新建conf/bblayers.conf檔案,內容如下:

BBLAYERS ?= " \
        /home/cxy/Repository/BitBake/hello/meta-mylayer \
        "

其中,BBLAYERS變數指定了我們要使用的層的絕對路徑(你需要把你的層路徑替換掉我的)。
現在你檢查一下自己的目錄是否和我一樣:

cxy@ubuntu:~/Repository/BitBake/hello$ tree -L 3 .
.
├── classes
│   └── base.bbclass
├── conf
│   ├── bblayers.conf
│   └── bitbake.conf
└── meta-mylayer
    ├── conf
    │   └── layer.conf
    └── printhello.bb

4 directories, 5 files

如果沒有檔案和內容沒有問題,執行bitbake printhello命令,你將獲得如下內容:

result

恭喜你,到此你已經成功的完成了你的BitBake初次旅行,讓我們給自己慶祝一下吧!!!

後續

本文案例及介紹參考自Yocto中的文件,有興趣的同學可以去啃一啃這篇手冊。
雖然我們只是輸出了一些無用資訊,但是我們已經掌握了BitBake最核心的執行邏輯,也對其使用的檔案有了一個較為直觀的感受。在之後的時間裡,我們將繼續學習相應的語法知識,命令用法以及怎樣使用它完成一個複雜的工程構建任務。當然啦,也希望大家能多多支援一下博主,碼字不易,還望一鍵三連,如果想請博主喝杯茶也可以,右下角可以打賞哦,再次謝謝大家能看到這個地方。


我是chegxy,歡迎關注!!!

相關文章