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


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

如何在現有項目加入自己的APP

Buildroot從零開始構建的過程還是很復雜的,以后的文章會一步步介紹。我們先來看看如何在現有項目中加入一個自己的應用的構建方法,快速上手。實際上,快速添加應用包的方法,在官方網站也有一份英文文檔:https://buildroot.org/downloads/manual/manual.html#adding-packages  詳細的原理可以參考這篇文檔。

這里以加入自己的demo_app應用為例,在mini2440_defconfig的項目下,加入demo_app的package,將demo_app的應用源代碼編譯生成到rootfs根文件系統中。構建方法如下:

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中來管理。

Figure3  在packahe/Config.in 中加入demo_app的Config.in

4.      在package/demo_app/Config.in 這個類似Kconfig的配置文件中,按照命名格式和Linux Kernel 的 Kconfig文件規范,加入自己的配置變量,參考代碼如下:

 

config BR2_PACKAGE_DEMO_APP  
bool"demo app"  
help  
  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的參考代碼如下:

 

################################################################################  
#  
# demo app  
#  
################################################################################  
DEMO_APP_VERSION = master  
DEMO_APP_SITE_METHOD = git  
DEMO_APP_SITE = /mnt/sdb/git_repo/demo_app  
DEMO_APP_SOURCE = demo_app-$(DEMO_APP_VERSION).tar.gz  
DEMO_APP_ALWAYS_BUILD = YES  
DEMO_APP_INSTALL_STAGING = YES  
DEMO_APP_CFLAGS =   
DEMO_APP_LDFLAGS =   
OUT_BIN = demo_app  
DEMO_APP_MAKE_FLAGS += \  
        CROSS_COMPILE="$(CCACHE) $(TARGET_CROSS)" \  
        CC=$(TARGET_CC)      \  
        OUT_BIN=$(OUT_BIN)  \  
        AR=$(TARGET_AR)      \  
        STRIP=$(TARGET_STRIP) \  
        CFLAGS=$(DEMO_APP_CFLAGS) \  
        LDFLAGS=$(DEMO_APP_LDFLAGS) \  
        STAGING_DIR=$(STAGING_DIR)  \  
        TARGET_DIR=$(TARGET_DIR)   
  
define DEMO_APP_BUILD_CMDS  
    $(MAKE) clean  -C $(@D)   
    $(MAKE) $(DEMO_APP_MAKE_FLAGS)  -C $(@D)  
endef  
  
define DEMO_APP_INSTALL_TARGET_CMDS  
    $(INSTALL) -m 0755 -D $(@D)/$(OUT_BIN)  $(TARGET_DIR)/usr/bin  
endef  
  
$(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 框架下所支持的指令部分截圖呀

 

原文鏈接:http://blog.csdn.net/zhou_chenz/article/details/52335634


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM