一、测试环境

  • 开发板: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

  1. 创建 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;
    }
  2. 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.
  3. 加到 menuconfig 配置中

    打开“buildroot/package/Config.in”文件。跳转到最后一个“endmenu”下添加如下示例代码(注意:必须在此文件的最后一个 endmenu 前添加)。代码如下所示:

    menu "app_demo"
    source "package/app_demo/Config.in"
    endmenu

  4. 在 menuconfig 打开项目

    这里需要注意的是,需要编译项目时,在 menuconfig 中配置完成后,需要使用命令 make savedefconfig 保存配置。打开项目如下图所示:

  5. 编译项目

    每次编译完成后都会在 output/build 目录下生成对应的包

    # 编译项目
    make app_demo # 清除项目
    make app_demo-dirclean

3.2 cmake

不论是使用 make 构建还是使用 cmake 构建,所操作的流程都是一样的,只是编译规则有一点区别,所以这里就不描述具体的流程了,只将不同的文件贴上即可,其他流程是一样的

  1. 在 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 目录下

  2. 将 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
  3. 编译结果如下所示

四、修改软件版本

完成上面操作后,应给会发现,软件包不只是自定义的,也有从线上下载的。有时候需要更改线上包的版本,情况稍微有一点不一样,所以这里记录了一下。

可能会有小伙伴和我做同样的尝试,上一篇笔记中有提到软件包下载的目录在 Buildroot/dl 下,所以就将需要的版本软件下载到 dl 目录下,便会发现这样的操作是不可行的,需要更改一下配置文件,这里以 iperf3 为例,流程如下:

  1. 进入 buildroot/package/iperf3/ 目录,如下图所示

  2. 重要文件

    图中的文件中,有三个比较重要的文件,分别是:

    • Config.in 相当于内核的 Kconfig;
    • iperf3.hash 软件包的校验码;
    • iperf3.mk 相对于内核的 Makefile;
  3. 修改软件版本

    打开 iperf3.mk 文件,可以看到包的下载地址和版本号(有时候下载地址在 Config.in 里),进入下载网站后,可以找到自己需要的版本,然后修改文件,如下图所示:

  4. 下载测试

    使用命令 make iperf3-source 可以进行下载,如下图所示

  5. 生成源码的 hash 值

    sha256sum buildroot/dl/iperf-3.9.tar.gz

  6. 修改 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 进行配置和查看,如下图所示:

  1. fs overlay

    buildroot 会将 BR2_ROOTFS_OVERLAY 配置路径的文件替换到 buildroot/output/xxx/build/target/ 目录下存在或不存在的文件,所以只需要将脚本放在 BR2_ROOTFS_OVERLAY 中对应的目录下即可

  2. 通过脚本操作

    除了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))

  3. 脚本打包

    除了上面两种方式进行替换之外,还可以在脚本打包的环节进行替换,这个方式我没有研究过,有需要的小伙伴可以自行尝试一下。

常见问题

  1. 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

