17. Buildroot用户手册-将软件包添加到Buildroot

转载请注明原文链接:https://blog.csdn.net/haimo_free/article/details/107677667

文章目录

17. 将软件包添加到Buildroot

本节介绍如何将新软件包(用户空间的库或应用程序)集成到Buildroot中。它还显示了如何集成现有的软件包,这是解决问题或调整其配置所必须的。

添加新软件包时,请确保在各种条件下对其进行测试(请参阅第17.23.3节“如何测试您的软件包”),并检查其编码格式(请参阅第17.23.2“如何检查编码格式”)。

17.1 软件包目录

首先,在package目录下为你的软件包创建子目录,例如libfoo。

一些软件包已经通过主题子目录进行了分组,如x11r7、qt5和gstreamer。如果你的软件包属于这些类别,请在这些类别中创建软件包目录。不建议使用新的子目录。

17.2 Config配置文件

为了使软件包显示在配置界面中,你需要在软件包目录中创建一个Config文件。有两种类型:Config.in和Config.in.host。

17.2.1 Config.in

对于目标机上使用的软件包,创建一个名为Config.in的配置文件。该文件包含与软件包libfoo相关的选项说明,这些选项说明将在配置界面中使用和显示。它基本上包含:

config BR2_PACKAGE_LIBFOO
        bool "libfoo"
        help
          This is a comment that explains what libfoo is. The help text
          should be wrapped.

          http://foosoftware.org/libfoo/

bool、help行以及其他元数据信息行必须使用一个Tab缩进。帮助文本本身应缩进一个Tab和两个空格,且应换行以适应72列,其中制表符占8字符,因此实际文本本身应以62个字符换行。帮助文本后空一行,说明软件包的URL。

按照Buildroot的约定,属性的顺序如下:

  1. bool、string……:选项类型
  2. default:默认值,如果需要
  3. depends on:对目标机的依赖项
  4. depends on:对工具链的依赖项
  5. depends on:对其他软件包的依赖项
  6. select:需要选择的依赖项
  7. help:帮助文本

你可以在if BR2_PACKAGE_LIBFOO…endif语句中添加其他子选项以配置软件中的特定内容,你可以在其他软件包中查看示例。Config.in文件的语法与内核Kconfig文件的语法相同。有关此语法的文档,请参阅:http://kernel.org/doc/Documentation/kbuild/kconfig-language.txt

最后,你必须将新软件包的libfoo/Config.in添加到package/Config.in(如果你决定将该软件包放到子类别下,则添加到该类别的子目录中)。其中包含的文件按类别按字母顺序排序,除了软件包的名称外不应包含任何其他内容。

17.2.2 Config.in.host

一些软件包还需要为宿主机系统构建。这里有两个选项:

  • 如果宿主机软件包只是为了满足一个或多个目标机软件包构建时的依赖项,在这种情况下,仅需在目标软件包的BAR_DEPENDENCIES变量添加host-foo依赖即可,无需创建Config.in.host文件。
  • 宿主机软件包需要用户从配置菜单中明确选择,在这种情况下,请为该软件包创建
Config.in.host文件:
config BR2_PACKAGE_HOST_FOO
        bool "host foo"
        help
          This is a comment that explains what foo for the host is.

          http://foosoftware.org/foo/

其编码样式和选项与Config.in文件相同。

最后,你必须将新添加的libfoo/Config.in.host添加到package/Config.in.host文件。其中包含的文件按字母顺序排序,除了软件包的名称外不应包含任何其他内容。之后,就可以从Host utilities菜单中看到该软件包。

source "package/foo/Config.in.host"
17.2.3 选择depends on或select

软件包的Config.in文件需要确保正确设置了依赖关系。通常,Buildroot使用以下规则:

  • 使用select指明对库的依赖关系。这些依赖关系通常并不明显,因此让kconfig系统确保选择了依赖项是有意义的。例如,libgtk2软件包使用select BR2_PACKAGE_LIBGLIB2确保libglib2库被启用。
  • 当用户确实需要了解依赖关系时,使用depends on指明依赖关系。通常,Buildroot使用这种类型的依赖关系来实现对目标体系结构、MMU和工具链的依赖关系(参阅第17.2.4“对目标和工具链选项的依赖”)或对“大”事物(例如X.org系统)的依赖关系。

注意,当前kconfig语言的问题是,这两个依赖项语义没有内部链接。因此,可以选择依赖项未满足要求的软件包。

一个同时使用select和depends on的示例:

config BR2_PACKAGE_RRDTOOL
        bool "rrdtool"
        depends on BR2_USE_WCHAR
        select BR2_PACKAGE_FREETYPE
        select BR2_PACKAGE_LIBART
        select BR2_PACKAGE_LIBPNG
        select BR2_PACKAGE_ZLIB
        help
          RRDtool is the OpenSource industry standard, high performance
          data logging and graphing system for time series data.

          http://oss.oetiker.ch/rrdtool/

comment "rrdtool needs a toolchain w/ wchar"
        depends on !BR2_USE_WCHAR

请注意,这两种依赖关系仅相同类型的依赖关系可以传递。这意味着以下示例:

config BR2_PACKAGE_A
        bool "Package A"

config BR2_PACKAGE_B
        bool "Package B"
        depends on BR2_PACKAGE_A

config BR2_PACKAGE_C
        bool "Package C"
        depends on BR2_PACKAGE_B

config BR2_PACKAGE_D
        bool "Package D"
        select BR2_PACKAGE_B

config BR2_PACKAGE_E
        bool "Package E"
        select BR2_PACKAGE_D

软件包C仅在软件包B已选择时才可见,且B仅在A已选择时才可见。

若选择软件包E,则软件包D、B将同时被选择,此时不会判断软件包B的依赖项,因此不会选择软件包A。

由于软件包B被选择,而软件包A未选择,因此违反了软件包B对软件包A的依赖关系。因此,在这种情况下,必须显示添加传递依赖项:

config BR2_PACKAGE_D
        bool "Package D"
        select BR2_PACKAGE_B
        depends on BR2_PACKAGE_A

config BR2_PACKAGE_E
        bool "Package E"
        select BR2_PACKAGE_D
        depends on BR2_PACKAGE_A

总体而言,对于软件包的依赖关系,select应该是首选。

请注意,这些依赖关系仅确保启用了依赖项,但不一定在构建你的软件包之前构建。为此,还需要在.mk文件中明确依赖项。

进一步的样式细节,请参阅第15章“编码样式”。

17.2.4 对目标和工具链选项的依赖

很多软件包依赖于工具链的某些选项:C库的选择、C++支持、线程支持、RPC支持、wchar支持或动态库支持等。某些软件包只能在某些目标体系结构上构建,或者需要CPU支持MMU才可以构建。

这些依赖关系必须在Config.in文件中用适当的depends on语句声明。此外,对于工具链选项的依赖,当选择未开启时需要显示一段提示文本,以使用户明白为什么软件包不可用。对目标体系结构或MMU支持的依赖不应该在注释中显示:因为用户不太可能可以自由选择另一个目标体系结构,因此明确这些依赖关系没有任何意义。
只有当配置选项本身在满足工具链选项依赖关系可见时,注释才应该可见。这意味着必须在注释中重复软件包的所有其他依赖项(包括对目标体系结构和MMU支持的依赖)。为了保持简洁,对非工具链选项的depends on语句应与对工具链选项的depends on语句分开。如果对同一文件(通常是主程序包)中的配置选项存在依赖关系,那么最好使用全局if……elseif结构,而不是在注释和其他配置选项上重复该depends on语句。

软件包的依赖项注释的一般格式为:

foo needs a toolchain w/ featA, featB, featC
mpd needs a toolchain w/ C++, threads, wchar
crda needs a toolchain w/ threads

注意,注释文本应保持简短,以使其适合80个字符的终端。

本节的剩余部分列举了不同的目标体系结构和工具链选项、要依赖的配置符号以及在注释中使用的文本。

  • 目标体系结构
    • 依赖符号:BR2_powerpc,BR2_mips……(请参阅arch/Config.in)
    • 注释文本:无需添加注释
  • MMU支持
    • 依赖符号: BR2_USE_MMU
    • 注释文本:无需添加注释
  • Gcc_sync* 用于原子操作的GCC内置函数,有1字节、2字节、4字节及8字节的变体版本可用。由于不同的体系结构支持不同大小的原子操作,因此每种大小都有一个依赖符号。
    • 依赖符号: BR2_TOOLCHAIN_HAS_SYNC_1 、BR2_TOOLCHAIN_HAS_SYNC_2、BR2_TOOLCHAIN_HAS_SYNC_4、BR2_TOOLCHAIN_HAS_SYNC_8
    • 注释文本:无需添加注释
  • Gcc_atomic* 用于原子操作的GCC内置函数。
    • 依赖符号: BR2_TOOLCHAIN_HAS_ATOMIC
    • 注释文本:无需添加注释
  • 内核头文件
    • 依赖符号:BR2_TOOLCHAIN_HEADERS_AT_LEAST_X_Y(将X_Y替换为正确的版本,参加toolchain/Config.in)
    • 注释文本:headers >= X.Y and/or headers <= X.Y(将X_Y替换为正确的版本)
  • Gcc版本
    • 依赖符号:BR2_TOOLCHAIN_GCC_AT_LEAST_X_Y(将X_Y替换为正确的版本)
    • 注释文本:gcc >= X.Y and/or gcc <= X.Y
  • 宿主系统Gcc版本
    • 依赖符号:BR2_HOST_GCC_AT_LEAST_X_Y(将X_Y替换为正确的版本)
    • 注释文本:无需添加注释
      注意,通常不是软件包本身需要宿主系统Gcc最小版本限制,而是它所依赖的宿主机软件包需要。
  • C库
    • 依赖符号:BR2_TOOLCHAIN_USES_GLIBC, BR2_TOOLCHAIN_USES_MUSL,BR2_TOOLCHAIN_USES_UCLIBC
    • 注释文本:对于C库,使用的注释文本略有不同,如foo needs a glibc toolchain或foo needs a glibc toolchain w/ C++
  • C++支持
    • 依赖符号:BR2_INSTALL_LIBSTDCPP
    • 注释文本:C++
  • D支持
    • 依赖符号:BR2_TOOLCHAIN_HAS_DLANG
    • 注释文本:Dlang
  • Fortran支持
    • 依赖符号:BR2_TOOLCHAIN_HAS_FORTRAN
    • 注释文本:fortran
  • thread支持
    • 依赖符号:BR2_TOOLCHAIN_HAS_THREADS
    • 注释文本:threads(除非BR2_TOOLCHAIN_HAS_THREADS_NPTL 也需要,在这种情况下,仅指定NPTL就足够了)
  • NPTL thread支持
    • 依赖符号:BR2_TOOLCHAIN_HAS_THREADS_NPTL
    • 注释文本:NPTL
  • RPC支持
    • 依赖符号:BR2_TOOLCHAIN_HAS_NATIVE_RPC
    • 注释文本:RPC
  • wchar支持
    • 依赖符号:BR2_USE_WCHAR
    • 注释文本:wchar
  • 动态库
    • 依赖符号: !BR2_STATIC_LIBS
    • 注释文本:dynamic library
