前言
本文基于 RK3588 + Buildroot 编写.
在RK3588开发板环境下,开发者通常利用Buildroot来定制适合RK3588芯片特性的嵌入式Linux系统。通过Buildroot,开发者能够根据实际需求裁剪系统组件、添加特定驱动、配置内核特性,并集成用户应用程序,最终生成最小化且高效的Bootloader、Linux内核镜像、根文件系统镜像(例如rootfs.ext2或 squashfs格式)以及其他必要的启动和系统配置文件。
结合RK3588芯片的强大功能与Buildroot的高度灵活性,开发者能够快速实现针对RK3588平台的嵌入式Linux系统的定制开发,确保系统不仅满足性能要求,还能达到资源占用小、启动速度快、稳定性高的目标,广泛应用于各种工业控制、智能家居、物联网终端等应用场景。
目标:
- 增加自定义软件模块(模块使用Cmake + C/C++, 源文件基于本地)
- 模块单独编译并支持配置默认编译
1. 增加自定义软件模块(模块使用Cmake + C/C++, 源文件基于本地)
增加模块配置:
buildroot/package/test_app/
├── Config.in
└── test.mk
package/test_app/Config.in
config BR2_PACKAGE_TEST_APP bool "TestApp build!" help Add add app for test!
package/test_app/test.mk
TEST_APP_SITE = $(TOPDIR)/test_app TEST_APP_SITE_METHOD = local TEST_APP_INSTALL_STAGING = YES #TEST_APP_CONF_OPTS = -DBUILD_DEMOS=ON $(eval $(cmake-package))
模块C和CMakeLists源码
buildroot/test_app/
├── CMakeLists.txt
└── main.c
test_app/CMakeLists.txt
cmake_minimum_required(VERSION 3.1.0) set(CMAKE_CXX_STANDARD 11) project(test_app) include_directories(inc) set(SOURCES main.c) add_executable(${PROJECT_NAME} ${SOURCES}) install(TARGETS test_app DESTINATION bin)
test_app/main.c
#include <stdio.h> int main() { printf("Test App by add new package!\n"); return 0; }
2. 模块单独编译并支持配置默认编译
参考: The Buildroot user manual:Understanding how to rebuild packages 和RK的SDK文档.
## 切换到buildroot目录下.
source build/envsetup.sh (config_name)
## 编译模块和系统
#选好编译平台,接下来就可以编译每⼀个package,它主要是config、build、install三部分组成
make <package>-reconfigure
make <package>-rebuild
make <package>-reinstall
#清理包命令如下:
make <package>-dirclean
# 其他的一些编译命令:
make <package>-<target>
Package-specific:
<pkg> - Build and install <pkg> and all its dependencies
<pkg>-source - Only download the source files for <pkg>
<pkg>-extract - Extract <pkg> sources
<pkg>-patch - Apply patches to <pkg>
<pkg>-depends - Build <pkg>'s dependencies
<pkg>-configure - Build <pkg> up to the configure step
<pkg>-build - Build <pkg> up to the build step
<pkg>-graph-depends - Generate a graph of <pkg>'s dependencies
<pkg>-dirclean - Remove <pkg> build directory
<pkg>-reconfigure - Restart the build from the configure step
<pkg>-rebuild - Restart the build from the build step
相关package的开发,可以参考 /buildroot/package/* , 其中package/rockchip是Rockchip开发的相关package
添加后模块不会参与编译, 增加配置项到构建系统也很简单:
buildroot/package/Config.in
diff --git a/buildroot/package/Config.in b/buildroot/package/Config.in index 75cfa5799..e593037ca 100755 --- a/buildroot/package/Config.in +++ b/buildroot/package/Config.in @@ -2601,4 +2601,8 @@ menu "Text editors and viewers" source "package/vim/Config.in" endmenu +menu "Customize Packages" + source "package/test_app/Config.in" +endmenu + endmenu
在文件末尾增加模块的Config.in
运行 make menuconfig 进入 Target packages
可以看到增加的菜单, 进入后可以看到并选中菜单.
保存配置后, 重新make即可.
编译完成后可以看到:
一些问题记录
- No rule to make target ‘test_app’. Stop
$ make test_app
/xxx/...../buildroot/../prebuilts/gcc/linux-x86/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf GCC10
arm64 arm64 arm64
arm64
make[1]: *** No rule to make target 'test_app'. Stop.
make: *** [Makefile:88: _all] Error 2
test_app 实际上是模块的文件夹名称, 如: package/test_app, 写成*package/testapp 会报这个问题
- package/test_app/test_app.mk中 test_app.mk 的文件名没有限定, 也可以存在多个, 只要内容定义不冲突
比如, 前面的代码用的文件名是: test.mk - does not appear to contain CMakeLists.txt.
buildroot/../prebuilts/gcc/linux-x86/arm/gcc-arm-10.3-2021.07-x86_64-arm-none-linux-gnueabihf GCC10
arm64 arm64 arm64
arm64
>>> test_app Extracting
>>> test_app Patching
>>> test_app Configuring
(mkdir -p /buildroot/output/rockchip_rk3588/build/test_app/ && cd /buildroot/output/rockchip_rk3588/build/test_app/ && rm -f CMakeCache.txt && sed -e 's#@@STAGING_SUBDIR@@#aarch64-buildroot-linux-gnu/sysroot#' -e 's#@@RELOCATED_HOST_DIR@@#/buildroot/output/rockchip_rk3588/host/share/buildroot/#' -e 's#@@TARGET_CFLAGS@@#-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -g0 -D_FORTIFY_SOURCE=1#' -e 's#@@TARGET_CXXFLAGS@@#-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Os -g0 -D_FORTIFY_SOURCE=1#' -e 's#@@TARGET_FCFLAGS@@#-Os -g0#' -e 's#@@TARGET_LDFLAGS@@##' -e 's#@@TARGET_CC@@#bin/aarch64-buildroot-linux-gnu-gcc#' -e 's#@@TARGET_CXX@@#bin/aarch64-buildroot-linux-gnu-g++#' -e 's#@@TARGET_AR@@#bin/aarch64-buildroot-linux-gnu-ar#' -e 's#@@TARGET_AS@@#bin/aarch64-buildroot-linux-gnu-as#' -e 's#@@TARGET_LD@@#bin/aarch64-buildroot-linux-gnu-ld#' -e 's#@@TARGET_NM@@#bin/aarch64-buildroot-linux-gnu-nm#' -e 's#@@TARGET_RANLIB@@#bin/aarch64-buildroot-linux-gnu-ranlib#' -e 's#@@TARGET_READELF@@#bin/aarch64-buildroot-linux-gnu-readelf#' -e 's#@@TARGET_STRIP@@#bin/aarch64-buildroot-linux-gnu-strip#' -e 's#@@TARGET_OBJCOPY@@#bin/aarch64-buildroot-linux-gnu-objcopy#' -e 's#@@TARGET_OBJDUMP@@#bin/aarch64-buildroot-linux-gnu-objdump#' -e 's#@@TARGET_FC@@#bin/aarch64-buildroot-linux-gnu-gfortran#' -e 's#@@CMAKE_SYSTEM_PROCESSOR@@#aarch64#' -e 's#@@TOOLCHAIN_HAS_CXX@@#1#' -e 's#@@TOOLCHAIN_HAS_FORTRAN@@#0#' -e 's#@@CMAKE_BUILD_TYPE@@#Release#' /buildroot/support/misc/toolchainfile.cmake.in > /buildroot/output/rockchip_rk3588/build/test_app//toolchainfile.cmake && PATH="/buildroot/output/rockchip_rk3588/host/bin:/buildroot/output/rockchip_rk3588/host/sbin:/home/anson/.local/bin:/home/anson/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" /usr/bin/cmake /buildroot/output/rockchip_rk3588/build/test_app/ -DCMAKE_TOOLCHAIN_FILE="/buildroot/output/rockchip_rk3588/build/test_app//toolchainfile.cmake" -DCMAKE_INSTALL_PREFIX="/usr" -DCMAKE_COLOR_MAKEFILE=OFF -DBUILD_DOC=OFF -DBUILD_DOCS=OFF -DBUILD_EXAMPLE=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TEST=OFF -DBUILD_TESTS=OFF -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=ON )
CMake Error: The source directory "/buildroot/output/rockchip_rk3588/build/test_app" does not appear to contain CMakeLists.txt.
Specify --help for usage, or press the help button on the CMake GUI.
make[1]: *** [package/pkg-generic.mk:287: /buildroot/output/rockchip_rk3588/build/test_app/.stamp_configured] Error 1
make: *** [Makefile:88: _all] Error 2
出现这个问题的原因是test.mk中的配置问题:
TESTAPP_SITE = $(TOPDIR)/work/test_app
TESTAPP_SITE_METHOD = local
TESTAPP_INSTALL_STAGING = YES
$(eval $(cmake-package))
TESTAPP 名称需要与编译模块对应, 假如是make test_app, 对应应该是TEST_APP_*
所以, 正确的配置是:
TEST_APP_SITE = $(TOPDIR)/work/test_app
TEST_APP_SITE_METHOD = local
TEST_APP_INSTALL_STAGING = YES
$(eval $(cmake-package))
- 关于MK文件(内容来自Google bard)
# 模块源码的路径
TEST_APP_SITE = $(TOPDIR)/work/test_app
#
TEST_APP_SITE_METHOD = local
TEST_APP_INSTALL_STAGING = YES
TEST_APP_SITE 变量定义测试应用程序的源代码目录。在本例中,它位于 $(TOPDIR)/work/test_app
。
TEST_APP_SITE_METHOD 变量定义测试应用程序的获取方式。在本例中,它设置为 local
,表示应用程序源代码已存在于本地目录 $(TEST_APP_SITE)
中。
TEST_APP_INSTALL_STAGING 变量定义是否将测试应用程序安装到暂存目录。在本例中,它设置为 YES
,表示应用程序将安装到 $(STAGING_DIR)
目录。
以下是这段代码的详细解释:
- TEST_APP_SITE 变量:
- 该变量定义测试应用程序的源代码目录。
- 可以使用绝对路径或相对路径。
- 如果使用相对路径,则相对于
$(TOPDIR)
目录。
- TEST_APP_SITE_METHOD 变量:
- 该变量定义测试应用程序的获取方式。
- 可以设置以下值:
local
:表示应用程序源代码已存在于本地目录$(TEST_APP_SITE)
中。git
:表示应用程序源代码将从 Git 仓库克隆。svn
:表示应用程序源代码将从 SVN 仓库检出。http
:表示应用程序源代码将从 HTTP 服务器下载。ftp
:表示应用程序源代码将从 FTP 服务器下载。
- TEST_APP_INSTALL_STAGING 变量:
- 该变量定义是否将测试应用程序安装到暂存目录。
- 可以设置以下值:
YES
:表示应用程序将安装到$(STAGING_DIR)
目录。NO
:表示应用程序不会安装到暂存目录。
示例
假设 TEST_APP_SITE
设置为 $(TOPDIR)/work/test_app
,TEST_APP_SITE_METHOD
设置为 local
,TEST_APP_INSTALL_STAGING
设置为 YES
。
在这种情况下,Buildroot 将执行以下操作:
- 从
$(TOPDIR)/work/test_app
目录获取测试应用程序源代码。 - 编译测试应用程序。
- 将测试应用程序安装到
$(STAGING_DIR)
目录。
注意
- 如果
TEST_APP_SITE_METHOD
设置为git
、svn
、http
或ftp
,则 Buildroot 将自动下载应用程序源代码。 - 如果
TEST_APP_INSTALL_STAGING
设置为NO
,则 Buildroot 将只编译测试应用程序,不会将其安装到暂存目录。
参考
[ 编译篇 ] Buildroot Add Package的一些坑
嵌入式Linux构建框架Buildroot创建自己的软件包(基于传统makefile和cmake)(篇二)
buildroot中配置自定义APP