1. 程式人生 > >簡單搭建MIPS交叉編譯環境------新手推薦

簡單搭建MIPS交叉編譯環境------新手推薦

 去如下網站下載一個工具包就OK了,o(∩_∩)o...哈哈,過程很簡單了


下載一個buildroot,這是個工具集,接下來所要做的事情就是把gcc、binutils等檔案下載下來,放在buildroot下的dl目錄下

(如果沒有這個目錄就自己建立一個就OK了)
當然,你也可以讓buildroot自動下載,MAKE的時候會自動解析DL目錄下的檔案,不過速度較慢。
選擇目標的為MIPS,以及一些工具的版本,順利的話,你編譯完後就能得到MIPS的gcc交叉編譯器了。

還包括檔案系統(busybox),n多的可選應用程式(sqlite等)。

果真好東西,是初學者的福音,推薦。

相關內容請參照一下解釋。

 Buildroot的用法和文件由Thomas Petazzoni提供,文稿由Karsten Kruse、Ned Ludd、Martin Herren等整理。

最後修改時間:2007-09-19 02:08:10 -0700 (Wed, 19 Sep 2007)

l     關於Buildroot

l     獲取Buildroot

l     使用Buildroot

l     定製目標檔案系統

l     定製Busybox的配置

l     定製uClibc的配置

l     Buildroot執行方式

l     使用uClibc 工具鏈

l     在Buildroot外部使用 uClibc 工具鏈

l     被下載包的存放位置

l     使用其他軟體來擴充套件Buildroot

l         資源

關於Buildroot