17.2.5 对Linux内核的依赖

一些软件包需要Linux内核才能由Buildroot构建,这些通常是内核模块或固件。应该在Config.in文件中添加注释以表名这种依赖性,类似于对工具链选项的依赖。通用格式为:

foo needs a Linux kernel to be built

如果同时依赖于工具链选项和Linux内核,请使用以下格式:

foo needs a toolchain w/ featA, featB, featC and a Linux kernel to be built
17.2.6 对udev设备管理的依赖

如果软件包需要udev设备管理,则应依赖于BR2_PACKAGE_HAS_UDEV,并添加以下注释:

foo needs udev /dev management

如果同时依赖于工具链选项和udev设备管理,请使用以下格式:

foo needs udev /dev management and a toolchain w/ featA, featB, featC
17.2.7 对虚拟软件包的依赖

某些功能可以由多个软件包提供,例如OpenGL库。有关虚拟软件包的更多信息,请参阅第17.11节“虚拟软件包的基础结构”。

17.3 .mk文件

最后,也是最难的部分,创建一个名为libfoo.mk的文件。它描述了如何下载、配置、构建和安装软件包。

根据软件包的类型,.mk文件必须使用不同的基础结构以不同的方式写入文件:

  • 通用的Makefile(不使用autotools或CMake):与基于autotools的软件包的Makefile基础结构类似,但是需要开发人员做更多的工作。它们指明了应如何配置、编译和安装软件包。此基础结构必须用于所有不使用autotools的软件包。将来,可能会为其他构建系统编写其专用基础结构,我们将通过教程和参考资料来介绍它们。
  • 基于autotools的Makefile(autoconf、automake等):由于autotools是非常常见的构建系统,因此Buildroot为此类软件包提供了专用的基础结构。此基础结构必须用于依赖autotools作为其构建系统的软件包。
  • 基于CMake的Makefile:由于CMake构建系统越来越常用且具有标准化行为,Buildroot为此类软件包提供了专用的基础结构。此基础结构必须用于依赖CMake作为其构建系统的软件包。
  • Python模块的Makefile:针对使用distutils或setuptools机制的Python模块,Buildroot提供了专用的基础结构。
  • Lua模块的Makefile:通过LuaRocks网站可使用Lua模块的专用基础结构。

更多样式细节,参阅https://buildroot.org/downloads/manual/manual.html#writing-rules-mk

17.4 .hash文件

如果可能,你必须添加一个名为lifoo.hash的文件,它包含了libfoo软件包下载文件的哈希值。不添加.hash文件的唯一原因是由于软件包的下载方式无法进行哈希检查。
当软件包有多个版本可选择时,哈希文件可以存储在以版本号命名的子目录中,例如package/libfoo/1.2.3/libfoo.hash。如果不同版本具有不同的许可条款,但他们又存储在同一文件中,这一点尤其重要。否则,哈希文件应保留在软件包的目录中。
存储在该文件中的哈希值用于验证下载文件和许可文件的完整性。

该文件的格式为每行一个文件,每行包含以下三个字段,并个两个空格隔开:

  • 哈希类型,取以下值之一:
    • md5、sha1、sha224、sha256、sha384、sha512、none
  • 哈希值
    • none:一个或多个非空字符,通常使用字符串xxx
    • md5:32个十六进制字符
    • sha1:40个十六进制字符
    • sha224:56个十六进制字符
    • sha256:64个十六进制字符
    • sha384:96个十六进制字符
    • sha512:128个十六进制字符
  • 文件名
    • 源文件:文件名称,不包含目录
    • 许可文件:FOO_LICENSE_FILES设置的文件路径

以#开头的行为注释。注释及空行将被忽略。

一个文件可以有多个哈希值,每个哈希值单独一行。在这种情况下,所有哈希值都必须匹配。

注意:理想情况下,哈希文件中存储的哈希值应与软件提供商在官网、邮件中发布的哈希值匹配。如果软件提供商提供了多种类型的哈希(如sha1和sha512),则最好添加所有这些哈希值。如果软件提供商不提供任何哈希值,或仅提供md5哈希,则最好自己再计算一个强哈希值(最好是sha256),并在.hash文件的注释行中说明。

注意:许可文件的哈希值用于检查软件包版本变更时其许可文件是否变更,在make legal-info运行期间检查许可文件的哈希。对于具有多个版本的软件包(如Qt5),创建子目录并在子目录中创建.hash文件(请参阅第18.2节“如何应用补丁”)。

哈希类型none用于从仓库下载,如git clone或svnsersion checkout等。

以下示例展示了libfoo-1.2.3.tar.bz2软件包的哈希定义:

# Hashes from: http://www.foosoftware.org/download/libfoo-1.2.3.tar.bz2.{sha1,sha256}:
sha1  486fb55c3efa71148fe07895fd713ea3a5ae343a  libfoo-1.2.3.tar.bz2
sha256  efc8103cc3bcb06bda6a781532d12701eb081ad83e8f90004b39ab81b65d4369  libfoo-1.2.3.tar.bz2

# md5 from: http://www.foosoftware.org/download/libfoo-1.2.3.tar.bz2.md5, sha256 locally computed:
md5  2d608f3c318c6b7557d551a5a09314f03452f1a1  libfoo-data.bin
sha256  01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b  libfoo-data.bin

# Locally computed:
sha256  ff52101fb90bbfc3fe9475e425688c660f46216d7e751c4bbdb1dc85cdccacb9  libfoo-fix-blabla.patch

# No hash for 1234:
none  xxx  libfoo-1234.tar.gz

# Hash for license files:
sha256  a45a845012742796534f7e91fe623262ccfb99460a2bd04015bd28d66fba95b8  COPYING
sha256  01b1f9f2c8ee648a7a596a1abe8aa4ed7899b1c9e5551bda06da6e422b04aa55  doc/COPYING.LGPL

如果.hash文件存在,并且其中包含一个或多个下载文件的哈希,则Buildroot计算出的哈希必须与.hash文件中存储的哈希匹配。如果一个或多个哈希不匹配,Buildroot会认为下载错误,将删除并终止任务。

如果.hash文件存在,但不不含下载文件的哈希,则Buildroot会认为是错误并终止任务。但是,下载的文件会保留在下载目录中,因为这通常表示.hash文件错误,而下载的文件可能没有问题。

当前会检测从http/ftp服务器、Git仓库、scp复制的文件及本地文件的哈希值,不检查其他版本控制系统(如SVN、CVS等)的哈希。因为从这些版本控制系统下载源码时,Buildroot无法生成可再现的tar包。

应该仅保存稳定文件的哈希值在.hash文件中。例如,不能保证由Github自动生成的补丁是稳定的,因此其哈希值会随着时间而变化。此类补丁不应下载,而应该添加到本地软件包目录。

如果.hash文件不存在,则完全不进行检查。

17.5 具有特定构建系统的软件包的基础结构

具有特定构建系统的软件包,是指其构建系统不是标准的autotools或CMake等的软件包,通常其构建系统基于手写的Makefile或Shell脚本。

