本文轉載自:http://blog.csdn.net/zhou_chenz/article/details/52335634html
Buildroot官方全英文使用手冊的連接是https://buildroot.org/downloads/manual/manual.html,須要知道每個細節的朋友,能夠仔細查閱,這篇文章只是我本身從中提煉出來的一下快速上手的技巧。linux
Buildroot從零開始構建的過程仍是很複雜的,之後的文章會一步步介紹。咱們先來看看如何在現有項目中加入一個本身的應用的構建方法,快速上手。實際上,快速添加應用包的方法,在官方網站也有一份英文文檔:https://buildroot.org/downloads/manual/manual.html#adding-packages 詳細的原理能夠參考這篇文檔。git
這裏以加入本身的demo_app應用爲例,在mini2440_defconfig的項目下,加入demo_app的package,將demo_app的應用源代碼編譯生成到rootfs根文件系統中。構建方法以下:app
1. 在buildroot/package/ 下執行 mkdir demo_app ,建立demo_app 的文件夾框架
Figure1 在package/ 目錄下建立demo_app/函數
2. 在demo_app 中touch Config.in , touch demo_app.mk 建立這兩個文件,注意,文件名很關鍵,demo_app.mk要小寫,並且不能亂取其它名字,由於Buildroot框架有一套根據命名,展開app package的規則,因此buildroot裏面構建項目,必定要遵照文章中的命名規則,不然會有各類報錯。工具
Figure2 添加Config.in 與 demo_app.mk 文件網站
3. 在package/Config.in 中加入 source "package/demo_app/Config.in" ,以便將demo_app 的配置文件包含到Buildroot的package中來管理。ui
Figure3 在packahe/Config.in 中加入demo_app的Config.inspa
4. 在package/demo_app/Config.in 這個相似Kconfig的配置文件中,按照命名格式和Linux Kernel 的 Kconfig文件規範,加入本身的配置變量,參考代碼以下:
這段配置中,命名規則也一樣重要,BR2_PACKAGE_DEMO_APP是demo_app 可被Buildroot識別編譯成package的配置變量。Package應用必定要以BR2_PACKAGE_做爲開頭,以DEMO_APP即demo_app的大寫來填充這個變量名,這樣才能被Buildroot命名框架識別、展開,才能經過make menuconfig來配置。
bool是變量的類型,即只要true(編譯選中,false(編譯未選中),兩種狀況,和Kconfig的規則是同樣的,後面的字符串和help都是在make menuconfig時的提示文本。
實際上,在Config.in中,能夠參考linux Kernel的Kconfig文件,根據語法規範,加入本身的配置邏輯和其它可配置的變量(好比app的下載地址連接),在此就不詳細說了,你們能夠參考其它的package/的Config.in文件的寫法,這裏只說重點,就是BR2_PACKAGE_DEMO_APP這個變量必定要有,必定要被選上才能編譯。
5. 在demo_app.mk中,按照Makefile文件的格式和語法規範,編寫demo_app的上層構建規則,demo_app.mk的參考代碼以下:
注意,demo_app.mk並不能實際代替demo_app源代碼的Makefile文件,它只是一個上層的make文件,告訴Buildroot,應該到哪一個地方拿源代碼,應該如何解壓源代碼,應該給源代碼中的Makefile中的變量傳遞哪些編譯參數,編譯出來的庫和bin文件,應該安裝到rootfs的哪一個路徑下。具體demo_app源代碼是如何一步一步編譯的,還得靠demo_app源代碼自己的Makefile去作。
這段makefile代碼大概有什麼規範呢:
a) 全部的變量都已DEMO_APP_ 開頭,這樣Buildroot纔可以經過命名框架去解析
b) _VERSION結尾的變量,是下載demo_app源代碼的版本號, _SITE_METHOD結尾的變量是demo_app變量的下載方法,_SITE結尾的變量是demo_app的下載地址,其它的變量是幹嗎用的,能夠慢慢查閱官方手冊。
c) 全部define 並以_CMDS結尾的代碼塊,相似函數的東西,其實是構建過程當中會被Buildroot框架執行的指令,這些指令到底有哪些,具體也得讀手冊。固然這些相似函數,開頭也得是DEMO_APP_, Buildroot中命名規則很重要,重要的話說三遍。
d) _BUILD_CMDS結尾的函數,是構建過程函數,通常是給demo_app源代碼傳遞編譯和連接選項,調用源代碼的Makefile執行編譯。
e) INSTALL_TARGET_CMDS結尾的函數,就是demo_app編譯完以後,自動安裝的執行,通常是讓Buildroot把編譯出來庫和bin文件安裝到指定的目錄。
f) $(eval$(generic-package)) 最核心的就是這個東西了,必定不可以漏了,否則demo_app是編譯不出來的,這個函數就是把整個demo_app.mk構建腳本,經過Buildroot框架的方式,展開到Buildroot/目錄下的Makfile中,生成demo_app的構建目標(構建目標是什麼,還記得Makefile中的定義嗎?)。
g) 實際上,這些構建命名框架還有$(eval $(generic-package))這個黑魔法,都在package/pkg-generic.mk 這個文件中,generic-package是這個文件最後的調用的函數生成的,其它 _BUILD_CMDS,INSTALL_TARGET_CMDS這些函數如何被Buildroot框架嵌入的, 以前那些變量是如何被調用的,在package/pkg-generic.mk中都能找到,可是仍是要必定的Makefile功底才能讀懂這個的,之後再解釋package/pkg-generic.mk的框架原理。
講了這麼多條規範,那麼這段makefile代碼大概是什麼意思呢?
這段代碼描述的流程是, 經過Git clone的方法從/mnt/sdb/git_repo/demo_app這個目錄下的git倉庫中拿到demo_app的源代碼-->傳遞編譯參數,而且編譯demo_app(DEMO_APP_BUILD_CMDS函數作的事情)-->把編譯出來的bin文件安裝到$(TARGET_DIR)/usr/bin目錄下(DEMO_APP_INSTALL_TARGET_CMDS函數作的事情)。
爲何咱們本身不用寫從git倉庫下載demo_app源代碼的函數呢,其實是Buildroot幫咱們寫好了,在package/ pkg-download.mk 文件裏面,因此咱們只有經過DEMO_APP_SITE_METHOD和DEMO_APP_SITE設置下載的方法和地址就能夠。至於爲何DEMO_APP_VERSION是master,瞭解git的朋友應該看得明白,就是git clone以後會checkout到master版本,其實也就是master分支最新的版本啦,固然也能夠換成本身的版本號,前提是該版本號存在,可以用git checkout 切換過去。
這段代碼的執行前提是要在Linux上搭建本身的git倉庫,維護本身的demo_app源代碼,在用Buildroot前,git倉庫是現成的。
可是不熟悉git 的朋友怎麼辦呢?其實還有其它方法,demo_app.mk的代碼稍作修改:
Figure4 採用file方法下載源代碼
主要,DEMO_APP_SITE_METHOD改爲了file,這樣就不用構建git參考,能夠用file,也就是直接cp的方法,把源代碼拷貝到buildroot中來。可是buildroot到哪裏去cp源代碼呢,實際上,這裏不是DEMO_APP_SITE = /mnt/sdb/git_repo/demo_app這個地址,這個地方被我註釋掉了。
在buildroot/下 makemenuconfig --> Build options -->Mirrors and Download locations 能夠看到如下的畫面:
Figure5 設置file方法cp文件的路徑
只有按照上面的格式,也就是file:// + 你的文件絕對路徑的地址的格式配置這個選項,而後保存,就OK,以後Buildroot就知道去該路徑下找源代碼包了。
另外記得,必定要把demo_app的源代碼壓縮包保存到該路徑下,而且名字必定要和DEMO_APP_SOURCE變量的名字同樣哦!
Figure6 demo_app 源代碼的存放路徑
6. demo_app的源代碼
demo_app就是一個hello world 程序參考的makefile和源代碼以下:
其中Makefie會被demo_app.mk中的DEMO_APP_BUILD_CMDS函數調用,Makefie中的變量參數的值均可以經過DEMO_APP_BUILD_CMD傳入。
Figure7 demo_app 的Makefie
Figure8 demo_app.c 源代碼
7. 構建方法
a). make mini2440_defconfig --> makemenuconfig --> Target packages下選中demo app --> make demo_app
Figure9 menuconfig中選中 demo app,
make demo_app這個命令,其實是隻是編譯demo_app以及demo_app依賴鏈上的package, 固然,toolchain會被全部package依賴,因此buildroot會先編譯toolchain。
編譯完成後,會發現buildroot/output/build/目標下的demo_app-master目錄,即demo_app編譯後現場,以及在buildroot/output/target/usr/bin/目錄下,安裝好的編譯出來的demo_appbin文件。而且確實是ARM交叉工具鏈編譯出來的。
Figure10 demo_app 源代碼編譯現場路徑
Figure11 安裝好的demo_app bin文件
至此,在Buildroot中添加app package的過程就完成了。
Buildroot 一次make all要把整個系統編譯出來,真麻煩,我只想要一個能夠boot起來的最小系統,不須要什麼其它package,它有什麼快捷方式能夠辦到嗎?這個固然問buildroot,咱們能夠這麼作。
make help 看看buildroot怎麼說
Figure12 make help 以後的buildroot系統提示
如下是buildroot的help命令提示,其中有一項是
make allnopackageconfig
在make xxx_defconfig 以後,執行make allnopackageconfig,那麼再make all就能夠只編toolchain,boot,kernel,busybox,rootfs這個幾個能構成系統啓動的最小系統的模塊。
固然,在make mini2440_defconfig時,因爲mini2440的toolchain是toolchain-buildroot,即buildroot從零開始製做工具鏈,而不是toolchain-external,即buildroot使用已經制做好的工具鏈,這樣的話,若是toolchain尚未在前一次生成,則make allnopackageconfig 再make all以後編譯過程會報錯,由於製做零製做toolchain須要編譯某些package做爲原材料,而這些package被make allnopackageconfig去掉了。
已經制做好工具鏈,或者採用toolchain-external模式的狀況下,make allnopackageconfig 編譯最小系統是沒用問題的。
最後看看buildroot有哪些實用技巧:
make help
-以前演示過了,打印出幫助菜單
make show-targets
- 顯示出本次配置所要編譯全部的目標,這些目標能夠單獨做爲模塊,用 make <pkg-target> 命令進行單獨編譯。從這條命令的顯示結果來看,mini2440_defconfig須要編譯uclibc(微型C庫),busybox等目標,固然demo_app也是一個編譯目標,是我在menocunfig時候加進去的,因此能夠用make demo_app來編譯。
Figure13 make show-targets 的顯示結果
make <pkg-target>
- 單獨編譯某個pkg模塊以及其依賴的模塊,好比make demo_app
make pkg-rebuild
- 從新編譯pkg
make pkg-extract
- 只下載解壓pkg,不編譯,pkg解壓後放在 output/build/目錄對應的pkg-dir目錄下
make pkg-source
- 只下載某pkg,而後不作任何事情
其它還有不少快捷指令,在package/pkg-generic.mk中都能找到,這些快捷指令實際是是由pkg-指令這種命名框架合成的,更詳細的內容請參考手冊和package/pkg-generic.mk。
Figure14 package/pkg-generic.mk 框架下所支持的指令部分截圖呀