本文为译文,英文原文地址:The Buildroot user manual
Buildroot是一个工具,它使用交叉编译简化了为嵌入式系统构建完整Linux系统的过程,并实现了自动化。
为了实现这一点,Buildroot能够为您的目标生成交叉编译工具链( a cross-compilation toolchain)、根文件系统(a root filesystem)、Linux内核映像(a Linux kernel image)和引导加载程序(a bootloader)。Buildroot可以独立地用于这些选项的任何组合(例如,您可以使用现有的交叉编译工具链,只用Buildroot构建您的根文件系统)。
Buildroot主要适用于使用嵌入式系统的人。嵌入式系统通常使用的处理器不是每个人都习惯在个人电脑中使用的常规x86处理器。它们可以是PowerPC处理器,MIPS处理器,ARM处理器等。
Buildroot支持许多处理器及其变体;它还提供了几种现成电路板的默认配置。除此之外,很多第三方项目都是基于,或者在Buildroot之上开发他们的BSP[1]或SDK[2]。
Buildroot设计用于在Linux系统上运行。
虽然Buildroot本身将构建它编译所需的大多数主机包,但某些标准的Linux实用程序预计已经安装在主机系统上。下面是强制包和可选包的概述(注意,不同发行版的包名称可能有所不同)。
以下是 Linux 环境上必须安装的程序:
// Build tools:
which
sed
make (version 3.81 or any later)
binutils
build-essential (only for Debian based systems)
gcc (version 4.8 or any later)
g++ (version 4.8 or any later)
bash
patch
gzip
bzip2
perl (version 5.8.7 or any later)
tar
cpio
unzip
rsync
file (must be in /usr/bin/file)
bc
//Source fetching tools:
wget
以下是可选安装的程序:
Buildroot中的一些特性或实用程序,如the legal-info
或the graph generation tools
,有额外的依赖关系。尽管它们不是简单构建的强制要求,但仍然强烈推荐使用:
python (version 2.7 or any later)
对于这些库,您需要同时安装运行时数据和开发数据,在许多发行版中,这些数据是单独打包的。开发包通常有一个-dev
或-devel
后缀。
ncurses5 to use the menuconfig interface
qt5 to use the xconfig interface
glib2, gtk2 and glade2 to use the gconfig interface
在官方树中,大多数包源都是使用wget
从ftp
、http
或https
位置检索的。少数软件包只能通过版本控制系统获得。此外,Buildroot还可以通过其他工具下载资源,如rsync
或scp
(参阅第20章,下载基础设施了解更多细节)。如果您使用以下任何一种方法启用包,您将需要在主机系统上安装相应的工具:
bazaar
cvs
git
mercurial
rsync
scp
subversion
Java-related packages, if the Java Classpath needs to be built for the target system:
The javac compiler
The jar tool
Documentation generation tools:
asciidoc, version 8.6.3 or higher
w3m
python with the argparse module (automatically present in 2.7+ and 3.2+)
dblatex (required for the pdf manual only)
Graph generation tools:
graphviz to use graph-depends and
python-matplotlib to use graph-build
Buildroot版本每3个月发布一次,分别是在2月、5月、8月和11月。版本号的格式为YYYY.MM
,例如2013.02
,2014.08
。发布tarball可以在http://buildroot.org/downloads/上找到。
有两种方式可以搭建起 Buildroot 开发环境:
为方便起见,在Buildroot源代码树的support/misc/Vagrantfile中提供了一个Vagrantfile,用于快速设置一个虚拟机,其中包含启动所需的依赖项。
如果你想在Linux或Mac Os X上建立一个独立的构建根环境,请将这一行粘贴到你的终端上:
curl -O https://buildroot.org/downloads/Vagrantfile; vagrant up
如果你在Windows上,把这个粘贴到你的powershell:
(new-object System.Net.WebClient).DownloadFile(
"https://buildroot.org/downloads/Vagrantfile","Vagrantfile");
vagrant up
如果您想继续开发,可以使用日常快照或复制Git存储库。更多详细信息,请参考Buildroot网站的下载页面。
重要:你可以并且应该像普通用户一样构建一切。配置和使用Buildroot不需要是root。通过作为普通用户运行所有命令,可以保护系统免受包在编译和安装期间行为不正常的影响。
使用Buildroot的第一步是创建一个配置。Buildroot有一个很好的配置工具,类似于您可以在Linux内核或BusyBox中找到的那个。
From the buildroot directory, run
$ make menuconfig
for the original curses-based configurator, or
$ make nconfig
for the new curses-based configurator, or
$ make xconfig
for the Qt-based configurator, or
$ make gconfig
for the GTK-based configurator.
所有这些make
命令都需要构建一个配置实用程序(包括接口),因此您可能需要为配置实用程序使用的相关库安装“开发”包。请参阅第2章 系统需求,以获得更多的细节,特别是可选的需求,以获得您喜欢的接口的依赖关系。
对于配置工具中的每个菜单项,您可以找到描述该项用途的相关帮助。关于一些具体配置方面的细节,请参阅第6章 Buildroot配置。
一旦一切配置完成,配置工具将生成一个包含整个配置的.config
文件。这个文件将由顶级Makefile读取。
要启动构建过程,只需运行:
$ make
默认情况下,Buildroot不支持顶级并行构建,所以没有必要运行make -jN
。不过,也有对顶层并行构建的实验性支持,请参见8.12节“顶层并行构建”。
上述make
命令一般执行如下步骤:
Buildroot
输出存储在单个目录output/
中。这个目录包含几个子目录:
images/
where all the images (kernel image, bootloader and root filesystem images) are stored. These are the files you need to put on your target system.build/
where all the components are built (this includes tools needed by Buildroot on the host and packages compiled for the target). This directory contains one subdirectory for each of these components. // 所有组件都是在这里构建的(这包括Buildroot在主机上需要的工具和为目标编译的包)。这个目录包含每个组件的一个子目录。host/
contains both the tools built for the host, and the sysroot of the target toolchain. The former is an installation of tools compiled for the host that are needed for the proper execution of Buildroot, including the cross-compilation toolchain. The latter is a hierarchy similar to a root filesystem hierarchy. It contains the headers and libraries of all user-space packages that provide and install libraries used by other packages. However, this directory is not intended to be the root filesystem for the target: it contains a lot of development files, unstripped binaries and libraries that make it far too big for an embedded system. These development files are used to compile libraries and applications for the target that depend on other libraries.staging/
is a symlink to the target toolchain sysroot inside host/, which exists for backwards compatibility.target/
which contains almost the complete root filesystem for the target: everything needed is present except the device files in /dev/ (Buildroot can’t create them because Buildroot doesn’t run as root and doesn’t want to run as root). Also, it doesn’t have the correct permissions (e.g. setuid for the busybox binary). Therefore, this directory should not be used on your target. Instead, you should use one of the images built in the images/ directory. If you need an extracted image of the root filesystem for booting over NFS, then use the tarball image generated in images/ and extract it as root. Compared to staging/, target/ contains only the files and libraries needed to run the selected target applications: the development files (headers, etc.) are not present, the binaries are stripped./dev/
中的设备文件(Buildroot不能创建它们,因为Buildroot不是作为root运行的,也不想作为root运行)。此外,它没有正确的权限(例如busybox二进制文件的setuid)。因此,不应该在目标上使用这个目录。相反,您应该使用images/目录中构建的映像。如果您需要根文件系统的解压映像以用于在NFS上引导,那么使用images/中生成的tarball映像并将其解压为根文件。与staging/
相比,target/
只包含运行所选目标应用程序所需的文件和库:开发文件(头文件等)不存在,二进制文件被剥离调试信息。这些命令make menuconfig
|nconfig
|gconfig
|xconfig
和make
是最基本的命令,它们允许您通过启用的所有特性和应用程序轻松快速地生成符合您需求的图像。
关于make
命令使用的更多细节在8.1节“make tips”中给出。
社区资源 (略)。
make *config
中的所有配置选项都有一个帮助文本,提供关于该选项的详细信息。
make *config
命令也提供了一个搜索工具。阅读不同前端菜单中的帮助信息,了解如何使用它:
menuconfig
中,搜索工具通过按/
;xconfig
中,通过按Ctrl + f
调用搜索工具。搜索结果显示匹配项的帮助信息。在menuconfig
中,左边列中的数字
为相应的条目提供了快捷方式。只要输入这个数字
就可以直接跳转到条目,或者跳转到包含的菜单(如果条目由于缺少依赖项而无法选择的话)。
尽管条目的菜单结构和帮助文本应该具有足够的自解释性,但有一些主题需要额外的解释,这些内容不容易在帮助文本中介绍,因此将在下面的部分中介绍。
编译工具链是一组允许您为系统编译代码的工具。它包括一个编译器
(在我们的例子中是gcc)、汇编器和链接器之类的二进制utils
(在我们的例子中是binutils)和一个C标准库
(例如GNU Libc, uClibc-ng)。
安装在开发站上的系统肯定已经有一个编译工具链,您可以使用它编译在系统上运行的应用程序。如果您使用的是PC,那么编译工具链运行在x86处理器上,并为x86处理器生成代码。在大多数Linux系统下,编译工具链使用GNU libc (glibc)作为C标准库。这个编译工具链称为“宿主编译工具链”。运行它和您工作的机器称为“主机系统”[3]。
编译工具链由您的发行版提供,而Buildroot与它无关(除了使用它来构建交叉编译工具链和在开发主机上运行的其他工具)。
如上所述,系统附带的编译工具链运行在主机系统中的处理器上并为其生成代码。由于嵌入式系统具有不同的处理器,因此需要一个交叉编译工具链——一个运行在主机系统上但为目标系统(和目标处理器)生成代码的编译工具链。例如,如果您的主机系统使用x86,而目标系统使用ARM,那么主机上的常规编译工具链运行在x86上并生成针对x86的代码,而交叉编译工具链运行在x86上并生成针对ARM的代码。
Buildroot为交叉编译工具链提供了两种解决方案:
Internal toolchain backend
),在配置界面中称为Buildroot工具链(Buildroot toolchain
)。External toolchain backend
),在配置界面中称为外部工具链(External toolchain
)。使用Toolchain菜单中的Toolchain Type选项可以在这两个解决方案之间进行选择。一旦选择了一个解决方案,就会出现许多配置选项,以下部分将详细介绍这些选项。
在为目标嵌入式系统构建用户空间应用程序和库之前,内部工具链后端是Buildroot自己构建交叉编译工具链的后端。
这个后端支持几个C库:uClibc-ng
、glibc
和musl
。
一旦您选择了这个后端,就会出现许多选项。最重要的是以下选项:
值得注意的是,每当其中一个选项被修改时,就必须重新构建整个工具链和系统。请参阅第8.2节 “了解什么时候需要进行完全重建”。
这个后端的优点:
这个后端的缺点:
make clean
时需要重建工具链,这需要时间。如果您试图减少构建时间,请考虑使用External工具链后端。外部工具链后端允许使用现有的预构建的交叉编译工具链。Buildroot
知道许多著名的交叉编译工具链(从Linaro
for ARM、Sourcery CodeBench
for ARM、x86-64、PowerPC和MIPS),并且能够自动下载它们,或者它可以指向一个定制的工具链,可以下载或在本地安装。
目前,你有三个解决方案来使用外部工具链:
Toolchain
from the available ones. This is definitely the easiest solution.Toolchain
中从可用的工具链概要文件中选择工具链概要文件。这绝对是最简单的解决方案。Toolchain
through the available ones, unselect Download toolchain automatically
, and fill the Toolchain path
text entry with the path to your cross-compiling toolchain.Toolchain
中选择工具链配置文件,取消选择自动下载工具链,并在Toolchain path
文本条目中填写交叉编译工具链的路径。crosstool-NG
or with Buildroot
itself. To do this, select the Custom toolchain
solution in the Toolchain
list. You need to fill the Toolchain path
, Toolchain prefix
and External toolchain C library
options. Then, you have to tell Buildroot what your external toolchain supports. If your external toolchain uses the glibc library, you only have to tell whether your toolchain supports C++ or not and whether it has built-in RPC support. If your external toolchain uses the uClibc library, then you have to tell Buildroot if it supports RPC, wide-char, locale, program invocation, threads and C++. At the beginning of the execution, Buildroot will tell you if the selected options do not match the toolchain configuration.crosstool-NG
或Buildroot
本身生成的工具链特别有用。为此,在Toolchain
列表中选择Custom toolchain
解决方案。您需要填充Toolchain path
、Toolchain prefix
和External toolchain C library
选项。然后,你必须告诉Buildroot你的外部工具链支持什么。如果您的外部工具链使用glibc库,您只需告诉您的工具链是否支持c++,以及它是否有内置的RPC支持。如果您的外部工具链使用了uClibc库,那么您必须告诉Buildroot它是否支持RPC、宽字符、区域设置、程序调用、线程和c++。在执行的开始,Buildroot将告诉您所选择的选项是否与工具链配置不匹配。我们的外部工具链支持已经通过来自CodeSourcery
和Linaro
的工具链、由crosstool-NG
生成的工具链和由Buildroot
本身生成的工具链进行了测试。一般来说,所有支持sysroot特性的工具链都应该工作。如果没有,不要犹豫联系开发人员。
我们不支持
openenembedded
或Yocto
生成的工具链或SDK,因为这些工具链不是纯工具链(即编译器、binutils、C和c++库)。相反,这些工具链带有一组非常大的预编译库和程序。因此,Buildroot不能导入工具链的sysroot,因为它将包含数百兆字节的预编译库,而这些库通常是由Buildroot构建的。
我们也不支持使用发行版工具链(即由
发行版
安装的gcc/binutils/C库)作为构建目标软件的工具链。这是因为你的分发工具链不是一个“纯”的工具链(即只使用C/ c++库),所以我们不能正确地将它导入Buildroot构建环境中。因此,即使您正在为x86或x86_64目标构建系统,也必须使用Buildroot或crosstool-NG生成交叉编译工具链。
如果你想为你的项目生成一个自定义的工具链,可以在Buildroot中作为外部工具链使用,我们的建议是使用Buildroot本身(见6.1.3节“使用Buildroot构建一个外部工具链”)或者使用crosstool-NG。
这个后端的优点:
这个后端的缺点:
Buildroot内部工具链选项可用于创建外部工具链。下面是构建内部工具链并将其打包以供Buildroot自身(或其他项目)重用的一系列步骤。
1、创建一个新的Buildroot配置,详细信息如下:
Target options
for your target CPU architectureToolchain
menu, keep the default of Buildroot toolchain
for Toolchain
type, and configure your toolchain as desiredSystem configuration
menu, select None
as the Init system
and none
as /bin/sh
Target packages
menu, disable BusyBox
Filesystem images
menu, disable tar the root filesystem
2、然后,我们可以触发构建,并要求Buildroot生成一个SDK。这将方便地为我们生成一个包含工具链的tarball:
make sdk
这将在$(O)/images
中生成SDK tarball,其名称类似于arm-buildroot-linux-uclibcgnueabi_sdk-buildroot.tar.gz
。保存这个tarball,因为现在它是您可以在其他Buildroot项目中作为外部工具链重用的工具链。
3、在其他的Buildroot项目中,在Toolchain菜单中:
Toolchain type
to External toolchain
Toolchain
to Custom toolchain
Toolchain origin
to Toolchain to be downloaded and installed
Toolchain URL
to file:///path/to/your/sdk/tarball.tar.gz
当使用外部工具链时,Buildroot生成一个wrapper
程序,该程序透明地将适当的选项(根据配置)传递给外部工具链程序。如果您需要调试这个wrapper
来检查传递了哪些参数,您可以将环境变量BR2_DEBUG_WRAPPER
设置为以下任意一个:
在Linux系统中,/dev
目录包含特殊的文件,称为设备文件(device files
),允许用户空间应用程序访问Linux内核管理的硬件设备。如果没有这些设备文件,您的用户空间应用程序将不能使用硬件设备,即使它们被Linux内核正确识别。
在System configuration
,/dev management
下,Buildroot提供了四种不同的解决方案来处理/dev
目录:
Static using device table
. This is the old classical way of handling device files in Linux. With this method, the device files are persistently stored in the root filesystem (i.e. they persist across reboots), and there is nothing that will automatically create and remove those device files when hardware devices are added or removed from the system. Buildroot therefore creates a standard set of device files using a device table
, the default one being stored in system/device_table_dev.txt
in the Buildroot source code. This file is processed when Buildroot generates the final root filesystem image, and the device files are therefore not visible in the output/target
directory. The BR2_ROOTFS_STATIC_DEVICE_TABLE
option allows to change the default device table used by Buildroot, or to add an additional device table, so that additional device files
are created by Buildroot during the build. So, if you use this method, and a device file
is missing in your system, you can for example create a board/<yourcompany>/<yourproject>/device_table_dev.txt
file that contains the description of your additional device files, and then you can set BR2_ROOTFS_STATIC_DEVICE_TABLE
to system/device_table_dev.txt
board/<yourcompany>/<yourproject>/device_table_dev.txt
. For more details about the format of the device table file, see Chapter 25, Makedev syntax documentation.system/device_table_dev.txt
中。这个文件在Buildroot生成最终的根文件系统映像时被处理,因此设备文件在输出/目标目录中是不可见的。BR2_ROOTFS_STATIC_DEVICE_TABLE
选项允许更改Buildroot使用的默认设备表,或添加一个额外的设备表,以便Buildroot在构建期间创建额外的设备文件。所以,如果你使用这个方法,并且你的系统中缺少一个设备文件,例如,你可以创建一个board///device_table_dev.txt
文件,其中包含你的附加设备文件的描述,然后你可以设置BR2_ROOTFS_STATIC_DEVICE_TABLE
为system/device_table_dev.txt
board/<yourcompany>/<yourproject>/device_table_dev.txt
。有关设备表文件格式的更多详细信息,请参见第25章Makedev语法文档。Dynamic using devtmpfs only
. devtmpfs
is a virtual filesystem inside the Linux kernel that has been introduced in kernel 2.6.32 (if you use an older kernel, it is not possible to use this option). When mounted in /dev, this virtual filesystem will automatically make device files appear and disappear as hardware devices are added and removed from the system. This filesystem is not persistent across reboots: it is filled dynamically by the kernel. Using devtmpfs requires the following kernel configuration options to be enabled: CONFIG_DEVTMPFS
and CONFIG_DEVTMPFS_MOUNT
. When Buildroot is in charge of building the Linux kernel for your embedded device, it makes sure that those two options are enabled. However, if you build your Linux kernel outside of Buildroot, then it is your responsibility to enable those two options (if you fail to do so, your Buildroot system will not boot).devtmpfs
是内核2.6.32中引入的Linux内核中的一个虚拟文件系统(如果使用旧内核,则不可能使用此选项)。当挂载到/dev中时,这个虚拟文件系统将自动使设备文件随着硬件设备的添加和从系统中移除而出现和消失。这个文件系统在重新引导时不是持久的:它是由内核动态填充的。使用devtmpfs需要启用以下内核配置选项:CONFIG_DEVTMPFS
和CONFIG_DEVTMPFS_MOUNT
。当Buildroot负责为您的嵌入式设备构建Linux内核时,它会确保启用这两个选项。但是,如果您在Buildroot之外构建Linux内核,那么您就有责任启用这两个选项(如果您没有这样做,那么您的Buildroot系统将无法引导)。Dynamic using devtmpfs + mdev
. This method also relies on the devtmpfs virtual filesystem detailed above (so the requirement to have CONFIG_DEVTMPFS
and CONFIG_DEVTMPFS_MOUNT
enabled in the kernel configuration still apply), but adds the mdev userspace utility on top of it. mdev
is a program part of BusyBox that the kernel will call every time a device is added or removed. Thanks to the /etc/mdev.conf
configuration file, mdev can be configured to for example, set specific permissions or ownership on a device file, call a script or application whenever a device appears or disappear, etc. Basically, it allows userspace to react on device addition and removal events. mdev can for example be used to automatically load kernel modules when devices appear on the system. mdev is also important if you have devices that require a firmware, as it will be responsible for pushing the firmware contents to the kernel. mdev is a lightweight implementation (with fewer features) of udev. For more details about mdev and the syntax of its configuration file, see http://git.busybox.net/busybox/tree/docs/mdev.txt./etc/mdev.conf
配置文件,mdev可以配置为例如,设置特定的权限或对设备文件的所有权,每当设备出现或消失时调用脚本或应用程序,等等。基本上,它允许用户空间对设备添加和删除事件做出反应。例如,当设备出现在系统上时,可以使用Mdev自动加载内核模块。如果您有需要固件的设备,Mdev也很重要,因为它将负责将固件内容推送到内核。Mdev是udev的一个轻量级实现(具有更少的特性)。有关mdev及其配置文件语法的详细信息,请参见http://git.busybox.net/busybox/tree/docs/mdev.txt。Dynamic using devtmpfs + eudev
. This method also relies on the devtmpfs virtual filesystem detailed above, but adds the eudev userspace daemon on top of it. eudev is a daemon that runs in the background, and gets called by the kernel when a device gets added or removed from the system. It is a more heavyweight solution than mdev, but provides higher flexibility. eudev is a standalone version of udev, the original userspace daemon used in most desktop Linux distributions, which is now part of Systemd. For more details, see http://en.wikipedia.org/wiki/Udev.Buildroot开发人员的建议是从Dynamic using devtmpfs only
的解决方案开始,直到您需要通知用户空间何时添加/删除设备,或是否需要固件,在这种情况下,Dynamic using devtmpfs + mdev
通常是一个很好的解决方案。
注意,如果选择systemd
作为init
系统,/dev
管理将由systemd
提供的udev
程序执行。
init
程序是由内核启动的第一个用户空间程序(它的PID号为1),负责启动用户空间服务和程序(例如:web服务器、图形应用程序、其他网络服务器等)。
Buildroot允许使用三种不同类型的初始化系统,可以从System configuration
, Init system
中选择:
BusyBox
. Amongst many programs, BusyBox has an implementation of a basic init program, which is sufficient for most embedded systems. Enabling the BR2_INIT_BUSYBOX will ensure BusyBox will build and install its init program. This is the default solution in Buildroot. The BusyBox init program will read the /etc/inittab
file at boot to know what to do. The syntax of this file can be found in http://git.busybox.net/busybox/tree/examples/inittab (note that BusyBox inittab syntax is special: do not use a random inittab documentation from the Internet to learn about BusyBox inittab). The default inittab in Buildroot is stored in system/skeleton/etc/inittab
. Apart from mounting a few important filesystems, the main job the default inittab does is to start the /etc/init.d/rcS
shell script, and start a getty program (which provides a login prompt).systemV
. This solution uses the old traditional sysvinit program, packed in Buildroot in package/sysvinit
. This was the solution used in most desktop Linux distributions, until they switched to more recent alternatives such as Upstart or Systemd. sysvinit also works with an inittab file (which has a slightly different syntax than the one from BusyBox). The default inittab installed with this init solution is located in package/sysvinit/inittab
.systemd
. systemd is the new generation init system for Linux. It does far more than traditional init programs: aggressive parallelization capabilities, uses socket and D-Bus activation for starting services, offers on-demand starting of daemons, keeps track of processes using Linux control groups, supports snapshotting and restoring of the system state, etc. systemd will be useful on relatively complex embedded systems, for example the ones requiring D-Bus and services communicating between each other. It is worth noting that systemd brings a fairly big number of large dependencies: dbus, udev and more. For more details about systemd, see http://www.freedesktop.org/wiki/Software/systemd.Buildroot开发人员推荐的解决方案是使用BusyBox init
,因为它对于大多数嵌入式系统来说已经足够了。Systemd
可以用于更复杂的情况。
在尝试修改下面的任何组件之前,请确保您已经配置了Buildroot本身,并启用了相应的包。
如果您已经有一个BusyBox配置文件,您可以直接在Buildroot配置中指定这个文件,使用BR2_PACKAGE_BUSYBOX_CONFIG
。否则,Buildroot将从默认的BusyBox配置文件启动。
要对配置进行后续更改,请使用make busybox-menuconfig
打开BusyBox配置编辑器。
还可以通过环境变量指定BusyBox配置文件,不过不建议这样做。请参阅8.6节“环境变量”了解更多细节。
uClibc的配置方法与BusyBox相同。指定现有配置文件的配置变量是BR2_UCLIBC_CONFIG
。进行后续更改的命令是make uclibc-menuconfig
。
如果您已经有了一个内核配置文件,那么可以使用BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG
在Buildroot配置中直接指定这个文件。
如果您还没有内核配置文件,那么您可以使用BR2_LINUX_KERNEL_USE_DEFCONFIG
在Buildroot配置中指定defconfig,或者使用BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG
创建一个空文件并将其指定为自定义配置文件。
要对配置进行后续更改,请使用make Linux-menuconfig
打开Linux配置编辑器。
Barebox的配置方法与Linux内核的配置方法相同。对应的配置变量是BR2_TARGET_BAREBOX_USE_CUSTOM_CONFIG
和BR2_TARGET_BAREBOX_USE_DEFCONFIG
。要打开配置编辑器,请使用make barebox-menuconfig
。
U-Boot(2015.04及以上版本)的配置方法与Linux内核相同。对应的配置变量是BR2_TARGET_UBOOT_USE_CUSTOM_CONFIG
和BR2_TARGET_UBOOT_USE_DEFCONFIG
。打开配置编辑器,使用make uboot-menuconfig
。
这是一组技巧,可以帮助你充分利用Buildroot。
Display all commands executed by make:
$ make V=1
Display the list of boards with a defconfig:
$ make list-defconfigs
Display all available targets:
$ make help
并不是所有的目标都是可用的,.config
文件中的一些设置可能会隐藏一些目标:
busybox-menuconfig
only works when busybox
is enabled;
linux-menuconfig
and linux-savedefconfig
only work when linux
is enabled;
uclibc-menuconfig
is only available when the uClibc C library
is selected in the internal toolchain backend;
barebox-menuconfig
and barebox-savedefconfig
only work when the barebox
bootloader is enabled.
uboot-menuconfig
and uboot-savedefconfig
only work when the U-Boot
bootloader is enabled.
To delete all build products (including build directories, host, staging and target trees, the images and the toolchain)/ 删除所有构建产品(包括构建目录、主机、暂存和目标树、映像和工具链):
$ make clean
Generating the manual: The present manual sources are located in the docs/manual
directory. To generate the manual:
$ make manual-clean
$ make manual
Resetting Buildroot for a new target: To delete all build products as well as the configuration:
$ make distclean
如果启用了ccache,运行make clean或distclean不会清空Buildroot使用的编译器缓存。要删除它,请参考8.14.3节“在Buildroot中使用ccache”。
Dumping the internal make variables: 可以dump已知的make变量及其值:
$ make -s printvars VARS='VARIABLE1 VARIABLE2'
VARIABLE1=value_of_variable
VARIABLE2=value_of_variable
可以使用一些变量来调整输出:
VARS
will limit the listing to variables which names match the specified make-patterns - this must be set else nothing is printed // 将列表限制为名称与指定make-patterns
匹配的变量—这必须设置,否则不打印任何内容
QUOTED_VARS
, if set to YES, will single-quote the value // 如果设置为YES,将单引号引用该值
RAW_VARS
, if set to YES, will print the unexpanded value // 如果设置为YES,将打印未展开的值
$ make -s printvars VARS=BUSYBOX_%DEPENDENCIES
BUSYBOX_DEPENDENCIES=skeleton toolchain
BUSYBOX_FINAL_ALL_DEPENDENCIES=skeleton toolchain
BUSYBOX_FINAL_DEPENDENCIES=skeleton toolchain
BUSYBOX_FINAL_PATCH_DEPENDENCIES=
BUSYBOX_RDEPENDENCIES=ncurses util-linux
$ make -s printvars VARS=BUSYBOX_%DEPENDENCIES QUOTED_VARS=YES
BUSYBOX_DEPENDENCIES='skeleton toolchain'
BUSYBOX_FINAL_ALL_DEPENDENCIES='skeleton toolchain'
BUSYBOX_FINAL_DEPENDENCIES='skeleton toolchain'
BUSYBOX_FINAL_PATCH_DEPENDENCIES=''
BUSYBOX_RDEPENDENCIES='ncurses util-linux'
$ make -s printvars VARS=BUSYBOX_%DEPENDENCIES RAW_VARS=YES
BUSYBOX_DEPENDENCIES=skeleton toolchain
BUSYBOX_FINAL_ALL_DEPENDENCIES=$(sort $(BUSYBOX_FINAL_DEPENDENCIES) $(BUSYBOX_FINAL_PATCH_DEPENDENCIES))
BUSYBOX_FINAL_DEPENDENCIES=$(sort $(BUSYBOX_DEPENDENCIES))
BUSYBOX_FINAL_PATCH_DEPENDENCIES=$(sort $(BUSYBOX_PATCH_DEPENDENCIES))
BUSYBOX_RDEPENDENCIES=ncurses util-linux
带引号的变量的输出可以在shell脚本中重用,例如:
$ eval $(make -s printvars VARS=BUSYBOX_DEPENDENCIES QUOTED_VARS=YES)
$ echo $BUSYBOX_DEPENDENCIES
skeleton toolchain
当通过make menuconfig、make xconfig或其他配置工具改变系统配置时,Buildroot不会试图检测应该重新构建系统的哪些部分。在某些情况下,Buildroot应该重建整个系统,在某些情况下,只重建软件包的特定子集。但是以一种完全可靠的方式检测它是非常困难的,因此Buildroot开发人员决定不尝试这样做。
相反,用户有责任知道什么时候需要进行完全重新构建。作为提示,这里有一些经验法则可以帮助你理解如何使用Buildroot:
一般来说,当您面临构建错误并且不确定所做的配置更改的潜在后果时,请执行完整的重新构建。如果您得到相同的构建错误,那么您可以肯定这个错误与包的部分重构无关,如果这个错误发生在来自官方Buildroot的包上,请不要犹豫报告这个问题!随着您使用Buildroot的经验的积累,您将逐步了解什么时候真正需要一个完整的重建,您将节省越来越多的时间。
作为参考,完全重建可以通过运行:
$ make clean all
Buildroot用户最常问的问题之一是如何重新构建给定的包,或者如何在不重新构建所有内容的情况下删除包。
如果不从头重新构建,Buildroot不支持删除包。这是因为Buildroot没有跟踪哪个包在output/staging
目录和output/target
目录中安装了什么文件,或者哪个包会根据另一个包的可用性进行不同的编译。
从头重新构建单个包的最简单方法是删除output/build
中的构建目录。然后,Buildroot将重新提取、重新配置、重新编译和重新安装这个包。你可以通过make <package>-dirclean
命令要求buildroot这样做。
另一方面,如果只希望从编译步骤重新启动包的构建过程,可以运行make <package>-rebuild
。它将重新启动包的编译和安装,但不是从头开始:它基本上会在包内重新执行make
和make install
,因此它只会重新构建更改过的文件。
如果您想从配置步骤重新启动包的构建过程,可以运行make <package>-reconfigure
。它将重新启动包的配置、编译和安装。
虽然<package>-rebuild
意味着<package>-reinstall
,<package>-reconfigure
意味着<package>-rebuild
,但是这些目标以及只对上述<package>
起作用,并且不会触发重新创建根文件系统映像。如果需要重新创建根文件系统,还应该运行make
或make all
。
在内部,Buildroot创建所谓的戳文件(stamp files
),以跟踪每个包的哪些构建步骤已经完成。它们存储在包构建目录output/build/<package>-<version>/
中,命名为.stamp_<step-name>
。上面详细介绍的命令只是操作这些戳文件,以强制Buildroot重新启动包构建过程的一组特定步骤。
关于包装特殊制造目标的进一步细节在8.14.5节“特定于包装的制造目标”中解释。
如果你打算进行离线构建,并且只是想下载你之前在配置器(menuconfig, nconfig, xconfig或gconfig)中选择的所有源代码,那么发出:
$ make source
现在可以断开dl目录的内容或将其复制到构建主机中。
默认情况下,Buildroot构建的所有内容都存储在Buildroot树的输出目录中。
Buildroot还支持用类似于Linux内核的语法从树外构建。要使用它,请在make命令行中添加O=<directory>
:
$ make O=/tmp/build
or
$ cd /tmp/build; make O=$PWD -C path/to/buildroot
所有输出文件将位于/tmp/build目录下。如果O
路径不存在,Buildroot将创建它。
注意:O
路径可以是绝对路径,也可以是相对路径,但如果它作为相对路径传递,需要注意的是,它是相对于Buildroot主源目录解释的,而不是当前工作目录。
当使用树外构建时,Buildroot .config
和临时文件也存储在输出目录中。这意味着您可以使用相同的源代码树安全地并行运行多个构建,只要它们使用唯一的输出目录。
为了便于使用,Buildroot在输出目录中生成了一个Makefile包装器-所以在第一次运行之后,你不再需要传递O=<…>
and-C <…>
,只需运行(在输出目录中):
$ make <target>
Buildroot也遵循一些环境变量,当它们被传递到环境中make
或set
时:
HOSTCXX
, the host C++ compiler to use // 主机c++编译器HOSTCC
, the host C compiler to use // 主机c编译器UCLIBC_CONFIG_FILE=<path/to/.config>
, path to the uClibc configuration file, used to compile uClibc, if an internal toolchain is being built. Note that the uClibc configuration file can also be set from the configuration interface, so through the Buildroot .config file; this is the recommended way of setting it.BUSYBOX_CONFIG_FILE=<path/to/.config>
, path to the BusyBox configuration file. Note that the BusyBox configuration file can also be set from the configuration interface, so through the Buildroot .config file; this is the recommended way of setting it.BR2_CCACHE_DIR
to override the directory where Buildroot stores the cached files when using ccache. // 来覆盖Buildroot在使用ccache时存储缓存文件的目录。BR2_DL_DIR
to override the directory in which Buildroot stores/retrieves downloaded files. Note that the Buildroot download directory can also be set from the configuration interface, so through the Buildroot .config file. See Section 8.14.4, “Location of downloaded packages” for more details on how you can set the download directory.vBR2_GRAPH_ALT
, if set and non-empty, to use an alternate color-scheme in build-time graphsBR2_GRAPH_OUT
to set the filetype of generated graphs, either pdf (the default), or png.BR2_GRAPH_DEPS_OPTS
to pass extra options to the dependency graph; see Section 8.9, “Graphing the dependencies between packages” for the accepted optionsBR2_GRAPH_DOT_OPTS
is passed verbatim as options to the dot utility to draw the dependency graph.BR2_GRAPH_SIZE_OPTS
to pass extra options to the size graph; see Section 8.11, “Graphing the filesystem size contribution of packages” for the acepted options下面是一个使用顶层目录和$HOME中的配置文件的例子:
$ make UCLIBC_CONFIG_FILE=uClibc.config BUSYBOX_CONFIG_FILE=$HOME/bb.config
如果您想使用默认的gcc或g++以外的编译器在您的主机上构建辅助二进制文件,那么就这样做:
$ make HOSTCXX=g++-4.3-HEAD HOSTCC=gcc-4.3-HEAD
文件系统映像可以变得相当大,这取决于你选择的文件系统、包的数量,以及你是否提供了空闲空间……然而,文件系统映像中的一些位置可能只是空的(例如,长期运行的0);这样的文件称为稀疏文件。
大多数工具都可以有效地处理稀疏文件,并且只存储或编写稀疏文件中非空的那些部分。
例如:
tar accepts the -S option to tell it to only store non-zero blocks of sparse files:
tar cf archive.tar -S [files…] will efficiently store sparse files in a tarball
tar xf archive.tar -S will efficiently store sparse files extracted from a tarball
cp accepts the --sparse=WHEN option (WHEN is one of auto, never or always):
cp --sparse=always source.file dest.file will make dest.file a sparse file if source.file has long runs of zeroes
其他工具可能有类似的选项。请参阅他们各自的手册页。
如果您需要存储文件系统映像(例如,从一台机器传输到另一台机器),或者需要发送它们(例如,发送到Q&A团队),那么您可以使用稀疏文件。
但是请注意,当使用dd
的稀疏模式时,将文件系统映像烧录到设备上可能会导致文件系统损坏(例如,ext2文件系统的块位图可能损坏;或者,如果您的文件系统中有稀疏文件,那么这些部分在回读时可能不是全零)。您应该只在构建机器上处理文件时使用稀疏文件,而不是将它们传输到目标上使用的实际设备时。
Buildroot可以生成一个JSON简介,描述当前配置中启用的包集,以及它们的依赖项、许可和其他元数据。这个JSON简介是通过使用show-info
make目标产生的:
make show-info
Buildroot还可以使用pkg-stats
make 目标生成关于包的HTML和JSON输出的详细信息。除了其他内容外,这些细节包括已知的cve(安全漏洞)是否会影响当前配置中的包。它还显示了这些包是否有更新的上游版本。
make pkg-stats
Buildroot的工作之一是了解包之间的依赖关系,并确保它们以正确的顺序构建。这些依赖有时非常复杂,对于一个给定的系统,通常不容易理解为什么Buildroot将这样或那样的包引入构建中。
为了帮助理解依赖关系,从而更好地理解不同组件在嵌入式Linux系统中的角色,Buildroot能够生成依赖关系图。
要生成你所编译的整个系统的依赖关系图,只需运行:
make graph-depends
您将在output/graphs/graph-dependencies.pdf
中找到生成的图形。
如果您的系统相当大,依赖关系图可能过于复杂和难以阅读。因此,为给定的包生成依赖关系图是可能的:
make <pkg>-graph-depends
您将在output/graph/<pkg>-graph-depends.pdf
中找到生成的图形。
请注意,依赖关系图是使用Graphviz
项目中的点工具生成的,要使用此特性,必须在系统上安装该工具。在大多数发行版中,它可以作为graphviz包使用。
默认情况下,依赖关系图是以PDF格式生成的。但是,通过传递BR2_GRAPH_OUT
环境变量,您可以切换到其他输出格式,如PNG、PostScript或SVG。支持点工具的-T
选项所支持的所有格式。
BR2_GRAPH_OUT=svg make graph-depends
可以通过在BR2_GRAPH_DEPS_OPTS环境变量中设置选项来控制依赖于图形的行为。接受的选项有:
--depth N, -d N
, to limit the dependency depth to N levels. The default, 0, means no limit.
// 将依赖深度限制为N个级别。默认值0表示没有限制。
--stop-on PKG, -s PKG
, to stop the graph on the package PKG. PKG can be an actual package name, a glob, the keyword virtual (to stop on virtual packages), or the keyword host (to stop on host packages). The package is still present on the graph, but its dependencies are not.
// PKG可以是一个实际的包名、一个glob、关键字virtual(在虚拟包上停止)或关键字host(在主机包上停止)。包仍然显示在图中,但是它的依赖项不存在了。
--exclude PKG, -x PKG
, like --stop-on
, but also omits PKG from the graph.
// 例如--stop-on
,但是也从图中省略了PKG。
--transitive, --no-transitive
, to draw (or not) the transitive dependencies. The default is to not draw transitive dependencies.
// 绘制(或不绘制)传递依赖关系。默认是不绘制传递依赖项。
--colors R,T,H
, the comma-separated list of colors to draw the root package , the target packages (T) and the host packages (H). Defaults to: lightblue,grey,gainsboro
// 用逗号分隔的颜色列表来绘制根包,目标包(T)和主机包(H)。默认为:浅蓝色,灰色,gainsboro
BR2_GRAPH_DEPS_OPTS='-d 3 --no-transitive --colors=red,green,blue' make graph-depends
当构建一个系统需要很长时间时,有时能够了解哪些包的构建时间最长,看看是否可以做些什么来加快构建速度是很有用的。为了帮助这样的构建时间分析,Buildroot收集每个包的每个步骤的构建时间,并允许从这些数据生成图表。
要在构建后生成构建时间图,运行:
make graph-build
将会生成一系列文件在 output/graphs
中:
build.hist-build.pdf
, a histogram of the build time for each package, ordered in the build order.build.hist-duration.pdf
, a histogram of the build time for each package, ordered by duration (longest first)build.hist-name.pdf
, a histogram of the build time for each package, order by package name.build.pie-packages.pdf
, a pie chart of the build time per packagebuild.pie-steps.pdf
, a pie chart of the global time spent in each step of the packages build process.这个图形构建目标需要安装Python Matplotlib
和Numpy库
(大多数发行版上是Python-Matplotlib和Python-Numpy),如果使用的是2.7以上的Python版本(大多数发行版上是Python-argparse),还需要安装argparse
模块。
默认情况下,图形的输出格式是PDF,但是可以使用BR2_GRAPH_OUT
环境变量选择另一种格式。唯一支持的其他格式是PNG:
BR2_GRAPH_OUT=png make graph-build
当目标系统增长时,有时了解每个Buildroot包对总体根文件系统大小的贡献是有用的。为了帮助进行这样的分析,Buildroot收集了关于每个包安装的文件的数据,并使用这些数据生成一个图表和CSV文件,详细说明不同包的大小贡献。
要在构建后生成这些数据,运行:
make graph-size
将会生成:
output/graphs/graph-size.pdf
, a pie chart of the contribution of each package to the overall root filesystem sizeoutput/graphs/package-size-stats.csv
, a CSV file giving the size contribution of each package to the overall root filesystem sizeoutput/graphs/file-size-stats.csv
, a CSV file giving the size contribution of each installed file to the package it belongs, and to the overall filesystem size.这个图形大小的目标需要安装Python Matplotlib库(大多数发行版上是Python - Matplotlib),如果使用的是2.7以上的Python版本(大多数发行版上是Python -argparse),还需要安装argparse模块。
与持续时间图一样,也支持BR2_GRAPH_OUT环境变量来调整输出文件格式。关于这个环境变量的详细信息,请参见8.9节“绘制包之间的依赖关系”。
此外,还可以设置环境变量BR2_GRAPH_SIZE_OPTS来进一步控制生成的图。接受的选项是:
--size-limit X, -l X
, will group all packages which individual contribution is below X percent, to a single entry labelled Others in the graph. By default, X=0.01, which means packages each contributing less than 1% are grouped under Others. Accepted values are in the range [0.0…1.0].--iec, --binary, --si, --decimal
, to use IEC (binary, powers of 1024) or SI (decimal, powers of 1000; the default) prefixes.--biggest-first
, to sort packages in decreasing size order, rather than in increasing size order.Note. The collected filesystem size data is only meaningful after a complete clean rebuild. Be sure to run make clean all before using make graph-size.
To compare the root filesystem size of two different Buildroot compilations, for example after adjusting the configuration or when switching to another Buildroot release, use the size-stats-compare script. It takes two file-size-stats.csv files (produced by make graph-size) as input. Refer to the help text of this script for more details:
请注意。收集到的文件系统大小数据只有在完成干净重建后才有意义。确保在使用make graph-size
之前运行make clean all
。
要比较两个不同Buildroot编译的根文件系统大小,例如在调整配置后或切换到另一个Buildroot版本时,可以使用size-stats-compare
脚本。它以两个file-size-stats.csv
文件(由make graph-size
生成)作为输入。有关更多细节,请参阅此脚本的帮助文本:
utils/size-stats-compare -h
请注意。本节讨论一个非常实验性的特性,它在一些普通的情况下可以实现收支平衡。使用风险自负。
Buildroot一直能够在每个包的基础上使用并行构建:每个包都是由Buildroot使用make -jN
(或者对非基于make的构建系统的等价调用)构建的。并行级别的默认值是cpu数量+ 1,但是可以使用BR2_JLEVEL
配置选项进行调整。
然而,直到2020.02年,Buildroot还在以串行方式构建包:每个包一个接一个地构建,而没有在包之间并行构建。到2020.02年,Buildroot已经对顶级并行构建提供了实验性的支持,通过并行构建没有依赖关系的包,可以大大节省构建时间。然而,这一特性被标记为实验性的,并且已知在某些情况下不起作用。
为了使用顶层并行构建,必须:
BR2_PER_PACKAGE_DIRECTORIES
in the Buildroot configurationmake -jN
when starting the Buildroot build在内部,BR2_PER_PACKAGE_DIRECTORIES
将启用一种名为每个包目录
的机制,它将产生以下效果:
Instead of a global target directory and a global host directory common to all packages, per-package target and host directories will be used, in $(O)/per-package/<pkg>/target/
and $(O)/per-package/<pkg>/host/
respectively. Those folders will be populated from the corresponding folders of the package dependencies at the beginning of <pkg>
build. The compiler and all other tools will therefore only be able to see and access files installed by dependencies explicitly listed by <pkg>
.
// 与所有包共用的全局目标目录和全局主机目录不同,每个包的目标目录和主机目录将分别在
(
O
)
/
p
e
r
−
p
a
c
k
a
g
e
/
/
t
a
r
g
e
t
/
和
(O)/per-package//target/和
(O)/per−package//target/和(O)/per-package//host/中使用。这些文件夹将从构建开始时包依赖项的相应文件夹中填充。因此,编译器和所有其他工具只能查看和访问由显式列出的依赖项安装的文件。
At the end of the build, the global target and host directories will be populated, located in $(O)/target
and $(O)/host
respectively. This means that during the build, those folders will be empty and it’s only at the very end of the build that they will be populated.
// 在构建结束时,将填充全局目标和主机目录,分别位于
(
O
)
/
t
a
r
g
e
t
和
(O)/target和
(O)/target和(O)/host中。这意味着在构建过程中,这些文件夹将是空的,只有在构建的最后才会填充它们。
一部分嵌入式Linux开发人员喜欢经典的文本编辑器(如Vim或Emacs)和基于命令行的界面,而其他一些嵌入式Linux开发人员喜欢更丰富的图形界面来完成他们的开发工作。Eclipse是最流行的集成开发环境之一,Buildroot与Eclipse集成是为了简化Eclipse用户的开发工作。
我们与Eclipse的集成简化了构建在Buildroot系统之上的应用程序和库的编译、远程执行和远程调试。它没有将Buildroot配置和构建过程本身与Eclipse集成在一起。因此,Eclipse集成的典型使用模型是:
在https://github.com/mbats/eclipse-buildroot-bundle/wiki上详细描述了Buildroot Eclipse集成的安装过程和使用方法。
您可能希望针对您的目标编译您自己的程序或其他没有打包在Buildroot中的软件。为了做到这一点,您可以使用Buildroot生成的工具链。
Buildroot生成的工具链默认位于output/host/
。使用它最简单的方法是将output/host/bin/
添加到PATH环境变量中,然后使用ARCH-linux-gcc
, ARCH-linux-objdump
, ARCH-linux-ld
等。
另外,Buildroot也可以通过执行make SDK
命令,导出所有选定包的工具链和开发文件,作为SDK。这将生成主机目录output/host/
内容的tar文件,名为<TARGET-TUPLE>_sdk-buildroot.tar.gz
(可以通过设置环境变量BR2_SDK_PREFIX来覆盖),该文件位于输出目录output/images/
中。
然后,当应用程序开发人员希望开发尚未打包为Buildroot包的应用程序时,可以将这个tarball分发给他们。
在提取SDK压缩包后,用户必须运行脚本relocate-sdk.sh
(位于SDK的顶部目录),以确保所有路径都使用新位置更新。
或者,如果你只是想准备SDK而不生成tarball(例如,因为你将只是移动主机目录,或将生成tarball自己),Buildroot也允许你只准备SDK与make prepare-sdk
,而不实际生成tarball。
为了方便起见,通过选择BR2_PACKAGE_HOST_ENVIRONMENT_SETUP
选项,可以将environment-setup
脚本安装到output/host/
中,从而安装到SDK中。此脚本可以使用。你的/sdk/path/environment-setup
导出一些环境变量,这些变量将帮助你使用Buildroot sdk交叉编译你的项目:PATH
将包含SDK二进制文件,标准的autotools
变量将用适当的值定义,CONFIGURE_FLAGS
将包含基本的。./configure
选项来交叉编译autotools项目。它还提供了一些有用的命令。但是请注意,一旦该脚本来源于此脚本,环境就只设置为交叉编译,而不再设置为本机编译。
gdb
in BuildrootBuildroot允许进行交叉调试,调试器在构建机器上运行,并与目标上的gdbserver通信,以控制程序的执行。
为实现这一目标:
BR2_PACKAGE_HOST_GDB
, BR2_PACKAGE_GDB
and BR2_PACKAGE_GDB_SERVER
. This ensures that both the cross gdb
and gdbserver
get built, and that gdbserver gets installed to your target.BR2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY
, which will copy the gdbserver
included with the external toolchain to the target. If your external toolchain does not have a cross gdb or gdbserver, it is also possible to let Buildroot build them, by enabling the same options as for the internal toolchain backend.现在,为了开始调试一个叫做foo的程序,你应该在目标上运行:
gdbserver :2345 foo
这将导致gdbserver在TCP端口2345上监听来自交叉gdb的连接。
然后,在主机上,您应该使用以下命令行启动交叉gdb:
<buildroot>/output/host/bin/<tuple>-gdb -x <buildroot>/output/staging/usr/share/buildroot/gdbinit foo
当然,foo必须在当前目录中可用,使用调试符号构建。通常,您从构建foo的目录启动此命令(而不是从output/target/
,因为该目录中的二进制文件被剥离)。
/output/staging/usr/share/buildroot/gdbinit
文件将告诉交叉gdb在哪里可以找到目标库。
最后,从交叉gdb连接到目标:
(gdb) target remote <target ip address>:2345
ccache
in BuildrootCcache是一个编译器缓存。它存储每个编译过程产生的目标文件,并且能够通过使用预先存在的目标文件跳过将来对同一源文件(使用相同的编译器和相同的参数)的编译。当多次从头进行几乎相同的构建时,它可以很好地加快构建过程。
ccache支持集成在Buildroot中。你只需要在Build选项中启用编译器缓存。这将自动构建ccache,并在每个主机和目标编译中使用它。
缓存位于$HOME/.buildrooot-ccache
中。它存储在Buildroot输出目录之外,以便可以由单独的Buildroot构建共享。如果您想删除缓存,只需删除此目录。
您可以通过运行make ccache-stats
获取缓存的统计信息(大小、命中次数、未命中次数等)。
make目标ccache-options
和CCACHE_OPTIONS
变量提供了对缓存的更多的访问。例如
# set cache limit size // 设置缓存限制大小
make CCACHE_OPTIONS="--max-size=5G" ccache-options
# zero statistics counters // 清零统计计数器
make CCACHE_OPTIONS="--zero-stats" ccache-options
Ccache对源文件和编译器选项进行hash。如果编译器选项不同,缓存的目标文件将不会被使用。然而,许多编译器选项包含到暂存目录的绝对路径。因此,在不同的输出目录中构建会导致许多缓存丢失。
为了避免这个问题,buildroot有使用相对路径选项(BR2_CCACHE_USE_BASEDIR
)。这将把指向输出目录内的所有绝对路径重写为相对路径。因此,更改输出目录不再会导致缓存丢失。
相对路径的一个缺点是,它们最终也是对象文件中的相对路径。因此,例如,调试器将不再找到该文件,除非您首先cd到输出目录。
有关这种重写绝对路径的详细信息,请参阅ccache手册的Compiling in different directories一节。
Buildroot下载的各种tarball都存储在BR2_DL_DIR
中,默认情况下该目录是dl
目录。如果您想保留一个完整的Buildroot版本(已知它使用了相关的tarball),您可以对此目录创建一个副本。这将允许您用完全相同的版本重新生成工具链和目标文件系统。
如果您维护多个Buildroot树,那么最好使用一个共享的下载位置。这可以通过将BR2_DL_DIR
环境变量指向一个目录来实现。如果设置了此值,则会覆盖Buildroot配置中的BR2_DL_DIR
的值。以下一行应该添加到<~/.bashrc>
。
export BR2_DL_DIR=<shared download location>
还可以在.config
文件中使用BR2_DL_DIR
选项设置下载位置。与.config
文件中的大多数选项不同,这个值被BR2_DL_DIR
环境变量覆盖。
运行make <package>
会构建并安装那个特定的包及其依赖项。
对于依赖于Buildroot框架的包,有许多特殊的make目标可以像这样独立调用:
make <package>-<target>
包构建目标有(按照执行的顺序):
command/target
Description
source
Fetch the source (download the tarball, clone the source repository, etc)
depends
Build and install all dependencies required to build the package
extract
Put the source in the package build directory (extract the tarball, copy the source, etc)
patch
Apply the patches, if any
configure
Run the configure commands, if any
build
Run the compilation commands
install-staging
target package: Run the installation of the package in the staging directory, if necessary
install-target
target package: Run the installation of the package in the target directory, if necessary
install
target package: Run the 2 previous installation commands
host package: Run the installation of the package in the host directory
此外,还有其他一些有用的make目标:
command/target
Description
show-depends
Displays the first-order dependencies required to build the package
show-recursive-depends
Recursively displays the dependencies required to build the package
show-rdepends
Displays the first-order reverse dependencies of the package (i.e packages that directly depend on it)
show-recursive-rdepends
Recursively displays the reverse dependencies of the package (i.e the packages that depend on it, directly or indirectly)
graph-depends
Generate a dependency graph of the package, in the context of the current Buildroot configuration. See this section for more details about dependency graphs.
graph-rdepends
Generate a graph of this package reverse dependencies (i.e the packages that depend on it, directly or indirectly)
dirclean
Remove the whole package build directory
reinstall
Re-run the install commands
rebuild
Re-run the compilation commands - this only makes sense when using the OVERRIDE_SRCDIR feature or when you modified a file directly in the build directory
reconfigure
Re-run the configure commands, then rebuild - this only makes sense when using the OVERRIDE_SRCDIR feature or when you modified a file directly in the build directory
Buildroot的正常操作是下载一个tarball,提取它,配置,编译和安装在这个tarball中找到的软件组件。源代码在output/build/<package>-<version>
中提取,这是一个临时目录:每当使用make clean
时,这个目录将被完全删除,并在下一次调用make时重新创建。即使使用Git或Subversion存储库作为包源代码的输入,Buildroot也会从中创建一个tarball,然后像往常一样使用tarball。
当Buildroot主要用作集成工具来构建和集成嵌入式Linux系统的所有组件时,这种行为非常适合。然而,如果一个人在开发系统的某些组件时使用Buildroot,这种行为就不是很方便了:相反,人们会希望对一个包的源代码做一个小的更改,并能够用Buildroot快速地重建系统。
直接在output/build/<package>-<version>
中进行更改不是合适的解决方案,因为make clean时会删除此目录。
因此,Buildroot为这个用例提供了一个特定的机制:<pkg>_OVERRIDE_SRCDIR
机制。Buildroot读取覆盖文件,该文件允许用户告诉Buildroot某些包的源代码位置。
覆盖文件的默认位置是$(CONFIG_DIR)/local.mk
。由BR2_PACKAGE_OVERRIDE_FILE
配置选项定义。$(CONFIG_DIR)
是Buildroot .config
文件的位置,所以是本地的。local.mk
默认与.config
文件并排存在,这意味着:
top-level
Buildroot source directory for in-tree
builds (i.e., when O=
is not used)out-of-tree
directory for out-of-tree
builds (i.e., when O=
is used)out-of-tree
构建的out-of-tree
目录中(即使用O=时)如果需要不同于这些默认值的位置,可以通过BR2_PACKAGE_OVERRIDE_FILE
配置选项指定。
在这个覆盖文件中,Buildroot期望找到表单中的行:
<pkg1>_OVERRIDE_SRCDIR = /path/to/pkg1/sources
<pkg2>_OVERRIDE_SRCDIR = /path/to/pkg2/sources
例如:
LINUX_OVERRIDE_SRCDIR = /home/bob/linux/
BUSYBOX_OVERRIDE_SRCDIR = /home/bob/busybox/
当Buildroot发现对于给定的包,已经定义了<pkg>_OVERRIDE_SRCDIR
,它将不再尝试下载、解压缩和打补丁。相反,它将直接使用指定目录中可用的源代码,而make clean
将不触及此目录。这允许将Buildroot指向您自己的目录,该目录可以由Git、Subversion或任何其他版本控制系统管理。为了实现这一点,Buildroot将使用rsync将组件的源代码从指定的<pkg>_OVERRIDE_SRCDIR
复制到output/build/<package>-custom/
。
此机制最好与make <pkg>-rebuild
和make <pkg>-reconfigure
目标一起使用。make <pkg>-rebuild all
序列将把源代码从<pkg>_OVERRIDE_SRCDIR
rsync到output/build/<package>-custom
(多亏了rsync,只有修改后的文件被复制),并重新启动这个包的构建过程。
在上面的linux包的例子中,开发者可以在/home/bob/linux
中修改源代码,然后运行:
make linux-rebuild all
并在几秒钟内在output/images
中获得更新后的Linux内核映像。类似地,可以在/home/bob/busybox
和后面对BusyBox源代码进行更改:
make busybox-rebuild all
output/images
中的根文件系统映像包含更新后的BusyBox。
大型项目的源代码树通常包含数百或数千个不需要构建的文件,但会减慢用rsync复制源代码的过程。还可以定义<pkg>_OVERRIDE_SRCDIR_RSYNC_EXCLUSIONS
来跳过源树中某些文件的同步。例如,当处理webkitgtk
包时,以下内容将从本地WebKit源代码树中排除测试和树内构建:
WEBKITGTK_OVERRIDE_SRCDIR = /home/bob/WebKit
WEBKITGTK_OVERRIDE_SRCDIR_RSYNC_EXCLUSIONS = \
--exclude JSTests --exclude ManualTests --exclude PerformanceTests \
--exclude WebDriverTests --exclude WebKitBuild --exclude WebKitLibraries \
--exclude WebKit.xcworkspace --exclude Websites --exclude Examples
默认情况下,Buildroot会跳过VCS工件的同步(例如,.git和.svn目录)。有些包希望在构建过程中使用这些VCS目录,例如自动确定版本信息的精确提交引用。要以较慢的速度撤销此内置过滤,请将以下目录添加回:
LINUX_OVERRIDE_SRCDIR_RSYNC_EXCLUSIONS = --include .git
对于一个特定的项目,你可能需要执行的典型行动是:
BR2_ROOTFS_OVERLAY
)BR2_ROOTFS_POST_BUILD_SCRIPT
)BR2_ROOTFS_POST_BUILD_SCRIPT
)BR2_ROOTFS_DEVICE_TABLE
)BR2_ROOTFS_STATIC_DEVICE_TABLE
)BR2_ROOTFS_USERS_TABLES
)BR2_ROOTFS_POST_IMAGE_SCRIPT
)BR2_GLOBAL_PATCH_DIR
)关于此类project-specific
的自定义的重要说明:请仔细考虑哪些更改确实是特定于项目的,哪些更改对项目之外的开发人员也是有用的。Buildroot社区强烈推荐并鼓励对官方Buildroot项目的改进、包和板的支持。当然,有时上游是不可能或不可取的,因为变更是高度特定或专有的。
本章描述了如何在Buildroot中进行此类特定于项目的定制,以及如何以一种可以以可重复的方式构建相同映像的方式存储它们,甚至在运行make clean之后。通过遵循推荐的策略,您甚至可以使用相同的Buildroot树来构建多个不同的项目!
在为项目定制Buildroot时,您将创建一个或多个特定于项目的文件,这些文件需要存储在某个地方。虽然大多数这些文件可以放在任何位置,因为它们的路径将在Buildroot配置中指定,但Buildroot开发人员推荐了一个特定的目录结构,这将在本节中描述。
与这个目录结构正交的是,您可以选择将这个结构本身放在哪里:要么放在Buildroot树中,要么使用br2-external tree
放在它的外部。这两个选项都是有效的,选择取决于您。
+-- board/
| +-- <company>/
| +-- <boardname>/
| +-- linux.config
| +-- busybox.config
| +-- <other configuration files>
| +-- post_build.sh
| +-- post_image.sh
| +-- rootfs_overlay/
| | +-- etc/
| | +-- <some file>
| +-- patches/
| +-- foo/
| | +-- <some patch>
| +-- libbar/
| +-- <some other patches>
|
+-- configs/
| +-- <boardname>_defconfig
|
+-- package/
| +-- <company>/
| +-- Config.in (if not using a br2-external tree)
| +-- <company>.mk (if not using a br2-external tree)
| +-- package1/
| | +-- Config.in
| | +-- package1.mk
| +-- package2/
| +-- Config.in
| +-- package2.mk
|
+-- Config.in (if using a br2-external tree)
+-- external.mk (if using a br2-external tree)
+-- external.desc (if using a br2-external tree)
上述文件的细节将在本章中进一步给出。
注意:如果您选择将这个结构放在Buildroot树的外部,但放在br2-external树中,那么
<company>
和<boardname>
组件可能是多余的,可以被删除。
对于一个用户来说,有几个相关的项目部分需要相同的自定义,这是很常见的。与其为每个项目重复这些定制,不如使用分层定制方法,如本节所述。
Buildroot中几乎所有可用的定制方法,比如构建后脚本post-build scripts
和根文件系统root filesystem overlays
覆盖,都接受空格分隔的项列表。指定的项总是按从左到右的顺序处理。通过创建多个这样的项,一个用于公共定制,另一个用于真正的特定于项目的定制,您可以避免不必要的重复。每一层通常都包含在board/<company>/
内部的一个单独目录中。根据项目的不同,您甚至可以引入两个以上的层。
一个用户有两个自定义层common
和fooboard
的目录结构示例是:
+-- board/
+-- <company>/
+-- common/
| +-- post_build.sh
| +-- rootfs_overlay/
| | +-- ...
| +-- patches/
| +-- ...
|
+-- fooboard/
+-- linux.config
+-- busybox.config
+-- <other configuration files>
+-- post_build.sh
+-- rootfs_overlay/
| +-- ...
+-- patches/
+-- ...
例如,如果用户将BR2_GLOBAL_PATCH_DIR
配置选项设置为:
BR2_GLOBAL_PATCH_DIR="board/<company>/common/patches board/<company>/fooboard/patches"
然后首先应用普通层的补丁,然后应用底层的补丁。
正如9.1节“推荐的目录结构”中已经简要提到的,您可以将特定于项目的自定义放置在两个位置:
通过将BR2_EXTERNAL
make变量设置为要使用的br2-external树的路径,可以告诉Buildroot使用一个或多个br2-external树。它可以传递给任何Buildroot make调用。它自动保存在输出目录中隐藏的.br2-external.mk
的文件。因此,无需在每次make调用时传递BR2_EXTERNAL。但是,它可以在任何时候通过传递一个新值来更改,也可以通过传递一个空值来删除。
请注意。到br2-external树的路径可以是绝对路径,也可以是相对路径。如果它是作为相对路径传递的,那么一定要注意,它是相对于Buildroot主源目录而不是Buildroot输出目录来解释的。
注意:如果在Buildroot 2016.11之前使用br2-external树,你需要先转换它,然后才能在Buildroot 2016.11之后使用它。请参阅第27.1节,“迁移到2016年11月”,以获得相关帮助。
一些例子:
buildroot/ $ make BR2_EXTERNAL=/path/to/foo menuconfig
From now on, definitions from the /path/to/foo br2-external tree will be used:
buildroot/ $ make
buildroot/ $ make legal-info
We can switch to another br2-external tree at any time:
buildroot/ $ make BR2_EXTERNAL=/where/we/have/bar xconfig
We can also use multiple br2-external trees:
buildroot/ $ make BR2_EXTERNAL=/path/to/foo:/where/we/have/bar menuconfig
Or disable the usage of any br2-external tree:
buildroot/ $ make BR2_EXTERNAL= xconfig
一个br2-external树必须包含至少这三个文件,在以下章节中描述:
除了这些强制文件之外,br2-external树中还可能存在其他可选内容,比如configs/
或provides/
目录。它们也将在下面的章节中进行描述。
后面还将描述一个完整的示例br2-external树布局。
The external.desc
file
这个文件描述了 br2-external tree: the name
and description
for that br2-external tree.
该文件的格式是逐行的,每行以一个关键字开头,后面跟着一个冒号和一个或多个空格,然后是分配给该关键字的值。目前识别的关键字有两个:
name
, mandatory, defines the name for that br2-external tree. That name must only use ASCII characters in the set [A-Za-z0-9_]; any other character is forbidden. Buildroot sets the variable BR2_EXTERNAL_$(NAME)_PATH to the absolute path of the br2-external tree, so that you can use it to refer to your br2-external tree. This variable is available both in Kconfig, so you can use it to source your Kconfig files (see below) and in the Makefile, so that you can use it to include other Makefiles (see below) or refer to other files (like data files) from your br2-external tree.
// Name(强制)定义了br2-external树的名称。该名称在集合[A-Za-z0-9_]中只能使用ASCII字符;禁止使用其他任何字符。Buildroot将变量BR2_EXTERNAL_$(NAME)_PATH
设置为br2-external树的绝对路径,这样您就可以使用它来引用br2-external树。这个变量在Kconfig中可用,因此您可以使用它来生成Kconfig文件(见下文)和Makefile,这样您就可以使用它来包含其他Makefile(见下文)或引用br2-external树中的其他文件(如数据文件)。
Note: Since it is possible to use multiple br2-external trees at once, this name is used by Buildroot to generate variables for each of those trees. That name is used to identify your br2-external tree, so try to come up with a name that really describes your br2-external tree, in order for it to be relatively unique, so that it does not clash with another name from another br2-external tree, especially if you are planning on somehow sharing your br2-external tree with third parties or using br2-external trees from third parties.
// 注意:因为可以一次使用多个br2-external树,所以这个名称被Buildroot用来为每个树生成变量。这个名字是用来识别你的br2-外部树的,所以试着想出一个真正描述你的br2-外部树的名字,为了让它相对独特,这样它就不会和另一个来自另一个br2-外部树的名字冲突,特别是当您计划以某种方式与第三方共享您的br2-external树或使用来自第三方的br2-external树时。
desc
, optional, provides a short description for that br2-external tree. It shall fit on a single line, is mostly free-form (see below), and is used when displaying information about a br2-external tree (e.g. above the list of defconfig files, or as the prompt in the menuconfig); as such, it should relatively brief (40 chars is probably a good upper limit). The description is available in the BR2_EXTERNAL_$(NAME)_DESC variable.
// Desc(可选)提供了br2-external树的简短描述。它应该适合一行,大部分是自由形式的(见下文),用于显示关于br2-external树的信息(例如,在defconfig文件列表上面,或作为menuconfig中的提示符);因此,它应该相对简短(40字符可能是一个很好的上限)。该描述可在BR2_EXTERNAL_$(NAME)_DESC
变量中获得。
名称示例和相应的BR2_EXTERNAL_$(NAME)_PATH
变量:
FOO
→ BR2_EXTERNAL_FOO_PATH
BAR_42
→ BR2_EXTERNAL_BAR_42_PATH
在下面的例子中,假定名称设置为BAR_42
。
注意:
BR2_EXTERNAL_$(NAME)_PATH
和BR2_EXTERNAL_$(NAME)_DESC
都在Kconfig文件和makefile中可用。它们也被导出到环境中,因此可以在构建后、生成映像后和伪造后脚本中使用。
The Config.in
and external.mk
files
这些文件(可能每个都是空的)可以用来定义包配方(例如foo/Config.in
和foo/foo.mk
就像Buildroot本身的包)。在和foo / foo。或者其他自定义配置选项或make逻辑。
构建根自动从每个br2-external树中包含Config.in
使其显示在顶级配置菜单中,并包含external.mk
从每个br2-external树和其余的makefile逻辑。
它的主要用途是存储package recipes
。推荐的方法是编写一个Config.in
像这样:
source "$BR2_EXTERNAL_BAR_42_PATH/package/package1/Config.in"
source "$BR2_EXTERNAL_BAR_42_PATH/package/package2/Config.in"
然后,有一个external.mk
文件看起来像这样:
include $(sort $(wildcard $(BR2_EXTERNAL_BAR_42_PATH)/package/*/*.mk))
然后在$(BR2_EXTERNAL_BAR_42_PATH)/package/package1
和$(BR2_EXTERNAL_BAR_42_PATH)/package/package2
中创建普通的Buildroot包配方,如第18章,添加新包到Buildroot。如果您愿意,还可以将包分组到名为的子目录中,并相应地调整上述路径。
您还可以在Config.in
定义自定义配置选项。在external.mk
自定义make逻辑。
The configs/
directory
可以将Buildroot defconfigs存储在br2-external树的configs子目录中。Buildroot会自动在make list-defconfigs
的输出中显示它们,并允许使用普通的make <name>_defconfig
命令加载它们。它们将在make list-defconfigs
输出中可见,位于External configs
标签下面,该标签包含定义它们的br2-external树的名称。
注意:如果一个defconfig文件存在于多个br2-external树中,那么将使用最后一个br2-external树中的那个。因此,可以覆盖Buildroot或另一个br2-external树中绑定的defconfig。
The provides/
directory
对于某些包,Buildroot提供了两个(或更多)api兼容包的实现。例如,可以选择libjpeg
或jpeg-turbo
;openssl
和libressl
之间有一个;有一个选择一个已知的,预先配置的工具链…
br2-external可以通过提供一组定义这些替代方案的文件来扩展这些选择:
provides/toolchains.in
defines the pre-configured toolchains, which will then be listed in the toolchain selection;provides/jpeg.in
defines the alternative libjpeg implementations;provides/openssl.in
defines the alternative openssl implementations;provides/skeleton.in
defines the alternative skeleton implementations;provides/init.in
defines the alternative init system implementations, this can be used to select a default skeleton for your init.Free-form content
可以将所有特定于板的配置文件存储在那里,比如内核配置、根文件系统覆盖层,或者任何其他Buildroot允许设置位置的配置文件(通过使用BR2_EXTERNAL_$(NAME)_PATH
变量)。例如,你可以将路径设置为一个全局补丁目录,一个rootfs覆盖和内核配置文件,如下所示(例如,通过运行make menuconfig
并填写这些选项):
BR2_GLOBAL_PATCH_DIR=$(BR2_EXTERNAL_BAR_42_PATH)/patches/
BR2_ROOTFS_OVERLAY=$(BR2_EXTERNAL_BAR_42_PATH)/board/<boardname>/overlay/
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE=$(BR2_EXTERNAL_BAR_42_PATH)/board/<boardname>/kernel.config
Additional Linux kernel extensions
额外的Linux内核扩展(请参见18.21.2节,“Linux -kernel-extensions”)可以通过将它们存储在br2-external树的根Linux/
目录中来添加。
Example layout
下面是一个使用br2-external所有特性的示例布局(示例内容显示在上面的文件中,当它与解释br2-external树相关时;当然,这完全是为了说明而编造的):
/path/to/br2-ext-tree/
|- external.desc
| |name: BAR_42
| |desc: Example br2-external tree
| `----
|
|- Config.in
| |source "$BR2_EXTERNAL_BAR_42_PATH/toolchain/toolchain-external-mine/Config.in.options"
| |source "$BR2_EXTERNAL_BAR_42_PATH/package/pkg-1/Config.in"
| |source "$BR2_EXTERNAL_BAR_42_PATH/package/pkg-2/Config.in"
| |source "$BR2_EXTERNAL_BAR_42_PATH/package/my-jpeg/Config.in"
| |
| |config BAR_42_FLASH_ADDR
| | hex "my-board flash address"
| | default 0x10AD
| `----
|
|- external.mk
| |include $(sort $(wildcard $(BR2_EXTERNAL_BAR_42_PATH)/package/*/*.mk))
| |include $(sort $(wildcard $(BR2_EXTERNAL_BAR_42_PATH)/toolchain/*/*.mk))
| |
| |flash-my-board:
| | $(BR2_EXTERNAL_BAR_42_PATH)/board/my-board/flash-image \
| | --image $(BINARIES_DIR)/image.bin \
| | --address $(BAR_42_FLASH_ADDR)
| `----
|
|- package/pkg-1/Config.in
| |config BR2_PACKAGE_PKG_1
| | bool "pkg-1"
| | help
| | Some help about pkg-1
| `----
|- package/pkg-1/pkg-1.hash
|- package/pkg-1/pkg-1.mk
| |PKG_1_VERSION = 1.2.3
| |PKG_1_SITE = /some/where/to/get/pkg-1
| |PKG_1_LICENSE = blabla
| |
| |define PKG_1_INSTALL_INIT_SYSV
| | $(INSTALL) -D -m 0755 $(PKG_1_PKGDIR)/S99my-daemon \
| | $(TARGET_DIR)/etc/init.d/S99my-daemon
| |endef
| |
| |$(eval $(autotools-package))
| `----
|- package/pkg-1/S99my-daemon
|
|- package/pkg-2/Config.in
|- package/pkg-2/pkg-2.hash
|- package/pkg-2/pkg-2.mk
|
|- provides/jpeg.in
| |config BR2_PACKAGE_MY_JPEG
| | bool "my-jpeg"
| `----
|- package/my-jpeg/Config.in
| |config BR2_PACKAGE_PROVIDES_JPEG
| | default "my-jpeg" if BR2_PACKAGE_MY_JPEG
| `----
|- package/my-jpeg/my-jpeg.mk
| |# This is a normal package .mk file
| |MY_JPEG_VERSION = 1.2.3
| |MY_JPEG_SITE = https://example.net/some/place
| |MY_JPEG_PROVIDES = jpeg
| |$(eval $(autotools-package))
| `----
|
|- provides/init.in
| |config BR2_INIT_MINE
| | bool "my custom init"
| | select BR2_PACKAGE_MY_INIT
| | select BR2_PACKAGE_SKELETON_INIT_MINE if BR2_ROOTFS_SKELETON_DEFAULT
| `----
|
|- provides/skeleton.in
| |config BR2_ROOTFS_SKELETON_MINE
| | bool "my custom skeleton"
| | select BR2_PACKAGE_SKELETON_MINE
| `----
|- package/skeleton-mine/Config.in
| |config BR2_PACKAGE_SKELETON_MINE
| | bool
| | select BR2_PACKAGE_HAS_SKELETON
| |
| |config BR2_PACKAGE_PROVIDES_SKELETON
| | default "skeleton-mine" if BR2_PACKAGE_SKELETON_MINE
| `----
|- package/skeleton-mine/skeleton-mine.mk
| |SKELETON_MINE_ADD_TOOLCHAIN_DEPENDENCY = NO
| |SKELETON_MINE_ADD_SKELETON_DEPENDENCY = NO
| |SKELETON_MINE_PROVIDES = skeleton
| |SKELETON_MINE_INSTALL_STAGING = YES
| |$(eval $(generic-package))
| `----
|
|- provides/toolchains.in
| |config BR2_TOOLCHAIN_EXTERNAL_MINE
| | bool "my custom toolchain"
| | depends on BR2_some_arch
| | select BR2_INSTALL_LIBSTDCPP
| `----
|- toolchain/toolchain-external-mine/Config.in.options
| |if BR2_TOOLCHAIN_EXTERNAL_MINE
| |config BR2_TOOLCHAIN_EXTERNAL_PREFIX
| | default "arch-mine-linux-gnu"
| |config BR2_PACKAGE_PROVIDES_TOOLCHAIN_EXTERNAL
| | default "toolchain-external-mine"
| |endif
| `----
|- toolchain/toolchain-external-mine/toolchain-external-mine.mk
| |TOOLCHAIN_EXTERNAL_MINE_SITE = https://example.net/some/place
| |TOOLCHAIN_EXTERNAL_MINE_SOURCE = my-toolchain.tar.gz
| |$(eval $(toolchain-external-package))
| `----
|
|- linux/Config.ext.in
| |config BR2_LINUX_KERNEL_EXT_EXAMPLE_DRIVER
| | bool "example-external-driver"
| | help
| | Example external driver
| |---
|- linux/linux-ext-example-driver.mk
|
|- configs/my-board_defconfig
| |BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_BAR_42_PATH)/patches/"
| |BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_BAR_42_PATH)/board/my-board/overlay/"
| |BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_BAR_42_PATH)/board/my-board/post-image.sh"
| |BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_BAR_42_PATH)/board/my-board/kernel.config"
| `----
|
|- patches/linux/0001-some-change.patch
|- patches/linux/0002-some-other-change.patch
|- patches/busybox/0001-fix-something.patch
|
|- board/my-board/kernel.config
|- board/my-board/overlay/var/www/index.html
|- board/my-board/overlay/var/www/my.css
|- board/my-board/flash-image
`- board/my-board/post-image.sh
|#!/bin/sh
|generate-my-binary-image \
| --root ${BINARIES_DIR}/rootfs.tar \
| --kernel ${BINARIES_DIR}/zImage \
| --dtb ${BINARIES_DIR}/my-board.dtb \
| --output ${BINARIES_DIR}/image.bin
`----
br2-external树将在menuconfig中可见(布局展开):
External options --->
*** Example br2-external tree (in /path/to/br2-ext-tree/)
[ ] pkg-1
[ ] pkg-2
(0x10AD) my-board flash address
如果你使用了多个br2-external树,它看起来应该是这样的(布局展开,第二个名字为FOO_27
,但在external.desc中没有desc:字段):
External options --->
Example br2-external tree --->
*** Example br2-external tree (in /path/to/br2-ext-tree)
[ ] pkg-1
[ ] pkg-2
(0x10AD) my-board flash address
FOO_27 --->
*** FOO_27 (in /path/to/another-br2-ext)
[ ] foo
[ ] bar
此外,jpeg提供程序将在jpeg选项中可见:
Target packages --->
Libraries --->
Graphics --->
[*] jpeg support
jpeg variant () --->
( ) jpeg
( ) jpeg-turbo
*** jpeg from: Example br2-external tree ***
(X) my-jpeg
*** jpeg from: FOO_27 ***
( ) another-jpeg
工具链也类似:
Toolchain --->
Toolchain () --->
( ) Custom toolchain
*** Toolchains from: Example br2-external tree ***
(X) my custom toolchain
请注意。工具链选项toolchain/toolchain-external-mine/Config.in.options
将不会出现在工具链菜单中。它们必须显式地包含在br2-external的顶级Config.in
和将因此出现在External options
菜单中。
可以使用make savedefconfig
命令存储Buildroot配置。
这将通过删除默认值的配置选项来删除Buildroot配置。结果存储在一个名为defconfig
的文件中。如果你想把它保存在另一个地方,请更改Buildroot配置本身的BR2_DEFCONFIG
选项,或者使用make savedefconfig BR2_DEFCONFIG=<path-to-defconfig>
调用make。
这个defconfig的推荐存储位置是configs/<boardname>_defconfig
。如果您遵循此建议,该配置将在make help
中列出,并且可以通过运行make <boardname>_defconfig
再次设置。
或者,您可以将文件复制到任何其他地方,并使用make defconfig BR2_DEFCONFIG=<path-to-defconfig-file>
重新构建。
BusyBox、Linux内核、Barebox、U-Boot和uClibc的配置文件如有更改,也应保存。对于每一个组件,都有一个Buildroot配置选项指向一个输入配置文件,例如BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
。要存储它们的配置,请将这些配置选项设置为您希望保存配置文件的路径,然后使用下面描述的帮助器目标来实际存储配置。
如9.1节“推荐的目录结构”所述,这些配置文件的推荐存储路径为board/<company>/<boardname>/foo.config
。
确保在更改BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
等选项之前创建了一个配置文件。否则,Buildroot将尝试访问这个配置文件,它还不存在,并将失败。您可以通过运行make linux-menuconfig
等来创建配置文件。
Buildroot提供了一些帮助器目标,以简化配置文件的保存。
make linux-update-defconfig
saves the linux configuration to the path specified by BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
. It simplifies the config file by removing default values. However, this only works with kernels starting from 2.6.33. For earlier kernels, use make linux-update-config
.make busybox-update-config
saves the busybox configuration to the path specified by BR2_PACKAGE_BUSYBOX_CONFIG
.make uclibc-update-config
saves the uClibc configuration to the path specified by BR2_UCLIBC_CONFIG
.make barebox-update-defconfig
saves the barebox configuration to the path specified by BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE
.make uboot-update-defconfig
saves the U-Boot configuration to the path specified by BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE
.BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_CONFIG_FILE
.除了通过make *config
改变配置之外,还有一些其他的方法来定制最终的目标文件系统。
两种推荐的方法可以共存,即根文件系统覆盖root filesystem overlay
和后构建脚本post build script
。
Root filesystem overlays (BR2_ROOTFS_OVERLAY
)
文件系统覆盖层是在构建目标文件系统之后直接复制的文件树。要启用此特性,请将配置选项BR2_ROOTFS_OVERLAY
(在System configuration
菜单中)设置为覆盖的根。您甚至可以指定多个以空格分隔的叠加。如果你指定一个相对路径,它将是相对于Buildroot树的根。版本控制系统的隐藏目录,如.git、.svn、.hg等,名为.empty的文件和以~结尾的文件都将被排除在副本之外。
当BR2_ROOTFS_MERGED_USR
被启用时,覆盖层必须不包含/bin
、/lib
或/sbin
目录,因为Buildroot将把它们创建为指向/usr
中相关文件夹的符号链接。在这种情况下,如果覆盖层有任何程序或库,它们应该放在/usr/bin
, /usr/sbin
和/usr/lib
.
如9.1节“推荐的目录结构”所示,此覆盖的推荐路径为board/<company>/<boardname>/rootfs-overlay
。
Post-build scripts (BR2_ROOTFS_POST_BUILD_SCRIPT
)
构建后脚本是在Buildroot构建所有选择的软件之后,但在组装rootfs映像之前调用的shell脚本。要启用此特性,请在配置选项BR2_ROOTFS_POST_BUILD_SCRIPT
(在System configuration
菜单中)中指定一个空格分隔的构建后脚本列表。如果你指定一个相对路径,它将是相对于Buildroot树的根。
使用构建后脚本,您可以删除或修改目标文件系统中的任何文件。但是,您应该小心地使用该特性。每当您发现某个包生成错误或不需要的文件时,您应该修复该包,而不是使用一些构建后清理脚本来处理它。
如9.1节“推荐的目录结构”所示,该脚本推荐的路径为board/<company>/<boardname>/post_build.sh
。
构建后脚本将以主Buildroot树作为当前工作目录运行。目标文件系统的路径作为每个脚本的第一个参数传递。如果配置选项BR2_ROOTFS_POST_SCRIPT_ARGS
不是空的,这些参数也将被传递到脚本。所有的脚本都将被传递完全相同的参数集,不可能给每个脚本传递不同的参数集。
此外,你也可以使用这些环境变量:
BR2_CONFIG
: the path to the Buildroot .config
fileCONFIG_DIR
: the directory containing the .config
file, and therefore the top-level Buildroot Makefile to use (which is correct for both in-tree and out-of-tree builds)HOST_DIR
, STAGING_DIR
, TARGET_DIR
: see Section 18.5.2, “generic-package reference”BUILD_DIR
: the directory where packages are extracted and builtBINARIES_DIR
: the place where all binary files (aka images) are storedBASE_DIR
: the base output directory下面将介绍另外三种自定义目标文件系统的方法,但不推荐使用。
Direct modification of the target filesystem
对于临时修改,您可以直接修改目标文件系统并重新构建映像。目标文件系统在output/target/
下可用。完成更改后,运行make重新构建目标文件系统映像。
这个方法允许您对目标文件系统做任何操作,但是如果您需要使用make clean
来清除Buildroot树,那么这些更改将会丢失。这种清理在一些情况下是必要的,请参阅第8.2节“了解什么时候需要完全重新构建”以了解细节。因此,此解决方案只适用于快速测试:更改无法通过make clean命令保存。一旦您验证了您的更改,您应该确保它们将在make clean之后持久存在,使用根文件系统覆盖或构建后脚本。
Custom target skeleton (BR2_ROOTFS_SKELETON_CUSTOM
)
根文件系统映像是从目标框架skeleton
创建的,所有包都在目标框架之上安装它们的文件。在构建和安装任何包之前,将框架复制到目标目录output/target
。默认的目标框架提供了标准的Unix文件系统布局和一些基本的初始化脚本和配置文件。
如果默认框架(在system/skeleton
下可用)不符合您的需求,您通常会使用根文件系统覆盖或构建后脚本对其进行调整。但是,如果默认框架与您所需要的完全不同,那么使用自定义框架可能更合适。
要启用此功能,请启用配置选项BR2_ROOTFS_SKELETON_CUSTOM
,并将BR2_ROOTFS_SKELETON_CUSTOM_PATH
设置为自定义骨架的路径。这两个选项都可以在System configuration
菜单中使用。如果你指定一个相对路径,它将是相对于Buildroot树的根。
自定义框架不需要包含/bin
、/lib
或/sbin
目录,因为它们是在构建过程中自动创建的。当启用BR2_ROOTFS_MERGED_USR
时,自定义框架必须不包含/bin、/lib或/sbin目录,因为Buildroot将把它们创建为指向/usr中相关文件夹的符号链接。在这种情况下,如果框架有任何程序或库,它们应该放在/usr/bin、/usr/sbin和/usr/lib.
不建议使用此方法,因为它复制了整个框架,这妨碍了利用在以后的Buildroot版本中对默认框架进行的修复或改进。
Post-fakeroot scripts (BR2_ROOTFS_POST_FAKEROOT_SCRIPT
)
当聚合最终的映像时,这个过程的某些部分需要根权限:在/dev
中创建设备节点,设置文件和目录的权限或所有权……这并不能完全替代实际的root,但已经足够满足Buildroot的需求了。
fakeroot后脚本是在fakeroot阶段结束时,即在调用文件系统映像生成器之前调用的shell脚本。因此,它们被称为在fakeroot上下文中。
当您需要调整文件系统以进行通常只对根用户可用的修改时,Post-fakeroot脚本可能非常有用。
注意:建议使用现有的机制来设置文件权限或在/dev中创建条目(见9.5.1节,“设置文件权限和所有权并添加自定义设备节点”)或创建用户(见9.6节,“添加自定义用户帐户”)
注意:后构建脚本(上面提到的)和fakeroot脚本之间的区别在于,后构建脚本不会在fakeroot上下文中被调用。
注意:使用fakeroot并不能完全替代实际的root。Fakeroot只会伪造文件访问权限和类型(常规,块或char设备…)和uid/gid;这些是在内存中模拟的。
有时需要在文件或设备节点上设置特定的权限或所有权。例如,某些文件可能需要root用户拥有。由于构建后脚本不是作为root运行的,因此您不能从那里进行此类更改,除非从构建后脚本中使用显式的fakeroot。
相反,Buildroot提供了对所谓权限表permission tables
的支持。要使用此特性,请将配置选项BR2_ROOTFS_DEVICE_TABLE
设置为以空格分隔的权限表列表,即遵循makedev语法的常规文本文件。
如果你正在使用一个静态设备表(即不使用devtmpfs, mdev,或(e)udev),那么你可以使用相同的语法添加设备节点,在所谓的设备表device tables
。要使用此特性,请将配置选项BR2_ROOTFS_STATIC_DEVICE_TABLE
设置为用空格分隔的设备表列表。
如9.1节“推荐的目录结构”所示,这些文件的推荐位置是board/<company>/<boardname>/
。
需要注意的是,如果特定的权限或设备节点与特定的应用程序相关,你应该在包的.mk文件中设置变量FOO_PERMISSIONS
和FOO_DEVICES
(参见18.5.2节,“通用包引用”)。
有时需要在目标系统中添加特定的用户。为了满足这一需求,Buildroot提供了对所谓用户表users tables
的支持。要使用此特性,请将配置选项BR2_ROOTFS_USERS_TABLES
设置为一个空格分隔的用户表列表,即遵循makeusers语法的常规文本文件。
如9.1节“推荐的目录结构”所示,这些文件的推荐位置是board/<company>/<boardname>/
。
需要注意的是,如果自定义用户与特定的应用程序相关,你应该在包的.mk文件中设置变量FOO_USERS
(参见18.5.2节,“通用包引用”)。
当构建后脚本post-build scripts
(第9.5节,“自定义生成的目标文件系统”)在构建文件系统映像、内核和引导加载程序之前运行时,可以使用后映像脚本post-image scripts
在创建所有映像之后执行一些特定的操作。
例如,可以使用后映像脚本post-image scripts
在NFS服务器导出的位置中自动提取根文件系统tarball,或者创建一个将根文件系统和内核映像绑定在一起的特殊固件映像,或者您的项目所需的任何其他自定义操作。
要启用这个特性,在配置选项BR2_ROOTFS_POST_IMAGE_SCRIPT
中指定一个空格分隔的后映像脚本列表(在System configuration
菜单中)。如果你指定一个相对路径,它将是相对于Buildroot树的根。
就像编译后脚本一样,编译后图像脚本运行时将主要Buildroot树作为当前工作目录。图像输出目录的路径作为每个脚本的第一个参数传递。如果配置选项BR2_ROOTFS_POST_SCRIPT_ARGS
不是空的,这些参数也将被传递到脚本。所有的脚本都将被传递完全相同的参数集,不可能给每个脚本传递不同的参数集。
同样,与构建后脚本一样,脚本可以访问环境变量BR2_CONFIG
、HOST_DIR
、STAGING_DIR
、TARGET_DIR
、BUILD_DIR
、BINARIES_DIR
、CONFIG_DIR
和BASE_DIR
。
后映像脚本将以执行Buildroot同样的用户的身份执行,该用户通常不应该是根用户。因此,这些脚本中任何需要root权限的操作都需要特殊处理(fakeroot或sudo的使用),这就交给脚本开发人员了。
在Buildroot中提供的包的基础上应用额外的补丁有时是有用的。例如,这可能用于支持项目中的自定义特性,或者在处理新体系结构时。
BR2_GLOBAL_PATCH_DIR
配置选项可用于指定一个空格分隔的包含包补丁的一个或多个目录列表。
对于特定包<packagename>
的特定版本<packageversion>
,补丁从BR2_GLOBAL_PATCH_DIR
应用,如下所示:
对于BR2_GLOBAL_PATCH_DIR
中存在的每个目录 <global-patch-dir>
,<package-patch-dir>
将确定,如下所示:
<global-patch-dir>/<packagename>/<packageversion>/
if the directory exists.<global-patch-dir>/<packagename>
if the directory exists.然后补丁将会从<package-patch-dir>
应用,如下所示:
series
文件,则根据series
文件应用补丁;*.patch
的补丁文件。补丁按字母顺序应用。因此,为了确保它们按照正确的顺序应用,强烈建议将补丁文件命名为:<number>-<description>.patch
,其中<number>
表示应用顺序。有关如何为一个包应用补丁的信息,请参见第19.2节“如何应用补丁”。
BR2_GLOBAL_PATCH_DIR
选项是为包指定自定义补丁目录的首选方法。它可以用于为buildroot中的任何包指定补丁目录。它也应该用来代替U-Boot和Barebox等软件包可用的自定义补丁目录选项。通过这样做,它将允许用户从一个顶级目录管理他们的补丁。
BR2_GLOBAL_PATCH_DIR作为指定自定义补丁的首选方法的例外情况是
BR2_LINUX_KERNEL_PATCH。BR2_LINUX_KERNEL_PATCH
应该用于指定在URL中可用的内核补丁。注意:BR2_LINUX_KERNEL_PATCH
指定了在BR2_GLOBAL_PATCH_DIR
中可用的补丁之后应用的内核补丁,因为它是从Linux包的补丁后钩子post-patch hook
执行的。
一般来说,任何新包都应该直接添加到包目录中,并提交给Buildroot上游项目。在第18章“向Buildroot添加新包”中详细介绍了如何向Buildroot添加包,这里不再重复。但是,您的项目可能需要一些不能上行的专有包。本节将解释如何将这些特定于项目的包保存在特定于项目的目录中。
如9.1节“推荐的目录结构”所示,项目特定包的推荐位置是package/<company>/
。如果你正在使用br2-external树特性(参见9.2节,“保持自定义在Buildroot之外”),推荐的位置是将它们放在br2-external树的名为package/
的子目录中。
但是,除非我们执行一些额外的步骤,否则Buildroot不会知道这个位置中的包。正如第18章“向Buildroot添加新包”中所解释的,Buildroot中的包基本上由两个文件组成:一个.mk
文件(描述如何构建包)和一个Config.in
文件(描述此包的配置选项)。
Buildroot会自动将.mk
文件包含在package
目录的一级子目录中(使用模式package/*/*.mk
)。如果我们想让Buildroot包含更深层次的子目录(比如package/<company>/package1
)中的.mk
文件,那么我们只需在包含这些额外的.mk
文件的第一级子目录中添加一个.mk
文件。因此,创建一个文件package/<company>/<company>.mk
以下内容(假设你在package/<company>/
下面只有一个额外的目录级别):
include $(sort $(wildcard package/<company>/*/*.mk))
For the Config.in files, create a file package//Config.in that includes the Config.in files of all your packages. An exhaustive list has to be provided since wildcards are not supported in the source command of kconfig. For example:
对于Config.in
文件,创建一个文件package/<company>/Config.in
其中包括你所有软件包的文件里Config.in
。必须提供详尽的列表,因为在kconfig的源命令中不支持通配符。例如:
source "package/<company>/package1/Config.in"
source "package/<company>/package2/Config.in"
包括这个新的文件package/<company>/Config.in
从package/Config.in
。最好是在特定于公司的菜单中,以便与未来的Buildroot版本更容易合并。
如果使用br2-external树,请参考9.2节“保持自定义在Buildroot之外”,了解如何填写这些文件。
在本章的前面,已经描述了用于进行特定于项目的定制的不同方法。本节将通过提供存储特定于项目的自定义的逐步说明来总结所有这些内容。显然,可以跳过与项目无关的步骤。
make menuconfig
to configure toolchain, packages and kernel.make linux-menuconfig
to update the kernel config, similar for other configuration like busybox, uclibc, …mkdir -p board/<manufacturer>/<boardname>
board/<manufacturer>/<boardname>/<package>.config
(as far as they are relevant):BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE
BR2_PACKAGE_BUSYBOX_CONFIG
BR2_UCLIBC_CONFIG
BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_CONFIG_FILE
BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE
BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE
make linux-update-defconfig
make busybox-update-config
make uclibc-update-config
cp <output>/build/at91bootstrap3-*/.config board/<manufacturer>/<boardname>/at91bootstrap3.config
make barebox-update-defconfig
make uboot-update-defconfig
board/<manufacturer>/<boardname>/rootfs-overlay/
and fill it with additional files you need on your rootfs, e.g. board/<manufacturer>/<boardname>/rootfs-overlay/etc/inittab
. Set BR2_ROOTFS_OVERLAY
to board/<manufacturer>/<boardname>/rootfs-overlay
.board/<manufacturer>/<boardname>/post_build.sh
. Set BR2_ROOTFS_POST_BUILD_SCRIPT
to board/<manufacturer>/<boardname>/post_build.sh
board/<manufacturer>/<boardname>/device_table.txt
and add that path to BR2_ROOTFS_DEVICE_TABLE
.board/<manufacturer>/<boardname>/users_table.txt
and add that path to BR2_ROOTFS_USERS_TABLES
.BR2_GLOBAL_PATCH_DIR
to board/<manufacturer>/<boardname>/patches/
and add your patches for each package in a subdirectory named after the package. Each patch should be called <packagename>-<num>-<description>.patch
.BR2_LINUX_KERNEL_PATCH
with as main advantage that it can also download patches from a URL. If you do not need this, BR2_GLOBAL_PATCH_DIR
is preferred. U-Boot, Barebox, at91bootstrap and at91bootstrap3 also have separate options, but these do not provide any advantage over BR2_GLOBAL_PATCH_DIR
and will likely be removed in the future.package/<manufacturer>/
and place your packages in that directory. Create an overall <manufacturer>.mk
file that includes the .mk
files of all your packages. Create an overall Config.in
file that sources the Config.in
files of all your packages. Include this Config.in
file from Buildroot’s package/Config.in
file.make savedefconfig
to save the buildroot configuration.cp defconfig configs/<boardname>_defconfig
SELinux是一个执行访问控制策略的Linux内核安全模块。除了传统的文件权限和访问控制列表之外,SELinux还允许为用户或进程编写访问资源(文件、套接字……)的特定功能的规则。
SELinux有三种操作模式:
在Buildroot中,操作模式由BR2_PACKAGE_REFPOLICY_POLICY_STATE_*
配置选项控制。Linux内核还有各种配置选项,这些选项会影响如何启用SELinux(请参阅Linux内核源代码中的security/ ELinux/Kconfig
)。
默认情况下,在Buildroot中,SELinux策略是由上游refpolicy项目提供的,由BR2_PACKAGE_REFPOLICY
启用。
要在Buildroot生成的系统中正确支持SELinux,必须启用以下配置选项:
BR2_PACKAGE_LIBSELINUX
BR2_PACKAGE_REFPOLICY
此外,文件系统映像格式必须支持扩展属性。
SELinux repolicy包含可以在构建时启用或禁用的模块。每个模块都提供了许多SELinux规则。在Buildroot中,默认情况下非基本模块是禁用的,提供了几种启用这些模块的方法:
SELinux
modules within the refpolicy using the <packagename>_SELINUX_MODULES
variable.<packagename>_SELINUX_MODULES
变量在refpolicy中启用SELinux模块列表。SELinux
modules by putting them (.fc, .if and .te files) in package/<packagename>/selinux/
.package/<packagename>/selinux/
SELinux
modules can be added in directories pointed by the BR2_REFPOLICY_EXTRA_MODULES_DIRS
configuration option.BR2_REFPOLICY_EXTRA_MODULES_DIRS
配置选项所指向的目录中。refpolicy
can be enabled if listed in the BR2_REFPOLICY_EXTRA_MODULES_DEPENDENCIES
configuration option.BR2_REFPOLICY_EXTRA_MODULES_DEPENDENCIES
配置选项中列出,则可以启用repolicy中的其他模块。Buildroot还允许完全覆盖repolicy。这允许提供专门为给定系统设计的完整自定义策略。当采用这种方式时,上述所有机制都将被禁用:没有额外的SElinux模块添加到策略中,并且自定义策略中的所有可用模块都将被启用并构建到最终的二进制策略中。自定义策略必须是官方重新策略的一个分支。
为了完全覆盖repolicy,必须设置以下配置变量:
BR2_PACKAGE_REFPOLICY_CUSTOM_GIT
BR2_PACKAGE_REFPOLICY_CUSTOM_REPO_URL
BR2_PACKAGE_REFPOLICY_CUSTOM_REPO_VERSION
引导进程以下消息以后似乎挂起(消息不一定完全相似,取决于所选包的列表):
Freeing init memory: 3972K
Initializing random number generator... done.
Starting network...
Starting dropbear sshd: generating rsa key... generating dsa key... OK
这意味着系统正在运行,但没有在串行控制台上启动shell。为了让系统在您的串行控制台上启动一个shell,您必须进入Buildroot配置,在System configuration,
中,修改Run a getty (login prompt) after boot
,并在getty options
子菜单中设置适当的端口和波特率。这将自动调整生成的系统的/etc/inittab
文件,以便shell在正确的串口上启动。
已经决定从Buildroot-2012.11版本开始停止对目标板原生编译器的支持,因为:
如果你的目标上需要一个编译器,那么Buildroot不适合你的目的。在这种情况下,你需要一个真正的发行版,你应该选择如下内容:
因为目标上没有可用的编译器(参见11.2节,“为什么目标上没有编译器?”),所以在头文件或静态库上浪费空间是没有意义的。
因此,自Buildroot-2012.11发布以来,这些文件总是从目标中删除。
因为Buildroot主要针对有限资源(CPU、ram、大容量存储)的小型或非常小的目标硬件,所以用文档数据浪费空间是没有意义的。
如果您无论如何都需要目标上的文档数据,那么Buildroot并不适合您的目的,您应该寻找一个真正的发行版(参见11.2节,“为什么目标上没有编译器?”)。
如果一个包存在于Buildroot树中,并且没有出现在配置菜单中,这很可能意味着该包的某些依赖项没有满足。
要了解更多关于包的依赖关系,可以在配置菜单中搜索包的符号(见8.1节“make tips”)。
然后,您可能必须递归地启用几个选项(对应于未满足的依赖项),以便最终能够选择包。
如果包因为一些未满足的工具链选项而不可见,那么您当然应该运行一个完整的重新构建(参见8.1节“make tips”以获得更多解释)。
有很多理由不使用目标目录chroot
,其中:
由于这些原因,使用目标目录作为新的根,通过chroot
运行的命令很可能会失败。
如果您想在chroot中运行目标文件系统,或者作为NFS根运行,那么使用images/
中生成的tarball映像并将其作为根解压。
在Buildroot列表中经常讨论的一个特性是“包管理”package management
的一般主题。总的来说,这个想法是添加一些跟踪哪个Buildroot包安装了什么文件,目的是:
通常,大多数人认为这很容易做到:只需跟踪哪个软件包安装了什么,并在软件包未被选中时删除它。然而,实际情况要复杂得多:
target/
directory, but also the sysroot in host/<tuple>/sysroot
and the host/
directory itself. All files installed in those directories by various packages must be tracked.target/
目录,而且还涉及到host/<tuple>/sysroot
中的sysroot和host/
目录本身。必须跟踪由各种包安装在这些目录中的所有文件。由于所有这些原因,结论是,当包未被选中时,添加已安装文件的跟踪来删除它们,或者生成二进制包的存储库,是非常难以可靠地实现的,并且会增加很多复杂性。
在这个问题上,Buildroot开发者发表了如下立场声明:
由于Buildroot经常涉及到对整个系统进行完整的重建,这可能会很长,所以我们提供以下一些技巧来帮助减少构建时间:
Use a pre-built external toolchain instead of the default Buildroot internal toolchain. By using a pre-built Linaro toolchain (on ARM) or a Sourcery CodeBench toolchain (for ARM, x86, x86-64, MIPS, etc.), you will save the build time of the toolchain at each complete rebuild, approximately 15 to 20 minutes. Note that temporarily using an external toolchain does not prevent you to switch back to an internal toolchain (that may provide a higher level of customization) once the rest of your system is working;
// 使用预构建的外部工具链,而不是默认的Buildroot内部工具链。通过使用预构建的Linaro工具链(在ARM上)或Sourcery CodeBench工具链(适用于ARM、x86、x86-64、MIPS等),您将在每次完成重建时节省工具链的构建时间,大约15到20分钟。请注意,临时使用外部工具链并不妨碍您在系统的其余部分正常工作后切换回内部工具链(可能提供更高级别的定制);
Use the ccache
compiler cache (see: Section 8.14.3, “Using ccache in Buildroot”);
// 使用ccache编译器缓存(见:8.14.3节,“在Buildroot中使用ccache”);
Learn about rebuilding only the few packages you actually care about (see Section 8.3, “Understanding how to rebuild packages”), but beware that sometimes full rebuilds are anyway necessary (see Section 8.2, “Understanding when a full rebuild is necessary”);
// 了解如何只重新构建您真正关心的几个包(参见8.3节“了解如何重新构建包”),但要注意,有时完全重新构建是必要的(参见8.2节“了解什么时候需要完全重新构建”);
Make sure you are not using a virtual machine for the Linux system used to run Buildroot. Most of the virtual machine technologies are known to cause a significant performance impact on I/O, which is really important for building source code;
// 确保没有为用于运行Buildroot的Linux系统使用虚拟机。众所周知,大多数虚拟机技术都会对I/O造成显著的性能影响,这对于构建源代码非常重要;
Make sure that you’re using only local files: do not attempt to do a build over NFS, which significantly slows down the build. Having the Buildroot download folder available locally also helps a bit.
// 确保您只使用本地文件:不要尝试通过NFS进行构建,这会显著降低构建速度。在本地提供Buildroot下载文件夹也有一定帮助。
Buy new hardware. SSDs and lots of RAM are key to speeding up the builds.
// 购买新的硬件。ssd和大量RAM是加速构建的关键。
Experiment with top-level parallel build, see Section 8.12, “Top-level parallel build”.
// 尝试顶层并行构建,请参见8.12节“顶层并行构建”。
It is not possible to pass extra linker options via BR2_TARGET_LDFLAGS
if such options contain a $
sign. For example, the following is known to break: BR2_TARGET_LDFLAGS="-Wl,-rpath='$ORIGIN/../lib'"
// 如果这些选项包含$符号,则不可能通过BR2_TARGET_LDFLAGS传递额外的链接器选项。例如,下面的代码会出错
The libffi
package is not supported on the SuperH 2 and ARC architectures.
// superh2和ARC架构不支持libffi包。
The prboom package triggers a compiler failure with the SuperH 4 compiler from Sourcery CodeBench, version 2012.09.
// prboom包触发superh4编译器从Sourcery CodeBench,版本2012.09编译失败。
Buildroot的所有最终产品(工具链、根文件系统、内核、引导加载器)都包含开源软件,在各种许可下发布。
使用开源软件使您可以自由地构建丰富的嵌入式系统,可以从各种各样的包中进行选择,但也强加了一些您必须知道和遵守的义务。有些许可证要求您在产品文档中发布许可证文本。另一些则要求您将软件的源代码重新分发给接收您产品的人。
每个许可的确切要求都记录在每个包中,遵守这些要求是您的责任(或您的法律办公室的责任)。为了让你更容易做到这一点,Buildroot可以为你收集一些你可能需要的材料。要生成这个材料,在你用make menuconfig、make xconfig或make gconfig配置了Buildroot之后,运行:
make legal-info
Buildroot将在legal-info/
子目录下的输出目录中收集与法律相关的材料。在那里你会发现:
buildroot.config
:这是通常由make menuconfig生成的Buildroot配置文件,它对于重新生成构建是必要的。请注意,Buildroot的法律信息特性的目的是生成所有与软件包许可的法律遵从有关的材料。Buildroot并没有试图生产出你必须以某种方式公开的确切材料。当然,生产的材料比严格遵守法律所需要的要多。例如,它为在类似bsd的许可下发布的包生成源代码,您不需要以源代码的形式重新发布这些包。
此外,由于技术限制,Buildroot不能生成您将要或可能需要的一些材料,例如一些外部工具链的工具链源代码和Buildroot源代码本身。当您运行make legal-info时,Buildroot会在README文件中产生警告,通知您无法保存的相关材料。
最后,请记住,make legal-info的输出基于每个包recipes中的声明性语句。Buildroot开发人员尽其所能保持那些声明性语句尽可能准确,就他们所知。然而,很可能这些陈述性的陈述并不都完全准确或详尽无遗。您(或您的法律部门)在使用make legal-info作为您自己的合规交付之前,必须检查其输出。参见Buildroot发行版根目录的copy文件中的NO WARRANTY条款(第11和12条)。
Buildroot本身是一个开源软件,根据GNU通用公共许可证(General Public License)版本2或(由您选择)任何更新版本发布,除了下面详细介绍的包补丁。然而,作为一个构建系统,它通常不是最终产品的一部分:如果您为一个设备开发根文件系统、内核、引导加载程序或工具链,那么Buildroot的代码只出现在开发机器上,而不是在设备存储中。
然而,Buildroot开发人员的普遍看法是,当发布包含gpl许可软件的产品时,应该将Buildroot源代码与其他包的源代码一起发布。这是因为GNU GPL将可执行作品的“完整源代码”定义为“它包含的所有模块的所有源代码,加上任何关联的接口定义文件,加上用来控制可执行作品的编译和安装的脚本”。Buildroot是用于控制可执行文件的编译和安装的脚本的一部分,因此它被认为是必须重新分发的材料的一部分。
请记住,这只是Buildroot开发人员的意见,如果您有任何疑问,应该咨询您的法律部门或律师。
Buildroot还捆绑补丁文件,应用于各种包的源代码。这些补丁不在Buildroot的许可范围内。相反,它们是由应用补丁的软件的许可证所覆盖的。当上述软件在多个许可下可用时,Buildroot补丁只在公共可访问的许可下提供。
技术细节请参见第19章补丁包。
要实现nfs引导,请在filesystem映像菜单中启用tar根文件系统。
完成构建后,只需运行以下命令设置nfs根目录:
sudo tar -xavf /path/to/output_dir/rootfs.tar -C /path/to/nfs_root_dir
请记住将此路径添加到/etc/exports
.
然后,可以从目标执行nfs引导。
要构建一个实时CD映像,请启用文件系统映像菜单中的iso映像选项。注意,这个选项只适用于x86和x86-64体系结构,如果您正在使用Buildroot构建内核的话。
您可以使用IsoLinux、Grub或Grub 2作为引导加载程序构建一个活动CD映像,但只有IsoLinux支持使该映像同时作为活动CD和活动USB使用(通过构建混合映像选项)。
You can test your live CD image using QEMU:
qemu-system-i386 -cdrom output/images/rootfs.iso9660
Or use it as a hard-drive image if it is a hybrid ISO:
qemu-system-i386 -hda output/images/rootfs.iso9660
It can be easily flashed to a USB drive with dd:
dd if=output/images/rootfs.iso9660 of=/dev/sdb
如果你想在生成的映像中使用chroot,那么有几件事你应该注意:
qemu-*
binary and correctly set it within the binfmt
properties to be able to run the binaries built for the target on your host machine;host-qemu
and binfmt
correctly built and set for that kind of use.正如上面提到的,Buildroot基本上是一组makefile文件,它们使用正确的选项下载、配置和编译软件。它还包括各种软件包的补丁——主要是交叉编译工具链(gcc、binutils和uClibc)中涉及的补丁。
基本上每个软件包都有一个Makefile,它们以.mk
扩展名命名。makefile被分成许多不同的部分:
toolchain/
directory contains the Makefiles and associated files for all software related to the cross-compilation toolchain: binutils, gcc, gdb, kernel-headers and uClibc.arch/
directory contains the definitions for all the processor architectures that are supported by Buildroot.package/
directory contains the Makefiles and associated files for all user-space tools and libraries that Buildroot can compile and add to the target root filesystem. There is one sub-directory per package.linux/
directory contains the Makefiles and associated files for the Linux kernel.boot/
directory contains the Makefiles and associated files for the bootloaders supported by Buildroot.system/
directory contains support for system integration, e.g. the target filesystem skeleton
and the selection of an init system
.fs/
directory contains the Makefiles and associated files for software related to the generation of the target root filesystem image.每个目录至少包含2个文件:
something.mk
is the Makefile that downloads, configures, compiles and installs the package something.Config.in
is a part of the configuration tool description file. It describes the options related to the package.主Makefile执行以下步骤(一旦配置完成):
output/
,可以使用O=
指定另一个值)总之,这些编码风格规则可以帮助您在Buildroot中添加新文件或重构现有文件。
如果你稍微修改一些现有的文件,重要的是保持整个文件的一致性,这样你就可以:
Config.in
文件包含Buildroot几乎所有可配置的条目。
一个条目具有以下模式:
config BR2_PACKAGE_LIBFOO
bool "libfoo"
depends on BR2_PACKAGE_LIBBAZ
select BR2_PACKAGE_LIBBAR
help
This is a comment that explains what libfoo is. The help text
should be wrapped.
http://foosoftware.org/libfoo/
bool
, depends on
, select
and help
行缩进一个制表符。Header: The file starts with a header. It contains the module name, preferably in lowercase, enclosed between separators made of 80 hashes. A blank line is mandatory after the header:
// 文件以头文件开始。它包含模块名,最好是小写,用由80个散列组成的分隔符包围。标题后必须有一个空行:
################################################################################
#
#
################################################################################
Assignment: use = preceded and followed by one space:
// 赋值: = 前面和后面加一个空格:
LIBFOO_VERSION = 1.0
LIBFOO_CONF_OPTS += --without-python-support
Do not align the = signs. // 不要将=号对齐。
Indentation: use tab only: // 缩进:只使用制表符:
define LIBFOO_REMOVE_DOC
$(RM) -fr $(TARGET_DIR)/usr/share/libfoo/doc <br />
$(TARGET_DIR)/usr/share/man/man3/libfoo*
endef
请注意,定义块中的commands
应该总是以tab
开始,这样make将它们识别为命令。
Optional dependency: // 选项依赖:
YES:
ifeq ($(BR2_PACKAGE_PYTHON),y)
LIBFOO_CONF_OPTS += --with-python-support
LIBFOO_DEPENDENCIES += python
else
LIBFOO_CONF_OPTS += --without-python-support
endif
NO:
LIBFOO_CONF_OPTS += --with$(if $(BR2_PACKAGE_PYTHON),,out)-python-support
LIBFOO_DEPENDENCIES += $(if $(BR2_PACKAGE_PYTHON),python,)
Optional hooks: keep hook definition and assignment together in one if block.
// 可选钩子:将钩子定义和赋值放在一个if块中。
YES:
ifneq ($(BR2_LIBFOO_INSTALL_DATA),y)
define LIBFOO_REMOVE_DATA
$(RM) -fr $(TARGET_DIR)/usr/share/libfoo/data
endef
LIBFOO_POST_INSTALL_TARGET_HOOKS += LIBFOO_REMOVE_DATA
endif
NO:
define LIBFOO_REMOVE_DATA
$(RM) -fr $(TARGET_DIR)/usr/share/libfoo/data
endef
ifneq ($(BR2_LIBFOO_INSTALL_DATA),y)
LIBFOO_POST_INSTALL_TARGET_HOOKS += LIBFOO_REMOVE_DATA
endif
The documentation uses the asciidoc format.
For further details about the asciidoc syntax, refer to http://www.methods.co.nz/asciidoc/userguide.html.
Some scripts in the support/
and utils/
directories are written in Python and should follow the PEP8 Style Guide for Python Code.
Buildroot包含几个公开可用硬件板的基本配置,这样这样一个板的用户就可以轻松地构建一个已知可以工作的系统。你也可以在Buildroot中添加对其他板的支持。
为此,您需要创建一个普通的Buildroot配置,它为硬件构建一个基本的系统:(内部)工具链、内核、引导加载程序、文件系统和一个简单的BusyBox-only用户空间。不应该选择特定的包:配置应该尽可能少,并且应该只为目标平台构建一个可工作的基本BusyBox系统。当然,您可以为您的内部项目使用更复杂的配置,但是Buildroot项目将只集成基本的板配置。这是因为包选择是高度特定于应用程序的。
一旦您有了一个已知的工作配置,运行make savedefconfig
。这将在Buildroot源树的根生成一个最小的defconfig文件。将此文件移到configs/
目录中,并将其重命名为<boardname>_defconfig
。如果配置有点复杂,最好手动重新格式化并将其划分为多个部分,每个部分之前都有注释。典型的部分是架构、工具链选项(通常只是linux头文件版本)、固件、引导装载程序、内核和文件系统。
对于不同的组件,总是使用固定版本或提交散列,而不是“最新”版本。例如,将BR2_LINUX_KERNEL_CUSTOM_VERSION=y
和BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE
设置为您测试的内核版本。
建议尽可能多地使用Linux内核和引导加载程序的上游版本,并尽可能多地使用默认的内核和引导加载程序配置。如果它们对您的板不正确,或没有默认存在,我们鼓励您发送修复到相应的上游项目。
然而,与此同时,您可能希望存储特定于目标平台的内核或引导加载程序配置或补丁。为此,创建一个board/<manufacturer>
和子目录board/<manufacturer>/<boardname>
。然后,您可以将补丁和配置存储在这些目录中,并从主要的Buildroot配置中引用它们。有关更多细节,请参阅第9章,特定于项目的定制。
本节介绍如何将新的包(用户空间库或应用程序)集成到Buildroot中。它还展示了如何集成现有的包,这是修复问题或调优其配置所需要的。
当您添加一个新的包时,请确保在各种条件下对它进行测试(参见第18.24.3节,“如何测试您的包”),并检查它的编码风格(参见第18.24.2节,“如何检查编码风格”)。
首先,在软件package
目录下为您的软件创建一个目录,例如libfoo
。
有些包按主题分组在子目录中:x11r7
、qt5
和gstreamer
。如果您的包符合其中一个类别,那么在这些类别中创建您的包目录。但是,不建议创建新的子目录。
对于要在配置工具中显示的包,您需要在您的包目录中创建一个Config文件。有两种类型:Config.in
and Config.in.host
。
Config.in
file对于在目标上使用的包,创建一个名为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
缩进。帮助文本本身应该缩进一个制表符和两个空格,行应该换行以适应72列,其中制表符计数为8,所以文本本身的62个字符。帮助文本必须在空行之后提到项目的上游URL。
作为特定于Buildroot的约定,属性的顺序如下:
bool
, string…
with the promptdefault
value(s)depends on
formdepends on
表单,描述对目标的依赖depends on
formdepends on
表单,描述对工具链的依赖depends on
formdepends on
表单,描述对其他包的依赖select
formselect
表单,描述任何依赖您可以将其他子选项添加到if BR2_PACKAGE_LIBFOO…endif
语句中,以配置软件中的特定内容。您可以查看其他包中的示例。配置的语法与内核Kconfig
文件相同。此语法的文档可在 http://kernel.org/doc/Documentation/kbuild/kconfig-language.txt 获得
最后,您必须将新的libfoo/Config
添加进package/Config.in
(或者在一个类别子目录中,如果您决定将您的包放在一个现有类别中)。其中包含的文件按每个类别的字母顺序排序,除了包的名字之外不应该包含任何内容。
source "package/libfoo/Config.in"
Config.in.host
file还需要为主机系统构建一些包。这里有两个选择:
The host package is only required to satisfy build-time dependencies of one or more target packages. In this case, add host-foo
to the target package’s BAR_DEPENDENCIES
variable. No Config.in.host
file should be created.
// 宿主包只需要满足一个或多个目标包的构建时依赖关系。在这种情况下,将host-foo
添加到目标包的BAR_DEPENDENCIES
变量中。不需要创建Config.in.host
文件。
The host package should be explicitly selectable by the user from the configuration menu. In this case, create a Config.in.host file for that host package:
// 用户应该可以从配置菜单中显式地选择主机包。在本例中,为该主机包创建一个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
相同的编码风格和选项。在文件中是有效的。
Finally you have to add your new libfoo/Config.in.host to package/Config.in.host. The files included there are sorted alphabetically and are NOT supposed to contain anything but the bare name of the package.
最后,必须添加新的libfoo/Config.in.host
到package/Config.in.host
。其中包含的文件是按字母顺序排序的,除了包的名字之外不应该包含任何内容。
source "package/foo/Config.in.host"
然后主机包在Host utilities
菜单中有效。
depends on
or select
在包的Config.in
文件中还必须确保启用了依赖项。通常,Buildroot使用以下规则:
select
type of dependency for dependencies on libraries. These dependencies are generally not obvious and it therefore make sense to have the kconfig system ensure that the dependencies are selected. For example, the libgtk2
package uses select BR2_PACKAGE_LIBGLIB
2 to make sure this library is also enabled. The select
keyword expresses the dependency with a backward semantic.select
类型的依赖项。这些依赖关系通常不明显,因此让kconfig系统确保选择了这些依赖关系是有意义的。例如,libgtk2包使用select BR2_PACKAGE_LIBGLIB2
来确保也启用了这个库。select关键字用向后语义
表示依赖关系。depends on
type of dependency when the user really needs to be aware of the dependency. Typically, Buildroot uses this type of dependency for dependencies on target architecture, MMU support and toolchain options (see Section 18.2.4, “Dependencies on target and toolchain options”), or for dependencies on “big” things, such as the X.org system. The depends on
keyword expresses the dependency with a forward semantic.前向语义
表示依赖关系。请注意。kconfig语言的当前问题是这两个依赖语义没有内部链接。因此,有可能
select
一个包,它的一个依赖项/需求没有被满足。
下面的例子说明了select和depends的用法:
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
Selecting Package C
will be visible if Package B
has been selected, which in turn is only visible if Package A
has been selected.
// 如果选择了包B,那么选择包C将是可见的,并且只有在选择了包A时才可见。
Selecting Package E
will select Pac
kage D, which will select
Package B, it will not check for the dependencies of
Package B, so it will not select
Package A`.
// 选择包E将选择包D,包D将选择包B,它不会检查包B的依赖关系,所以它不会选择包A。
Since Package B
is selected but Package A
is not, this violates the dependency of Package B
on Package A
. Therefore, in such a situation, the transitive dependency has to be added explicitly:
// 因为选择了包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
文件中表示依赖关系。
进一步的格式化细节:参见编码风格。
许多包依赖于工具链的某些选项:C库、c++支持、线程支持、RPC支持、wchar支持或动态库支持的选择。有些包只能在特定的目标体系结构上构建,或者在处理器中有MMU的情况下。
这些依赖项必须用Config.in
文件中的适当依赖项语句来表示。此外,对于工具链选项的依赖项,当选项未启用时,应该显示注释comment
,以便用户知道包不可用的原因。对目标体系结构或MMU支持的依赖不应该在注释comment
中可见:因为用户不太可能自由选择另一个目标,显式地显示这些依赖没有什么意义。
只有当满足工具链选项依赖关系时,config选项本身才会可见,注释comment
才应该可见。这意味着包的所有其他依赖项(包括对目标体系结构和MMU支持的依赖项)都必须在注释定义上重复。为了保持清晰,这些非工具链选项的依赖语句应该与工具链选项的依赖语句分开。如果在同一个文件(通常是主包)中存在对配置选项的依赖,最好使用全局If…endif
构造,而不是在注释和其他配置选项上重复依赖语句。
foo包的依赖注释comment
的一般格式是:
foo needs a toolchain w/ featA, featB, featC
for example:
mpd needs a toolchain w/ C++, threads, wchar
or
crda needs a toolchain w/ threads
请注意,本文故意保持简短,以便适合80个字符的终端。
本节的其余部分枚举了不同的目标和工具链选项、要依赖的相应配置符号以及注释中要使用的文本。
Target architecture
MMU support
Gcc _sync* built-ins used for atomic operations. They are available in variants operating on 1 byte, 2 bytes, 4 bytes and 8 bytes. Since different architectures support atomic operations on different sizes, one dependency symbol is available for each size:
Gcc _atomic* built-ins used for atomic operations.
Kernel headers
GCC version
Host GCC version
C library
C++ support
D support
Fortran support
thread support
NPTL thread support
RPC support
wchar support
dynamic library
有些包需要一个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
如果一个包需要 udev
/dev
管理,它应该依赖于符号BR2_PACKAGE_HAS_UDEV
,并且应该添加以下注释:
foo needs udev /dev management
如果同时存在对工具链选项和udev /dev管理的依赖,使用以下格式:
foo needs udev /dev management and a toolchain w/ featA, featB, featC
一些特性可以由多个包提供,比如openGL
库。
关于虚拟包的更多信息,请参见第18.11节“虚拟包的基础结构”。
最后,这是最困难的部分。创建一个名为libfoo.mk
的文件。它描述了该包应该如何下载、配置、构建、安装等。
根据包类型的不同,.mk
文件必须以不同的方式编写,使用不同的基础结构:
Makefiles for generic packages
(not using autotools or CMake): These are based on an infrastructure similar to the one used for autotools-based packages, but require a little more work from the developer. They specify what should be done for the configuration, compilation and installation of the package. This infrastructure must be used for all packages that do not use the autotools as their build system. In the future, other specialized infrastructures might be written for other build systems. We cover them through in a tutorial and a reference.Makefiles for autotools-based software
(autoconf, automake, etc.): We provide a dedicated infrastructure for such packages, since autotools is a very common build system. This infrastructure must be used for new packages that rely on the autotools as their build system. We cover them through a tutorial and reference.Makefiles for cmake-based software
: We provide a dedicated infrastructure for such packages, as CMake is a more and more commonly used build system and has a standardized behaviour. This infrastructure must be used for new packages that rely on CMake. We cover them through a tutorial and reference.Makefiles for Python modules
: We have a dedicated infrastructure for Python modules that use either the distutils or the setuptools mechanism. We cover them through a tutorial and a reference.Makefiles for Lua modules
: We have a dedicated infrastructure for Lua modules available through the LuaRocks web site. We cover them through a tutorial and a reference.进一步的格式化细节:请参见编写规则。
如果可能,您必须添加第三个名为libfoo.hash
的文件。它包含libfoo
包下载文件的哈希值。不添加.hash
文件的唯一原因是由于下载包的方式而无法进行hash检查。
当一个包有版本选择选项时,哈希文件可以存储在以版本命名的子目录中,例如package/libfoo/1.2.3/libfoo.hash
。如果不同的版本具有不同的许可条款,但它们存储在同一个文件中,那么这一点尤其重要。否则,hash 文件应该留在包的目录中。
存储在该文件中的 hash 用于验证下载文件和许可证文件的完整性。
这个文件的格式是每行检查哈希值的文件,每行有以下三个字段,用两个空格分隔:
the type of hash, one of:
the hash of the file:
the name of the file:
以#
符号开头的行被认为是注释,并被忽略。空行会被忽略。
一个文件可以有多个hash
,每个hash
在它自己的行上。在这种情况下,所有hash
必须匹配。
请注意。理想情况下,存储在该文件中的哈希值应该与上游发布的哈希值匹配,例如,在其网站上,在电子邮件公告中……如果upstream不提供任何哈希值,或者只提供md5哈希值,那么至少自己计算一个强散列(最好是sha256,但不是md5),并在散列上面的注释行中提到这一点。
请注意。许可证文件的哈希值用于检测许可证变更,当软件包版本被碰撞时。在make legal-info
目标运行期间检查哈希值。对于具有多个版本的包(如Qt5),在该包的子目录<packageversion>
中创建哈希文件(参见第19.2节,“如何应用补丁”)。
none
hash类型保留给那些从存储库下载的档案,比如git克隆,subversion签出…
下面的例子定义了上游发布的libfoo-1.2.3.tar.bz2
主版本的sha1
和sha256
。来自上游的md5和本地计算的sha256哈希值(二进制blob), sha256值(下载的补丁),以及没有哈希值的存档:
# 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复制的文件和本地文件中获取的文件。对于其他版本控制系统(如Subversion、CVS等),不会检查哈希值,因为从这些版本控制系统获取源代码时,Buildroot目前不会生成可重复的tarballs。
哈希应该只添加在.hash文件中,用于保证稳定的文件。例如,Github自动生成的补丁不能保证是稳定的,因此它们的哈希值会随着时间的推移而改变。不应该下载此类补丁,而应该在本地将其添加到包文件夹中。
如果.hash文件丢失,则根本不进行检查。
对于带有特定构建系统的包,我们的意思是所有的构建系统不是标准的包(比如autotools或CMake)。这通常包括构建系统基于手工编写的makefile或shell脚本的包。
generic-package
tutorial01: ################################################################################
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
)、包含包的tarball名称(LIBFOO_SOURCE
)(推荐使用xz格式的tarball)、可以从Internet上下载tarball的位置(LIBFOO_SITE
)、许可证(LIBFOO_LICENSE
)和带有许可证文本的文件(LIBFOO_LICENSE_FILES
)。所有变量都必须以相同的前缀开始,在本例中是LIBFOO_
。这个前缀总是包名的大写版本(请参阅下面了解包名的定义位置)。
在第12行,我们指定这个包想要安装一些东西到暂存空间。库经常需要这样做,因为它们必须在暂存空间中安装头文件和其他开发文件。这将确保执行LIBFOO_INSTALL_STAGING_CMDS
变量中列出的命令。
在第13行中,我们指定需要对LIBFOO_INSTALL_STAGING_CMDS
阶段安装的一些libfoo-config
文件进行一些修复。这些*-config
文件是位于$(STAGING_DIR)/usr/bin
目录下的可执行shell脚本文件,由其他第三方包执行,以找出这个特定包的位置和链接标志。
问题是,所有这些*-config
文件默认情况下给出错误的主机系统链接标志,不适合交叉编译。
For example: -I/usr/include
instead of -I$(STAGING_DIR)/usr/include
or: -L/usr/lib
instead of -L$(STAGING_DIR)/usr/lib
因此,对这些脚本执行了一些sed
魔法,使它们给出正确的标志。给LIBFOO_CONFIG_SCRIPTS
的参数是需要修复的shell脚本的文件名。所有这些名称都相对于$(STAGING_DIR)/usr/bin
,如果需要,可以给出多个名称。
另外,LIBFOO_CONFIG_SCRIPTS
中列出的脚本将从$(TARGET_DIR)/usr/bin
中删除,因为它们在目标上不需要。
Example 18.1. Config script: divine package
包 divine 的安装shell脚本$(STAGING_DIR)/usr/bin/divine-config
。
所以它的修正是:
DIVINE_CONFIG_SCRIPTS = divine-config
Example 18.2. Config script: imagemagick package:
Package imagemagick 安装以下脚本: $(STAGING_DIR)/usr/bin/{Magick,Magick++,MagickCore,MagickWand,Wand}-config
So it’s fixup would be:
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行,我们定义了一个由这个包使用的用户(例如,以非root身份运行守护进程)(LIBFOO_USERS
)。
在第35到37行,我们定义了一个由这个包使用的设备节点文件(LIBFOO_DEVICES
)。
在39到41行,我们定义了权限来设置这个包安装的特定文件(LIBFOO_PERMISSIONS
)。
最后,在第43行,我们调用泛型包函数,该函数根据前面定义的变量生成使包工作所需的所有Makefile代码。
generic-package
reference通用目标有两种变体。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
, mandatory, must contain the version of the package. Note that if HOST_LIBFOO_VERSION doesn’t exist, it is assumed to be the same as LIBFOO_VERSION. It can also be a revision number or a tag for packages that are fetched directly from their version control system. Examples:
// LIBFOO_VERSION,必选,必须包含包的版本。注意,如果HOST_LIBFOO_VERSION不存在,就会假定它与LIBFOO_VERSION相同。它还可以是版本号或直接从版本控制系统获取的包的标记。例子:
Note: Using a branch name as FOO_VERSION
is not supported, because it does not and can not work as people would expect it should:
// 注意:不支持使用一个分支名作为FOO_VERSION,因为它不像人们期望的那样工作:
LIBFOO_SOURCE
may contain the name of the tarball of the package, which Buildroot will use to download the tarball from LIBFOO_SITE
. If HOST_LIBFOO_SOURCE
is not specified, it defaults to LIBFOO_SOURCE
. If none are specified, then the value is assumed to be libfoo-$(LIBFOO_VERSION).tar.gz
. Example: LIBFOO_SOURCE = foobar-$(LIBFOO_VERSION).tar.bz2
// LIBFOO_SOURCE可能包含包的tarball名称,Buildroot将使用它从LIBFOO_SITE下载tarball。如果未指定HOST_LIBFOO_SOURCE,则默认为LIBFOO_SOURCE。如果没有指定,则假定该值为libfoo-
(
L
I
B
F
O
O
V
E
R
S
I
O
N
)
.
t
a
r
.
g
z
。
例
如
:
L
I
B
F
O
O
S
O
U
R
C
E
=
f
o
o
b
a
r
−
(LIBFOO_VERSION).tar.gz。例如:LIBFOO_SOURCE = foobar-
(LIBFOOVERSION).tar.gz。例如:LIBFOOSOURCE=foobar−(LIBFOO_VERSION).tar.bz2
LIBFOO_PATCH
may contain a space-separated list of patch file names, that Buildroot will download and apply to the package source code. If an entry contains ://
, then Buildroot will assume it is a full URL and download the patch from this location. Otherwise, Buildroot will assume that the patch should be downloaded from LIBFOO_SITE. If HOST_LIBFOO_PATCH is not specified, it defaults to LIBFOO_PATCH. Note that patches that are included in Buildroot itself use a different mechanism: all files of the form *.patch present in the package directory inside Buildroot will be applied to the package after extraction (see patching a package). Finally, patches listed in the LIBFOO_PATCH variable are applied before the patches stored in the Buildroot package directory.
// LIBFOO_PATCH可能包含一个空格分隔的补丁文件名列表,Buildroot将下载并应用于包源代码。如果一个条目包含://,那么Buildroot会假定它是一个完整的URL,并从这个位置下载补丁。否则,Buildroot会假定补丁应该从LIBFOO_SITE下载。如果未指定HOST_LIBFOO_PATCH,则默认为LIBFOO_PATCH。请注意,包含在Buildroot中的补丁使用了一种不同的机制:所有形式为*.patch
的文件。在解压后,Buildroot中的包目录中的补丁将被应用到包中(参见给包打补丁)。最后,在应用Buildroot包目录中的补丁之前,应用LIBFOO_PATCH变量中列出的补丁。
LIBFOO_SITE
provides the location of the package, which can be a URL or a local filesystem path. HTTP, FTP and SCP are supported URL types for retrieving package tarballs. In these cases don’t include a trailing slash: it will be added by Buildroot between the directory and the filename as appropriate. Git, Subversion, Mercurial, and Bazaar are supported URL types for retrieving packages directly from source code management systems. There is a helper function to make it easier to download source tarballs from GitHub (refer to Section 18.24.4, “How to add a package from GitHub” for details). A filesystem path may be used to specify either a tarball or a directory containing the package source code. See LIBFOO_SITE_METHOD below for more details on how retrieval works. Note that SCP URLs should be of the form scp://[user@]host:filepath, and that filepath is relative to the user’s home directory, so you may want to prepend the path with a slash for absolute paths: scp://[user@]host:/absolutepath. If HOST_LIBFOO_SITE is not specified, it defaults to LIBFOO_SITE. Examples: 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_SITE提供了包的位置,可以是URL或本地文件系统路径。HTTP、FTP和SCP是用于从支持的URL类型检索包tarball。在这些情况下,不要包含末尾的斜杠:它将被Buildroot添加到目录和文件名之间。Git、Subversion、Mercurial和Bazaar都是支持的URL类型,可以直接从源代码管理系统检索包。有一个帮助器函数可以使从GitHub下载源压缩包变得更容易(请参阅18.24.4节“如何从GitHub添加一个包”以获得详细信息)。文件系统路径可以用来指定一个tarball或包含包源代码的目录。请参阅下面的LIBFOO_SITE_METHOD了解更多关于检索如何工作的细节。注意,SCP url的格式应该是SCP://[user@]host:filepath
,而且filepath是相对于用户的主目录的,所以您可能希望在路径前加一个斜杠来表示绝对路径:SCP://[user@]host:/absolutepath
。如果未指定HOST_LIBFOO_SITE,则默认为LIBFOO_SITE。例如: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 .gz
LIBFOO_DL_OPTS
is a space-separated list of additional options to pass to the downloader. Useful for retrieving documents with server-side checking for user logins and passwords, or to use a proxy. All download methods valid for LIBFOO_SITE_METHOD are supported; valid options depend on the download method (consult the man page for the respective download utilities).
// LIBFOO_DL_OPTS是一个空格分隔的附加选项列表,用于传递给下载程序。用于检索文档,并通过服务器端检查用户登录和密码,或使用代理。LIBFOO_SITE_METHOD
支持所有有效的下载方法;有效的选项取决于下载方法(有关各自的下载实用程序,请参阅手册页)。
LIBFOO_EXTRA_DOWNLOADS
is a space-separated list of additional files that Buildroot should download. If an entry contains / then Buildroot will assume it is a complete URL and will download the file using this URL. Otherwise, Buildroot will assume the file to be downloaded is located at LIBFOO_SITE. Buildroot will not do anything with those additional files, except download them: it will be up to the package recipe to use them from $(LIBFOO_DL_DIR).
// LIBFOO_EXTRA_DOWNLOADS是一个空格分隔的附加文件列表,Buildroot应该下载这些文件。如果一个条目包含://
,那么Buildroot会假定它是一个完整的URL,并使用这个URL下载文件。否则,Buildroot会假定要下载的文件位于LIBFOO_SITE。Buildroot不会对这些额外的文件做任何事情,除了下载它们:它将取决于包配方从$(LIBFOO_DL_DIR)
使用它们。
LIBFOO_SITE_METHOD
determines the method used to fetch or copy the package source code. In many cases, Buildroot guesses the method from the contents of LIBFOO_SITE and setting LIBFOO_SITE_METHOD is unnecessary. When HOST_LIBFOO_SITE_METHOD is not specified, it defaults to the value of LIBFOO_SITE_METHOD. The possible values of LIBFOO_SITE_METHOD are:
// LIBFOO_SITE_METHOD确定用于获取或复制包源代码的方法。在很多情况下,Buildroot从LIBFOO_SITE的内容猜测方法,设置LIBFOO_SITE_METHOD是不必要的。当未指定HOST_LIBFOO_SITE_METHOD时,默认为LIBFOO_SITE_METHOD的值。LIBFOO_SITE_METHOD可能的值是:
wget
for normal FTP/HTTP downloads of tarballs. Used by default when LIBFOO_SITE
begins with http://
, https://
or ftp://
.LIBFOO_SITE
以http://,开始时默认使用:https://或ftp://.scp
for downloads of tarballs over SSH with scp. Used by default when LIBFOO_SITE begins with scp://
.svn
for retrieving source code from a Subversion repository. Used by default when LIBFOO_SITE begins with svn://
. When a http://
Subversion repository URL is specified in LIBFOO_SITE, one must specify LIBFOO_SITE_METHOD=svn. Buildroot performs a checkout which is preserved as a tarball in the download cache; subsequent builds use the tarball instead of performing another checkout.cvs
for retrieving source code from a CVS repository. Used by default when LIBFOO_SITE begins with cvs://
. The downloaded source code is cached as with the svn method. Anonymous pserver mode is assumed otherwise explicitly defined on LIBFOO_SITE. Both LIBFOO_SITE=cvs://libfoo.net:/cvsroot/libfoo and LIBFOO_SITE=cvs://:ext:libfoo.net:/cvsroot/libfoo are accepted, on the former anonymous pserver access mode is assumed. LIBFOO_SITE must contain the source URL as well as the remote repository directory. The module is the package name. LIBFOO_VERSION is mandatory and must be a tag, a branch, or a date (e.g. “2014-10-20”, “2014-10-20 13:45”, “2014-10-20 13:45+01” see “man cvs” for further details).cvs://
时默认使用。下载的源代码缓存为svn方法。假设匿名pserver模式是LIBFOO_SITE上显式定义的。LIBFOO_SITE=cvs://libfoo.net:/cvsroot/libfoo和LIBFOO_SITE=cvs://:ext:libfoo.net:/cvsroot/libfoo都被接受,假设是在以前的匿名pserver访问模式下。LIBFOO_SITE必须包含源URL以及远程存储库目录。模块是包的名称。LIBFOO_VERSION是强制的,必须是一个标签,一个分支,或者一个日期。“2014-10-20”,“2014-10-20 13:45”,“2014-10-20 13:45+01”详见“man cvs”)。git
for retrieving source code from a Git repository. Used by default when LIBFOO_SITE begins with git://
. The downloaded source code is cached as with the svn method.git://
开头时默认使用。下载的源代码缓存为svn方法。hg
for retrieving source code from a Mercurial repository. One must specify LIBFOO_SITE_METHOD=hg when LIBFOO_SITE contains a Mercurial repository URL. The downloaded source code is cached as with the svn method.bzr
for retrieving source code from a Bazaar repository. Used by default when LIBFOO_SITE begins with bzr://. The downloaded source code is cached as with the svn method.bzr://
开头时默认使用。下载的源代码缓存为svn方法。file
for a local tarball. One should use this when LIBFOO_SITE specifies a package tarball as a local filename. Useful for software that isn’t available publicly or in version control.local
for a local source code directory. One should use this when LIBFOO_SITE specifies a local directory path containing the package source code. Buildroot copies the contents of the source directory into the package’s build directory. Note that for local packages, no patches are applied. If you need to still patch the source code, use LIBFOO_POST_RSYNC_HOOKS, see Section 18.22.1, “Using the POST_RSYNC hook”.LIBFOO_GIT_SUBMODULES
can be set to YES
to create an archive with the git submodules in the repository. This is only available for packages downloaded with git (i.e. when LIBFOO_SITE_METHOD=git). Note that we try not to use such git submodules when they contain bundled libraries, in which case we prefer to use those libraries from their own package.
// LIBFOO_GIT_SUBMODULES可以被设置为YES来创建一个带有git子模块的存档。这只适用于使用git下载的包(即当LIBFOO_SITE_METHOD=git时)。请注意,当这些git子模块包含绑定的库时,我们尽量不使用它们,在这种情况下,我们倾向于使用它们自己包中的那些库。
LIBFOO_STRIP_COMPONENTS
is the number of leading components (directories) that tar must strip from file names on extraction. The tarball for most packages has one leading component named “-”, thus Buildroot passes --strip-components=1 to tar to remove it. For non-standard packages that don’t have this component, or that have more than one leading component to strip, set this variable with the value to be passed to tar. Default: 1.
// LIBFOO_STRIP_COMPONENTS是在提取时,tar必须从文件名中删除的前导组件(目录)的数量。大多数包的tarball都有一个名为<pkg-name>-<pkg-version>
的主要组件,因此Buildroot通过--strip-components=1
来删除它。对于没有此组件的非标准包,或有多个前置组件需要剥离的非标准包,使用要传递给tar的值设置此变量。默认值:1。
LIBFOO_EXCLUDES is
a space-separated list of patterns to exclude when extracting the archive. Each item from that list is passed as a tar’s --exclude option. By default, empty.
// libfoo_exclude是一个用空格分隔的模式列表,用于在提取归档文件时排除。该列表中的每一项都作为tar的--exclude
选项传递。默认情况下,空的。
LIBFOO_DEPENDENCIES
lists the dependencies (in terms of package name) that are required for the current target package to compile. These dependencies are guaranteed to be compiled and installed before the configuration of the current package starts. However, modifications to configuration of these dependencies will not force a rebuild of the current package. In a similar way, HOST_LIBFOO_DEPENDENCIES lists the dependencies for the current host package.
// LIBFOO_DEPENDENCIES列出了编译当前目标包所需的依赖项(根据包名)。这些依赖项保证在启动当前包的配置之前被编译和安装。但是,修改这些依赖项的配置并不会强制重新生成当前包。以类似的方式,HOST_LIBFOO_DEPENDENCIES列出当前主机包的依赖项。
LIBFOO_EXTRACT_DEPENDENCIES
lists the dependencies (in terms of package name) that are required for the current target package to be extracted. These dependencies are guaranteed to be compiled and installed before the extract step of the current package starts. This is only used internally by the package infrastructure, and should typically not be used directly by packages.
// LIBFOO_EXTRACT_DEPENDENCIES列出了要提取当前目标包所需的依赖项(根据包名)。这些依赖项保证在启动当前包的提取步骤之前被编译和安装。这只被包基础结构内部使用,通常不应该被包直接使用。
LIBFOO_PATCH_DEPENDENCIES
lists the dependencies (in terms of package name) that are required for the current package to be patched. These dependencies are guaranteed to be extracted and patched (but not necessarily built) before the current package is patched. In a similar way, HOST_LIBFOO_PATCH_DEPENDENCIES lists the dependencies for the current host package. This is seldom used; usually, LIBFOO_DEPENDENCIES is what you really want to use.
// LIBFOO_PATCH_DEPENDENCIES列出了补丁当前包所需要的依赖项(以包名的形式)。保证在当前包打补丁之前提取并修补这些依赖项(但不一定是构建)。以类似的方式,HOST_LIBFOO_PATCH_DEPENDENCIES列出了当前主机包的依赖项。这种方法很少使用;通常,LIBFOO_DEPENDENCIES是您真正想要使用的。
LIBFOO_PROVIDES
lists all the virtual packages libfoo is an implementation of. See Section 18.11, “Infrastructure for virtual packages”.
// LIBFOO_PROVIDES列出了libfoo实现的所有虚拟包。参见第18.11节,“虚拟包的基础结构”。
LIBFOO_INSTALL_STAGING
can be set to YES or NO (default). If set to YES, then the commands in the LIBFOO_INSTALL_STAGING_CMDS variables are executed to install the package into the staging directory.
// LIBFOO_INSTALL_STAGING可以设置为YES或NO(默认)。如果设置为YES,那么将执行LIBFOO_INSTALL_STAGING_CMDS变量中的命令来将包安装到暂存目录中。
LIBFOO_INSTALL_TARGET
can be set to YES (default) or NO. If set to YES, then the commands in the LIBFOO_INSTALL_TARGET_CMDS variables are executed to install the package into the target directory.
// LIBFOO_INSTALL_TARGET可以设置为YES(默认)或NO。如果设置为YES,则执行LIBFOO_INSTALL_TARGET_CMDS变量中的命令将包安装到目标目录中。
LIBFOO_INSTALL_IMAGES
can be set to YES or NO (default). If set to YES, then the commands in the LIBFOO_INSTALL_IMAGES_CMDS variable are executed to install the package into the images directory.
// LIBFOO_INSTALL_IMAGES可以设置为YES或NO(默认)。如果设置为YES,则执行LIBFOO_INSTALL_IMAGES_CMDS变量中的命令将包安装到images目录中。
LIBFOO_CONFIG_SCRIPTS
lists the names of the files in $(STAGING_DIR)/usr/bin that need some special fixing to make them cross-compiling friendly. Multiple file names separated by space can be given and all are relative to $(STAGING_DIR)/usr/bin. The files listed in LIBFOO_CONFIG_SCRIPTS are also removed from $(TARGET_DIR)/usr/bin since they are not needed on the target.
// LIBFOO_CONFIG_SCRIPTS列出了
(
S
T
A
G
I
N
G
D
I
R
)
/
u
s
r
/
b
i
n
中
的
文
件
名
称
,
这
些
文
件
需
要
一
些
特
殊
的
修
复
以
使
它
们
能
够
进
行
交
叉
编
译
。
可
以
给
出
多
个
以
空
格
分
隔
的
文
件
名
,
并
且
所
有
文
件
名
都
相
对
于
(STAGING_DIR)/usr/bin中的文件名称,这些文件需要一些特殊的修复以使它们能够进行交叉编译。可以给出多个以空格分隔的文件名,并且所有文件名都相对于
(STAGINGDIR)/usr/bin中的文件名称,这些文件需要一些特殊的修复以使它们能够进行交叉编译。可以给出多个以空格分隔的文件名,并且所有文件名都相对于(STAGING_DIR)/usr/bin。LIBFOO_CONFIG_SCRIPTS中列出的文件也从$(TARGET_DIR)/usr/bin中删除,因为它们在目标上不需要。
LIBFOO_DEVICES
lists the device files to be created by Buildroot when using the static device table. The syntax to use is the makedevs one. You can find some documentation for this syntax in the Chapter 25, Makedev syntax documentation. This variable is optional.
// LIBFOO_DEVICES列出了在使用静态设备表时由Buildroot创建的设备文件。使用的语法是makedevs语法。您可以在第25章Makedev语法文档中找到关于此语法的一些文档。这个变量是可选的。
LIBFOO_PERMISSIONS
lists the changes of permissions to be done at the end of the build process. The syntax is once again the makedevs one. You can find some documentation for this syntax in the Chapter 25, Makedev syntax documentation. This variable is optional.
// LIBFOO_PERMISSIONS列出了在构建过程结束时要做的权限更改。语法同样是makedevs。您可以在第25章Makedev语法文档中找到关于此语法的一些文档。这个变量是可选的。
LIBFOO_USERS
lists the users to create for this package, if it installs a program you want to run as a specific user (e.g. as a daemon, or as a cron-job). The syntax is similar in spirit to the makedevs one, and is described in the Chapter 26, Makeusers syntax documentation. This variable is optional.
// LIBFOO_USERS列出了要为这个包创建的用户,如果它安装了一个您希望作为特定用户(例如作为守护进程或作为cron-job)运行的程序。该语法在精神上类似于makedevs,在第26章Makeusers语法文档中有描述。这个变量是可选的。
LIBFOO_LICENSE
defines the license (or licenses) under which the package is released. This name will appear in the manifest file produced by make legal-info. If the license appears in the SPDX License List, use the SPDX short identifier to make the manifest file uniform. Otherwise, describe the license in a precise and concise way, avoiding ambiguous names such as BSD which actually name a family of licenses. This variable is optional. If it is not defined, unknown will appear in the license field of the manifest file for this package. The expected format for this variable must comply with the following rules:
// LIBFOO_LICENSE定义了软件包发布时使用的一个或多个许可证。该名称将出现在make legal-info生成的清单文件中。如果license出现在“SPDX license List”中,请使用SPDX短标识符,使清单文件统一。否则,要以精确而简洁的方式描述许可证,避免使用不明确的名称,例如BSD,后者实际上是对许可证家族的名称。这个变量是可选的。如果未定义,则未知将出现在此包的清单文件的license字段中。这个变量的期望格式必须符合以下规则:
LIBFOO_LICENSE_FILES
is a space-separated list of files in the package tarball that contain the license(s) under which the package is released. make legal-info copies all of these files in the legal-info directory. See Chapter 13, Legal notice and licensing for more information. This variable is optional. If it is not defined, a warning will be produced to let you know, and not saved will appear in the license files field of the manifest file for this package.
// LIBFOO_LICENSE_FILES是包tarball中的一个空格分隔的文件列表,其中包含发布包的许可。Make legal-info复制legal-info目录中的所有文件。更多信息见第13章,法律通知和许可。这个变量是可选的。如果未定义,将产生一个警告让您知道,并且not saved将出现在此包的清单文件的许可证文件字段中。
LIBFOO_ACTUAL_SOURCE_TARBALL
only applies to packages whose LIBFOO_SITE / LIBFOO_SOURCE pair points to an archive that does not actually contain source code, but binary code. This a very uncommon case, only known to apply to external toolchains which come already compiled, although theoretically it might apply to other packages. In such cases a separate tarball is usually available with the actual source code. Set LIBFOO_ACTUAL_SOURCE_TARBALL to the name of the actual source code archive and Buildroot will download it and use it when you run make legal-info to collect legally-relevant material. Note this file will not be downloaded during regular builds nor by make source.
// LIBFOO_ACTUAL_SOURCE_TARBALL只适用于LIBFOO_SITE / LIBFOO_SOURCE对指向一个实际上不包含源代码,而是二进制代码的归档包。这是一种非常少见的情况,只适用于已经编译好的外部工具链,尽管理论上它可能适用于其他包。在这种情况下,实际源代码通常附带一个单独的tarball。将LIBFOO_ACTUAL_SOURCE_TARBALL设置为实际源代码归档文件的名称,Buildroot将下载它,并在运行make legal-info时使用它来收集与法律相关的材料。注意,这个文件不会在常规构建期间下载,也不会通过make source下载。
LIBFOO_ACTUAL_SOURCE_SITE
provides the location of the actual source tarball. The default value is LIBFOO_SITE, so you don’t need to set this variable if the binary and source archives are hosted on the same directory. If LIBFOO_ACTUAL_SOURCE_TARBALL is not set, it doesn’t make sense to define LIBFOO_ACTUAL_SOURCE_SITE.
// LIBFOO_ACTUAL_SOURCE_SITE提供了实际源tarball的位置。默认值是LIBFOO_SITE,所以如果二进制归档文件和源归档文件托管在同一个目录中,则不需要设置这个变量。如果没有设置LIBFOO_ACTUAL_SOURCE_TARBALL,那么定义LIBFOO_ACTUAL_SOURCE_SITE没有意义。
LIBFOO_REDISTRIBUTE
can be set to YES (default) or NO to indicate if the package source code is allowed to be redistributed. Set it to NO for non-opensource packages: Buildroot will not save the source code for this package when collecting the legal-info.
// LIBFOO_REDISTRIBUTE可以设置为YES(默认)或NO来指示是否允许重分发包源代码。对于非开源包,设置为NO: Buildroot在收集legal-info时不会保存此包的源代码。
LIBFOO_FLAT_STACKSIZE
defines the stack size of an application built into the FLAT binary format. The application stack size on the NOMMU architecture processors can’t be enlarged at run time. The default stack size for the FLAT binary format is only 4k bytes. If the application consumes more stack, append the required number here.
// LIBFOO_FLAT_STACKSIZE定义了内置于FLAT二进制格式的应用程序的堆栈大小。NOMMU体系结构处理器上的应用程序堆栈大小不能在运行时扩大。FLAT二进制格式的默认堆栈大小只有4k字节。如果应用程序消耗了更多的堆栈,在这里添加所需的数量。
LIBFOO_BIN_ARCH_EXCLUDE
is a space-separated list of paths (relative to the target directory) to ignore when checking that the package installs correctly cross-compiled binaries. You seldom need to set this variable, unless the package installs binary blobs outside the default locations, /lib/firmware, /usr/lib/firmware, /lib/modules, /usr/lib/modules, and /usr/share, which are automatically excluded.
// LIBFOO_BIN_ARCH_EXCLUDE是一个用空格分隔的路径列表(相对于目标目录),当检查包是否正确安装交叉编译的二进制文件时可以忽略它。您很少需要设置这个变量,除非包在默认位置/lib/firmware、/usr/lib/firmware、/lib/modules、/usr/lib/modules和/usr/share之外安装二进制blob,这些会被自动排除。
LIBFOO_IGNORE_CVES
is a space-separated list of CVEs that tells Buildroot CVE tracking tools which CVEs should be ignored for this package. This is typically used when the CVE is fixed by a patch in the package, or when the CVE for some reason does not affect the Buildroot package. A Makefile comment must always precede the addition of a CVE to this variable. Example:
// LIBFOO_IGNORE_CVES是一个空格分隔的CVE列表,它告诉Buildroot CVE跟踪工具在这个包中应该忽略哪个CVE。这通常用于CVE被包中的补丁修复,或者CVE由于某些原因不影响Buildroot包时。Makefile注释必须总是在向该变量添加CVE之前。例子:
LIBFOO_IGNORE_CVES += CVE-2020-12345
LIBFOO_IGNORE_CVES += CVE-2020-54321
LIBFOO_CPE_ID_*
variables is a set of variables that allows the package to define its CPE identifier. The available variables are:
// LIBFOO_CPE_ID_*变量是一组变量,允许包定义它的CPE标识符。可用的变量有:
LIBFOO_CPE_ID_PREFIX
, specifies the prefix of the CPE identifier, i.e the first three fields. When not defined, the default value is cpe:2.3:a.LIBFOO_CPE_ID_VENDOR
, specifies the vendor part of the CPE identifier. When not defined, the default value is _project.LIBFOO_CPE_ID_PRODUCT
, specifies the product part of the CPE identifier. When not defined, the default value is .LIBFOO_CPE_ID_VERSION
, specifies the version part of the CPE identifier. When not defined the default value is $(LIBFOO_VERSION).LIBFOO_CPE_ID_UPDATE
specifies the update part of the CPE identifier. When not defined the default value is *.如果定义了这些变量中的任何一个,那么通用包基础结构假定包提供了有效的CPE信息。在这种情况下,通用包基础结构将定义LIBFOO_CPE_ID。
对于一个主机包,如果它的LIBFOO_CPE_ID_*变量没有定义,它将从相应的目标包继承这些变量的值。
定义这些变量的推荐方法是使用以下语法:
LIBFOO_VERSION = 2.32
现在,定义在构建过程的不同步骤中应该执行什么的变量:
LIBFOO_EXTRACT_CMDS
lists the actions to be performed to extract the package. This is generally not needed as tarballs are automatically handled by Buildroot. However, if the package uses a non-standard archive format, such as a ZIP or RAR file, or has a tarball with a non-standard organization, this variable allows to override the package infrastructure default behavior.LIBFOO_CONFIGURE_CMDS
lists the actions to be performed to configure the package before its compilation.LIBFOO_BUILD_CMDS
lists the actions to be performed to compile the package.HOST_LIBFOO_INSTALL_CMDS
lists the actions to be performed to install the package, when the package is a host package. The package must install its files to the directory given by $(HOST_DIR). All files, including development files such as headers should be installed, since other packages might be compiled on top of this package.LIBFOO_INSTALL_TARGET_CMDS
lists the actions to be performed to install the package to the target directory, when the package is a target package. The package must install its files to the directory given by $(TARGET_DIR). Only the files required for execution of the package have to be installed. Header files, static libraries and documentation will be removed again when the target filesystem is finalized.LIBFOO_INSTALL_STAGING_CMDS
lists the actions to be performed to install the package to the staging directory, when the package is a target package. The package must install its files to the directory given by $(STAGING_DIR). All development files should be installed, since they might be needed to compile other packages.LIBFOO_INSTALL_IMAGES_CMDS
lists the actions to be performed to install the package to the images directory, when the package is a target package. The package must install its files to the directory given by $(BINARIES_DIR). Only files that are binary images (aka images) that do not belong in the TARGET_DIR but are necessary for booting the board should be placed here. For example, a package should utilize this step if it has binaries which would be similar to the kernel image, bootloader or root filesystem images.LIBFOO_INSTALL_INIT_SYSV
, LIBFOO_INSTALL_INIT_OPENRC and LIBFOO_INSTALL_INIT_SYSTEMD list the actions to install init scripts either for the systemV-like init systems (busybox, sysvinit, etc.), openrc or for the systemd units. These commands will be run only when the relevant init system is installed (i.e. if systemd is selected as the init system in the configuration, only LIBFOO_INSTALL_INIT_SYSTEMD will be run). The only exception is when openrc is chosen as init system and LIBFOO_INSTALL_INIT_OPENRC has not been set, in such situation LIBFOO_INSTALL_INIT_SYSV will be called, since openrc supports sysv init scripts. When systemd is used as the init system, buildroot will automatically enable all services using the systemctl preset-all command in the final phase of image building. You can add preset files to prevent a particular unit from being automatically enabled by buildroot.LIBFOO_HELP_CMDS
lists the actions to print the package help, which is included to the main make help output. These commands can print anything in any format. This is seldom used, as packages rarely have custom rules. Do not use this variable, unless you really know that you need to print help.LIBFOO_LINUX_CONFIG_FIXUPS
lists the Linux kernel configuration options that are needed to build and use this package, and without which the package is fundamentally broken. This shall be a set of calls to one of the kconfig tweaking option: KCONFIG_ENABLE_OPT, KCONFIG_DISABLE_OPT, or KCONFIG_SET_OPT. This is seldom used, as package usually have no strict requirements on the kernel options.定义这些变量的首选方法是:
define LIBFOO_CONFIGURE_CMDS
action 1
action 2
action 3
endef
在action
定义中,你可以使用以下变量:
$(LIBFOO_PKGDIR)
contains the path to the directory containing the libfoo.mk and Config.in files. This variable is useful when it is necessary to install a file bundled in Buildroot, like a runtime configuration file, a splashscreen image…$(@D)
, which contains the directory in which the package source code has been uncompressed.$(LIBFOO_DL_DIR)
contains the path to the directory where all the downloads made by Buildroot for libfoo are stored in.$(TARGET_CC)
, $(TARGET_LD)
, etc. to get the target cross-compilation utilities$(TARGET_CROSS)
to get the cross-compilation toolchain prefix$(HOST_DIR)
, $(STAGING_DIR)
and $(TARGET_DIR)
variables to install the packages properly. Those variables point to the global host, staging and target directories, unless per-package directory support is used, in which case they point to the current package host, staging and target directories. In both cases, it doesn’t make any difference from the package point of view: it should simply use HOST_DIR, STAGING_DIR and TARGET_DIR. See Section 8.12, “Top-level parallel build” for more details about per-package directory support.最后,您还可以使用钩子。有关更多信息,请参见第18.22节“各种构建步骤中可用的钩子”。
autotools-package
tutorial首先,让我们看看如何为一个基于自动工具的包编写一个.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))
autotools-package
宏,该宏生成所有实际允许构建包的Makefile规则。autotools-package
referenceautotoolspackage基础结构的主要宏是autotools-package
。它类似于generic-package
宏。通过host-autotools-package
宏,还可以拥有目标包和主机包。
与generic
基础结构一样,autotools基础结构通过在调用autotools-package
宏之前定义大量变量来工作。
首先,所有存在于通用基础架构中的包元数据信息变量也存在于自动工具基础架构中:LIBFOO_VERSION、LIBFOO_SOURCE、LIBFOO_PATCH、LIBFOO_SITE、LIBFOO_SUBDIR、LIBFOO_DEPENDENCIES、LIBFOO_INSTALL_STAGING、LIBFOO_INSTALL_TARGET。
还可以定义一些特定于autotools基础结构的额外变量。它们中的许多只在非常特定的情况下有用,因此典型的包只会使用其中的一些:
LIBFOO_SUBDIR
may contain the name of a subdirectory inside the package that contains the configure script. This is useful, if for example, the main configure script is not at the root of the tree extracted by the tarball. If HOST_LIBFOO_SUBDIR is not specified, it defaults to LIBFOO_SUBDIR.
// LIBFOO_SUBDIR可能包含包含配置脚本的包中的子目录名。这很有用,例如,如果主配置脚本不在tarball提取的树的根上。如果未指定HOST_LIBFOO_SUBDIR,则默认为LIBFOO_SUBDIR。
LIBFOO_CONF_ENV
, to specify additional environment variables to pass to the configure script. By default, empty.
// LIBFOO_CONF_ENV,以指定要传递给配置脚本的其他环境变量。默认情况下,空的。
LIBFOO_CONF_OPTS
, to specify additional configure options to pass to the configure script. By default, empty.
// LIBFOO_CONF_OPTS,以指定传递给配置脚本的其他配置选项。默认情况下,空的。
LIBFOO_MAKE
, to specify an alternate make command. This is typically useful when parallel make is enabled in the configuration (using BR2_JLEVEL) but that this feature should be disabled for the given package, for one reason or another. By default, set to
(
M
A
K
E
)
.
I
f
p
a
r
a
l
l
e
l
b
u
i
l
d
i
n
g
i
s
n
o
t
s
u
p
p
o
r
t
e
d
b
y
t
h
e
p
a
c
k
a
g
e
,
t
h
e
n
i
t
s
h
o
u
l
d
b
e
s
e
t
t
o
L
I
B
F
O
O
M
A
K
E
=
(MAKE). If parallel building is not supported by the package, then it should be set to LIBFOO_MAKE=
(MAKE).Ifparallelbuildingisnotsupportedbythepackage,thenitshouldbesettoLIBFOOMAKE=(MAKE1).
// LIBFOO_MAKE,以指定另一个make命令。如果在配置中启用了并行make(使用BR2_JLEVEL),但是由于某种原因,对于给定的包应该禁用此特性,那么这通常是有用的。默认设置为
(
M
A
K
E
)
。
如
果
这
个
包
不
支
持
并
行
构
建
,
那
么
它
应
该
被
设
置
为
L
I
B
F
O
O
M
A
K
E
=
(MAKE)。如果这个包不支持并行构建,那么它应该被设置为LIBFOO_MAKE=
(MAKE)。如果这个包不支持并行构建,那么它应该被设置为LIBFOOMAKE=(MAKE1)。
LIBFOO_MAKE_ENV
, to specify additional environment variables to pass to make in the build step. These are passed before the make command. By default, empty.
// LIBFOO_MAKE_ENV指定要在构建步骤中传递给make的其他环境变量。这些在make命令之前传递。默认情况下,空的。
LIBFOO_MAKE_OPTS
, to specify additional variables to pass to make in the build step. These are passed after the make command. By default, empty.
// LIBFOO_MAKE_OPTS,以指定在构建步骤中传递给make的其他变量。这些是在make命令之后传递的。默认情况下,空的。
LIBFOO_AUTORECONF
, tells whether the package should be autoreconfigured or not (i.e. if the configure script and Makefile.in files should be re-generated by re-running autoconf, automake, libtool, etc.). Valid values are YES and NO. By default, the value is NO
// LIBFOO_AUTORECONF,告诉是否应该自动重新配置包(即,如果配置脚本和Makefile。在文件中应该通过重新运行autoconf, automake, libtool等重新生成)。取值为“YES”和“NO”。缺省值为NO
LIBFOO_AUTORECONF_ENV
, to specify additional environment variables to pass to the autoreconf program if LIBFOO_AUTORECONF=YES. These are passed in the environment of the autoreconf command. By default, empty.
// LIBFOO_AUTORECONF_ENV,指定当LIBFOO_AUTORECONF=YES时传递给autoreconf程序的附加环境变量。这些是在autoreconf命令的环境中传递的。默认情况下,空的。
LIBFOO_AUTORECONF_OPTS
to specify additional options passed to the autoreconf program if LIBFOO_AUTORECONF=YES. By default, empty.
// LIBFOO_AUTORECONF_OPTS指定当LIBFOO_AUTORECONF=YES时传递给autoreconf程序的附加选项。默认情况下,空的。
LIBFOO_GETTEXTIZE
, tells whether the package should be gettextized or not (i.e. if the package uses a different gettext version than Buildroot provides, and it is needed to run gettextize.) Only valid when LIBFOO_AUTORECONF=YES. Valid values are YES and NO. The default is NO.
// LIBFOO_GETTEXTIZE表示该包是否应该被gettextize(即,如果该包使用的gettext版本与Buildroot提供的不同,并且需要它来运行gettextize)。仅当LIBFOO_AUTORECONF=YES时有效。取值为“YES”和“NO”。默认为NO。
LIBFOO_GETTEXTIZE_OPTS
, to specify additional options passed to the gettextize program, if LIBFOO_GETTEXTIZE=YES. You may use that if, for example, the .po files are not located in the standard place (i.e. in po/ at the root of the package.) By default, -f.
// LIBFOO_GETTEXTIZE_OPTS,如果LIBFOO_GETTEXTIZE=YES,则指定传递给gettextize程序的附加选项。例如,如果.po文件不在标准位置(即在包的根目录po/中),则可以使用。默认情况下,- f。
LIBFOO_LIBTOOL_PATCH
tells whether the Buildroot patch to fix libtool cross-compilation issues should be applied or not. Valid values are YES and NO. By default, the value is YES
// LIBFOO_LIBTOOL_PATCH告诉是否应该应用修复libtool交叉编译问题的Buildroot补丁。取值为“YES”和“NO”。缺省值:YES
LIBFOO_INSTALL_STAGING_OPTS
contains the make options used to install the package to the staging directory. By default, the value is DESTDIR=$(STAGING_DIR) install, which is correct for most autotools packages. It is still possible to override it.
// LIBFOO_INSTALL_STAGING_OPTS包含make选项,用于将包安装到暂存目录。默认情况下,该值为DESTDIR=$(STAGING_DIR) install,这对于大多数自动工具包是正确的。仍然有可能推翻它。
LIBFOO_INSTALL_TARGET_OPTS
contains the make options used to install the package to the target directory. By default, the value is DESTDIR=$(TARGET_DIR) install. The default value is correct for most autotools packages, but it is still possible to override it if needed.
// LIBFOO_INSTALL_TARGET_OPTS包含make选项,用于将包安装到目标目录。默认值为:DESTDIR=$(TARGET_DIR) install。默认值对于大多数自动工具包是正确的,但是如果需要,仍然可以覆盖它。
使用autotools基础结构,已经定义了构建和安装包所需的所有步骤,对于大多数基于autotools的包来说,这些步骤通常可以很好地工作。然而,当需要时,仍然可以自定义在任何特定步骤中所做的事情:
Linux内核包可以使用一些基于包挂钩的特定基础设施来构建Linux内核工具或/和构建Linux内核扩展。
通用基础结构(以及派生的autotools和cmake基础结构)允许包指定钩子。这些定义了在现有步骤之后要执行的进一步操作。大多数钩子对于通用包并不是真正有用,因为.mk文件已经完全控制了包构造的每个步骤中执行的操作。
以下是可用的挂钩点:
这些变量是变量名的列表,其中包含在这个钩子点上要执行的操作。这允许在一个给定的钩子点注册几个钩子。下面是一个例子:
define LIBFOO_POST_PATCH_FIXUP
action1
action2
endef
LIBFOO_POST_PATCH_HOOKS += LIBFOO_POST_PATCH_FIXUP
POST_RSYNC钩子只对使用本地源的包运行,要么通过本地站点方法,要么通过OVERRIDE_SRCDIR机制。在本例中,使用rsync将包源从本地位置复制到buildroot构建目录中。但是,rsync命令不会从源目录复制所有文件。属于版本控制系统的文件,如.git、.hg等目录不会被复制。对于大多数包来说,这已经足够了,但是一个给定的包可以使用POST_RSYNC钩子执行额外的操作。
原则上,钩子可以包含您想要的任何命令。不过,一个特定的用例是有意使用rsync复制版本控制目录。在钩子中使用的rsync命令可以使用以下变量:
包也可以在LIBFOO_TARGET_FINALIZE_HOOKS
中注册钩子。这些钩子在构建所有包之后,但在生成文件系统映像之前运行。它们很少被使用,您的包可能不需要它们。
In Buildroot, there is some relationship between:
It is mandatory to maintain consistency between these elements, using the following rules:
// 必须使用以下规则保持这些元素之间的一致性:
package/foo-bar_boo/foo-bar_boo.mk
);.
和-
字符替换为_
,前缀为BR2_PACKAGE_
(例如:BR2_PACKAGE_FOO_BAR_BOO
);*.mk
文件变量前缀是大写的包名带.
和-
字符替换为_
(例如:FOO_BAR_BOO_VERSION)。Buildroot在utils/check-package中提供了一个脚本,用于检查新的或更改的文件的编码风格。它不是一个完整的语言验证器,但它能捕获许多常见错误。在创建提交的补丁之前,它将在您创建或修改的实际文件中运行。
这个脚本可以用于包、文件系统makefiles、Config。在文件等。它不检查定义包基础结构的文件和包含类似公共代码的其他文件。
要使用它,运行检查包脚本,告诉你创建或修改了哪些文件:
$ ./utils/check-package package/new-package/*
If you have the utils directory in your path you can also run:
$ cd package/new-package/
$ check-package *
The tool can also be used for packages in a br2-external:
$ check-package -b /path/to/br2-ext-tree/package/my-package/*
一旦您添加了新的包,在不同的条件下测试它是很重要的:它是为所有架构构建的吗?它使用不同的C库构建吗?它需要线程吗,NPTL?等等……
Buildroot运行连续测试随机配置的autobuilders。但是,这些只构建了git树的主分支,而你的新包还没有在那里。
Buildroot在utils/test-pkg
中提供了一个脚本,它使用与autobuilders使用的相同的基本配置,因此您可以在相同的条件下测试您的包。
首先,创建一个配置片段,其中包含启用您的包所需的所有必要选项,但不包含任何架构或工具链选项。例如,让我们创建一个配置片段,只启用libcurl,没有任何TLS后端:
$ cat libcurl.config
BR2_PACKAGE_LIBCURL=y
如果您的包需要更多的配置选项,您可以将它们添加到配置片段中。例如,下面是在openssl作为TLS后端和curl程序的情况下如何测试libcurl:
$ 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
The results mean:
当出现故障时,您可以使用相同的选项重新运行脚本(在修复包之后);该脚本将尝试为所有工具链重新构建用-p指定的包,而不需要重新构建该包的所有依赖项。
test-pkg脚本接受一些选项,你可以通过运行这些选项得到一些帮助:
$ ./utils/test-pkg -h
GitHub上的包通常没有带有发布tarball的下载区域。但是,可以直接从GitHub上的存储库下载tarball。由于GitHub在过去已经改变了下载机制,所以应该如下所示使用GitHub助手函数。
# Use a tag or a full commit ID
FOO_VERSION = 1.0
FOO_SITE = $(call github,<user>,<package>,v$(FOO_VERSION))
Notes:
如果你想要添加的包在GitHub上有一个发布部分,维护人员可能已经上传了一个发布tarball,或者发布可能只是指向git标签中自动生成的tarball。如果有一个由维护人员上传的发布tarball,我们更喜欢使用它,因为它可能有一些细微的不同(例如,它包含一个配置脚本,所以我们不需要做AUTORECONF)。
你可以在发布页面上看到,如果它是一个上传的tarball或git标签:
类似于18.24.4节中描述的github宏,“如何从github中添加一个包”,Buildroot还提供了从gitlab库下载的gitlab宏。它可以用来下载由Gitlab生成的自动生成tarball,用于特定的标签或提交:
# Use a tag or a full commit ID
FOO_VERSION = 1.0
FOO_SITE = $(call gitlab,<user>,<package>,v$(FOO_VERSION))
默认情况下,它将使用.tar.gz
tarball,但Gitlab也提供了.tar。因此,通过添加一个<pkg>_SOURCE
变量,这个.tar.bz2
压缩包可以使用:
# Use a tag or a full commit ID
FOO_VERSION = 1.0
FOO_SITE = $(call gitlab,<user>,<package>,v$(FOO_VERSION))
FOO_SOURCE = foo-$(FOO_VERSION).tar.bz2
如果上游开发人员在 https://gitlab.com//releases/ 中上传了一个特定的tarball,不要使用这个宏,而是直接使用到该tarball的链接。
如您所见,将一个软件包添加到Buildroot仅仅是一个使用现有示例编写Makefile并根据该包所需的编译过程修改它的问题。
如果您打包的软件可能对其他人有用,不要忘记向Buildroot邮件列表发送一个补丁(见第22.5节,“提交补丁”)!
在集成新包或更新现有包时,可能需要对软件源代码打补丁,以便在Buildroot中交叉构建。
Buildroot提供了一个基础设施来在构建过程中自动处理这个问题。它支持三种应用补丁集的方式:下载的补丁、内置根中提供的补丁和位于用户定义的全局补丁目录中的补丁。
如果需要应用一个可以下载的补丁,那么将它添加到<packagename>_PATCH
变量中。如果一个条目包含://
,那么Buildroot会假定它是一个完整的URL,并从这个位置下载补丁。否则,Buildroot会假设补丁应该从<packagename>_SITE
下载。它可以是单个补丁,也可以是包含补丁系列的tarball。
与所有下载一样,应该在中添加一个<packagename>.hash
文件。
这种方法通常用于来自Debian的包。
大多数补丁都是在Buildroot包目录中提供的;它们通常旨在修复交叉编译、libc支持或其他此类问题。
这些补丁文件应该命名为<number>-<description>.patch
。
注意:
<number>
的为申请顺序,从1开始;它更倾向于用0到4位填充数字,就像git-format-patc
h做的那样。例如:0001-foobar-the-buz.patch
<package>-<number>-<description>.patch
。但现在不是这样了。现有的包将随着时间的推移而固定。不要用包名作为补丁的前缀。quilt
使用的系列文件也可以添加到包目录中。在这种情况下,系列文件定义了补丁应用程序的顺序。这是不赞成的,并将在将来被删除。不要使用系列文件。BR2_GLOBAL_PATCH_DIR
配置文件选项可用于指定包含全局包补丁的一个或多个目录的空格分隔列表。参见第9.8节“添加特定于项目的补丁”了解详细信息。
<packagename>_PRE_PATCH_HOOKS
commands if defined;*.rej
files;<packagename>_PATCH
is defined, then patches from these tarballs are applied;*.patch
files in the package’s Buildroot directory or in a package subdirectory named , then:series
file;*.patch
are applied in alphabetical order. So, to ensure they are applied in the right order, it is highly recommended to name the patch files like this: <number>-<description>.patch,
where refers to the apply order.BR2_GLOBAL_PATCH_DIR
is defined, the directories will be enumerated in the order they are specified. The patches are applied as described in the previous step.<packagename>_POST_PATCH_HOOKS
commands if defined.If something goes wrong in the steps 3 or 4, then the build fails.
补丁是在与它们所应用的软件相同的许可证下发布的(见章节13.2,“符合Buildroot许可证”)。
一条解释补丁做什么的消息,以及为什么需要它,应该添加在补丁的标题注释中。
您应该在每个补丁的标题中添加一个Signed-off-by声明,以帮助跟踪更改,并证明该补丁是在与被修改的软件相同的许可证下发布的。
如果软件处于版本控制状态,建议使用上游的SCM软件生成补丁集。
否则,将头与diff -purN package-version的输出连接起来。源自/包版本/命令。
如果你更新了一个现有的补丁(例如,当碰撞包版本时),确保现有的From头和Signed-off-by标签没有被删除,但是在适当的时候更新补丁注释的其余部分。
最后,补丁看起来应该是这样的:
configure.ac: add C++ support test
Signed-off-by: John Doe <john.doe@noname.org>
--- configure.ac.orig
+++ configure.ac
@@ -40,2 +40,12 @@
AC_PROG_MAKE_SET
+
+AC_CACHE_CHECK([whether the C++ compiler works],
+ [rw_cv_prog_cxx_works],
+ [AC_LANG_PUSH([C++])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],
+ [rw_cv_prog_cxx_works=yes],
+ [rw_cv_prog_cxx_works=no])
+ AC_LANG_POP([C++])])
+
+AM_CONDITIONAL([CXX_WORKS], [test "x$rw_cv_prog_cxx_works" = "xyes"])
当集成一个您不是作者的补丁时,您必须在补丁本身的标题中添加一些东西。
根据补丁是从项目存储库本身获得的,还是从web上的某个地方获得的,添加以下标记之一:
Backported from: <some commit id>
或
Fetch from: <some url>
在补丁中添加一些必要的修改也是明智的。
在构建包时,可以使用Buildroot所执行的步骤。定义变量BR2_INSTRUMENTATION_SCRIPTS
来包含一个或多个脚本(或其他可执行文件)的路径,在一个空格分隔的列表中,您希望在每个步骤之前和之后调用它。这些脚本被依次调用,有三个参数:
start
or end
to denote the start (resp. the end) of a step;step
about to be started, or which just ended;For example :
make BR2_INSTRUMENTATION_SCRIPTS="/path/to/my/script1 /path/to/my/script2"
The list of steps
is:
extract
patch
configure
build
install-host
, when a host-package is installed in $(HOST_DIR)install-target
, when a target-package is installed in $(TARGET_DIR)install-staging
, when a target-package is installed in $(STAGING_DIR)install-image
, when a target-package installs files in $(BINARIES_DIR)The script has access to the following variables:
BR2_CONFIG
: the path to the Buildroot .config fileHOST_DIR
, STAGING_DIR, TARGET_DIR: see Section 18.5.2, “generic-package reference”BUILD_DIR
: the directory where packages are extracted and builtBINARIES_DIR
: the place where all binary files (aka images) are storedBASE_DIR
: the base output directory手机扫一扫
移动阅读更方便
你可能感兴趣的文章