17.5.1 通用软件包教程
01: ################################################################################
02: #
03: # libfoo
04: #
05: ################################################################################
06:
07: LIBFOO_VERSION = 1.0
08: LIBFOO_SOURCE = libfoo-$(LIBFOO_VERSION).tar.gz
09: LIBFOO_SITE = http://www.foosoftware.org/download
10: LIBFOO_LICENSE = GPL-3.0+
11: LIBFOO_LICENSE_FILES = COPYING
12: LIBFOO_INSTALL_STAGING = YES
13: LIBFOO_CONFIG_SCRIPTS = libfoo-config
14: LIBFOO_DEPENDENCIES = host-libaaa libbbb
15:
16: define LIBFOO_BUILD_CMDS
17:     $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(@D) all
18: endef
19:
20: define LIBFOO_INSTALL_STAGING_CMDS
21:     $(INSTALL) -D -m 0755 $(@D)/libfoo.a $(STAGING_DIR)/usr/lib/libfoo.a
22:     $(INSTALL) -D -m 0644 $(@D)/foo.h $(STAGING_DIR)/usr/include/foo.h
23:     $(INSTALL) -D -m 0755 $(@D)/libfoo.so* $(STAGING_DIR)/usr/lib
24: endef
25:
26: define LIBFOO_INSTALL_TARGET_CMDS
27:     $(INSTALL) -D -m 0755 $(@D)/libfoo.so* $(TARGET_DIR)/usr/lib
28:     $(INSTALL) -d -m 0755 $(TARGET_DIR)/etc/foo.d
29: endef
30:
31: define LIBFOO_USERS
32:     foo -1 libfoo -1 * - - - LibFoo daemon
33: endef
34:
35: define LIBFOO_DEVICES
36:     /dev/foo  c  666  0  0  42  0  -  -  -
37: endef
38:
39: define LIBFOO_PERMISSIONS
40:     /bin/foo  f  4755  foo  libfoo   -  -  -  -  -
41: endef
42:
43: $(eval $(generic-package))

该Makefile文件从第7行至11行是元数据信息:软件包的版本(LIBFOO_VERSION)、包含该软件包的tar包的名称(LIBFOO_SOURCE)(建议适用.xz.tar包)以及下载连接(LIBFOO_SITE)、许可协议类型(LIBFOO_LICENSE)及许可协议文本(LIBFOO_LICENSE_FILES)。所有变量都必须以相同的前缀开头,本例中是LIBFOO_。该前缀始终是软件包名称的大写字母(请参阅下文了解如何定义软件包名称)。

第12行,我们指定此软件包要在staging空间中安装一些东西。通常库会要求这么做,因为他们必须在staging空间安装头文件和库文件。这将确保LIBFOO_INSTALL_STAGING_CMDS变量列出的命令被执行。

第13行,我们指定对LIBFOO_INSTALL_STAGING_CMDS阶段安装的某些文件使用libfoo-config进行修复。这些*-config文件是可执行的shell脚本文件,位于$(STAGING_DIR)/usr/bin目录,并由其他第三方包执行,以查找此特定包的位置和链接标志。

问题是,默认情况下,所有这些*-config文件默认都是错误的,宿主机的链接标志不适合交叉编译。例如,-I/usr/include使用-I ( S T A G I N G D I R ) / u s r / i n c l u d e 代 替 , − L / u s r / l i b 使 用 − L (STAGING_DIR)/usr/include代替,-L/usr/lib使用-L (STAGINGDIR)/usr/includeL/usr/lib使L(STAGING_DIR)/usr/lib代替。因此,对这些脚本做了一些变换,以使它们给出正确的标志。提供给LIBFOO_CONFIG_SCRIPTS的参数是需要修复的shell脚本的文件名,所有这些文件名都是相对于$(STAGING_DIR)/usr/bin的。如果需要,可以指定多个文件名,以空格分隔。

此外,LIBFOO_CONFIG_SCRIPTS列出的脚本会从$(TARGET_DIR)/usr/bin移除,因为目标系统并不需要这些文件。

示例17.1 配置脚本:divine软件包
divine软件包将安装$(STAGING_DIR)/usr/bin/divine-config脚本。

IVINE_CONFIG_SCRIPTS = divine-config

示例17.2 配置脚本:imagemagick软件包
软件包imagemagick将安装以下脚本:$(STAGING_DIR)/usr/bin/{Magick,Magick++,MagickCore,MagickWand,Wand}-config,其配置为:

IMAGEMAGICK_CONFIG_SCRIPTS = \
   Magick-config Magick++-config \
   MagickCore-config MagickWand-config Wand-config

第14行,我们指定此程序包所依赖的库列表。这些依赖以软件包的小写名称列出,可以是目标软件包(不带host-前缀),也可以是宿主软件包(带host-前缀)。Buildroot将确保在当前软件包编译之前其他软件包已构建并安装完成。

Makefile的其余部分,第16到29行,定义了在软件包配置、编译和安装的不同步骤应执行的操作。LIBFOO_BUILD_CMDS指定应该执行哪些步骤以构建软件包,LIBFOO_INSTALL_STAGING_CMDS指定应执行哪些步骤以在staging目录中安装软件包,LIBFOO_INSTALL_TARGET_CMDS指定应执行哪些步骤才能将软件包安装到目标空间中。

所有这些步骤都依赖 $(@D)变量,该变量包含已提取的软件包源码目录。

第31到33行,我们定义了一个该软件包使用的用户(LIBFOO_USERS)。例如,以非root用户身份运行守护进程。

第35到37行,我们定义了一个该软件包使用的设备节点文件(LIBFOO_DEVICES)。

第39到41行,我们定义了该软件包安装的特定文件的权限(LIBFOO_PERMISSIONS)。

最后,第43行,调用generic-package函数,该函数根据之前定义的变量生成软件包的Makefile代码。

17.5.2 通用软件包参考

通用目标有两个变体。generic-package宏用于交叉编译目标软件包,host-generic-package宏用于编译宿主软件包。可以在一个.mk文件中调用它们:一次创建规则以生成目标软件包,一次创建规则生成宿主软件包。

$(eval $(generic-package))
$(eval $(host-generic-package))

如果目标软件包的编译需要在宿主机上安装一些工具,这可能会很有用。如果软件包名称为libfoo,则目标软件包的名称也为libfoo,而宿主软件包的名称为host-libfoo。如果有其他软件包依赖该软件包,则在其他软件包的DEPENDENCIES变量中使用libfoo或host-libfoo。

generic-package和host-generic-package宏的调用必须位于.mk文件的最后,且host-generic-package宏位于generic-package宏之后。

对于目标软件包,generic-package宏会使用.mk文件定义的以LIBFOO-*作为前缀的变量,host-generic-package宏使用HOST_LIBFOO_*为前缀的变量。对于某些变量,如果不存在HOST_LIBFOO_为前缀的变量,则使用LIBFOO_为前缀的变量。

.mk文件中可以用来设置元数据信息的变量有(假设软件包名称为libfoo):

  • LIBFOO_VERSION 必填,软件包的版本。请注意,如果HOST_LIBFOO_VERSION不存在,则使用LIBFOO_VERSION。它也可以是修订号或从版本控制系统中获取的TAG。例如:
    • 版本号:LIBFOO_VERSION = 0.1.2
    • GIT提交ID:LIBFOO_VERSION = cb9d6aa9429e838f0e54faa3d455bcbab5eef057
    • GIT TAG:LIBFOO_VERSION = v0.1.2
      注意:不可以使用GIT分支名作为LIBFOO_VERSION,因为它不起作用并且不像我们期望的那样:
      • 由于本地缓存,Buildroot不会重新获取该仓库,因此希望能够访问远程仓库的人会感到非常惊讶和失望。
      • 由于GIT分支随时都会有提交,所以两个用户使用相同的Buildroot构建相同的配置可能获取到不同的软件源码,从而导致构建结果不同。
  • LIBFOO_SOURCE 可选,指定软件包的tar包名称,Buildroot会使用该名称从LIBFOO_SITE下载其源码。如果HOST_LIBFOO_SOURCE未指定,则默认为LIBFOO_SOURCE。如果未指定,则默认值为libfoo-$(LIBFOO_VERSION).tar.gz。例如:LIBFOO_SOURCE = foobar-$(LIBFOO_VERSION).tar.bz2。
  • LIBFOO_PATCH 可选,指定补丁文件列表,以空格分隔。Buildroot会下载该补丁并将其应用于软件包源码。如果指定的文件名包括://,则Buildroot将假定它是完整的URL并从该位置下载补丁,否则将从LIBFOO_SITE下载。如果- HOST_LIBFOO_PATCH未指定,则默认为LIBFOO_PATCH。请注意,Buildroot本身包含的补丁程序使用不同的机制:Buildroot package目录中存在的所有*.patch补丁将在提取源码后应用于该软件包。LIBFOO_PATCH指定的补丁先与package目录中的补丁被应用。
  • LIBFOO_SITE 指定软件包的下载地址,可以是URL或本地文件路径,参阅之后关于LIBFOO_SITE_METHOD的介绍。如果HOST_LIBFOO_SITE未指定,则默认为 LIBFOO_SITE。
    • 支持HTTP、FTP及SCP。在这种情况下,不要在结尾加上/符号:Buildroot会在适当的目录和文件名之间添加/符号。注意,SCP URLs的格式应为scp://[user@]host:filepath,并且该文件路径是相对于用户家目录,因此你可能需要在路径前加上绝对路径的/符号,如scp://[user@]host:/absolutepath。
    • 支持Git、Subversion、Mercurial和Bazaar,直接从源代码管理系统中获取源代码。有一个辅助函数可以使得从Github下载源码tar包更容易(有关详细信息,请参阅第17.23.4节“如何从Github添加软件包”)。
    • 支持文件路径,可用于指定tar包或包含软件包源码的目录。

示例:

