寫在前面
《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
命令,你將獲得如下內容:
恭喜你,到此你已經成功的完成了你的BitBake初次旅行,讓我們給自己慶祝一下吧!!!
後續
本文案例及介紹參考自Yocto中的文件,有興趣的同學可以去啃一啃這篇手冊。
雖然我們只是輸出了一些無用資訊,但是我們已經掌握了BitBake最核心的執行邏輯,也對其使用的檔案有了一個較為直觀的感受。在之後的時間裡,我們將繼續學習相應的語法知識,命令用法以及怎樣使用它完成一個複雜的工程構建任務。當然啦,也希望大家能多多支援一下博主,碼字不易,還望一鍵三連,如果想請博主喝杯茶也可以,右下角可以打賞哦,再次謝謝大家能看到這個地方。
我是chegxy,歡迎關注!!!