一、测试环境
-
开发板: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 int main() { printf("buildroot helloworldn"); 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 目录下
-
将 Build服务器托管网root/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
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。Seata 为用户提供了 AT、TCC、SAGA、XA 等多种事务模式,帮助解决不同业务场景下的事务一致性问题。 本文主要介绍 Seata Saga 模式的使…