LIBFOO_SITE=http://www.libfoosoftware.org/libfoo
LIBFOO_SITE=http://svn.xiph.org/trunk/Tremor
LIBFOO_SITE=/opt/software/libfoo.tar.gz
LIBFOO_SITE=$(TOPDIR)/../src/libfoo
  • LIBFOO_DL_OPTS 可选,传递给下载器的选项,以空格分隔。当服务端校验用户名和密码或使用代理时会非常有用。支持LIBFOO_SITE_METHOD指定的所有下载方法,具体有效的参数取决于下载方法。

  • LIBFOO_EXTRA_DOWNLOADS 以空格分隔的需要Buildroot下载的文件列表。如果文件路径包含://则Buildroot假定它是完整的URL,并使用该URL下载文件。否则,Buildroot将假定要下载的文件位于LIBFOO_SITE。Buildroot对这些文件不会做任何操作,只是下载它们,取决于如何使用它们来打包软件包(由$(LIBFOO_DL_DIR)指定)。

  • LIBFOO_SITE_METHOD 确定用于获取或复制软件包源代码的方法。在多数情况下,Buildroot会根据LIBFOO_SITE的内容猜测该方法,如果HOST_LIBFOO_SITE_METHOD未指定,则默认为使用LIBFOO_SITE_METHOD。LIBFOO_SITE_METHOD可能的值为:

    • wget 用于tar包的HTTP/FTP下载。LIBFOO_SITE开头为http://、https://或 ftp://默认使用该方法。
    • scp LIBFOO_SITE开头为scp://时默认使用scp通过SSH下载。
    • svn 用于从Subversion存储库中检索源代码。LIBFOO_SITE开头为svn://默认使用该方法。如果LIBFOO_SITE指定的Subversion存储库URL为http://形式时,必须指定LIBFOO_SITE_METHOD为svn。Buildroot会执行代码签出,并保存为压缩包,之后的构建使用该压缩包而不是重新签出代码。
    • cvs 用于从CVS存储库中检索代码。LIBFOO_SITE开头为csv://默认使用该方法。所下载的源代码与svn一样会被缓存。
    • git 用于从GIT存储库中检索代码。LIBFOO_SITE开头为git://默认使用该方法。所下载的源代码与svn一样会被缓存。
    • hg 用于从Mercurial存储库中检索代码。当LIBFOO_SITE指定Mercurial存储库的URL时,必须设定LIBFOO_SITE_METHOD=hg。
    • bzr 用于从Bazaar存储库中检索源代码。LIBFOO_SITE开头为bzr://默认使用该方法。所下载的源代码与svn一样会被缓存。
    • file 本地tar包。当LIBFOO_SITE指定本地tar包文件名时,应该使用此选项。这对于不公开或版本控制不可用的软件很有用。
    • local 本地源代码路径。当LIBFOO_SITE指定本地源代码路径时,应该使用此选项。Buildroot会将源代码目录的内容复制到软件包的build目录中。请注意,对于本地软件包,不会应用补丁。如果仍然需要修改代码,请使用LIBFOO_POST_RSYNC_HOOKS,参阅17.22.1“使用POST RSYNC挂钩”。
  • LIBFOO_GIT_SUBMODULES 当GIT存储库包含GIT子模块时,可以设置为YES。仅适用于使用GIT下载的软件包(即LIBFOO_SITE_METHOD=git)。注意,当GIT存储库包含子模块时,我们更倾向于使用子模块本身的存储库。

  • LIBFOO_STRIP_COMPONENTS 从tar包提取时从文件名中删除的父目录的层级数量。大多数软件包的tar包包含一个名为“ -”的父目录,因此Buildroot将–strip-components = 1传递给tar包将其删除。对于不具有此父目录的软件包或不止一级父目录的软件包,需要指定该变量并传递给tar,默认值为1。
    LIBFOO_EXCLUDES 以空格分隔的从tar包提取文件时删除的目录或文件。每一项都会传给tar --exclude参数,默认为空。

  • LIBFOO_DEPENDENCIES 列出了编译当前软件包的依赖项(以软件包名称表示)。这将确保Buildroot在编译该软件包之前先编译并安装这些依赖项。然而,修改依赖项配置并不会强制重新编译当前软件包。类似的,HOST_LIBFOO_DEPENDENCIES列出了当前对宿主的依赖项。

  • LIBFOO_EXTRACT_DEPENDENCIES 列出了提取当前软件包的依赖项(以软件包名称表示)。这将确保Buildroot在提取该软件包之前先编译并安装这些依赖项。它仅由通用软件包基础架构内部使用,通常不应直接由软件包使用。

  • LIBFOO_PATCH_DEPENDENCIES 列出了要修补当前软件包所需的依赖项(以软件包名称表示)。这将确保Buildroot在给当前软件包打补丁之前先提取并修补(但不一定构建)这些依赖项。类似的,HOST_LIBFOO_PATCH_DEPENDENCIES列出了对宿主的依赖项。通常很少使用。

  • LIBFOO_PROVIDES 列出了虚拟软件包libfoo的所有实现。参阅第17.11“虚拟软件包的基础结构”。

  • LIBFOO_INSTALL_STAGING 可以设置为YES或NO(默认)。若设置为YES,将执行LIBFOO_INSTALL_STAGING_CMDS列出的命令将软件包安装到staging目录。

  • LIBFOO_INSTALL_TARGET 可以设置为YES(默认)或NO。若设置为YES,将执行LIBFOO_INSTALL_TARGET_CMDS列出的命令将软件包安装到target目录。

  • LIBFOO_INSTALL_IMAGES 可以设置为YES或NO(默认)。若设置为YES,将执行LIBFOO_INSTALL_IMAGES_CMDS列出的命令将软件包安装到images目录。

  • LIBFOO_CONFIG_SCRIPTS 列出了$(STAGING_DIR)/usr/ bin目录下的一些文件名称,这些文件的名称需要进行一些特殊的修复才能使其用于交叉编译。可以给出多个文件名称,以空格分隔,所有文件都是相对于$(STAGING_DIR)/usr/ bin目录。此处列出的文件将从$(TARGET_DIR)/usr/bin删除,因为目标系统并不需要它们。

  • LIBFOO_DEVICES 列出了使用静态设备表时由Buildroot创建的设备文件。语法使用makedevs,请参阅第24章“Makedev语法文档”。可选选项。

  • LIBFOO_PERMISSIONS 列出了构建结束后需要更改的权限。语法使用makedevs,请参阅第24章“Makedev语法文档”。可选选项。

  • LIBFOO_USERS 列出了该软件包需要创建的用户,如果该程序安装的软件需要使用特定用户运行(例如,守护进程,或定时任务)。语法在本质上与makedevs相似,请参阅第24章“Makedev语法文档”。可选选项。

  • LIBFOO_LICENSE 定义了该软件包发布的一个或多个许可文件。该名称将出现在make legal-info产生的清单文件上。如果许可证出现在SPDX许可证列表中,请使用SPDX的短标识符使清单文件统一。否则,请使用精确简洁的方式描述许可证,避免使用模棱两可的名称,例如BSD实际上是许可证家族的命名。可选选项。如果未定义,软件包的许可证清单文件上将显示为unknown。此变量的预期格式必须符合以下规则:

    • 如果软件包的不同部分使用不同的许可证,请单独列出,如LIBFOO_LICENSE = GPL-2.0+, LGPL-2.1+。如果在哪个许可证许可了哪个组件之间有明显的区别,请在括号里注明该组件,如LIBFOO_LICENSE = GPL-2.0+ (programs), LGPL-2.1+ (libraries)。
    • 如果某些许可证以启用子选项为条件,请在条件许可证后附加逗号,如FOO_LICENSE += , GPL-2.0+ (programs)。Buildroot将在内部删除逗号前的空格。
    • 如果软件包是双重许可的,则使用or关键字来分隔许可,如LIBFOO_LICENSE = AFL-2.1 or GPL-2.0+。
  • LIBFOO_LICENSE_FILES 列出了软件包中的许可证文件,以空格分隔。make legal-info将所有这些文件复制到legal-info目录中。可选参数。如果未定义,将产生警告,该警告将在license files中标识为not saved。

  • LIBFOO_ACTUAL_SOURCE_TARBALL 仅适用于LIBFOO_SITE/ LIBTOO_SOURCE指向的不是源代码,而是二进制文件的情况。这是比较罕见的情况,已知的情况是适用于已经编译好的外部工具链,尽管从理论上可能适用于其他软件包。在这种情况下,实际的源代码通常会提供单独的tar包。设置LIBFOO_ACTUAL_SOURCE_TARBALL为实际源代码的名称,当运行make legal-info收集与法律相关的资料时,Buildroot将下载该tar包并使用它。请注意,在常规构建过程中,都不会下载该tar包,即使是make source。

  • LIBFOO_ACTUAL_SOURCE_SITE 提供源码tar包的下载位置,默认为LIBFOO_SITE。因此,如果源代码和二进制文件位于同一个目录中,则无需设置该变量。如果LIBFOO_ACTUAL_SOURCE_TARBALL未设置,则LIBFOO_ACTUAL_SOURCE_SITE的定义没有意义 。

  • LIBFOO_REDISTRIBUTE 可以设置为YES(默认)或NO指示是否允许重新发布软件包源码。设置为NO表示为非开源软件包。Buildroot在make legal-info时不会收集该软件包的源码。

  • LIBFOO_FLAT_STACKSIZE 指定内置FLAT二进制格式应用程序的堆栈大小。在NOMMU体系结构处理器上应用程序堆栈大小无法动态扩展。FLAT二进制格式的默认堆栈大小为4k字节。如果应用需要占用更多的堆栈,请在此处指定所需的字节数。

  • LIBFOO_BIN_ARCH_EXCLUDE 检查软件包是否正确安装了交叉编译的二进制文件时忽略的目录列表,以空格分隔。很少需要设置这个变量,除非该软件包将软件安装到了非默认位置,/lib/firmware、/usr/lib/firmware、/lib/modules、 /usr/lib/modules、和/usr/share会自动排除。

  • LIBFOO_IGNORE_CVES 指定软件包需要被Buildroot CVE跟踪工具忽略哪些CVE,以空格分隔。当CVE由软件包外的补丁程序修复时,或者由于某些原因CVE不影响Buildroot软件包时通常使用该方法。在使用该变量前必须添加Makefile注释,例如:

# 0001-fix-cve-2020-12345.patch
LIBFOO_IGNORE_CVES += CVE-2020-12345
# only when built with libbaz, which Buildroot doesn't support
LIBFOO_IGNORE_CVES += CVE-2020-54321
  • LIBFOO_EXTRACT_CMDS 指定提取软件包时要执行的操作。通常不需要手动指定,Buildroot会自动处理。然而,如果软件包使用了非标准的存档格式(例如ZIP或RAR格式),或者文件组织结构不标准的tar包,则此变量允许覆盖软件包基础结构的默认行为。

  • LIBFOO_CONFIGURE_CMDS 指定在编译软件包之前要执行的配置操作。
    LIBFOO_BUILD_CMDS 指定软件包编译操作。

  • HOST_LIBFOO_INSTALL_CMDS 指定当软件包是宿主软件包时需要执行的安装操作。软件包必须将其文件安装到给定的$(HOST_DIR)目录,并且应该安装所有文件,包括头文件等,其他软件包可能会依赖于该软件包才能编译。

  • LIBFOO_INSTALL_TARGET_CMDS 指定当软件包是目标软件包时需要执行的安装操作。软件包必须将其文件安装到的给定的$(TARGET_DIR)目录,并且只需要安装执行所需的文件即可。目标文件系统生成后,头文件、静态库和文档将再次被删除。

  • LIBFOO_INSTALL_STAGING_CMDS 指定当软件包是目标软件包时将软件包安装到staging目录需要执行的操作。软件包必须将文件安装到$(STAGING_DIR)目录,并且应该安装所有文件,其他软件包可能会依赖于该软件编译。

  • LIBFOO_INSTALL_IMAGES_CMDS 指定当软件包是目标软件包时将软件包安装到镜像目录时需要执行的操作。软件包必须将其文件安装到$(BINARIES_DIR)目录。只有不属于$(TARGET_DIR)目录但对于启动开发板必须的二进制镜像文件需要安装到该目录。例如,如果软件包的二进制文件与系统内核、引导加载程序或根文件系统相似,则应使用此步骤。

  • LIBFOO_INSTALL_INIT_SYSV、LIBFOO_INSTALL_INIT_OPENRC、LIBFOO_INSTALL_INIT_SYSTEMD 指定安装启动脚本需要执行的操作,例如systemV初始化系统(busybox、sysvinit等)、openrc或systemd等。仅当安装了相关的初始化系统时这些命令才会执行(即,如果选中systemd为初始化系统,则将仅执行LIBFOO_INSTALL_INIT_SYSTEMD)。唯一的例外是,如果选中openrc作为初始化系统,并且未指定LIBFOO_INSTALL_INIT_OPENRC时,这种情况下LIBFOO_INSTALL_INIT_SYSV将被执行,原因是openrc支持sysv初始化脚本。如果选中systemd为初始化系统,Buildroot将在镜像构建的最后阶段使用systemctl preset-all命令自动启用所有服务。你可以添加预设文件,以防止Buildroot自动启用特定模块。

  • LIBFOO_HELP_CMDS 指定输出软件包帮助时需要执行的操作,该帮助包含在make help的输出中。这些命令可打印任意格式的内容。由于软件包很少具有自定义规则,因此很少使用。除非你真的知道需要打印帮助,否则请不要使用此变量。

  • LIBFOO_LINUX_CONFIG_FIXUPS 指定构建和使用该软件包所需的Linux内核配置选项,没有这些选项,该软件包将无法编译或运行。这些是集成到kconfig的调整选项:CONFIG_ENABLE_OPT、 KCONFIG_DISABLE_OPT或KCONFIG_SET_OPT。该选项很少使用,因为软件包通常对内核选项没有严格的要求。

以上选项推荐的定义语法如下:

define LIBFOO_CONFIGURE_CMDS
        action 1
        action 2
        action 3
endef

在action定义中,可以使用以下变量:

  • $(LIBFOO_PKGDIR) libfoo.mk和Config.in所在的目录路径。
  • $(@D) 软件包源代码解压后的目录。
  • $(LIBFOO_DL_DIR) libfoo源代码下载目录。
  • $(TARGET_CC)、$(TARGET_LD)等交叉编译工具。
  • $(TARGET_CROSS) 交叉编译工具链前缀。
  • $(HOST_DIR)、$(STAGING_DIR)和$(TARGET_DIR) 等,指定软件包安装位置。

最后,你还可以使用hook。有关hook的更多信息,请参阅第17.22节“各构建步骤中可用的钩子”。

17.6 基于autotools构建系统的软件包基础结构

17.6.1 autotools软件包教程

首先,让我们看下如何编写基于autotools构建系统的.mk文件,示例如下:

01: ################################################################################
02: #
03: # libfoo
04: #
05: ################################################################################
06:
07: LIBFOO_VERSION = 1.0
08: LIBFOO_SOURCE = libfoo-$(LIBFOO_VERSION).tar.gz
09: LIBFOO_SITE = http://www.foosoftware.org/download
10: LIBFOO_INSTALL_STAGING = YES
11: LIBFOO_INSTALL_TARGET = NO
12: LIBFOO_CONF_OPTS = --disable-shared
13: LIBFOO_DEPENDENCIES = libglib2 host-pkgconf
14:
15: $(eval $(autotools-package))

第7行,我们声明了软件包的版本。

第8、9行,我们声明了tar包的名称(建议使用.tar.xz包)以及tar包的下载位置,Buildroot将自动从该位置下载tar包。

第10行,我们告诉Buildroot将该软件包安装到staging目录。output/staging/ 是所有软件包(包括头文件、库等)的安装目录。默认情况下,软件包不会安装到staging目录。通常只有库需要安装到staging目录,其他软件包需要依赖于这些库才能编译。同样,默认情况下,启用该选项后,将使用make install命令将软件包安装到staging目录。

第11行,告诉Buildroot不要将该软件包安装到target目录。该目录将成为根文件系统的目录。对于静态库,没必要将它们安装到target目录。默认情况下,该选项为启用状态,几乎不需要将此选项设置为NO。默认情况下,使用make install命令将软件包安装到target目录。

第12行,告诉Buildroot传递自定义选项给./configure命令。

第13行,声明了依赖项,以便在构建该软件包之前先构建其依赖的软件包。
最后,第15行,调用autotools-package宏,该宏生成构建该软件包的Makefile规则。

17.6.2 autotools软件包参考

autotools软件包基础结构的主要宏是 autotools-package,类似于generic-package宏。通过使用host-autotools-package宏还可以生宿主软件包。

类似通用软件包基础结构,autotools基础结构通过在调用autotools-package宏之前定义多个变量工作。

首先,所有通用软件包基础结构的元数据信息的变量同样存在于autotools基础结构,如:LIBFOO_VERSION、LIBFOO_SOURCE、 LIBFOO_PATCH、LIBFOO_SITE、LIBFOO_SUBDIR、LIBFOO_DEPENDENCIES、LIBFOO_INSTALL_STAGING、LIBFOO_INSTALL_TARGET。

还可以定义一些特定于autotools基础结构的变量。它们中的许多仅在非常特殊的情况下才有用,因此典型的软件包将仅使用其中的一部分。

  • LIBFOO_SUBDIR 指定源代码目录中包含configure脚本的子目录的名称。如果configure脚本不在源码的根目录中,这个变量会很有用。如果

  • HOST_LIBFOO_SUBDIR未指定,则默认为LIBFOO_SUBDIR。

  • LIBFOO_CONF_ENV 指定需要传递给configure脚本的其他环境变量,默认为空。

  • LIBFOO_CONF_OPTS 指定需要传递给configure脚本的配置选项,默认为空。

  • LIBFOO_MAKE 指定备用make命令。如果配置中启动了并行构建(使用BR2_JLEVEL),但出于某种原因,给定的软件包需要禁用并行构建,则可以使用该变量。默认设置为$(MAKE),如果软件包不支持并行构建,则应设置为 LIBFOO_MAKE=$(MAKE1)。

  • LIBFOO_MAKE_ENV 指定编译阶段需要传递给make命令的其他环境变量,默认为空。

  • LIBFOO_MAKE_OPTS 指定编译阶段需要传递给make命令的其他选项,默认为空。

  • LIBFOO_AUTORECONF 指定是否应自动重新配置软件包(即是否应通过重新运行autoconf、automake、libtool等重新生成配置脚本和Makefile.in文件)。有效值为YES和NO,默认为NO。

  • LIBFOO_AUTORECONF_ENV 指定需要传递给autoreconf命令的其他环节变量,仅当LIBFOO_AUTORECONF=YES时有效,默认为空。

  • LIBFOO_AUTORECONF_OPTS 指定需要传递给autoreconf命令的其他选项,仅当LIBFOO_AUTORECONF=YES时有效,默认为空。

  • LIBFOO_GETTEXTIZE 指定是否应该对软件包进行本地化(即,该软件包是否使用了与Buildroot提供的版本不同的gettext版本,此时需要执行gettextize)。仅当LIBFOO_AUTORECONF=YES有效,默认为NO。

  • LIBFOO_GETTEXTIZE_OPTS 指定传递给gettextize命令的其他选项,仅当LIBFOO_GETTEXTIZE=YES时有效。

  • LIBFOO_LIBTOOL_PATCH 指定是否应使用补丁修复libtool交叉编译问题。有效值为YES和NO,默认为YES。

  • LIBFOO_INSTALL_STAGING_OPTS 指定用于将软件包安装到staging目录的make选项,默认为DESTDIR=$(STAGING_DIR) install。

  • LIBFOO_INSTALL_TARGET_OPTS 指定用于将软件包安装到target目录的make选项,默认为DESTDIR=$(TARGET_DIR) install。

