一、測試環境
-
開發板:rv1126
-
buildroot版本:2018.02-rc3
二、.mk規則
-
PKG_NAME:定義軟體包的名稱。通常與軟體包原始碼的目錄名相同。
-
PKG_VERSION:定義軟體包的版本號。
-
PKG_SOURCE:定義軟體包原始碼的下載連結或路徑。可以是遠端 URL 或本地路徑。
-
PKG_HASH:定義軟體包原始碼的雜湊值,用於驗證下載檔案的完整性。通常使用 MD5 或 SHA256 演算法計算。
-
PKG_LICENSE:定義軟體包的許可證型別。可以是單個許可證或多個許可證的組合。
-
PKG_BUILD_DIR:定義軟體包構建過程中的臨時目錄。通常是 ${BUILD_DIR}/${PKG_NAME}-${PKG_VERSION}。
-
PKG_INSTALL_DIR:定義軟體包安裝到目標系統的目錄。通常是 ${TARGET_DIR}。
-
PKG_CONFIG_DEPENDS:定義軟體包構建過程中依賴的其他軟體包。這些依賴將被自動解析和構建。
-
PKG_BUILD_CMDS結尾的變數會在 buildroot 框架編譯的時候執行,用於給原始碼的 Makefile 傳遞編譯選項和連結選項,呼叫原始碼的Makefile。
-
PKG_INSTALL_TARGET_CMDS結尾的變數是在編譯完之後,自動安裝執行,一般是讓 buildroot 把編譯出來的的 bin 或 lib 複製到指定目錄。
-
$(eval $(autotools-package)):使用 Autotools 構建系統的軟體包規則。適用於使用 configure 指令碼的軟體包。
-
$(eval $(cmake-package)):使用 CMake 構建系統的軟體包規則。適用於使用 CMakeLists.txt 的軟體包。
-
$(eval $(generic-package)):通用的軟體包規則,適用於沒有特定構建系統的軟體包。需要手動定義構建和安裝過程。
-
$(eval $(host-generic-package)):適用於主機(開發機)上構建的通用軟體包規則。與目標系統無關。
-
$(eval $(python-package)):適用於 Python 軟體包的規則。用於構建和安裝 Python 模組。
三、建立自定義軟體包
對 buildroot 目錄還不熟的小夥伴可以看我之前的筆記【Buildroot】使用記錄
3.1 Makefile
-
建立 Buildroot 專案
在 SDK/app 目錄下建立 app_demo 檔案,並在檔案中建立 test.c 和 Makefile 檔案,內容如下檔案目錄
app_demo ├── test.c └── Makefile
Makefile 檔案
OPT = -O2 DEBUG = -g OTHER = -Wall -Wno-deprecated CFLAGS = $(OPT) $(OTHER) INCDIR = -I LIBDIR = -L LIBS = APP=app_demo SRCS=test.c .PHONY: all all: $(CC) -o $(APP) $(SRCS) $(CFLAGS) $(LIBDIR) $(INCDIR) $(LIBS) .PHONY: clean clean: rm -f *.o *~ $(APP) .PHONY: install install: cp -f $(APP) $(TARGET_DIR)/../oem .PHONY: uninstall uninstall: rm -f $(TARGET_DIR)/../oem/$(APP)
test.c 檔案
#include <stdio.h> int main() { printf("buildroot helloworld\n"); return 0; }
-
APP 的版本和編譯規則
在 Buildroot/package 目錄下建立 app_demo 目錄,並在目錄中建立 app_demo.mk 和 Config.in 檔案,內容如下檔案目錄
app_demo ├── app_demo.mk └── Config.in
app_demo.mk 檔案
################################################## # # app_demo.mk # ################################################## ifeq ($(BR2_PACKAGE_APP_DEMO), y) APP_DEMO_VERSION:=1.0.0 APP_DEMO_SITE=$(TOPDIR)/../app/app_demo APP_DEMO_SITE_METHOD=local #APP_INSTALL_TARGET:=YES define APP_DEMO_BUILD_CMDS $(TARGET_MAKE_ENV) $(MAKE) CC=$(TARGET_CC) CXX=$(TARGET_CXX) -C $(@D) endef define APP_DEMO_CLEAN_CMDS $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) clean endef define APP_DEMO_INSTALL_TARGET_CMDS $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) install endef define APP_DEMO_UNINSTALL_TARGET_CMDS $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) uninstall endef $(eval $(generic-package)) endif
Config.in 檔案
config BR2_PACKAGE_APP_DEMO bool "app_demo" help This is a demo to add app_demo.
-
加到 menuconfig 配置中
開啟“buildroot/package/Config.in”檔案。跳轉到最後一個“endmenu”下新增如下示例程式碼(注意:必須在此檔案的最後一個 endmenu 前新增)。程式碼如下所示:menu "app_demo" source "package/app_demo/Config.in" endmenu
-
在 menuconfig 開啟專案
這裡需要注意的是,需要編譯專案時,在 menuconfig 中配置完成後,需要使用命令make savedefconfig
儲存配置。開啟專案如下圖所示:
-
編譯專案
每次編譯完成後都會在 output/build 目錄下生成對應的包# 編譯專案 make app_demo # 清除專案 make app_demo-dirclean
3.2 cmake
不論是使用 make 構建還是使用 cmake 構建,所操作的流程都是一樣的,只是編譯規則有一點區別,所以這裡就不描述具體的流程了,只將不同的檔案貼上即可,其他流程是一樣的
-
在 SDK/app/app_demo 檔案中建立 CMakeLists.txt 檔案,內容如下
cmake_minimum_required(VERSION 3.1.0) set(CMAKE_CXX_STANDARD 11) project(app_demo1) set(SOURCES test.c) add_executable(${PROJECT_NAME} ${SOURCES}) install(TARGETS ${PROJECT_NAME} DESTINATION ../../oem)
注意:install 預設安裝的位置是 $(TARGET_DIR)/usr 目錄下
-
將 Buildroot/package/app_demo 目錄下的 app_demo.mk 檔案內容更改成以下內容
################################################## # # app_demo.mk # ################################################## ifeq ($(BR2_PACKAGE_APP_DEMO), y) APP_DEMO_VERSION:=1.0.0 APP_DEMO_SITE=$(TOPDIR)/../app/app_demo APP_DEMO_SITE_METHOD=local #UVC_APP_DEPENDENCIES = libdrm mpp $(eval $(cmake-package)) endif
-
編譯結果如下所示
四、修改軟體版本
完成上面操作後,應給會發現,軟體包不只是自定義的,也有從線上下載的。有時候需要更改線上包的版本,情況稍微有一點不一樣,所以這裡記錄了一下。
可能會有小夥伴和我做同樣的嘗試,上一篇筆記中有提到軟體包下載的目錄在 Buildroot/dl 下,所以就將需要的版本軟體下載到 dl 目錄下,便會發現這樣的操作是不可行的,需要更改一下配置檔案,這裡以 iperf3 為例,流程如下:
-
進入 buildroot/package/iperf3/ 目錄,如下圖所示
-
重要檔案
圖中的檔案中,有三個比較重要的檔案,分別是:- Config.in 相當於核心的 Kconfig;
- iperf3.hash 軟體包的校驗碼;
- iperf3.mk 相對於核心的 Makefile;
-
修改軟體版本
開啟 iperf3.mk 檔案,可以看到包的下載地址和版本號(有時候下載地址在 Config.in 裡),進入下載網站後,可以找到自己需要的版本,然後修改檔案,如下圖所示:
-
下載測試
使用命令make iperf3-source
可以進行下載,如下圖所示
-
生成原始碼的 hash 值
sha256sum buildroot/dl/iperf-3.9.tar.gz
-
修改 iperf3.hash 檔案
注意:因為 3.9 版本沒有補丁檔案的,所以將對應的補丁檔案刪除即可
五、開機自啟
開機時啟動自己的應用程式有兩種辦法,一種是進入檔案系統後,在 /etc/init.d/ 目錄新增自己的啟動指令碼;另一種將指令碼放在 buildroot 中,在編譯的時候,自動放在 /etc/init.d/ 目錄下。
由於在 /etc/init.d/ 目錄下建立指令碼的方式比較簡單,這裡就不介紹了,主要分析方式二,將啟動指令碼放在 buildroot 中進行替換。
在操作之前,先來科普一些東西,在 buildroot 編譯完成後,有一個最終確定目標的過程,在配置選項中預留了幾個介面,如下:
-
BR2_ROOTFS_OVERLAY:指向一個目錄,此目錄下的所有檔案將會覆蓋到output/target下。比如一些配置檔案,或者預編譯的庫等可以在此階段處理。
-
BR2_ROOTFS_POST_BUILD_SCRIPT:一個指令碼,更加複雜的對檔案進行刪除、重新命名、strip等等功能。
-
BR2_ROOTFS_POST_IMAGE_SCRIPT:對最終生成的images進行打包處理等。
注意: 配置檔案在 Buildroot/configs 目錄下。可以透過命令 make menuconfig
進行配置和檢視,如下圖所示:
-
fs overlay
buildroot 會將 BR2_ROOTFS_OVERLAY 配置路徑的檔案替換到 buildroot/output/xxx/build/target/ 目錄下存在或不存在的檔案,所以只需要將指令碼放在 BR2_ROOTFS_OVERLAY 中對應的目錄下即可 -
透過指令碼操作
除了fs overlay這種方式,buildroot還提供了一個指令碼進行更加複雜的處理。可以進行檔案刪除、重新命名,甚至對帶除錯資訊的檔案進行strip等。@$(foreach s, $(call qstrip,$(BR2_ROOTFS_POST_BUILD_SCRIPT)), \ $(call MESSAGE,"Executing post-build script $(s)"); \ $(EXTRA_ENV) $(s) $(TARGET_DIR) $(call qstrip,$(BR2_ROOTFS_POST_SCRIPT_ARGS))$(sep))
-
指令碼打包
除了上面兩種方式進行替換之外,還可以在指令碼打包的環節進行替換,這個方式我沒有研究過,有需要的小夥伴可以自行嘗試一下。
常見問題
- tar: ./usr/bin/pkg:警告:無法 stat: 沒有那個檔案或目錄
當安裝包的路徑變動時,可能會出現這個警告,只需要將 output/build 路徑下的 packages-file-list.txt 中的路徑給刪除即可,如下圖所示:
參考資料
buildroot/packages/app/的.mk規則的詳細解釋:https://blog.csdn.net/benco1986/article/details/131455637
嵌入式Linux構建框架Buildroot建立自己的軟體包(基於傳統makefile和cmake):https://zhuanlan.zhihu.com/p/451071335
【Buildroot】基礎知識:目錄、根檔案系統目錄覆蓋、編譯效能分析(編譯時間、目標尺寸、包依賴圖):https://blog.csdn.net/qq_28877125/article/details/130347075