Buildroot是一個Makefiles和patches的命令集,它可以非常簡單的為你的目標系統產生一個交叉編譯工具鏈和根檔案系統 。這個交叉編譯工具使用uClibc (http://www.uclibc.org/),uClibc是一個很小的標準庫。

Buildroot那些從事於嵌入式系統的人來說是很有用處的。嵌入式系統經常使用的處理器都不是平常用於普通電腦的x86處理器它可能是PowerPC、 MIPS、ARM等處理器.

一個編譯工具鏈就是一些工具的的命令集,這些工具允許你為你的目標系統編譯原始碼。它主要由編譯器(在我們的例子中為gcc),二進位制的工具集,如彙編程式和聯結器(在我們的例子中為binutils),還有就是C的標準庫(如GNU Libc、uClibc或者是dietlibc)。在你的開發平臺上安裝的系統裡面要包含一個編譯工具鏈,這個編譯工具鏈是你可以在你的系統上編譯應用程式。如果你使用的是一臺PC機,你的編譯工具鏈執行在x86處理器上,或者生成x86處理器可以執行的程式碼。在大多數的Linux系統裡面,這個編譯工具鏈使用的是GNU libc作為C的標準庫。這個編譯工具鏈被稱之為“主機編譯工具鏈”,而且通常來說,這臺你在上面工作的電腦被稱之為“主機系統”。這個編譯工具鏈由你的系統提供,與Buildroot無關。

如同上面所說的一樣,這個編譯工具鏈隨著你作業系統一起為你的主機系統上的處理器執行或者生成原始碼。就像你的嵌入式系統擁有一個不同的處理器一樣,你需要一個交叉編譯工具鏈:它是一個執行在你的主機系統上但是為你的目標系統(和處理器)生成程式碼的工具鏈。舉例來說,如果你的主機系統用的是x86處理器,你的目標系統用的是ARM處理器,你主機上的這個普通的編譯工具鏈執行在你的x86處理器上並且為x86生成程式碼,但是交叉編譯工具執行在你的x86處理器上但是為ARM生成程式碼

及時你的嵌入式系統用的是一個x86處理器,你也可能對Buildroot產生情趣,主要原因有以下兩點:

·   顯然,你的主機系統上的編譯工具集用的是GNU Libc,GNU Libc是一個完整的標準庫,但是它體積龐大。與你在你的目標系統上使用GNU Libc相比,你可以使用uClibc,uClibc是一個很微小的標準C庫。如果你想使用這個C庫,你需要一個編譯工具集來生成二進位制工具去連結它。Buldroot能夠替你完成這些事。

·    Buildroot 自動地使用工具如busybox來建立一個根檔案系統。它比手工完成一個根檔案系統的製作更簡單。

你可能很好奇了,為什麼這樣一個工具在你手工編譯gcc、binutils、uClibc和其他所有的工具的時候是必須的。當然,手工完成它也是可能的。但是在處理所有的配置選項的時候,由於所有的問題如每一個gcc或者binutls版本都是耗費時間和令人厭倦的Buildroot通過使用Makefiles檔案來自動操作這個過程,並且收集了每一個gcc和binutils版本的補丁,使他們能應用於更過的體系架構上面。

獲取 Buildroot

使用SVN來下載Buildroot,你可以簡單的使用uClibc buildroot 網站(http://buildroot.uclibc.org)下面的“Accessing SVN”頁面(http://buildroot.uclibc.org/subversion.html)裡描述的規則,並且下載SVN的各個模組。為了不讓你著急,下面是一個簡介的方法:

 $ svn co svn://uclibc.org/trunk/buildroot

使用 Buildroot

Buildroot有一個較好的配置工具,就像你在Linux(http://www.kernel.org/)核心和Busybox(http://www.busybox.org/)裡面看到的類似。 注意的是你作為一個普通使用者,你可以在裡面構造任何東西。這裡不需要你是一個超級使用者來配置和是用Buildroot。第一步是執行配置助手:

 $ make menuconfig

對於配置的每個條目來說,你都可以找到相關聯的幫助,幫助資訊描述了該條目的用途。

一個關鍵的配置專案是PROFECT,它決定了在構建這些包的位置,以及結果安裝的位置。

一旦所有的都配置完成了,配置工具將產生一個.config檔案,裡面包含了了你的配置資訊,它將會被Makefile使用,來決定需要哪些檔案。

讓我們繼續:

 $ make

這個命令將下載、配置並且編譯所有被選擇的工具,並且最後產生一個目標檔案系統。這個目標檔案系統被命名為root_fs_ARCH.EXT,ARCH是你的處理器架構型別,EXT依賴於你在配置工具中選擇的目標檔案系統。這個檔案存放在“binaries/$(PROJECT)/”目錄裡面。

建立你自己的目標板支援

一旦一個包被打開了,就可以手動的升級配置文。Buildroot能自動的儲存buildroot、linux、busybox、uclibc和u-boot的配置檔案,存放在 “local/$(PROJECT) ”中,使用的命令如下:

 $ make saveconfig

一旦一個buildroot的配置檔案同過saveconfig被建立了,預設的“$(TOPDIR)/.config” 檔案就可以通過下面的方式被覆蓋了:

 $ make BOARD=<project>

Buildroot以後會使用 “local/<project>/<project>.config”而不是“.config”。

如果你想修改你的目標板,你可以使用下面的命令來複制該工程的配置檔案到“.config”:

 $ make BOARD=<project> getconfig

你可以設定環境變數BUILDROOT_LOCAL使它指向這個目錄來在多個buildroot樹中共享你定製的目標板支援的資料夾。

離線構建

如果你想離線構建,並且僅僅是想下載之前在“make menuconfig”中選擇了的所有的原始碼,執行如下:

 $ make source

你現在可以斷開連線,複製你的dl目錄中的內容到你的build-host。

環境變數

Buildroot可以選擇的遵循了部分已經通過的環境變數:

·    HOSTCXX

·    HOSTCC

·    UCLIBC_CONFIG_FILE=<path/to/.config>

·    BUSYBOX_CONFIG_FILE=<path/to/.config>

一個例子,使用config檔案來定位頂級目錄資料夾和你的$HOME:

$ make UCLIBC_CONFIG_FILE=uClibc.config BUSYBOX_CONFIG_FILE=$HOME/bb.config

如果你想在你的主機上使用一個編譯器而不是預設的gcc或者是g++來構建helper-binaries,執行如下:

$ make HOSTCXX=g++-4.3-HEAD HOSTCC=gcc-4.3-HEAD

使用自動完成

如果你很懶散,你不想打字打出make menuconfigminglingh,你可以在你的shell中使用自動完成。這裡是怎麼樣你才可以使用你的bash:

$ complete -W menuconfig make

然後只是打出一行開頭的字元,通過按TAB鍵來呼叫bash去完成它:

$ make me<TAB>

這樣bash就會為你附加上nuconfig!

作為選擇,有些發行版(其中Debian和Mandriva就是一個例子)可以更好的補充。根據你的發行版本,你可能必須安裝一些軟體包以便完成. 在Mandriva上,這個包為bash-completion, 而Debian把它作為了bash軟體包的一部分。

其他的shells,比如zsh, 也有完成這個任務的措施。具體的檢視你的shell的文件。

定製目標檔案系統

這裡有一些定製最終目標檔案系統的方法:

·    直接定製目標檔案系統,並且重建映像檔案。目標檔案系統存放在project_build_ARCH/root/ 目錄下面,這裡的ARCH就是你選擇的目標架構。你可以很簡單的在這裡修改,並且重新編譯來重建目標檔案系統。這個方法允許你在目標檔案系統上進行任何的改變,但是如果你決定完全重新構建你的工具鏈和工具集,這些修改都會被被丟失。

·    定製目標檔案系統框架,存放在target/generic/target_skeleton/目錄下面,你可以在這裡自定義配置檔案或者其他東西。但是,完整的目錄層次還沒有實現,它是在編譯的過程中建立的。所以你不能在這個檔案系統框架上做任何事情,即使你完全重建了交叉編譯工具鏈和工具集,但是這種改變依然被存在。
你也可以自定義target/generic/device_table.txt 檔案,它是被工具集用來建立目標檔案系統的許可權設定和裝置節點。target/generic/skel.tar.gz 檔案包含了根檔案系統的主要資料夾,而且我們沒有要去改變它。在這個壓縮包裡面的主要檔案目錄都在框架裡面,因為它包含了指向框架的符號連結,以防被損壞。
這些自定義配置在真正的映像產生之前將被展開到project_build_ARCH/root/ 目錄裡面。所以通過執行make來重建映像會把所有的修改都傳遞到映像裡面。

·    當使用make menuconfig來配置要建立的系統時,你可以指定在PROJECT 中的/etc/hostname和/etc/issue (歡迎條)的內容。

定製Busybox的配置

Busybox是完全可以配置的,而且你也想定製它。你可以遵循下面的簡單步驟來配置它,它不是最佳的方式,但是它最簡單額日期額可以正常工作。

1. 首先使用buildroot執行一次busybox,在這一次裡面不需要進行任何的配置。

2. 呼叫make busybox-menuconfig。這個配置工具使你可以電腦告知所有的東西。

3. 再一此執行編譯buildroot的編譯。

另外,如果你知道你想要的修改的選項而不需要配置工具的話,你也可以修改package/busybox/busybox-<version>.config 檔案 。

如果你想使用busybox的已經存在的配置檔案,請參照後面的環境變數。

定製uClibc的配置

就像BusyBox一樣,uClibc提供了許多配置選項。 他們允許你根據你不同的需求和侷限性選擇不同的功能。

最簡單的修改uClibc配置的步驟如下:

1. 首先不定製uClibc來編譯執行一次buildroot。

2. 呼叫make uclibc-menuconfig。這是一個很好的配置工具,它與曾在Linux核心和Buildroot裡面所使用的類似。然後進行你的正確配置。

3. 拷貝.config到toolchain/uClibc/uClibc.config或者是到 toolchain/uClibc/uClibc.config-locale。如果你沒有在Buildroot裡面選擇本地支援的話就使用前者,相反就用後者。

4. 再一此執行編譯buildroot的編譯。

另外,你也可以直接修改toolchain/uClibc/uClibc.config或者 toolchain/uClibc/uClibc.config-locale而不需要使用上面的配置工具。

如果你想使用一個已經存在uclibc配置檔案,I請參照後面的環境變數。

Buildroot的執行方式

如上面所說的一樣, Buildroot是一個基本的並使用恰當的選項去下載、配置、編譯軟體的命令集。它還包括了一些軟體的補丁,主要的都是與交叉編譯工具鏈有關 (gcc,binutils 和uClibc)。

主要的是每一個軟體都有一個Makefile檔案,他們都被命名為以.mk為副檔名。Makefiles主要分成以下四部分:

·    工程 (在 project/ 目錄) 包含了在這個相同buildroot目錄樹裡面涉及到構建根檔案系統Makefiles和相關聯的檔案。

·    工具鏈 (在toolchain/ 目錄) 包含了所有的設計到交叉工具鏈(binutils,ccache, gcc,gdb,kernel-headers and uClibc)的Makefiles和相關聯的檔案。

·    包 (在package/ 目錄) 包含了Buildroot編譯並要載入到目標系統上的使用者空間的工具的Makefiles和相關聯的檔案。對於每一個工具都有想對應的子目錄。.

·    目標 (在target/目錄) 包含了用於生成一目標檔案系統映像的軟的Makefiles和相關檔案。有四種類型的檔案系統被支援:ext2,jffs2,cramfs和squashfs。他們中的每一個,都有一個子目錄來存放需要的檔案。這裡也有一個預設的default/ 目錄,裡面包含了目標檔案系統的框架。

每個資料夾至少包含兩個檔案:

·    something.mk 是一個用於下載、配置、編譯和安裝的Makefile。

·    Config.in是配置工具描述檔案的一部分,它描述了當前軟體的相關選項。

核心的Makefile檔案通過下面的步驟來完成任務(在配置完成以後):

1. 建立下載目錄(預設的為dl/)。該目錄就是被下載的壓縮包存放的地方。非常有必要去了解該目錄下的壓縮包,我們可以將它儲存到其他地方以免將來使用的時候再去下載。

2. 建立共享的構建目錄(預設的為build_ARCH/ ,ARCH是目標系統的體系架構)。在這個目錄裡面存放的是已經被編譯了的不需要配置的使用者空間的工具。當使用同一架構構建多個目標系統的時候,首先構建的會完全的通過下載、配置、編譯等步驟,但是第二個或者以後的就只需要拷貝第一次的結果,主要可以加速構建的進度。

3. 建立工程的詳細目錄 (預設的為project_build_ARCH/$(PROJECT), ARCH是目標系統的體系架構)。這裡是所有的可配置的使用者空間工具的被編譯的目錄。這個特殊的構建目錄是必須的, 如果兩個不用的目標體系架構都需要使用一個特殊的軟體包,這樣這個軟體包就根據目標體系架構有不同的配置,busybox和linux就是其中的例子。

4. 建立工程的結果目錄(預設的為binaries/$(PROJECT),ARCH是目標系統的體系架構)。這個目錄是根檔案系統映像存放的地方,也是存放目標系統的Linux核心映像和其他工具集、boot-loaders 等的地方。

5. 建立工具鏈目錄(預設的為toolchain_build_ARCH/,ARCH是目標系統的體系架構)。在這裡交叉工具鏈被編譯。

6.    設定平臺目錄(預設的為build_ARCH/staging_dir/)。這裡是交叉編譯工具鏈安裝的地方。如果你想使用相同的交叉編譯工具鏈來作為其他的用途,比如說編譯第三方的應用軟體,你可以新增build_ARCH/staging_dir/usr/b路徑到PATH中,只有你就可以使用arch-linux-gcc來編譯你的程式了。為了設定這個目錄,首先應該移除這個它,然後它在該目錄裡面建立子目錄和符號連線。

7. 建立目標檔案系統 (預設的為project_build_ARCH/root/) 和目標檔案系統框架。這個目錄將包含最終的根檔案系統。要使它更新,首先應該刪除它,然後解壓 target/generic/skel.tar.gz 檔案來建立主要的子目錄資料夾和符號連結,並拷貝在target/generic/target_skeleton中可用的框架,然後刪除沒有用的.svn/目錄。

8. 新增TARGETS的依賴關係。一般將會檢查這些包的配置選項是否可用,然後通過把它新增到TARGETS全域性變數中來定製要被編譯的軟體包。

在相同的buildroot原始碼目錄樹構建幾個不同的工程

背景知識

如果每個工程都是為不同的體系架構構建的話,buildroot支援在同一個原始碼目錄樹中構建若干不同的工程。

根檔案系統被建立在“build_<ARCH>/root”資料夾中,對於每一個體系架構來說,它都是唯一的。交叉工具鏈被建立在“toolchain_build_<ARCH>”目錄。

如果使用者希望為相同的體系架構構建若干個根檔案系統,就應該在配置中加上字首或者字尾,這樣的話,建立的根檔案系統就被放置在“<PREFIX>_build_<ARCH>_<SUFFIX>/root”。通過設定唯一的字首和字尾,使每一個工程都有一個唯一的根檔案系統樹。

這個方法的缺點就是為同一個晶片建立兩個工程,每一個工程都要建立一個新的工具鏈,這個構建過程將耗費更多的時間。

如果使用的是gcc-4.x.y 的話,這個缺點就不是那麼的明顯了,因為gcc-4.x.y 允許使用外部工具鏈。由於某些軟體包需要一些特殊功能,如果使用的一個外部的工具鏈,這可能就缺少一些必要的功能,來構建一個根檔案系統。

一個更大的問題是build_<ARCH>目錄樹也是拷貝的,這樣的話,每個軟體包也都為每一個工程重建一次,導致花費更長的時間。

共享工程的工具鏈和構建的軟體包

當工作在一個工程的時候,允許使用者在同一個目錄樹為同一個體系架構構建多個根目錄樹。工具鏈個軟體包的構建目錄將會被共享,但是每一個具體的工程都有一個專門的目錄。

在使用的這個方法的時候,更多的是,如果在第一個工程建立時,所有的軟體包都沒有被編譯。這個過程就幾乎同原來的過程一樣了,所有下載的軟體包被下載然後提取到共享目錄“build_<ARCH>/<package>”中,然後配置、編譯。

二進位制軟體包和標頭檔案被安裝到共享目錄$(STAGING_DIR)中,然後這個工程專門的根檔案系統被設定到“$(TARGET_DIR)”。

在構建結束的時候,還要通過這個根檔案系統來生成一個最後的二進位制根檔案系統。

一旦第一個工程構建結束,在構建其他工程的時候就只是呼叫已經共享在“build_<ARCH>/<>”目錄下的內容來生成新的檔案系統。

如果一些軟體包沒有用於第一個工程,就只能通過提取-配置-編譯的步驟了。

執行

核心是要建立兩個新的目錄:

·    project_build_<ARCH>

·    binaries;

每個目錄裡面都包含了每個工程的子目錄。子目錄的名字是使用者在配置buildroot的時候配置的,它由下面的內容組成:

Project Options ---> Project name

這裡定義$(PROJECT)變數。

預設的名字(project name)為“uclibc”。

"package/Makefile.in"定義為:

    PROJECT_BUILD_DIR:=project_build_$(ARCH)/$(PROJECT)

    BINARIES_DIR:=binaries/$(PROJECT)

它也定義了目標根檔案系統的本地路徑:

    TARGET_DIR:=$(PROJECT_BUILD_DIR)/$(PROJECT)/root

也就是說:如果使用者使用“myproject”作為$(PROJECT) 名稱:

·    "project_build_<ARCH>/myproject"

·    "binaries/myproject"

就會被建立。

現在,根檔案系統,busybox和AtmelU-Boot版本,還有Atmel專門的一些bootloader像阿通1-bootstrap和dataflashboot.bin都被構建在“$(PROJECT_BUILD_DIR)”中。

所有體系架構最後的二進位制檔案都存放在“$(BINARIES_DIR)”目錄中。

總結

工程將會共享不會引起衝突的資料夾,但是使用唯一的構建目錄,在該目錄中,使用者可以配置自己的配置。

該做的事情

1. Linux

當前的Linux版本總是有缺陷的, 它僅僅工作在使用者選擇使用較少額選項作為核心基本的標頭檔案。它僅服務於使用者選擇的少量的核心作為主要核心的基礎。雖然Makefle有一些關聯,允許開發者在target/device/*/* Makefiles中指定核心的版本,但是如果選擇了其他的版本,構建將會失敗的。

原因是核心的補丁沒有被"target/linux/linux.mk"用來編譯指令碼片段。他們僅用於"toolchain/kernel-headers/*.makefile"去編譯指令碼片段。

如果核心標頭檔案和Linux版本不一樣的話,在“build_<ARCH>/<>”將會有兩個“linux-2.6.X.Y”資料夾,每一個都自己的補丁命令。

在這個方案中的解決辦法是,將Linux的構建目錄移動到“project_build_<ARCH>/<project name>/linux-2.6.X.Y”,結合這個方法把可以應用的補丁進行配置。用於產生標頭檔案的Linux的原始碼目錄樹很可能會被移動到“toolchain_build_<ARCH>”目錄中去。

使用者可以選擇下面三種不同的策略:

o   保守策略: 僅僅使用核心標頭檔案支援的版本

o   穩定Linux的策略: 允許任何的2.6.X.Y 的組合體(最小為2.6.19)

o   激進使用者策略: 允許“-git”或者是“-mm”,或者是使用者下載核心

The current kernel patches can be configured to be applied to the linux source tree even if the version differs from the kernel header version.

Since the user can select any kernel-patch he/she will be able to select a non-working combination. If the patch fails, the user will have to generate a new proprietary kernel-patch or decide to not apply the kernel patches

Other optional patches will be board specific or architecture specific patches.

There will also be a way for the user to supply absolute or relative paths to patches, possibly outside the main tree. This can be used to apply custom kernel-header-patches, if the versions available in buildroot cannot be applied to the specific linux version used

Maybe, there will also be a possibility to supply an "URL" to a patch available on Internet.

2. Configurable packages

Many packages can, on top of the simple "enable/disable build", be further configured using Kconfig. Currently these packages will be compiled using the configuration specified in the ".config" file of the first project demanding the build of the package.

If another project uses the same packages, but with a different configuration,these packages will not be rebuilt, and the root file system for the new project will be populated with files from the build of the first project

If multiple project are built, and a specific package needs two different configuration, then the user must delete the package from the "build_<ARCH>" directory before rebuilding the new project.

A long term solution is to edit the package makefile and move the build of the configurable packages from "build_<ARCH>" to "project_build_<ARCH>/<project name>" and send a patch to the buildroot mailing list.

3. Naming conventions

Names of resulting binaries should reflect the "project name"

4. Generating File System binaries

Packages which needs to be installed with the "root" as owner, will generate a ".fakeroot.<package>" file which will be used for the final build of the root file system binary.

This was previously located in the "$(STAGING_DIR)" directory, but was recently moved to the "$(PROJECT_BUILD_DIR)" directory.

Currently only three packages: "at", "ltp-testsuite" and "nfs-utils" requests fakeroot.

The makefile fragments for each file system type like "ext2", "jffs2" or "squashfs" will, when the file system binary is generated, collect all present ".fakeroot.<package>" files to a single "_fakeroot.<file system>" file and call fakeroot.

".fakeroot.<package>" files are deleted as the last action of the Buildroot Makefile.

It needs to be evaluated if any further action for the file system binary build is needed.

Using the uClibc toolchain

You may want to compile your own programs or other software that are not packaged in Buildroot. In order to do this, you can use the toolchain that was generated by Buildroot.

The toolchain generated by Buildroot by default is located in build_ARCH/staging_dir/. The simplest way to use it is to add build_ARCH/staging_dir/usr/bin/ to your PATH environnement variable, and then to use arch-linux-gcc, arch-linux-objdump, arch-linux-ld, etc.

For example, you may add the following to your .bashrc (considering you're building for the MIPS architecture and that Buildroot is located in ~/buildroot/) :

export PATH="$PATH:~/buildroot/build_mips/staging_dir/usr/bin/"

Then you can simply do :

mips-linux-gcc -o foo foo.c

Important : do not try to move a gcc-3.x toolchain to an other directory, it won't work. There are some hardcoded paths in the gcc configuration. If the default toolchain directory doesn't suit your needs, please refer to the Using the uClibc toolchain outside of buildroot section.

If you are using a current gcc-4.x, then use --sysroot and -isysroot since these toolchains have fully functional sysroot support. No hardcoded paths do exist in these configurations.

Using the uClibc toolchain outside of buildroot

By default, the cross-compilation toolchain is generated inside build_ARCH/staging_dir/. But sometimes, it may be useful to install it somewhere else, so that it can be used to compile other programs or by other users. Moving the build_ARCH/staging_dir/ directory elsewhere is not possible if using gcc-3.x, because there are some hardcoded paths in the toolchain configuration. This works, thanks to sysroot support, with current, stable gcc-4.x toolchains, of course.

If you want to use the generated gcc-3.x toolchain for other purposes, you can configure Buildroot to generate it elsewhere using the option of the configuration tool : Build options -> Toolchain and header file location, which defaults to $(BUILD_DIR)/staging_dir/.

Location of downloaded packages

It might be useful to know that the various tarballs that are downloaded by the Makefiles are all stored in the DL_DIR which by default is the dl directory. It's useful for example if you want to keep a complete version of Buildroot which is know to be working with the associated tarballs. This will allow you to regenerate the toolchain and the target filesystem with exactly the same versions.

If you maintain several buildroot trees, it might be better to have a shared download location. This can be accessed by creating a symbolic link from the dl directory to the shared download location.

I.E:

ln -s <shared download location> dl

Another way of accessing a shared download location is to create the BUILDROOT_DL_DIR environment variable. If this is set, then the value of DL_DIR in the project is overridden. The following line should be added to "~/.bashrc".

export BUILDROOT_DL_DIR <shared download location>

Extending Buildroot with more software

This section will only consider the case in which you want to add user-space software.

Package directory

First of all, create a directory under the package directory for your software, for example foo.

Config.in file

Then, create a file named Config.in. This file will contain the portion of options description related to our foo software that will be used and displayed in the configuration tool. It should basically contain :

config BR2_PACKAGE_FOO

        bool "foo"

        default n

        help

      This is a comment that explains what foo is.

Of course, you can add other options to configure particular things in your software.

The real Makefile

Finally, here's the hardest part. Create a file named foo.mk. It will contain the Makefile rules that are in charge of downloading, configuring, compiling and installing the software. Below is an example that we will comment afterwards.

     1  #############################################################

     2  #

     3  # foo

     4  #

     5  #############################################################

     6  FOO_VERSION:=1.0

     7  FOO_SOURCE:=foo-$(FOO_VERSION).tar.gz

     8  FOO_SITE:=http://www.foosoftware.org/downloads

     9  FOO_DIR:=$(BUILD_DIR)/foo-$(FOO_VERSION)

    10  FOO_BINARY:=foo

    11  FOO_TARGET_BINARY:=usr/bin/foo

    12

    13  $(DL_DIR)/$(FOO_SOURCE):

    14          $(WGET) -P $(DL_DIR) $(FOO_SITE)/$(FOO_SOURCE)

    15

    16  $(FOO_DIR)/.source: $(DL_DIR)/$(FOO_SOURCE)

    17          $(ZCAT) $(DL_DIR)/$(FOO_SOURCE) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) -

    18          touch [email protected]

    19

    20  $(FOO_DIR)/.configured: $(FOO_DIR)/.source

    21          (cd $(FOO_DIR); rm -rf config.cache; /

    22                  $(TARGET_CONFIGURE_OPTS) /

    23                  $(TARGET_CONFIGURE_ARGS) /

    24                  ./configure /

    25                  --target=$(GNU_TARGET_NAME) /

    26                  --host=$(GNU_TARGET_NAME) /

    27                  --build=$(GNU_HOST_NAME) /

    28                  --prefix=/usr /

    29                  --sysconfdir=/etc /

    30          )

    31          touch [email protected]

    32

    33  $(FOO_DIR)/$(FOO_BINARY): $(FOO_DIR)/.configured

    34          $(MAKE) CC=$(TARGET_CC) -C $(FOO_DIR)

    35

    36  $(TARGET_DIR)/$(FOO_TARGET_BINARY): $(FOO_DIR)/$(FOO_BINARY)

    37          $(MAKE) prefix=$(TARGET_DIR)/usr -C $(FOO_DIR) install

    38          rm -Rf $(TARGET_DIR)/usr/man

    39

    40  foo: uclibc ncurses $(TARGET_DIR)/$(FOO_TARGET_BINARY)

    41

    42  foo-source: $(DL_DIR)/$(FOO_SOURCE)

    43

    44  foo-clean:

    45          $(MAKE) prefix=$(TARGET_DIR)/usr -C $(FOO_DIR) uninstall

    46          -$(MAKE) -C $(FOO_DIR) clean

    47

    48  foo-dirclean:

    49          rm -rf $(FOO_DIR)

    50

    51 #############################################################

    52 #

    53 # Toplevel Makefile options

    54 #

    55 #############################################################

    56 ifeq ($(strip $(BR2_PACKAGE_FOO)),y)

    57 TARGETS+=foo

    58 endif

First of all, this Makefile example works for a single binary software. For other software such as libraries or more complex stuff with multiple binaries, it should be adapted. Look at the other *.mk files in the package directory.

At lines 6-11, a couple of useful variables are defined :

·    FOO_VERSION : The version of foo that should be downloaded.

·    FOO_SOURCE : The name of the tarball of foo on the download website of FTP site. As you can see FOO_VERSION is used.

·    FOO_SITE : The HTTP or FTP site from which foo archive is downloaded. It must include the complete path to the directory where FOO_SOURCE can be found.

·    FOO_DIR : The directory into which the software will be configured and compiled. Basically, it's a subdirectory of BUILD_DIR which is created upon decompression of the tarball.

·    FOO_BINARY : Software binary name. As said previously, this is an example for a single binary software.

·    FOO_TARGET_BINARY : The full path of the binary inside the target filesystem.

Lines 13-14 defines a target that downloads the tarball from the remote site to the download directory (DL_DIR).

Lines 16-18 defines a target and associated rules that uncompress the downloaded tarball. As you can see, this target depends on the tarball file, so that the previous target (line 13-14) is called before executing the rules of the current target. Uncompressing is followed by touching a hidden file to mark the software has having been uncompressed. This trick is used everywhere in Buildroot Makefile to split steps (download, uncompress, configure, compile, install) while still having correct dependencies.

Lines 20-31 defines a target and associated rules that configures the software. It depends on the previous target (the hidden .source file) so that we are sure the software has been uncompressed. In order to configure it, it basically runs the well-known ./configure script. As we may be doing cross-compilation, target, host and build arguments are given. The prefix is also set to /usr, not because the software will be installed in /usr on your host system, but in the target filesystem. Finally it creates a .configured file to mark the software as configured.

Lines 33-34 defines a target and a rule that compiles the software. This target will create the binary file in the compilation directory, and depends on the software being already configured (hence the reference to the .configured file). It basically runs make inside the source directory.

Lines 36-38 defines a target and associated rules that install the software inside the target filesystem. It depends on the binary file in the source directory, to make sure the software has been compiled. It uses the install target of the software Makefile by passing a prefix argument, so that the Makefile doesn't try to install the software inside host /usr but inside target /usr. After the installation, the /usr/man directory inside the target filesystem is removed to save space.

Line 40 defines the main target of the software, the one that will be eventually be used by the top level Makefile to download, compile, and then install this package. This target should first of all depends on all needed dependecies of the software (in our example, uclibc and ncurses), and also depend on the final binary. This last dependency will call all previous dependencies in the correct order.

Line 42 defines a simple target that only downloads the code source. This is not used during normal operation of Buildroot, but is needed if you intend to download all required sources at once for later offline build. Note that if you add a new package providing a foo-source target is mandatory to support users that wish to do offline-builds. Furthermore it eases checking if all package-sources are downloadable.

Lines 44-46 define a simple target to clean the software build by calling the Makefiles with the appropriate option. The -clean target should run make clean on $(BUILD_DIR)/package-version and MUST uninstall all files of the package from $(STAGING_DIR) and from $(TARGET_DIR).

Lines 48-49 define a simple target to completely remove the directory in which the software was uncompressed, configured and compiled. The -dirclean target MUST completely rm $(BUILD_DIR)/ package-version.

Lines 51-58 adds the target foo to the list of targets to be compiled by Buildroot by first checking if the configuration option for this package has been enabled using the configuration tool, and if so then "subscribes" this package to be compiled by adding it to the TARGETS global variable. The name added to the TARGETS global variable is the name of this package's target, as defined on line 40, which is used by Buildroot to download, compile, and then install this package.

Conclusion

As you can see, adding a software to buildroot is simply a matter of writing a Makefile using an already existing example and to modify it according to the compilation process of the software.

If you package software that might be useful for other persons, don't forget to send a patch to Buildroot developers !

Resources

To learn more about Buildroot you can visit these websites: