Tool Chains
internal and external
buildroot提供了兩種方式的toolchain,統稱為『toolchain backend』:
- Internal toolchain, 代表的是所有的toolchain都是buildroot由source code建制出來的。
- External toolchain,你也可以使用本來在你電腦裡面就已經存在,或是外部的toolchain來建制。
如下圖,menuconfig要選擇你要用那一種:
Internal toolchain
使用這個選項的話,Buildroot會幫你從source code去建置整個cross-compilation toolchain,這個選項提供了非常彈性的組合,你可以選擇不同版本的『kernel header version』,不同類型的『C Library』,『gcc』...等等組合,但是除非你真的有這個需求,不然就不要亂弄會比較好,畢竟這部分的相容性也是很麻煩的。
Internal toolchain的相依性描述和建置的流程如下:
(來源 : free-electrons )
- 建置gcc所需要的host Tools和Library(host-m4, host-mpc, host-mpfr,host-gmp)
- 將上一步的結果安裝到『$(HOST_DIR)/usr/{bin,include,lib}』
- 建置host-binutils
- 將host-binutils安裝到『$(HOST_DIR)/usr/bin』
- 建置first stage 的compiler - 『host-gcc-initial』
- 將linux-kernel-headers安裝到『$(STAGING_DIR)/usr/include』
- 接下來建置並安裝C Library(這個例子是uclibc)到 『$(STAGING_DIR)/lib』,『$(STAGING_DIR)/usr/include』和 『$(TARGET_DIR)/lib』
- 最終就是建置host-gcc-final並且安裝到『$(HOST_DIR)/usr/bin』
建制出來的結果如下三個:
- $(HOST_DIR)/usr/bin/<tuple>-<tool>
為cross-compilation tools,包含了compiler,linker,assembler等等。 - $(HOST_DIR)/usr/<tuple>/
這個資料夾裡面的檔案都是host建制專案時會用到的檔案,像是kernel 標頭檔,C 函式庫標頭檔,C函式庫,C++函式庫標頭檔等等。 - $(TARGET_DIR)/
cross-compile出來的target board檔案,但還不是成品。
External toolchain
如果你有以下的幾個需求,那你可以嘗試著用這個外部的toolchain的選項,這樣的用處主要是可以重複使用,可以節省很多時間,不過這個選項算是進階選項吧,所以進階玩家可以試看看:
- 廠商有提供你他們的toolchain。
- 你之前已經有用buildroot建制過toolchain了。
- 你有從網路下載相關的toolchain。
- 使用已知的相關toolchain(CodeSourcery, Linaro 等等)。
- 其他客製化工具,像是Crosstool-NG。
如果你已經有你自己客製化的toolchain,你就要選擇選項:
『toolchain->Custom toolchain』,
然後在搭配底下的『Toolchain origin』,看你要『Toolchain to be downloaded and installed』,還是要『Pre-installed toolchain』,第一個選項比較適合多個開發者一起分享toolchain,主要是輸入目標URL,而第二個就要輸入你的toolchain的local路徑。但是不管是那一個選項,你都需要輸入其他的一些資訊,像是如下:
可以看到你還要跟系統說你的gcc版本,kernel版本等等資訊,這樣它才知道哪些套件可以用這個toolchain來建制。
external toolchain的建置流程如下:
- 將toolchain解壓縮到『$(HOST_DIR)/opt/ext-toolchain』
- 執行script檢查這個toolchain
- 將toolchain的sysroot (C的library和headers, kernel headers)複製到『$(STAGING_DIR)/usr/{include,lib}』
- 將toolchain的library複製到『$(TARGET_DIR)/usr/lib』
- 建立相關的Symbolic links或是wrappers,主要是從『$(HOST_DIR)/opt/ext-toolchain/bin/<tuple>-<tool>』到『$(HOST_DIR)/usr/bin/<tuple>-<tool>』
external toolchain建出來以後,就如同internal toolchain,會有以下的幾個輸出資料夾:
- $(HOST_DIR)/opt/ext-toolchain
這個資料夾主要是用來將你外部的toolchain tarball解開。 - $(HOST_DIR)/usr/bin/<tuple>-<tool>
跟internal的不一樣,這個資料夾除了compiler以外,其他只會存在連結到source toolchain的捷徑, - $(HOST_DIR)/usr/<tuple>/
- $(TARGET_DIR)/
以上這兩個資料夾,就跟internal toolchain差不多。
kernel headers version
在toolchain的部分,其中最重要的一個參數就是kernel標頭檔的版本資訊,kernel標頭檔是所有函式庫用來和kernel溝通的介面,所以只要這個介面出了問題的話,就會出錯。
這個kernel和user 空間的介面是向下相容的,所以這份標頭檔至少要跟你的標頭檔版本一樣,更舊也可以,但是不能更新,因為kernel的實作主體就是在這個版本,所以你的介面不能比他還要新阿,不然他會聽不懂。
How to Use cross-compiling
如剛剛所說,cross-compiler會被安裝到『$(HOST_DIR)/usr/bin』,這個cross-compiler可以被直接用來產生相對應架構的軟體,而會用到的函式庫和標頭檔都會自動的去搜尋『$(STAGING_DIR)』。
要使用cross-compiler,第一件事就是要設定環境變數『PATH』如下:
export PATH=$(pwd)/output/host/usr/bin:$PATH
記得要加入的路徑一定要在PATH前面,不然如果系統剛好有個相同的編譯器,就會用錯,假設你想要cross-compiling一個arm架構的程式,就必須要用:
export PATH=$(pwd)/output/host/usr/bin:$PATH
arm-linux-gcc -o foobar foobar.c
在cross-compiling的工具路徑底下,除了編譯器以外,還有須多的工具,像是『pkg-config』,『autoconfig』等等,要使用之前都要記得將路徑設定到『PATH』裡面。