基于autotools构建系统的基础结构,已经定义了构建和安装软件包所需的所有步骤,通常适用于大多数基于autotools的软件包。但是,在需要时,仍然可以自定义任意步骤的操作:

  • 添加钩子,在执行提取、打补丁、配置、编译或安装后执行自定义操作。
    重写某个步骤。例如,即使使用autotools基础结构,如果软件包.mk定义了

  • LIBFOO_CONFIGURE_CMDS变量,也将使用该变量指定的操作替代默认的操作。

17.7 基于cmake的软件包基础结构

17.7.1 cmake软件包教程

首先,让我们看下如何编写基于cmake构建系统的.mk文件,示例如下:

01: ################################################################################
02: #
03: # libfoo
04: #
05: ################################################################################
06:
07: LIBFOO_VERSION = 1.0
08: LIBFOO_SOURCE = libfoo-$(LIBFOO_VERSION).tar.gz
09: LIBFOO_SITE = http://www.foosoftware.org/download
10: LIBFOO_INSTALL_STAGING = YES
11: LIBFOO_INSTALL_TARGET = NO
12: LIBFOO_CONF_OPTS = -DBUILD_DEMOS=ON
13: LIBFOO_DEPENDENCIES = libglib2 host-pkgconf
14:
15: $(eval $(cmake-package))

第7行,声明了软件包的版本。

第8、9行,声明了tar包的名称(建议使用.tar.xz),以及tar的下载位置。Buildroot将自动从该位置下载压缩包。

第10行,告诉Buildroot将软件包安装到staging目录。output/staging/是所有软件包的安装目录。默认情况下,软件包不会安装到staging目录。通常只有库需要安装到staging目录,其他软件包需要依赖该库才能编译或运行。开启该选项后,将使用make install命令将软件包安装到此位置。

第11行,告诉Buildroot不要将软件包安装到target目录。该目录将成为目标系统根文件系统的一部分。对于纯静态库,没必要将它们安装到target目录中。默认情况下,该选项为启用,几乎不需要将此变量设置为NO。默认情况下,使用make install命令将软件包安装到此位置。

第12行,告诉Buildroot在配置软件包时传递自定义选项给cmake。

第13行,声明依赖项,以便在构建该软件包之前先构建依赖项。

第15行,调用cmake-package宏,该宏生成构建软件包的所有Makefile规则。

17.7.2 cmake软件包教程

cmake软件包基础结构的主要宏是cmake-package,类似于generic-package宏。通过host-cmake-package宏,还可以构建宿主软件包。

类似通用软件包基础结构,cmake基础结构通过在调用cmake-package宏之前定义多个变量工作。

首先,所有通用软件包基础结构的元数据信息的变量同样存在于cmake基础结构,如:LIBFOO_VERSION、LIBFOO_SOURCE、 LIBFOO_PATCH、LIBFOO_SITE、LIBFOO_SUBDIR、LIBFOO_DEPENDENCIES、LIBFOO_INSTALL_STAGING、LIBFOO_INSTALL_TARGET。

还可以定义一些特定于cmake基础结构的变量。它们中的许多仅在非常特殊的情况下才有用,因此典型的软件包将仅使用其中的一部分。

  • LIBFOO_SUBDIR 指定源代码目录中包含CMakeLists.txt文件的子目录的名称。如果CMakeLists.txt文件不在源代码的根目录中,这个变量会很有用。如果HOST_LIBFOO_SUBDIR未指定,则默认为LIBFOO_SUBDIR。

  • LIBFOO_CONF_ENV 指定需要传递给cmake的其他环境变量,默认为空。

  • LIBFOO_CONF_OPTS 指定需要传递给cmake的配置选项,默认为空。cmake基础结构设置了许多常见的cmake选项,因此无需在.mk文件中指定,除非你确实要覆盖重写:

    • CMAKE_BUILD_TYPE 由BR2_ENABLE_DEBUG决定。
    • CMAKE_INSTALL_PREFIX
      BUILD_SHARED_LIBS 由BR2_STATIC_LIBS决定。
    • BUILD_DOC 已被禁用
    • BUILD_EXAMPLE 已被禁用
    • BUILD_TEST、BUILD_TESTS、BUILD_TESTING 已被禁用
  • LIBFOO_SUPPORTS_IN_SOURCE_BUILD 当无法在源代码目录中构建该软件包时需要设置为NO。

  • LIBFOO_MAKE 指定备用make命令。如果配置中启动了并行构建(使用BR2_JLEVEL),但出于某种原因,给定的软件包需要禁用并行构建,则可以使用该变量。默认设置为$(MAKE),如果软件包不支持并行构建,则应设置为 LIBFOO_MAKE=$(MAKE1)。

  • LIBFOO_MAKE_ENV 指定编译阶段需要传递给make命令的其他环境变量,默认为空。

  • LIBFOO_MAKE_OPTS 指定编译阶段需要传递给make命令的其他选项,默认为空。

  • LIBFOO_INSTALL_STAGING_OPTS 指定用于将软件包安装到staging目录的make选项,默认为DESTDIR=$(STAGING_DIR) install。

  • LIBFOO_INSTALL_TARGET_OPTS 指定用于将软件包安装到target目录的make选项,默认为DESTDIR=$(TARGET_DIR) install。

基于cmake构建系统的基础结构,已经定义了构建和安装软件包所需的所有步骤,通常适用于大多数基于cmake的软件包。但是,在需要时,仍然可以自定义任意步骤的操作:

  • 添加钩子,在执行提取、打补丁、配置、编译或安装后执行自定义操作。
    重写某个步骤。例如,即使使用cmake基础结构,如果软件包.mk定义了

  • LIBFOO_CONFIGURE_CMDS变量,也将使用该变量指定的操作替代默认的操作。

17.8 Python软件包的基础结构

17.9 基于LuaRocks的软件包基础结构

17.10 Perl/CPAN软件包基础结构

17.11 虚拟软件包基础结构

在Buildroot中,虚拟软件包的功能由一个或多个其他软件包(称为提供者)提供。虚拟包管理提供了一种扩展机制,允许用户选择根文件系统中使用的提供者。

例如,OpenGL ES是嵌入式系统上2D和3D图形系统的API,对于Allwinner Tech Sunxi和德州仪器(TI)的OMAP35xx平台,此API的实现有所不同。因此,libgles是虚拟包,而sunxi-mali和ti-gfx是提供者。

17.11.1 虚拟软件包教程

在下面的示例中,我们将说明如何添加新的虚拟软件包(something-virtual)和提供者(some-provider)。

首先,先创建虚拟软件包。

17.11.2 虚拟软件包的Config.in文件

虚拟软件包的Config.in文件应保持以下内容:

01: config BR2_PACKAGE_HAS_SOMETHING_VIRTUAL
02:     bool
03:
04: config BR2_PACKAGE_PROVIDES_SOMETHING_VIRTUAL
05:     depends on BR2_PACKAGE_HAS_SOMETHING_VIRTUAL
06:     string

在此文件中,我们声明了两个选项BR2_PACKAGE_HAS_SOMETHING_VIRTUAL和 BR2_PACKAGE_PROVIDES_SOMETHING_VIRTUAL,提供者将使用其值。

17.11.3 虚拟软件包的.mk文件

虚拟软件包的.mk文件只调用virtual-package宏。使用host-virtual-package宏还可以创建宿主软件包。

01: ################################################################################
02: #
03: # something-virtual
04: #
05: ################################################################################
06:
07: $(eval $(virtual-package))
17.11.4 提供者的Config.in文件

将软件包作为提供者,仅Config.in文件需要进行一些修改。

提供者的Config.in文件应该包含以下内容:

01: config BR2_PACKAGE_SOME_PROVIDER
02:     bool "some-provider"
03:     select BR2_PACKAGE_HAS_SOMETHING_VIRTUAL
04:     help
05:       This is a comment that explains what some-provider is.
06:
07:       http://foosoftware.org/some-provider/
08:
09: if BR2_PACKAGE_SOME_PROVIDER
10: config BR2_PACKAGE_PROVIDES_SOMETHING_VIRTUAL
11:     default "some-provider"
12: endif

第3行,勾选BR2_PACKAGE_HAS_SOMETHING_VIRTUAL。

第11行,将BR2_PACKAGE_PROVIDES_SOMETHING_VIRTUAL设置为提供者的软件包名称,前提是选择了该软件包。

17.11.5 提供者的.mk文件

.mk文件需要新增声明SOME_PROVIDER_PROVIDES变量,其值包含它所实现的所有虚拟软件包的名称。例如:

01: SOME_PROVIDER_PROVIDES = something-virtual
17.11.6 关于虚拟软件包的注意事项

添加依赖于虚拟软件包提供的某个特性时,必须使用depends on

BR2_PACKAGE_HAS_FEATURE,如:
config BR2_PACKAGE_HAS_FEATURE
    bool

config BR2_PACKAGE_FOO
    bool "foo"
    depends on BR2_PACKAGE_HAS_FEATURE
17.11.7 关于依赖特定提供者的注意事件

如果你的软件包确实需要依赖特定的提供者,那你的软件包必须depends on该提供者,而不能select提供者。

假设我们提供以下两个FEATURE的提供者:

config BR2_PACKAGE_HAS_FEATURE
    bool

config BR2_PACKAGE_FOO
    bool "foo"
    select BR2_PACKAGE_HAS_FEATURE

config BR2_PACKAGE_BAR
    bool "bar"
    select BR2_PACKAGE_HAS_FEATURE