【Buildroot】工具包使用的更多相关文章

  1. Buildroot 用户手册 (中文)

    文章目录 I. Getting started 1. About Buildroot 2. System requirements 2.1. Mandatory packages 2.2. Optio ...

  2. 【翻译】Awesome R资源大全中文版来了,全球最火的R工具包一网打尽,超过300+工具,还在等什么?

    0.前言 虽然很早就知道R被微软收购,也很早知道R在统计分析处理方面很强大,开始一直没有行动过...直到 直到12月初在微软技术大会,看到我软的工程师演示R的使用,我就震惊了,然后最近在网上到处了解和 ...

  3. 【NLP】干货!Python NLTK结合stanford NLP工具包进行文本处理

    干货!详述Python NLTK下如何使用stanford NLP工具包 作者:白宁超 2016年11月6日19:28:43 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的 ...

  4. Werkzeug工具包学习-官方例子Shortly分析

    为了学习werkzeug的wsgi框架工具,今天真对官网的例子进行调试运行.涉及到了werkzeug工具包,jinja2前端模版,以及redis内存库,之后可以灵活定制自己主页.再次,作以记录. 首先 ...

  5. Win10 UWP 开发系列:使用多语言工具包让应用支持多语言

    之前我在一篇blog中写过如何使用多语言工具包,见http://www.cnblogs.com/yanxiaodi/p/3800767.html 在WinEcos社区也发布过一篇详细的文章介绍多语言工 ...

  6. Neo4j图数据库管理系统开发笔记之一:Neo4j Java 工具包

    1 应用开发概述 基于数据传输效率以及接口自定义等特殊性需求,我们暂时放弃使用Neo4j服务器版本,而是在Neo4j嵌入式版本的基础上进行一些封装性的开发.封装的重点,是解决Neo4j嵌入式版本Emb ...

  7. 脑成像数据分析:Python工具包

    来源:SealHuang 脑成像技术已经成为认知科学和心理学研究领域中一种重要的研究手段,帮助研究者不断深入发掘我们脑中的秘密.伴随着研究的不断深入,各式各样的指标参数和分析方法也不断推陈出新,以迅雷 ...

  8. doc2vec使用说明(二)gensim工具包 LabeledSentence

    欢迎交流,转载请注明出处. 本文介绍gensim工具包中,带标签(一个或者多个)的文档的doc2vec 的向量表示. 应用场景: 当每个文档不仅可以由文本信息表示,还有别的其他标签信息时,比如,在商品 ...

  9. Cookie对象工具包,对象添加,获取,修改-亲测可用

    先来了解下Cookie 和 Session对象的概念吧. 首先,Cookie是客户端缓存技术,大小一般为4kb左右,主要存储一些比较小的信息,常用的例子有用户名和密码,且是不安全的: Session是 ...

  10. Flat UI 工具包

    Flat UI是一套精美的扁平风格 UI 工具包,基于 Twitter Bootstrap 实现.这套界面工具包含许多基本的和复杂的 UI 部件,例如按钮,输入框,组合按钮,复选框,单选按钮,标签,菜 ...

随机推荐

  1. P3874 砍树 题解

    前置 树形 dp,二分. 题意 本质上是一个树上背包,需要选不少于 \(k\) 个物品,每个物品有一个重量 \(w\) 和价值 \(v\),求性价比最大值. 分析 既然是性价比,显然是分数规划. 先介 ...

  2. 《小白WEB安全入门》02. 开发篇

    @ 目录 初识HTML潜在漏洞 初识CSS潜在漏洞 初识JS潜在漏洞 初识后端潜在漏洞 后端能做什么 后端种类 后端框架 潜在漏洞 本系列文章只叙述一些超级基础理论知识,极少有实践部分 本文涉及到的语 ...

  3. 每日一题:如何判断是否是数组,一个既简单又复杂的问题。(不要再用Object.prototype.toString.call、instance of判断了!!!)

    1.不要使用Object.prototype.toString.call() 正常情况下: const arr = [1,2,3,4,5] const obj = {} console.log(Obj ...

  4. ChatGPT多个APIkey如何自主切换

    chatgpt目前账户大多数为18美金,那么用户在调用api时候出现金额不足要手动更换chatgpt 当前方法为了解决多账户自主切换api使用. 创建一个名为$arr的数组,它包含几个key.我们使用 ...

  5. The method dismissDialog(int) from the type Activity is deprecated

    The method showDialog(int) from the type Activity is deprecated in android?   up vote6down votefavor ...

  6. P8684 [蓝桥杯 2019 省 B] 灵能传输 题解

    P8684 [蓝桥杯 2019 省 B] 灵能传输 题解 Part 1 提示 题目传送门 欢迎大家指出错误并私信这个蒟蒻 欢迎大家在下方评论区写出自己的疑问(记得 @ 这个蒟蒻) Part 2 更新日 ...

  7. nodejs修改npm包安装位置

    适用于非个人电脑.便携使用 npm config set cache D:\nodejs\node_cache npm config set prefix D:\nodejs npm config s ...

  8. 回文自动机(PAM) 详解

    PAM 是一种高效存储字符串中所有回文子串的自动机,用于解决回文串相关问题. 虽然代码稍微长一点,但写起来比 manacher 容易很多,毕竟没有加了一堆字符再转回原串的若干上取整下取整问题. 前置知 ...

  9. QT(4)-QAbstractItemView

    @ 目录 1 说明 2 常用函数 2.1 交替行颜色 2.1.1 alternatingRowColors 2.1.2 setAlternatingRowColors 2.2 autoScroll 2 ...

  10. redis 怎么样查看key的大小,多大的key才算大key?

    查看key大小的命令 # 格式memory usage [key-name]# 例如:我要查 yino_hash_key 这个key的大小,就在命令行中输入 memory usage yino_has ...