Buildroot構建指南--快速上手與實用技巧【轉】

本文轉載自:http://blog.csdn.net/zhou_chenz/article/details/52335634html

Buildroot官方全英文使用手冊的連接是https://buildroot.org/downloads/manual/manual.html,須要知道每個細節的朋友,能夠仔細查閱,這篇文章只是我本身從中提煉出來的一下快速上手的技巧。linux

如何在現有項目加入本身的APP

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文件規範,加入本身的配置變量,參考代碼以下:

 

[plain]  view plain  copy
 
  1. config BR2_PACKAGE_DEMO_APP  
  2. bool"demo app"  
  3. help  
  4.   demo app to show  

 

 

 

這段配置中,命名規則也一樣重要,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的參考代碼以下:

 

[plain]  view plain  copy
 
  1. ################################################################################  
  2. #  
  3. # demo app  
  4. #  
  5. ################################################################################  
  6. DEMO_APP_VERSION = master  
  7. DEMO_APP_SITE_METHOD = git  
  8. DEMO_APP_SITE = /mnt/sdb/git_repo/demo_app  
  9. DEMO_APP_SOURCE = demo_app-$(DEMO_APP_VERSION).tar.gz  
  10. DEMO_APP_ALWAYS_BUILD = YES  
  11. DEMO_APP_INSTALL_STAGING = YES  
  12. DEMO_APP_CFLAGS =   
  13. DEMO_APP_LDFLAGS =   
  14. OUT_BIN = demo_app  
  15. DEMO_APP_MAKE_FLAGS += \  
  16.         CROSS_COMPILE="$(CCACHE) $(TARGET_CROSS)" \  
  17.         CC=$(TARGET_CC)      \  
  18.         OUT_BIN=$(OUT_BIN)  \  
  19.         AR=$(TARGET_AR)      \  
  20.         STRIP=$(TARGET_STRIP) \  
  21.         CFLAGS=$(DEMO_APP_CFLAGS) \  
  22.         LDFLAGS=$(DEMO_APP_LDFLAGS) \  
  23.         STAGING_DIR=$(STAGING_DIR)  \  
  24.         TARGET_DIR=$(TARGET_DIR)   
  25.   
  26. define DEMO_APP_BUILD_CMDS  
  27.     $(MAKE) clean  -C $(@D)   
  28.     $(MAKE) $(DEMO_APP_MAKE_FLAGS)  -C $(@D)  
  29. endef  
  30.   
  31. define DEMO_APP_INSTALL_TARGET_CMDS  
  32.     $(INSTALL) -m 0755 -D $(@D)/$(OUT_BIN)  $(TARGET_DIR)/usr/bin  
  33. endef  
  34.   
  35. $(eval $(generic-package))  

 

注意,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實用技巧與指令

最後看看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 框架下所支持的指令部分截圖呀

相關文章
相關標籤/搜索