而你需要添加一个软件包依赖FEATUER的foo提供者,而不是bar提供者。

如果你使用select BR2_PACKAGE_FOO,那用户仍然可以在make menuconfig中选择BR2_PACKAGE_BAR,这将导致配置不一致,从而FATURE将同时启用两个相同的提供者,一个由用户显示设置,另一个由你设置select隐式设置。

因此,你必须使用depends on BR2_PACKAGE_FOO,这样可以避免任何隐式设置的不一致。

17.12 使用kconfig作为配置文件的软件包基础结构

17.13 基于rebar的软件包基础结构

17.14 基于Waf的软件包基础结构

17.15 基于Meson的软件包基础结构

17.16 基于Cargo的软件包基础结构

17.17 Go软件包基础结构

17.18 基于QMake的软件包基础结构

17.19 系统内核模块软件包基础结构

Buildroot提供了一个帮助程序基础结构,以简化编写和构建内核模块。一些软件包仅包含内核模块,一些软件包除内核模块外还包含程序和库。Buildroot系统内核模块软件包的基础结构支持这两种情况。

17.19.1 内核模块教程

让我们从一个示例开始,该示例说明了如何准备一个仅构建内核模块而没有其他组件的简单软件包:

01: ################################################################################
02: #
03: # foo
04: #
05: ################################################################################
06:
07: FOO_VERSION = 1.2.3
08: FOO_SOURCE = foo-$(FOO_VERSION).tar.xz
09: FOO_SITE = http://www.foosoftware.org/download
10: FOO_LICENSE = GPL-2.0
11: FOO_LICENSE_FILES = COPYING
12:
13: $(eval $(kernel-module))
14: $(eval $(generic-package))

第7-11行,定义了常用的元数据信息,指定了版本、源代码压缩包名称,以及下载链接和许可信息。

第13行,调用kernel-module宏,该宏将生成构建内核模块所需的Makefile规则。
依赖项linux会自动添加,因此无需在FOO_DEPENDENCIES中指定。

与其他软件包基础结构不同,我们还需要显示地调用另一个宏generic-package,这将允许软件包构建内核模块。如果允许,还可以使用任何其他软件包基础结构来构建用户级组件(库、可执行文件等)。

让我们再看一个更复杂的例子:

01: ################################################################################
02: #
03: # foo
04: #
05: ################################################################################
06:
07: FOO_VERSION = 1.2.3
08: FOO_SOURCE = foo-$(FOO_VERSION).tar.xz
09: FOO_SITE = http://www.foosoftware.org/download
10: FOO_LICENSE = GPL-2.0
11: FOO_LICENSE_FILES = COPYING
12:
13: FOO_MODULE_SUBDIRS = driver/base
14: FOO_MODULE_MAKE_OPTS = KVERSION=$(LINUX_VERSION_PROBED)
15:
16: ifeq ($(BR2_PACKAGE_LIBBAR),y)
17: FOO_DEPENDENCIES = libbar
18: FOO_CONF_OPTS = --enable-bar
19: FOO_MODULE_SUBDIRS += driver/bar
20: else
21: FOO_CONF_OPTS = --disable-bar
22: endif
23:
24: $(eval $(kernel-module))
26: $(eval $(autotools-package))

在这里,我们定义了一个基于autotools构建系统的软件包,该软件包同时还构建了位于子目录driver/base下的内核模块。如果启用了libbar,还将构建位于子目录driver/bar目录的内核模块。

17.19.2 内核模块参考

内核模块基础结构的主要宏是kernel-module。与其他软件包基础结构不同,它不能独立存在,必须在其后调用其他*-package宏。

kernel-module定义了编译和安装后hook钩子。如果软件包的.mk需要访问已构建的内核模块,则应hook调用kernel-module宏后生成的钩子,并在其中访问内核模块。同样,如果软件包的.mk需要在安装后访问内核模块,则应hook调用kernel-module宏后生成的钩子,并在其中访问内核模块。示例如下:

$(eval $(kernel-module))

define FOO_DO_STUFF_WITH_KERNEL_MODULE
    # Do something with it...
endef
FOO_POST_BUILD_HOOKS += FOO_DO_STUFF_WITH_KERNEL_MODULE

$(eval $(generic-package))

此外,与其他软件包基础结构不同,内核模块没有host-kernel-module宏用于宿主内核模块。

以下变量可以进一步配置内核模块的构建:

  • FOO_MODULE_SUBDIRS 可以设置为内核模块所在的一个或多个子目录(相对于软件包源码顶层目录)。如果为空或未设置,则认为内核模块的源码位于软件包源码根目录。
  • FOO_MODULE_MAKE_OPTS 可以设置传递给Linux构建系统的额外选项。
    你还可以引用以下变量(但不能设置):
  • LINUX_DIR 提取后的Linux内核目录,即内核编译目录。
  • LINUX_VERSION 用户配置的版本字符串。
  • LINUX_VERSION_PROBED 内核实际版本字符串,可通过make -C $(LINUX_DIR) kernelrelease命令获取。
  • KERNEL_ARCH 当前CPU架构名称,如arm、mips等。

17.20 asciidoc文档的基础结构

17.21 Linux内核软件包专用的基础结构

Linux内核软件包可以使用基于软件包hook的特定基础结构来构建Linux内核工具和Linux内核扩展。

17.21.1 Linux内核工具

Buildroot提供了一个辅助基础结构用于编译Linux内核源码中运行于用户空间的一些工具。由于它们的源码是内核源码的一部分,因此内核工具(linux-tools)是一个特殊的软件包,使用目标系统的内核。

让我们看一个Linux工具的例子。对于名为foo的Linux工具,在package/linux-tools/Config.in中创建一个新的菜单入口,该文件包含每个内核工具相关的选项说明。示例如下:

01: config BR2_PACKAGE_LINUX_TOOLS_FOO
02:     bool "foo"
03:     select BR2_PACKAGE_LINUX_TOOLS
04:     help
05:       This is a comment that explains what foo kernel tool is.
06:
07:       http://foosoftware.org/foo/

选项的名称以BR2_PACKAGE_LINUX_TOOLS_作为前缀,后跟工具的大写名称。
注意,与其他软件包不同,内核工具软件包显示在Linux内核菜单的Linux Kernel Tools子菜单下,而不是Target packages主菜单下。

然后,针对每个Linux工具编写.mk.in文件,命名为package/linux-tools/linux-tool-foo.mk.in。其内容示例如下:

01: ################################################################################
02: #
03: # foo
04: #
05: ################################################################################
06:
07: LINUX_TOOLS += foo
08:
09: FOO_DEPENDENCIES = libbbb
10:
11: define FOO_BUILD_CMDS
12:     $(TARGET_MAKE_ENV) $(MAKE) -C $(LINUX_DIR)/tools foo
13: endef
14:
15: define FOO_INSTALL_STAGING_CMDS
16:     $(TARGET_MAKE_ENV) $(MAKE) -C $(LINUX_DIR)/tools \
17:             DESTDIR=$(STAGING_DIR) \
18:             foo_install
19: endef
20:
21: define FOO_INSTALL_TARGET_CMDS
22:     $(TARGET_MAKE_ENV) $(MAKE) -C $(LINUX_DIR)/tools \
23:             DESTDIR=$(TARGET_DIR) \
24:             foo_install
25: endef

第7行,将linux工具foo注册到Linux工具列表中。

第9行,指定该工具依赖的其他软件包。仅在foo工具选中后,这些依赖项才会添加到Linux软件包依赖项列表中。

第11-25行,定义了Linux工具构建不同步骤所执行的具体操作,类似于通用软件包(generic package)。仅在foo被选中后以上操作才会执行,且仅支持以下命令:_BUILD_CMDS, _INSTALL_STAGING_CMDS和INSTALL_TARGET_CMDS。
注意,不能调用$(eval $(generic-package))或其他软件包基础结构宏!Linux工具本身不是软件包,而是linux-tools软件包的一部分。

17.21.2 Linux内核扩展

一些软件包提供的特性需要修改Linux内核源码,这可以采用内核补丁的形式实现,也可以采用向内核添加新文件的方式实现。Buildroot的Linux内核扩展基础结构提供了一个简单的解决方案,可以在提取内核源码之后应用内核补丁之前自动执行此操作。使用该机制打包的内核扩展示例包括实时扩展Xenomai和RTAI,以及树外LCD屏幕驱动程序fbtft。

让我们看下如何添加新Linux扩展foo的示例。

首先,创建提供Linux内核扩展的软件包foo:该软件包是标准软件包,有关创建软件包的相关信息请参阅前面的章节。该软件包负责下载源码压缩包、检查哈希、定义许可证信息以及构建用户空间工具(如果有)。

然后,创建Linux扩展:在现有的目录中创建linux/Config.ext.in。该文件包含了将在配置工具中使用和显示的每个内核扩展相关的选项描述。示例如下:

01: config BR2_LINUX_KERNEL_EXT_FOO
02:     bool "foo"
03:     help
04:       This is a comment that explains what foo kernel extension is.
05:
06:       http://foosoftware.org/foo/

然后,为每个Linux扩展创建.mk文件,命名为linux/linux-ext-foo.mk。示例如下:

01: ################################################################################
02: #
03: # foo
04: #
05: ################################################################################
06:
07: LINUX_EXTENSIONS += foo
08:
09: define FOO_PREPARE_KERNEL
10:     $(FOO_DIR)/prepare-kernel-tree.sh --linux-dir=$(@D)
11: endef

第7行,将Linux扩展foo添加到Linux扩展的列表中。

第9-11行,定义了该扩展如何修改Linux内核树,这是Linux扩展特有的。可以使用软件包foo定义的变量,如$(FOO_DIR)、$(FOO_VERSION)等以及所有的Linux变量,如: $(LINUX_VERSION)、$(LINUX_VERSION_PROBED)、$(KERNEL_ARCH)等。

17.22 各个构建步骤支持的hook操作

通用基础结构(以及基于此派生出的基于autotools和cmake构建系统的基础结构)允许软件包指定hook钩子。这些钩子定义了执行完相应步骤后要执行的其他操作。大多数hook钩子对于通用软件包并不是真正有用,因为该.mk文件已经完全控制了软件包在构建过程每个步骤中执行的操作。

以下是有效的hook点:

  • LIBFOO_PRE_DOWNLOAD_HOOKS
  • LIBFOO_POST_DOWNLOAD_HOOKS
  • LIBFOO_PRE_EXTRACT_HOOKS
  • LIBFOO_POST_EXTRACT_HOOKS
  • LIBFOO_PRE_RSYNC_HOOKS
  • LIBFOO_POST_RSYNC_HOOKS
  • LIBFOO_PRE_PATCH_HOOKS
  • LIBFOO_POST_PATCH_HOOKS
  • LIBFOO_PRE_CONFIGURE_HOOKS
  • LIBFOO_POST_CONFIGURE_HOOKS
  • LIBFOO_PRE_BUILD_HOOKS
  • LIBFOO_POST_BUILD_HOOKS
  • LIBFOO_PRE_INSTALL_HOOKS (只对宿主软件包有效)
  • LIBFOO_POST_INSTALL_HOOKS (只对宿主软件包有效)
  • LIBFOO_PRE_INSTALL_STAGING_HOOKS (只对目标软件包有效)
  • LIBFOO_POST_INSTALL_STAGING_HOOKS (只对目标软件包有效)
  • LIBFOO_PRE_INSTALL_TARGET_HOOKS (只对目标软件包有效)
  • LIBFOO_POST_INSTALL_TARGET_HOOKS (只对目标软件包有效)
  • LIBFOO_PRE_INSTALL_IMAGES_HOOKS
  • LIBFOO_POST_INSTALL_IMAGES_HOOKS
  • LIBFOO_PRE_LEGAL_INFO_HOOKS
  • LIBFOO_POST_LEGAL_INFO_HOOKS

这些变量是变量名称的列表,其中包含要在此hook点执行的操作。允许在给定的hook点注册多个hook钩子。示例如下:

define LIBFOO_POST_PATCH_FIXUP
        action1
        action2
endef

LIBFOO_POST_PATCH_HOOKS += LIBFOO_POST_PATCH_FIXUP
17.22.1 使用POST_RSYNC钩子

POST_RSYNC钩子仅针对通过local站点或OVERRIDE_SRCDIR机制使用本地源的软件包有效。在这种情况下,使用rsync从本地位置将软件包源码复制到Buildroot构建目录中。但是,rsync命令不会从源码目录复制所有文件,例如属于版本控制系统的.git、.hg等文件不会被复制。对于大多数软件包来说这已经足够了,若有特殊情况,可以使用POST_RSYNC钩子执行其他操作。

原则上,钩子可以包含任意你想要执行的命令。一种常见的用法是使用rsync故意复制版本控制系统的目录。rsync命令中可使用以下变量:

  • $(SRCDIR) 源码目录
  • $(@D) 编译目录
17.22.2 目标生成钩子

软件包也已注册LIBFOO_TARGET_FINALIZE_HOOKS钩子,这些钩子将在所有软件包构建完成且文件系统镜像生成之前运行。它们很少会被使用。

17.23 Gettext集成以及与软件包的交互

17.24 技巧和窍门

17.24.1 软件包名称、配置入口名称及makefile变量之间的关系

在Buildroot中,它们之间存在一些关系:

  • 软件包名称,即软件包目录名称,也是.mk文件名称。
  • 配置入口名称为Config.in中声明的名称。
  • makefile变量前缀。

必须使用以下规则确保这些元素之间的一致性:

  • 软件包目录和.mk文件名即为软件包名称本身,如package/foo-bar_boo/foo-bar_boo.mk。
  • make目录名称是软件包名称本身,如foo-bar_boo。
  • 配置入口名称是软件包名称大写,其中-替换为_,并以BR2_PACKAGE_开头,如BR2_PACKAGE_FOO_BAR_BOO。
  • .mk文件变量前缀是软件包名称大写,其中-替换为_,如FOO_BAR_BOO_VERSION。
17.24.2 如何检查编码样式

Buildroot提供了一个脚本(utils/check-package)用于检查新文件或修改修改的编码样式。它不是一个完整的语言验证器,但是它会发现许多常见错误。

该脚本可用于软件包、文件系统、Makefiles文件、Config.in文件等。它不会检查定义软件包基础结构的文件或者其他包含通用代码的类似文件。

要检查编码样式,请运行check-package脚本:

$ ./utils/check-package package/new-package/*

该脚本也可以用于Buildroot目录树外编译,如:

$ check-package -b /path/to/br2-ext-tree/package/my-package/*
17.24.3 如何测试软件包

添加新软件包后,必须在各种条件下对其进行测试:是否适用于所有体系结构,是否适用于不同的C库、是否需要线程、NPTL等等。

Buildroot运行autobuilders工具自动测试不同随机配置。但是,该工具仅测试git仓库的master分支。

Buildroot提供了一个脚本utils/test-pkg,该脚本使用与autobuilders相同的基本配置,因此你可以在相同条件下测试你的软件包。

首先,创建一个配置文件,其中包含软件包所需的所有必选选项,但不包含任何体系结构或工具链选项。例如,让我们创建一个仅启用libcurl且没有任何TLS后端的的配置文件:

$ cat libcurl.config
BR2_PACKAGE_LIBCURL=y

如果你的软件包需要更多配置选项,则可以将他们添加到以上配置文件中。例如,以下是你测试libcurl且使用openssl和curl应用程序的配置文件:

$ cat libcurl.config
BR2_PACKAGE_LIBCURL=y
BR2_PACKAGE_LIBCURL_CURL=y
BR2_PACKAGE_OPENSSL=y

之后,运行test-pkg脚本:
$ ./utils/test-pkg -c libcurl.config -p libcurl

默认情况下,test-pkg将根据autobuilders使用的工具链的子集构建软件包,该子集已被Buildroot开发人员选定为最有用且最具代表性的子集。如果要测试所有工具链,请传递-a选项。请注意,在任何情况下,内部工具链都已经排除,因为它们花费的时间太长。

以下列出了所有经过测试的工具链及相应的结果(摘录,结果为假):

$ ./utils/test-pkg -c libcurl.config -p libcurl
                armv5-ctng-linux-gnueabi [ 1/11]: OK
              armv7-ctng-linux-gnueabihf [ 2/11]: OK
                        br-aarch64-glibc [ 3/11]: SKIPPED
                           br-arcle-hs38 [ 4/11]: SKIPPED
                            br-arm-basic [ 5/11]: FAILED
                  br-arm-cortex-a9-glibc [ 6/11]: OK
                   br-arm-cortex-a9-musl [ 7/11]: FAILED
                   br-arm-cortex-m4-full [ 8/11]: OK
                             br-arm-full [ 9/11]: OK
                    br-arm-full-nothread [10/11]: FAILED
                      br-arm-full-static [11/11]: OK
11 builds, 2 skipped, 2 build failed, 1 legal-info failed

结果:

  • OK:构建成功。
  • SKIPPED:配置文件中列出的一个或多个配置选项在最终的配置中不存在。这是由于工具链无法满足选项的依赖项,例如depends on BR2_USE_MMU使用不支持MMU的工具链。缺少的选项默认输出到~/br-test-pkg/TOOLCHAIN_NAME/missing.config。
  • FAILED:构建失败。检查logfile以确认具体出错原因:
    • 实际构建失败
    • 法律信息失败
    • 构建步骤之一失败

出现故障并修复软件包后,可以使用-p参数重新运行脚本,无需重新构建该软件包的所有依赖项。

test-pkg脚本支持一些选项,可通过以下方式获得帮助:

$ ./utils/test-pkg -h
17.24.4 如何从GitHub添加软件包

GitHub通常不提供软件包的发行版tar包下载区域,但是可以直接从GitHub的存储库下载tar包。若需从GitHub下载软件包,需配置如下选项:

# Use a tag or a full commit ID
FOO_VERSION = v1.0
FOO_SITE = $(call github,<user>,<package>,$(FOO_VERSION))

注意:

  • FOO_VERSION 可以是tag,也可以是commit ID。
  • github生成的tar包文件名与Buildroot的默认名称匹配,因此无需在.mk文件中指定,如foo-f6fb6654af62045239caed5950bc6c7971965e60.tar.gz。
  • 如果使用commit ID作为版本号,需要填写完整的40个十六进制字符。

如果要添加的软件包在GitHub上提供了发行版tar包下载链接,说明维护者可能已上传了发行版tar包,或者该发行版只是指向了git标签中自动生成的tar包。如果维护者上传了发行版tar包,我们最好使用该版本,因为它可能略有不同(例如,它包含配置文件,因此我们无需执行AUTORECONF)。

你可以在GitHub发布页面上看到下载链接:
在这里插入图片描述

17.25 结论

如你所见,向Buildroot添加软件包仅是编写Makefile并根据软件包所需的编译过程对其进行修改的问题。

如果你打包了可能对其他人有用的软件,请不要忘记将补丁发送到Buildroot邮件列表(详情参阅第21.5节提交补丁)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值