Buildroot 用户手册 (中文) 您所在的位置:网站首页 busybox用途 Buildroot 用户手册 (中文)

Buildroot 用户手册 (中文)

2023-12-02 19:17| 来源: 网络整理| 查看: 265

文章目录 I. Getting started1. About Buildroot2. System requirements2.1. Mandatory packages2.2. Optional packages 3. Getting Buildroot4. Buildroot quick start4.1 configuration4.2 build 5. Community resources II. User guide6. Buildroot configuration6.1. Cross-compilation toolchain6.1.1. Internal toolchain backend6.1.2. External toolchain backend6.1.3. Build an external toolchain with Buildroot6.1.4. External toolchain wrapper 6.2. /dev management6.3. init system 7. Configuration of other components8. General Buildroot usage8.1. make tips8.2. Understanding when a full rebuild is necessary8.3. Understanding how to rebuild packages8.4. Offline builds8.5. Building out-of-tree8.6. Environment variables8.7. Dealing efficiently with filesystem images8.8. Details about packages8.9. Graphing the dependencies between packages8.10. Graphing the build duration8.11. Graphing the filesystem size contribution of packages8.12. Top-level parallel build8.13. Integration with Eclipse8.14. Advanced usage8.14.1 Using the generated toolchain outside Buildroot8.14.2 Using `gdb` in Buildroot8.14.3 Using `ccache` in Buildroot8.14.4 Location of downloaded packages8.14.5 Package-specific make targets8.14.6 Using Buildroot during development 9. Project-specific customization9.1. Recommended directory structure9.1.1. Implementing layered customizations 9.2. Keeping customizations outside of Buildroot9.2.1. Layout of a br2-external tree 9.3. Storing the Buildroot configuration9.4. Storing the configuration of other components9.5. Customizing the generated target filesystem9.5.1. Setting file permissions and ownership and adding custom devices nodes 9.6. Adding custom user accounts9.7. Customization after the images have been created9.8. Adding project-specific patches9.9. Adding project-specific packages9.10. Quick guide to storing your project-specific customizations 10. Using SELinux in Buildroot10.1. Enabling SELinux support10.2. SELinux policy tweaking 11. Frequently Asked Questions & Troubleshooting11.1. The boot hangs after Starting network…11.2. Why is there no compiler on the target?11.3. Why are there no development files on the target?11.4. Why is there no documentation on the target?11.5. Why are some packages not visible in the Buildroot config menu?11.6. Why not use the target directory as a chroot directory?11.7. Why doesn’t Buildroot generate binary packages (.deb, .ipkg…)?11.8. How to speed-up the build process? 12. Known issues13. Legal notice and licensing13.1. Complying with open source licenses13.2. Complying with the Buildroot license13.2.1. Patches to packages 14. Beyond Buildroot14.1. Boot the generated images14.1.1. NFS boot14.1.2. Live CD 14.2. Chroot III. Developer guide15. How Buildroot works16. Coding style16.1. Config.in file16.2. The .mk file16.3. The documentation16.4. Support scripts 17. Adding support for a particular board18. Adding new packages to Buildroot18.1. Package directory18.2. Config files18.2.1. `Config.in` file18.2.2. `Config.in.host` file18.2.3. Choosing `depends on` or `select`18.2.4. Dependencies on target and toolchain options18.2.5. Dependencies on a Linux kernel built by buildroot18.2.6. Dependencies on udev /dev management18.2.7. Dependencies on features provided by virtual packages 18.3. The .mk file18.4. The .hash file18.5. Infrastructure for packages with specific build systems18.5.1. `generic-package` tutorial18.5.2. `generic-package` reference 18.6. Infrastructure for autotools-based packages18.6.1. `autotools-package` tutorial18.6.2. `autotools-package` reference 18.7. Infrastructure for CMake-based packages18.8. Infrastructure for Python packages18.9. Infrastructure for LuaRocks-based packages18.10. Infrastructure for Perl/CPAN packages18.11. Infrastructure for virtual packages18.12. Infrastructure for packages using kconfig for configuration files18.13. Infrastructure for rebar-based packages18.14. Infrastructure for Waf-based packages18.15. Infrastructure for Meson-based packages18.16. Integration of Cargo-based packages18.17. Infrastructure for Go packages18.18. Infrastructure for QMake-based packages18.19. Infrastructure for packages building kernel modules18.20. Infrastructure for asciidoc documents18.21. Infrastructure specific to the Linux kernel package18.21.1. linux-kernel-tools18.21.2. linux-kernel-extensions 18.22. Hooks available in the various build steps18.22.1. Using the POST_RSYNC hook18.22.2. Target-finalize hook 18.23. Gettext integration and interaction with packages18.24. Tips and tricks18.24.1. Package name, config entry name and makefile variable relationship18.24.2. How to check the coding style18.24.3. How to test your package18.24.4. How to add a package from GitHub18.24.5. How to add a package from Gitlab 18.25. Conclusion 19. Patching a package19.1. Providing patches19.1.1. Downloaded19.1.2. Within Buildroot19.1.3. Global patch directory 19.2. How patches are applied19.3. Format and licensing of the package patches19.4. Integrating patches found on the Web 20. Download infrastructure21. Debugging Buildroot22. Contributing to Buildroot22.1. Reproducing, analyzing and fixing bugs22.2. Analyzing and fixing autobuild failures22.3. Reviewing and testing patches22.4. Work on items from the TODO list22.5. Submitting patches22.6. Reporting issues/bugs or getting help22.7. Using the run-tests framework 23. DEVELOPERS file and get-developers24. Release Engineering24.1. Releases24.2. Development IV. Appendix25. Makedev syntax documentation26. Makeusers syntax documentation27. Migrating from older Buildroot versions27.1. Migrating to 2016.1127.2. Migrating to 2017.08

本文为译文,英文原文地址:The Buildroot user manual

I. Getting started 1. About Buildroot

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]。

2. System requirements

Buildroot设计用于在Linux系统上运行。

虽然Buildroot本身将构建它编译所需的大多数主机包,但某些标准的Linux实用程序预计已经安装在主机系统上。下面是强制包和可选包的概述(注意,不同发行版的包名称可能有所不同)。

2.1. Mandatory packages

以下是 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 2.2. Optional packages

以下是可选安装的程序:

Recommended dependencies:

Buildroot中的一些特性或实用程序,如the legal-info或the graph generation tools,有额外的依赖关系。尽管它们不是简单构建的强制要求,但仍然强烈推荐使用:

python (version 2.7 or any later) Configuration interface dependencies:

对于这些库,您需要同时安装运行时数据和开发数据,在许多发行版中,这些数据是单独打包的。开发包通常有一个-dev或-devel后缀。

ncurses5 to use the menuconfig interface qt5 to use the xconfig interface glib2, gtk2 and glade2 to use the gconfig interface Source fetching tools:

在官方树中,大多数包源都是使用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 -graph-depends python-matplotlib to use graph-build 3. Getting Buildroot

Buildroot版本每3个月发布一次,分别是在2月、5月、8月和11月。版本号的格式为YYYY.MM,例如2013.02,2014.08。发布tarball可以在http://buildroot.org/downloads/上找到。

有两种方式可以搭建起 Buildroot 开发环境:

1、Virtualbox 虚拟机

为方便起见,在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 2、手工下载

如果您想继续开发,可以使用日常快照或复制Git存储库。更多详细信息,请参考Buildroot网站的下载页面。

4. Buildroot quick start

重要:你可以并且应该像普通用户一样构建一切。配置和使用Buildroot不需要是root。通过作为普通用户运行所有命令,可以保护系统免受包在编译和安装期间行为不正常的影响。

4.1 configuration

使用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读取。

4.2 build

要启动构建过程,只需运行:

$ make

默认情况下,Buildroot不支持顶级并行构建,所以没有必要运行make -jN。不过,也有对顶层并行构建的实验性支持,请参见8.12节“顶层并行构建”。

上述make命令一般执行如下步骤:

download source files (as required);// 下载源文件(根据需要);configure, build and install the cross-compilation toolchain, or simply import an external toolchain;// 配置、构建和安装交叉编译工具链,或者简单地导入外部工具链;configure, build and install selected target packages;// 配置、构建和安装选定的目标包;build a kernel image, if selected;// 如果选择,构建一个内核映像;build a bootloader image, if selected;// 如果选择,构建一个引导加载程序映像;create a root filesystem in selected formats.// 以选定的格式创建根文件系统。

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.// 包含为该主机构建的工具和目标工具链的sysroot。前者是为正确执行Buildroot所需的主机编译的工具的安装,包括交叉编译工具链。后者是类似于根文件系统层次结构的层次结构。它包含所有提供和安装其他包使用的库的用户空间包的头和库。但是,这个目录并不打算作为目标的根文件系统:它包含大量开发文件、未剥离的二进制文件和库,这使得它对于嵌入式系统来说太大了。这些开发文件用于为依赖于其他库的目标编译库和应用程序。staging/ is a symlink to the target toolchain sysroot inside host/, which exists for backwards compatibility.// 指向host/内部目标工具链sysroot的符号链接,它的存在是为了向后兼容。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”中给出。

5. Community resources

社区资源 (略)。

II. User guide 6. Buildroot configuration

make *config中的所有配置选项都有一个帮助文本,提供关于该选项的详细信息。

make *config命令也提供了一个搜索工具。阅读不同前端菜单中的帮助信息,了解如何使用它:

在menuconfig中,搜索工具通过按/;在xconfig中,通过按Ctrl + f调用搜索工具。

搜索结果显示匹配项的帮助信息。在menuconfig中,左边列中的数字为相应的条目提供了快捷方式。只要输入这个数字就可以直接跳转到条目,或者跳转到包含的菜单(如果条目由于缺少依赖项而无法选择的话)。

尽管条目的菜单结构和帮助文本应该具有足够的自解释性,但有一些主题需要额外的解释,这些内容不容易在帮助文本中介绍,因此将在下面的部分中介绍。

6.1. Cross-compilation toolchain

编译工具链是一组允许您为系统编译代码的工具。它包括一个编译器(在我们的例子中是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选项可以在这两个解决方案之间进行选择。一旦选择了一个解决方案,就会出现许多配置选项,以下部分将详细介绍这些选项。

6.1.1. Internal toolchain backend

在为目标嵌入式系统构建用户空间应用程序和库之前,内部工具链后端是Buildroot自己构建交叉编译工具链的后端。

这个后端支持几个C库:uClibc-ng、glibc和musl。

一旦您选择了这个后端,就会出现许多选项。最重要的是以下选项:

Change the version of the Linux kernel headers used to build the toolchain. This item deserves a few explanations. In the process of building a cross-compilation toolchain, the C library is being built. This library provides the interface between userspace applications and the Linux kernel. In order to know how to “talk” to the Linux kernel, the C library needs to have access to the Linux kernel headers (i.e. the .h files from the kernel), which define the interface between userspace and the kernel (system calls, data structures, etc.). Since this interface is backward compatible, the version of the Linux kernel headers used to build your toolchain do not need to match exactly the version of the Linux kernel you intend to run on your embedded system. They only need to have a version equal or older to the version of the Linux kernel you intend to run. If you use kernel headers that are more recent than the Linux kernel you run on your embedded system, then the C library might be using interfaces that are not provided by your Linux kernel.// 更改用于构建工具链的Linux内核头文件的版本。这一项值得作一些解释。在构建交叉编译工具链的过程中,正在构建C库。这个库提供了用户空间应用程序和Linux内核之间的接口。为了知道如何与Linux内核“对话”,C库需要访问Linux内核的头文件(即来自内核的.h文件),它定义了用户空间和内核之间的接口(系统调用、数据结构等)。因为这个接口是向后兼容的,所以用于构建工具链的Linux内核头的版本不需要与您打算在嵌入式系统上运行的Linux内核的版本完全匹配。它们只需要一个与您要运行的Linux内核版本相同或更老的版本即可。如果您使用的内核头比您在嵌入式系统上运行的Linux内核更新,那么C库可能使用的接口不是由您的Linux内核提供的。Change the version of the GCC compiler, binutils and the C library.// 更改GCC编译器、binutils和C库的版本。Select a number of toolchain options (uClibc only): whether the toolchain should have RPC support (used mainly for NFS), wide-char support, locale support (for internationalization), C++ support or thread support. Depending on which options you choose, the number of userspace applications and libraries visible in Buildroot menus will change: many applications and libraries require certain toolchain options to be enabled. Most packages show a comment when a certain toolchain option is required to be able to enable those packages. If needed, you can further refine the uClibc configuration by running make uclibc-menuconfig. Note however that all packages in Buildroot are tested against the default uClibc configuration bundled in Buildroot: if you deviate from this configuration by removing features from uClibc, some packages may no longer build.// 选择一些工具链选项(仅限uClibc):工具链是否应该有RPC支持(主要用于NFS)、宽字符支持、区域支持(用于国际化)、c++支持或线程支持。根据您选择的选项,可见于Buildroot菜单中的用户空间应用程序和库的数量将会改变:许多应用程序和库需要启用某些工具链选项。当需要某个工具链选项来启用这些包时,大多数包都会显示注释。如果需要,您可以通过运行make uClibc -menuconfig来进一步优化uClibc配置。但是请注意,Buildroot中的所有包都是根据默认的uClibc配置进行测试的:如果你通过从uClibc中删除特性而偏离这个配置,一些包可能不再构建。

值得注意的是,每当其中一个选项被修改时,就必须重新构建整个工具链和系统。请参阅第8.2节 “了解什么时候需要进行完全重建”。

这个后端的优点:

Well integrated with Buildroot // 与Buildroot集成良好Fast, only builds what’s necessary // 快速,只构建必要的内容

这个后端的缺点:

Rebuilding the toolchain is needed when doing make clean, which takes time. If you’re trying to reduce your build time, consider using the External toolchain backend.// 在做make clean时需要重建工具链,这需要时间。如果您试图减少构建时间,请考虑使用External工具链后端。 6.1.2. External toolchain backend

外部工具链后端允许使用现有的预构建的交叉编译工具链。Buildroot知道许多著名的交叉编译工具链(从Linaro for ARM、Sourcery CodeBench for ARM、x86-64、PowerPC和MIPS),并且能够自动下载它们,或者它可以指向一个定制的工具链,可以下载或在本地安装。

目前,你有三个解决方案来使用外部工具链:

Use a predefined external toolchain profile, and let Buildroot download, extract and install the toolchain. Buildroot already knows about a few CodeSourcery and Linaro toolchains. Just select the toolchain profile in Toolchain from the available ones. This is definitely the easiest solution.// 使用预定义的外部工具链概要文件,并让Buildroot下载、提取和安装工具链。Buildroot已经知道一些CodeSourcery和Linaro工具链。只需在Toolchain中从可用的工具链概要文件中选择工具链概要文件。这绝对是最简单的解决方案。Use a predefined external toolchain profile, but instead of having Buildroot download and extract the toolchain, you can tell Buildroot where your toolchain is already installed on your system. Just select the toolchain profile in Toolchain through the available ones, unselect Download toolchain automatically, and fill the Toolchain path text entry with the path to your cross-compiling toolchain.// 使用一个预定义的外部工具链概要文件,但是不必让Buildroot下载和提取工具链,您可以告诉Buildroot您的工具链已经安装在系统的哪个位置。只需在Toolchain中选择工具链配置文件,取消选择自动下载工具链,并在Toolchain path文本条目中填写交叉编译工具链的路径。Use a completely custom external toolchain. This is particularly useful for toolchains generated using 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。

这个后端的优点:

Allows to use well-known and well-tested cross-compilation toolchains. // 允许使用众所周知和经过良好测试的交叉编译工具链。Avoids the build time of the cross-compilation toolchain, which is often very significant in the overall build time of an embedded Linux system. // 避免交叉编译工具链的构建时间,这在嵌入式Linux系统的总体构建时间中通常非常重要。

这个后端的缺点:

If your pre-built external toolchain has a bug, may be hard to get a fix from the toolchain vendor, unless you build your external toolchain by yourself using Buildroot or Crosstool-NG.// 如果你预构建的外部工具链有bug,可能很难从工具链供应商那里得到修复,除非你自己使用Buildroot或Crosstool-NG构建自己的外部工具链。 6.1.3. Build an external toolchain with Buildroot

Buildroot内部工具链选项可用于创建外部工具链。下面是构建内部工具链并将其打包以供Buildroot自身(或其他项目)重用的一系列步骤。

1、创建一个新的Buildroot配置,详细信息如下:

Select the appropriate Target options for your target CPU architectureIn the Toolchain menu, keep the default of Buildroot toolchain for Toolchain type, and configure your toolchain as desiredIn the System configuration menu, select None as the Init system and none as /bin/shIn the Target packages menu, disable BusyBoxIn the 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菜单中:

Set Toolchain type to External toolchainSet Toolchain to Custom toolchainSet Toolchain origin to Toolchain to be downloaded and installedSet Toolchain URL to file:///path/to/your/sdk/tarball.tar.gz 6.1.4. External toolchain wrapper

当使用外部工具链时,Buildroot生成一个wrapper程序,该程序透明地将适当的选项(根据配置)传递给外部工具链程序。如果您需要调试这个wrapper来检查传递了哪些参数,您可以将环境变量BR2_DEBUG_WRAPPER设置为以下任意一个:

0, empty or not set: no debug1: trace all arguments on a single line2: trace one argument per line 6.2. /dev management

在Linux系统中,/dev目录包含特殊的文件,称为设备文件(device files),允许用户空间应用程序访问Linux内核管理的硬件设备。如果没有这些设备文件,您的用户空间应用程序将不能使用硬件设备,即使它们被Linux内核正确识别。

在System configuration,/dev management下,Buildroot提供了四种不同的解决方案来处理/dev目录:

The first solution is 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///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///device_table_dev.txt. For more details about the format of the device table file, see Chapter 25, Makedev syntax documentation.// 第一个解决方案是静态使用设备表。这是Linux中处理设备文件的古老的经典方法。使用此方法,设备文件将持久化地存储在根文件系统中(即,它们在重新引导时持久化),当从系统中添加或删除硬件设备时,不会自动创建和删除这些设备文件。因此,Buildroot使用设备表创建一组标准的设备文件,默认的设备表存储在Buildroot源代码中的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///device_table_dev.txt。有关设备表文件格式的更多详细信息,请参见第25章Makedev语法文档。The second solution is 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动态。devtmpfs是内核2.6.32中引入的Linux内核中的一个虚拟文件系统(如果使用旧内核,则不可能使用此选项)。当挂载到/dev中时,这个虚拟文件系统将自动使设备文件随着硬件设备的添加和从系统中移除而出现和消失。这个文件系统在重新引导时不是持久的:它是由内核动态填充的。使用devtmpfs需要启用以下内核配置选项:CONFIG_DEVTMPFS和CONFIG_DEVTMPFS_MOUNT。当Buildroot负责为您的嵌入式设备构建Linux内核时,它会确保启用这两个选项。但是,如果您在Buildroot之外构建Linux内核,那么您就有责任启用这两个选项(如果您没有这样做,那么您的Buildroot系统将无法引导)。The third solution is 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.// 第三种解决方案是动态使用devtmpfs + mdev。这个方法还依赖于上面详细介绍的devtmpfs虚拟文件系统(因此在内核配置中启用CONFIG_DEVTMPFS和CONFIG_DEVTMPFS_MOUNT的要求仍然适用),但是在它上面添加了mdev用户空间实用程序。mdev是BusyBox的一个程序部分,每次添加或删除设备时内核都会调用它。由于/etc/mdev.conf配置文件,mdev可以配置为例如,设置特定的权限或对设备文件的所有权,每当设备出现或消失时调用脚本或应用程序,等等。基本上,它允许用户空间对设备添加和删除事件做出反应。例如,当设备出现在系统上时,可以使用Mdev自动加载内核模块。如果您有需要固件的设备,Mdev也很重要,因为它将负责将固件内容推送到内核。Mdev是udev的一个轻量级实现(具有更少的特性)。有关mdev及其配置文件语法的详细信息,请参见http://git.busybox.net/busybox/tree/docs/mdev.txt。The fourth solution is 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.// 第四种解决方案是动态使用devtmpfs + eudev。这个方法也依赖于上面详细介绍的devtmpfs虚拟文件系统,但是在它上面添加了eudev用户空间守护进程。Eudev是一个在后台运行的守护进程,当设备从系统中添加或删除时,内核会调用它。它是一个比mdev更重量级的解决方案,但提供了更高的灵活性。eudev是udev的一个独立版本,udev是大多数桌面Linux发行版中使用的原始用户空间守护进程,现在是Systemd的一部分。更多信息请参见http://en.wikipedia.org/wiki/Udev。

Buildroot开发人员的建议是从Dynamic using devtmpfs only的解决方案开始,直到您需要通知用户空间何时添加/删除设备,或是否需要固件,在这种情况下,Dynamic using devtmpfs + mdev通常是一个很好的解决方案。

注意,如果选择systemd作为init系统,/dev管理将由systemd提供的udev程序执行。

6.3. init system

init程序是由内核启动的第一个用户空间程序(它的PID号为1),负责启动用户空间服务和程序(例如:web服务器、图形应用程序、其他网络服务器等)。

Buildroot允许使用三种不同类型的初始化系统,可以从System configuration, Init system中选择:

The first solution is 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).// 第一个解决方案是BusyBox。在许多程序中,BusyBox有一个基本的init程序的实现,这对于大多数嵌入式系统来说已经足够了。启用BR2_INIT_BUSYBOX将确保BusyBox将构建并安装它的init程序。这是Buildroot中的默认解决方案。BusyBox初始化程序将在启动时读取/etc/inittab文件,以知道要做什么。该文件的语法可以在http://git.busybox.net/busybox/tree/examples/inittab中找到(注意,BusyBox的inittab语法是特殊的:不要使用Internet上随机的inittab文档来了解BusyBox的inittab)。“Buildroot”默认的“inittab”存放在“system/skeleton/etc/inittab”中。除了挂载一些重要的文件系统外,默认的inittab所做的主要工作是启动/etc/init. confd/rcS shell脚本,并启动getty程序(提供登录提示)。The second solution is 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.// 第二个解决方案是systemV。这个解决方案使用旧的传统的sysvinit程序,打包在Buildroot中的package/sysvinit。这是在大多数桌面Linux发行版中使用的解决方案,直到他们转向更近期的替代方案,如Upstart或Systemd。sysvinit还可以使用inittab文件(与BusyBox中的文件语法略有不同)。与此init解决方案一起安装的默认inittab位于package/sysvinit/inittab中。The third solution is 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.// 第三个解决方案是系统化的。systemd是Linux系统的新一代init系统。它比传统的初始化程序做得更多:使用socket和D-Bus激活来启动服务,提供按需启动守护进程,使用Linux控制组跟踪进程,支持系统状态的快照和恢复等。systemd在相对复杂的嵌入式系统上非常有用。例如需要D-Bus和服务相互通信的。值得注意的是,systemd带来了相当多的大型依赖:dbus, udev等等。有关systemd的更多信息,请参见http://www.freedesktop.org/wiki/Software/systemd。

Buildroot开发人员推荐的解决方案是使用BusyBox init,因为它对于大多数嵌入式系统来说已经足够了。Systemd可以用于更复杂的情况。

7. Configuration of other components

在尝试修改下面的任何组件之前,请确保您已经配置了Buildroot本身,并启用了相应的包。

BusyBox

如果您已经有一个BusyBox配置文件,您可以直接在Buildroot配置中指定这个文件,使用BR2_PACKAGE_BUSYBOX_CONFIG。否则,Buildroot将从默认的BusyBox配置文件启动。

要对配置进行后续更改,请使用make busybox-menuconfig打开BusyBox配置编辑器。

还可以通过环境变量指定BusyBox配置文件,不过不建议这样做。请参阅8.6节“环境变量”了解更多细节。

uClibc

uClibc的配置方法与BusyBox相同。指定现有配置文件的配置变量是BR2_UCLIBC_CONFIG。进行后续更改的命令是make uclibc-menuconfig。

Linux kernel

如果您已经有了一个内核配置文件,那么可以使用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

Barebox的配置方法与Linux内核的配置方法相同。对应的配置变量是BR2_TARGET_BAREBOX_USE_CUSTOM_CONFIG和BR2_TARGET_BAREBOX_USE_DEFCONFIG。要打开配置编辑器,请使用make barebox-menuconfig。

U-Boot

U-Boot(2015.04及以上版本)的配置方法与Linux内核相同。对应的配置变量是BR2_TARGET_UBOOT_USE_CUSTOM_CONFIG和BR2_TARGET_UBOOT_USE_DEFCONFIG。打开配置编辑器,使用make uboot-menuconfig。

8. General Buildroot usage 8.1. make tips

这是一组技巧,可以帮助你充分利用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.

Cleaning`: Explicit cleaning is required when any of the architecture or toolchain configuration options are changed. // 当任何架构或工具链配置选项发生更改时,需要显式清理。

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 8.2. Understanding when a full rebuild is necessary

当通过make menuconfig、make xconfig或其他配置工具改变系统配置时,Buildroot不会试图检测应该重新构建系统的哪些部分。在某些情况下,Buildroot应该重建整个系统,在某些情况下,只重建软件包的特定子集。但是以一种完全可靠的方式检测它是非常困难的,因此Buildroot开发人员决定不尝试这样做。

相反,用户有责任知道什么时候需要进行完全重新构建。作为提示,这里有一些经验法则可以帮助你理解如何使用Buildroot:

当目标体系结构配置发生更改时,需要进行完整的重新构建。改变架构变体(例如二进制格式或浮点策略)会对整个系统产生影响。当工具链配置发生更改时,通常需要进行一次完整的重新构建。更改工具链配置通常涉及更改编译器版本、C库的类型或其配置,或其他一些基本配置项,这些更改会对整个系统产生影响。当向配置中添加额外的包时,并不一定需要完全重新构建。Buildroot将检测到这个包从未被构建过,并将其构建。但是,如果这个包是一个可以被已经构建的包使用的库,那么Buildroot将不会自动重新构建这些库。您可以知道应该重新构建哪些包,并且可以手动重新构建它们,也可以进行完整的重新构建。例如,假设您已经构建了一个使用crbt包但不使用openssl的系统。您的系统可以工作,但是您意识到您希望在crbt中有SSL支持,所以您在Buildroot配置中启用openssl包并重新启动构建。Buildroot将检测是否应该构建openssl并将其构建,但它不会检测是否应该重新构建crbt以从openssl中获益以添加对openssl的支持。您将不得不做一个完全重建,或重建ctorrent本身。当从配置中删除一个包时,Buildroot不会做任何特殊的事情。它不会从目标根文件系统或工具链sysroot中删除该包安装的文件。要摆脱这个包,需要一个完整的重建。但是,通常您不需要立即删除这个包:您可以等到下一次午休时间重新开始构建。当包的子选项发生更改时,不会自动重新生成包。在做了这些更改之后,通常只重新构建这个包就足够了,除非启用包子选项将一些对已经构建的另一个包有用的特性添加到包中。同样,Buildroot不会跟踪什么时候应该重新构建包:一旦构建了一个包,它就永远不会重新构建,除非明确地告诉它这样做。当对根文件系统框架进行更改时,需要进行一次完整的重新构建。但是,当对根文件系统覆盖层、构建后脚本或图像后脚本进行更改时,就不需要进行完全的重新构建:一个简单的make调用将考虑这些更改。当在FOO_DEPENDENCIES中列出的包被重新构建或删除时,包foo不会自动重新构建。例如,如果在带有FOO_DEPENDENCIES = bar的FOO_DEPENDENCIES中列出了一个包bar,并且bar包的配置发生了改变,那么配置的改变不会自动导致foo包的重新构建。在这个场景中,您可能需要重新构建构建中引用bar中的DEPENDENCIES中的任何包,或者执行完整的重新构建以确保任何bar依赖的包都是最新的。

一般来说,当您面临构建错误并且不确定所做的配置更改的潜在后果时,请执行完整的重新构建。如果您得到相同的构建错误,那么您可以肯定这个错误与包的部分重构无关,如果这个错误发生在来自官方Buildroot的包上,请不要犹豫报告这个问题!随着您使用Buildroot的经验的积累,您将逐步了解什么时候真正需要一个完整的重建,您将节省越来越多的时间。

作为参考,完全重建可以通过运行:

$ make clean all 8.3. Understanding how to rebuild packages

Buildroot用户最常问的问题之一是如何重新构建给定的包,或者如何在不重新构建所有内容的情况下删除包。

如果不从头重新构建,Buildroot不支持删除包。这是因为Buildroot没有跟踪哪个包在output/staging目录和output/target目录中安装了什么文件,或者哪个包会根据另一个包的可用性进行不同的编译。

从头重新构建单个包的最简单方法是删除output/build中的构建目录。然后,Buildroot将重新提取、重新配置、重新编译和重新安装这个包。你可以通过make -dirclean命令要求buildroot这样做。

另一方面,如果只希望从编译步骤重新启动包的构建过程,可以运行make -rebuild。它将重新启动包的编译和安装,但不是从头开始:它基本上会在包内重新执行make和make install,因此它只会重新构建更改过的文件。

如果您想从配置步骤重新启动包的构建过程,可以运行make -reconfigure。它将重新启动包的配置、编译和安装。

虽然-rebuild意味着-reinstall,-reconfigure意味着-rebuild,但是这些目标以及只对上述起作用,并且不会触发重新创建根文件系统映像。如果需要重新创建根文件系统,还应该运行make或make all。

在内部,Buildroot创建所谓的戳文件(stamp files),以跟踪每个包的哪些构建步骤已经完成。它们存储在包构建目录output/build/-/中,命名为.stamp_。上面详细介绍的命令只是操作这些戳文件,以强制Buildroot重新启动包构建过程的一组特定步骤。

关于包装特殊制造目标的进一步细节在8.14.5节“特定于包装的制造目标”中解释。

8.4. Offline builds

如果你打算进行离线构建,并且只是想下载你之前在配置器(menuconfig, nconfig, xconfig或gconfig)中选择的所有源代码,那么发出:

$ make source

现在可以断开dl目录的内容或将其复制到构建主机中。

8.5. Building out-of-tree

默认情况下,Buildroot构建的所有内容都存储在Buildroot树的输出目录中。

Buildroot还支持用类似于Linux内核的语法从树外构建。要使用它,请在make命令行中添加O=:

$ 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 8.6. Environment variables

Buildroot也遵循一些环境变量,当它们被传递到环境中make或set时:

HOSTCXX, the host C++ compiler to use // 主机c++编译器HOSTCC, the host C compiler to use // 主机c编译器UCLIBC_CONFIG_FILE=, 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.// uClibc配置文件的路径,用于编译uClibc,如果一个内部工具链正在构建。请注意,uClibc配置文件也可以从配置界面设置,所以可以通过Buildroot .config文件;这是推荐的设置方法。BUSYBOX_CONFIG_FILE=, 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.// BusyBox配置文件的路径。注意,BusyBox配置文件也可以从配置界面设置,所以可以通过Buildroot .config文件;这是推荐的设置方法。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.// 覆盖Buildroot存储/检索下载文件的目录。注意,也可以从配置界面设置Buildroot下载目录,通过Buildroot .config文件。关于如何设置下载目录的更多细节,请参见8.14.4节“下载包的位置”。vBR2_GRAPH_ALT, if set and non-empty, to use an alternate color-scheme in build-time graphs// (如果设置为非空)用于在构建时图表中使用另一种颜色方案BR2_GRAPH_OUT to set the filetype of generated graphs, either pdf (the default), or png.// 设置生成图形的文件类型,pdf(默认)或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 options// 向依赖关系图传递额外选项;关于可接受的选项,请参见8.9节,“绘制包之间的依赖关系”BR2_GRAPH_DOT_OPTS is passed verbatim as options to the dot utility to draw the dependency graph.// 作为选项逐字传递给dot实用程序,以绘制依赖关系图。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// 向size图传递额外的选项;请参阅8.11节,“用图表示包的文件系统大小”来获得可接受的选项

下面是一个使用顶层目录和$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 8.7. Dealing efficiently with filesystem images

文件系统映像可以变得相当大,这取决于你选择的文件系统、包的数量,以及你是否提供了空闲空间……然而,文件系统映像中的一些位置可能只是空的(例如,长期运行的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文件系统的块位图可能损坏;或者,如果您的文件系统中有稀疏文件,那么这些部分在回读时可能不是全零)。您应该只在构建机器上处理文件时使用稀疏文件,而不是将它们传输到目标上使用的实际设备时。

8.8. Details about packages

Buildroot可以生成一个JSON简介,描述当前配置中启用的包集,以及它们的依赖项、许可和其他元数据。这个JSON简介是通过使用show-info make目标产生的:

make show-info

Buildroot还可以使用pkg-stats make 目标生成关于包的HTML和JSON输出的详细信息。除了其他内容外,这些细节包括已知的cve(安全漏洞)是否会影响当前配置中的包。它还显示了这些包是否有更新的上游版本。

make pkg-stats 8.9. Graphing the dependencies between packages

Buildroot的工作之一是了解包之间的依赖关系,并确保它们以正确的顺序构建。这些依赖有时非常复杂,对于一个给定的系统,通常不容易理解为什么Buildroot将这样或那样的包引入构建中。

为了帮助理解依赖关系,从而更好地理解不同组件在嵌入式Linux系统中的角色,Buildroot能够生成依赖关系图。

要生成你所编译的整个系统的依赖关系图,只需运行:

make graph-depends

您将在output/graphs/graph-dependencies.pdf中找到生成的图形。

如果您的系统相当大,依赖关系图可能过于复杂和难以阅读。因此,为给定的包生成依赖关系图是可能的:

make -graph-depends

您将在output/graph/-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 8.10. Graphing the build duration

当构建一个系统需要很长时间时,有时能够了解哪些包的构建时间最长,看看是否可以做些什么来加快构建速度是很有用的。为了帮助这样的构建时间分析,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 package// 每个包的构建时间饼图build.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 8.11. Graphing the filesystem size contribution of packages

当目标系统增长时,有时了解每个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 size// 每个包对总的根文件系统大小的贡献饼图output/graphs/package-size-stats.csv, a CSV file giving the size contribution of each package to the overall root filesystem size// CSV文件,给出每个包的大小对整个根文件系统大小的贡献output/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.// CSV文件,它给出了每个安装文件所属包的大小,以及整个文件系统的大小。

这个图形大小的目标需要安装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].// 将个人贡献低于X %的所有包分组到图中标记为Others的单个条目中。默认情况下,X=0.01,这意味着每个贡献少于1%的包被分组到Others下。可接受的值在[0.0…1.0]范围内。--iec, --binary, --si, --decimal, to use IEC (binary, powers of 1024) or SI (decimal, powers of 1000; the default) prefixes.// 使用iec(二进制,1024的幂)或si(十进制,1000的幂);默认的前缀。--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 8.12. Top-level parallel build

请注意。本节讨论一个非常实验性的特性,它在一些普通的情况下可以实现收支平衡。使用风险自负。

Buildroot一直能够在每个包的基础上使用并行构建:每个包都是由Buildroot使用make -jN(或者对非基于make的构建系统的等价调用)构建的。并行级别的默认值是cpu数量+ 1,但是可以使用BR2_JLEVEL配置选项进行调整。

然而,直到2020.02年,Buildroot还在以串行方式构建包:每个包一个接一个地构建,而没有在包之间并行构建。到2020.02年,Buildroot已经对顶级并行构建提供了实验性的支持,通过并行构建没有依赖关系的包,可以大大节省构建时间。然而,这一特性被标记为实验性的,并且已知在某些情况下不起作用。

为了使用顶层并行构建,必须:

Enable the option BR2_PER_PACKAGE_DIRECTORIES in the Buildroot configuration// 在Buildroot配置中启用BR2_PER_PACKAGE_DIRECTORIES选项Use make -jN when starting the Buildroot build// 在启动Buildroot构建时使用make -jN

在内部,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//target/ and $(O)/per-package//host/ respectively. Those folders will be populated from the corresponding folders of the package dependencies at the beginning of build. The compiler and all other tools will therefore only be able to see and access files installed by dependencies explicitly listed by .// 与所有包共用的全局目标目录和全局主机目录不同,每个包的目标目录和主机目录将分别在 ( 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中。这意味着在构建过程中,这些文件夹将是空的,只有在构建的最后才会填充它们。 8.13. Integration with Eclipse

一部分嵌入式Linux开发人员喜欢经典的文本编辑器(如Vim或Emacs)和基于命令行的界面,而其他一些嵌入式Linux开发人员喜欢更丰富的图形界面来完成他们的开发工作。Eclipse是最流行的集成开发环境之一,Buildroot与Eclipse集成是为了简化Eclipse用户的开发工作。

我们与Eclipse的集成简化了构建在Buildroot系统之上的应用程序和库的编译、远程执行和远程调试。它没有将Buildroot配置和构建过程本身与Eclipse集成在一起。因此,Eclipse集成的典型使用模型是:

Configure your Buildroot system with make menuconfig, make xconfig or any other configuration interface provided with Buildroot.// 使用make menuconfig, make xconfig或其他Buildroot提供的配置界面来配置你的Buildroot系统。Build your Buildroot system by running make.// 通过运行make来构建你的Buildroot系统。Start Eclipse to develop, execute and debug your own custom applications and libraries, that will rely on the libraries built and installed by Buildroot.// 启动Eclipse来开发、执行和调试您自己的自定义应用程序和库,这些程序和库将依赖于Buildroot构建和安装的库。

在https://github.com/mbats/eclipse-buildroot-bundle/wiki上详细描述了Buildroot Eclipse集成的安装过程和使用方法。

8.14. Advanced usage 8.14.1 Using the generated toolchain outside Buildroot

您可能希望针对您的目标编译您自己的程序或其他没有打包在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文件,名为_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项目。它还提供了一些有用的命令。但是请注意,一旦该脚本来源于此脚本,环境就只设置为交叉编译,而不再设置为本机编译。

8.14.2 Using gdb in Buildroot

Buildroot允许进行交叉调试,调试器在构建机器上运行,并与目标上的gdbserver通信,以控制程序的执行。

为实现这一目标:

If you are using an internal toolchain (built by Buildroot), you must enable 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.// 如果您正在使用内部工具链(由Buildroot构建),您必须启用BR2_PACKAGE_HOST_GDB、BR2_PACKAGE_GDB和BR2_PACKAGE_GDB_SERVER。这将确保构建交叉gdb和gdbserver,并将gdbserver安装到目标服务器上。If you are using an external toolchain, you should enable 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.// 如果您正在使用外部工具链,您应该启用BR2_TOOLCHAIN_EXTERNAL_GDB_SERVER_COPY,它将外部工具链包含的gdbserver复制到目标。如果您的外部工具链没有跨gdb或gdbserver,也可以让Buildroot构建它们,方法是启用与内部工具链后端相同的选项。

现在,为了开始调试一个叫做foo的程序,你应该在目标上运行:

gdbserver :2345 foo

这将导致gdbserver在TCP端口2345上监听来自交叉gdb的连接。

然后,在主机上,您应该使用以下命令行启动交叉gdb:

/output/host/bin/-gdb -x /output/staging/usr/share/buildroot/gdbinit foo

当然,foo必须在当前目录中可用,使用调试符号构建。通常,您从构建foo的目录启动此命令(而不是从output/target/,因为该目录中的二进制文件被剥离)。

/output/staging/usr/share/buildroot/gdbinit文件将告诉交叉gdb在哪里可以找到目标库。

最后,从交叉gdb连接到目标:

(gdb) target remote :2345 8.14.3 Using ccache in Buildroot

Ccache是一个编译器缓存。它存储每个编译过程产生的目标文件,并且能够通过使用预先存在的目标文件跳过将来对同一源文件(使用相同的编译器和相同的参数)的编译。当多次从头进行几乎相同的构建时,它可以很好地加快构建过程。

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一节。

8.14.4 Location of downloaded packages

Buildroot下载的各种tarball都存储在BR2_DL_DIR中,默认情况下该目录是dl目录。如果您想保留一个完整的Buildroot版本(已知它使用了相关的tarball),您可以对此目录创建一个副本。这将允许您用完全相同的版本重新生成工具链和目标文件系统。

如果您维护多个Buildroot树,那么最好使用一个共享的下载位置。这可以通过将BR2_DL_DIR环境变量指向一个目录来实现。如果设置了此值,则会覆盖Buildroot配置中的BR2_DL_DIR的值。以下一行应该添加到。

export BR2_DL_DIR=

还可以在.config文件中使用BR2_DL_DIR选项设置下载位置。与.config文件中的大多数选项不同,这个值被BR2_DL_DIR环境变量覆盖。

8.14.5 Package-specific make targets

运行make 会构建并安装那个特定的包及其依赖项。

对于依赖于Buildroot框架的包,有许多特殊的make目标可以像这样独立调用:

make -

包构建目标有(按照执行的顺序):

command/targetDescriptionsourceFetch the source (download the tarball, clone the source repository, etc)dependsBuild and install all dependencies required to build the packageextractPut the source in the package build directory (extract the tarball, copy the source, etc)patchApply the patches, if anyconfigureRun the configure commands, if anybuildRun the compilation commandsinstall-stagingtarget package: Run the installation of the package in the staging directory, if necessaryinstall-targettarget package: Run the installation of the package in the target directory, if necessaryinstalltarget package: Run the 2 previous installation commandshost package: Run the installation of the package in the host directory

此外,还有其他一些有用的make目标:

command/targetDescriptionshow-dependsDisplays the first-order dependencies required to build the packageshow-recursive-dependsRecursively displays the dependencies required to build the packageshow-rdependsDisplays the first-order reverse dependencies of the package (i.e packages that directly depend on it)show-recursive-rdependsRecursively displays the reverse dependencies of the package (i.e the packages that depend on it, directly or indirectly)graph-dependsGenerate a dependency graph of the package, in the context of the current Buildroot configuration. See this section for more details about dependency graphs.graph-rdependsGenerate a graph of this package reverse dependencies (i.e the packages that depend on it, directly or indirectly)dircleanRemove the whole package build directoryreinstallRe-run the install commandsrebuildRe-run the compilation commands - this only makes sense when using the OVERRIDE_SRCDIR feature or when you modified a file directly in the build directoryreconfigureRe-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 8.14.6 Using Buildroot during development

Buildroot的正常操作是下载一个tarball,提取它,配置,编译和安装在这个tarball中找到的软件组件。源代码在output/build/-中提取,这是一个临时目录:每当使用make clean时,这个目录将被完全删除,并在下一次调用make时重新创建。即使使用Git或Subversion存储库作为包源代码的输入,Buildroot也会从中创建一个tarball,然后像往常一样使用tarball。

当Buildroot主要用作集成工具来构建和集成嵌入式Linux系统的所有组件时,这种行为非常适合。然而,如果一个人在开发系统的某些组件时使用Buildroot,这种行为就不是很方便了:相反,人们会希望对一个包的源代码做一个小的更改,并能够用Buildroot快速地重建系统。

直接在output/build/-中进行更改不是合适的解决方案,因为make clean时会删除此目录。

因此,Buildroot为这个用例提供了一个特定的机制:_OVERRIDE_SRCDIR机制。Buildroot读取覆盖文件,该文件允许用户告诉Buildroot某些包的源代码位置。

覆盖文件的默认位置是$(CONFIG_DIR)/local.mk。由BR2_PACKAGE_OVERRIDE_FILE配置选项定义。$(CONFIG_DIR)是Buildroot .config文件的位置,所以是本地的。local.mk默认与.config文件并排存在,这意味着:

In the top-level Buildroot source directory for in-tree builds (i.e., when O= is not used)// 在顶级Buildroot源代码目录中,用于树内构建(也就是说,当O=未被使用时)In the 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期望找到表单中的行:

_OVERRIDE_SRCDIR = /path/to/pkg1/sources _OVERRIDE_SRCDIR = /path/to/pkg2/sources

例如:

LINUX_OVERRIDE_SRCDIR = /home/bob/linux/ BUSYBOX_OVERRIDE_SRCDIR = /home/bob/busybox/

当Buildroot发现对于给定的包,已经定义了_OVERRIDE_SRCDIR,它将不再尝试下载、解压缩和打补丁。相反,它将直接使用指定目录中可用的源代码,而make clean将不触及此目录。这允许将Buildroot指向您自己的目录,该目录可以由Git、Subversion或任何其他版本控制系统管理。为了实现这一点,Buildroot将使用rsync将组件的源代码从指定的_OVERRIDE_SRCDIR复制到output/build/-custom/。

此机制最好与make -rebuild和make -reconfigure目标一起使用。make -rebuild all序列将把源代码从_OVERRIDE_SRCDIR rsync到output/build/-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复制源代码的过程。还可以定义_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 9. Project-specific customization

对于一个特定的项目,你可能需要执行的典型行动是:

configuring Buildroot (including build options and toolchain, bootloader, kernel, package and filesystem image type selection)// 配置Buildroot(包括构建选项和工具链、引导加载程序、内核、包和文件系统映像类型选择)configuring other components, like the Linux kernel and BusyBox// 配置其他组件,如Linux内核和BusyBoxcustomizing the generated target filesystem自定义生成的目标文件系统 adding or overwriting files on the target filesystem (using BR2_ROOTFS_OVERLAY)// 在目标文件系统上添加或覆盖文件(使用BR2_ROOTFS_OVERLAY)modifying or deleting files on the target filesystem (using BR2_ROOTFS_POST_BUILD_SCRIPT)// 修改或删除目标文件系统上的文件(使用BR2_ROOTFS_POST_BUILD_SCRIPT)running arbitrary commands prior to generating the filesystem image (using BR2_ROOTFS_POST_BUILD_SCRIPT)// 在生成文件系统映像之前运行任意命令(使用BR2_ROOTFS_POST_BUILD_SCRIPT)setting file permissions and ownership (using BR2_ROOTFS_DEVICE_TABLE)// 设置文件权限和所有权(使用BR2_ROOTFS_DEVICE_TABLE)adding custom devices nodes (using BR2_ROOTFS_STATIC_DEVICE_TABLE)// 添加自定义设备节点(使用BR2_ROOTFS_STATIC_DEVICE_TABLE) adding custom user accounts (using BR2_ROOTFS_USERS_TABLES)// 添加自定义用户帐户(使用BR2_ROOTFS_USERS_TABLES)running arbitrary commands after generating the filesystem image (using BR2_ROOTFS_POST_IMAGE_SCRIPT)// 生成文件系统映像后运行任意命令(使用BR2_ROOTFS_POST_IMAGE_SCRIPT)adding project-specific patches to some packages (using BR2_GLOBAL_PATCH_DIR)// 向一些包添加特定于项目的补丁(使用BR2_GLOBAL_PATCH_DIR)adding project-specific packages// 添加特定项目包

关于此类project-specific的自定义的重要说明:请仔细考虑哪些更改确实是特定于项目的,哪些更改对项目之外的开发人员也是有用的。Buildroot社区强烈推荐并鼓励对官方Buildroot项目的改进、包和板的支持。当然,有时上游是不可能或不可取的,因为变更是高度特定或专有的。

本章描述了如何在Buildroot中进行此类特定于项目的定制,以及如何以一种可以以可重复的方式构建相同映像的方式存储它们,甚至在运行make clean之后。通过遵循推荐的策略,您甚至可以使用相同的Buildroot树来构建多个不同的项目!

9.1. Recommended directory structure

在为项目定制Buildroot时,您将创建一个或多个特定于项目的文件,这些文件需要存储在某个地方。虽然大多数这些文件可以放在任何位置,因为它们的路径将在Buildroot配置中指定,但Buildroot开发人员推荐了一个特定的目录结构,这将在本节中描述。

与这个目录结构正交的是,您可以选择将这个结构本身放在哪里:要么放在Buildroot树中,要么使用br2-external tree放在它的外部。这两个选项都是有效的,选择取决于您。

+-- board/ | +-- / | +-- / | +-- linux.config | +-- busybox.config | +-- | +-- post_build.sh | +-- post_image.sh | +-- rootfs_overlay/ | | +-- etc/ | | +-- | +-- patches/ | +-- foo/ | | +-- | +-- libbar/ | +-- | +-- configs/ | +-- _defconfig | +-- package/ | +-- / | +-- Config.in (if not using a br2-external tree) | +-- .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树中,那么和组件可能是多余的,可以被删除。

9.1.1. Implementing layered customizations

对于一个用户来说,有几个相关的项目部分需要相同的自定义,这是很常见的。与其为每个项目重复这些定制,不如使用分层定制方法,如本节所述。

Buildroot中几乎所有可用的定制方法,比如构建后脚本post-build scripts和根文件系统root filesystem overlays覆盖,都接受空格分隔的项列表。指定的项总是按从左到右的顺序处理。通过创建多个这样的项,一个用于公共定制,另一个用于真正的特定于项目的定制,您可以避免不必要的重复。每一层通常都包含在board//内部的一个单独目录中。根据项目的不同,您甚至可以引入两个以上的层。

一个用户有两个自定义层common和fooboard的目录结构示例是:

+-- board/ +-- / +-- common/ | +-- post_build.sh | +-- rootfs_overlay/ | | +-- ... | +-- patches/ | +-- ... | +-- fooboard/ +-- linux.config +-- busybox.config +-- +-- post_build.sh +-- rootfs_overlay/ | +-- ... +-- patches/ +-- ...

例如,如果用户将BR2_GLOBAL_PATCH_DIR配置选项设置为:

BR2_GLOBAL_PATCH_DIR="board//common/patches board//fooboard/patches"

然后首先应用普通层的补丁,然后应用底层的补丁。

9.2. Keeping customizations outside of Buildroot

正如9.1节“推荐的目录结构”中已经简要提到的,您可以将特定于项目的自定义放置在两个位置:

directly within the Buildroot tree, typically maintaining them using branches in a version control system so that upgrading to a newer Buildroot release is easy.// 直接在Buildroot树中,通常使用版本控制系统中的分支来维护它们,这样就可以很容易地升级到新的Buildroot版本。outside of the Buildroot tree, using the br2-external mechanism. This mechanism allows to keep package recipes, board support and configuration files outside of the Buildroot tree, while still having them nicely integrated in the build logic. We call this location a br2-external tree. This section explains how to use the br2-external mechanism and what to provide in a br2-external tree.// 在Buildroot树之外,使用br2-external机制。这种机制允许将包菜单、板支持和配置文件保留在Buildroot树之外,同时仍然将它们很好地集成到构建逻辑中。我们称这个位置为br2-external树。本节解释如何使用br2-external机制,以及在br2-external树中提供什么。

通过将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 9.2.1. Layout of a br2-external tree

一个br2-external树必须包含至少这三个文件,在以下章节中描述:

external.descexternal.mkConfig.in

除了这些强制文件之外,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_PATHBAR_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 _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;// 定义了可选的libjpeg实现;provides/openssl.in defines the alternative openssl implementations;// 定义了替代的openssl实现;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//overlay/ BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE=$(BR2_EXTERNAL_BAR_42_PATH)/board//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菜单中。

9.3. Storing the Buildroot configuration

可以使用make savedefconfig命令存储Buildroot配置。

这将通过删除默认值的配置选项来删除Buildroot配置。结果存储在一个名为defconfig的文件中。如果你想把它保存在另一个地方,请更改Buildroot配置本身的BR2_DEFCONFIG选项,或者使用make savedefconfig BR2_DEFCONFIG=调用make。

这个defconfig的推荐存储位置是configs/_defconfig。如果您遵循此建议,该配置将在make help中列出,并且可以通过运行make _defconfig再次设置。

或者,您可以将文件复制到任何其他地方,并使用make defconfig BR2_DEFCONFIG=重新构建。

9.4. Storing the configuration of other components

BusyBox、Linux内核、Barebox、U-Boot和uClibc的配置文件如有更改,也应保存。对于每一个组件,都有一个Buildroot配置选项指向一个输入配置文件,例如BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE。要存储它们的配置,请将这些配置选项设置为您希望保存配置文件的路径,然后使用下面描述的帮助器目标来实际存储配置。

如9.1节“推荐的目录结构”所述,这些配置文件的推荐存储路径为board///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.For at91bootstrap3, no helper exists so you have to copy the config file manually to BR2_TARGET_AT91BOOTSTRAP3_CUSTOM_CONFIG_FILE. 9.5. Customizing the generated target filesystem

除了通过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///rootfs-overlay。

Post-build scripts (BR2_ROOTFS_POST_BUILD_SCRIPT)

构建后脚本是在Buildroot构建所有选择的软件之后,但在组装rootfs映像之前调用的shell脚本。要启用此特性,请在配置选项BR2_ROOTFS_POST_BUILD_SCRIPT(在System configuration菜单中)中指定一个空格分隔的构建后脚本列表。如果你指定一个相对路径,它将是相对于Buildroot树的根。

使用构建后脚本,您可以删除或修改目标文件系统中的任何文件。但是,您应该小心地使用该特性。每当您发现某个包生成错误或不需要的文件时,您应该修复该包,而不是使用一些构建后清理脚本来处理它。

如9.1节“推荐的目录结构”所示,该脚本推荐的路径为board///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;这些是在内存中模拟的。

9.5.1. Setting file permissions and ownership and adding custom devices nodes

有时需要在文件或设备节点上设置特定的权限或所有权。例如,某些文件可能需要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///。

需要注意的是,如果特定的权限或设备节点与特定的应用程序相关,你应该在包的.mk文件中设置变量FOO_PERMISSIONS和FOO_DEVICES(参见18.5.2节,“通用包引用”)。

9.6. Adding custom user accounts

有时需要在目标系统中添加特定的用户。为了满足这一需求,Buildroot提供了对所谓用户表users tables的支持。要使用此特性,请将配置选项BR2_ROOTFS_USERS_TABLES设置为一个空格分隔的用户表列表,即遵循makeusers语法的常规文本文件。

如9.1节“推荐的目录结构”所示,这些文件的推荐位置是board///。

需要注意的是,如果自定义用户与特定的应用程序相关,你应该在包的.mk文件中设置变量FOO_USERS(参见18.5.2节,“通用包引用”)。

9.7. Customization after the images have been created

当构建后脚本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的使用),这就交给脚本开发人员了。

9.8. Adding project-specific patches

在Buildroot中提供的包的基础上应用额外的补丁有时是有用的。例如,这可能用于支持项目中的自定义特性,或者在处理新体系结构时。

BR2_GLOBAL_PATCH_DIR配置选项可用于指定一个空格分隔的包含包补丁的一个或多个目录列表。

对于特定包的特定版本,补丁从BR2_GLOBAL_PATCH_DIR应用,如下所示:

对于BR2_GLOBAL_PATCH_DIR中存在的每个目录 ,将确定,如下所示:

/// if the directory exists.Otherwise, / if the directory exists.

然后补丁将会从应用,如下所示:

如果package目录下存在series文件,则根据series文件应用补丁;否则,打上匹配*.patch的补丁文件。补丁按字母顺序应用。因此,为了确保它们按照正确的顺序应用,强烈建议将补丁文件命名为:-.patch,其中表示应用顺序。

有关如何为一个包应用补丁的信息,请参见第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执行的。

9.9. Adding project-specific packages

一般来说,任何新包都应该直接添加到包目录中,并提交给Buildroot上游项目。在第18章“向Buildroot添加新包”中详细介绍了如何向Buildroot添加包,这里不再重复。但是,您的项目可能需要一些不能上行的专有包。本节将解释如何将这些特定于项目的包保存在特定于项目的目录中。

如9.1节“推荐的目录结构”所示,项目特定包的推荐位置是package//。如果你正在使用br2-external树特性(参见9.2节,“保持自定义在Buildroot之外”),推荐的位置是将它们放在br2-external树的名为package/的子目录中。

但是,除非我们执行一些额外的步骤,否则Buildroot不会知道这个位置中的包。正如第18章“向Buildroot添加新包”中所解释的,Buildroot中的包基本上由两个文件组成:一个.mk文件(描述如何构建包)和一个Config.in文件(描述此包的配置选项)。

Buildroot会自动将.mk文件包含在package目录的一级子目录中(使用模式package/*/*.mk)。如果我们想让Buildroot包含更深层次的子目录(比如package//package1)中的.mk文件,那么我们只需在包含这些额外的.mk文件的第一级子目录中添加一个.mk文件。因此,创建一个文件package//.mk以下内容(假设你在package//下面只有一个额外的目录级别):

include $(sort $(wildcard package//*/*.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//Config.in其中包括你所有软件包的文件里Config.in。必须提供详尽的列表,因为在kconfig的源命令中不支持通配符。例如:

source "package//package1/Config.in" source "package//package2/Config.in"

包括这个新的文件package//Config.in从package/Config.in。最好是在特定于公司的菜单中,以便与未来的Buildroot版本更容易合并。

如果使用br2-external树,请参考9.2节“保持自定义在Buildroot之外”,了解如何填写这些文件。

9.10. Quick guide to storing your project-specific customizations

在本章的前面,已经描述了用于进行特定于项目的定制的不同方法。本节将通过提供存储特定于项目的自定义的逐步说明来总结所有这些内容。显然,可以跳过与项目无关的步骤。

1.make menuconfig to configure toolchain, packages and kernel.2.make linux-menuconfig to update the kernel config, similar for other configuration like busybox, uclibc, …3.mkdir -p board//4.Set the following options to board///.config (as far as they are relevant): BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILEBR2_PACKAGE_BUSYBOX_CONFIGBR2_UCLIBC_CONFIGBR2_TARGET_AT91BOOTSTRAP3_CUSTOM_CONFIG_FILEBR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILEBR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE 5.Write the configuration files: make linux-update-defconfigmake busybox-update-configmake uclibc-update-configcp /build/at91bootstrap3-*/.config board///at91bootstrap3.configmake barebox-update-defconfigmake uboot-update-defconfig 6.Create board///rootfs-overlay/ and fill it with additional files you need on your rootfs, e.g. board///rootfs-overlay/etc/inittab. Set BR2_ROOTFS_OVERLAY to board///rootfs-overlay.7.Create a post-build script board///post_build.sh. Set BR2_ROOTFS_POST_BUILD_SCRIPT to board///post_build.sh8.If additional setuid permissions have to be set or device nodes have to be created, create board///device_table.txt and add that path to BR2_ROOTFS_DEVICE_TABLE.9.If additional user accounts have to be created, create board///users_table.txt and add that path to BR2_ROOTFS_USERS_TABLES.10.To add custom patches to certain packages, set BR2_GLOBAL_PATCH_DIR to board///patches/ and add your patches for each package in a subdirectory named after the package. Each patch should be called --.patch.11.Specifically for the Linux kernel, there also exists the option 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.12.If you need to add project-specific packages, create package// and place your packages in that directory. Create an overall .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.13.make savedefconfig to save the buildroot configuration.14.cp defconfig configs/_defconfig 10. Using SELinux in Buildroot

SELinux是一个执行访问控制策略的Linux内核安全模块。除了传统的文件权限和访问控制列表之外,SELinux还允许为用户或进程编写访问资源(文件、套接字……)的特定功能的规则。

SELinux有三种操作模式:

Disabled: the policy is not applied// 禁用:不应用该策略Permissive: the policy is applied, and non-authorized actions are simply logged. This mode is often used for troubleshooting SELinux issues.// 允许的:策略被应用,未经授权的操作被简单地记录下来。此模式通常用于诊断SELinux问题。Enforcing: the policy is applied, and non-authorized actions are denied// 强制执行:应用策略,拒绝未经授权的操作

在Buildroot中,操作模式由BR2_PACKAGE_REFPOLICY_POLICY_STATE_*配置选项控制。Linux内核还有各种配置选项,这些选项会影响如何启用SELinux(请参阅Linux内核源代码中的security/ ELinux/Kconfig)。

默认情况下,在Buildroot中,SELinux策略是由上游refpolicy项目提供的,由BR2_PACKAGE_REFPOLICY启用。

10.1. Enabling SELinux support

要在Buildroot生成的系统中正确支持SELinux,必须启用以下配置选项:

BR2_PACKAGE_LIBSELINUX BR2_PACKAGE_REFPOLICY

此外,文件系统映像格式必须支持扩展属性。

10.2. SELinux policy tweaking

SELinux repolicy包含可以在构建时启用或禁用的模块。每个模块都提供了许多SELinux规则。在Buildroot中,默认情况下非基本模块是禁用的,提供了几种启用这些模块的方法:

Packages can enable a list of SELinux modules within the refpolicy using the _SELINUX_MODULES variable.// 可以使用_SELINUX_MODULES变量在refpolicy中启用SELinux模块列表。Packages can provide additional SELinux modules by putting them (.fc, .if and .te files) in package//selinux/.// 可以提供额外的SELinux模块,将它们放在(Fc, .if和.te文件)package//selinux/Extra SELinux modules can be added in directories pointed by the BR2_REFPOLICY_EXTRA_MODULES_DIRS configuration option.// 额外的SELinux模块可以添加到BR2_REFPOLICY_EXTRA_MODULES_DIRS配置选项所指向的目录中。Additional modules in the 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 11. Frequently Asked Questions & Troubleshooting 11.1. The boot hangs after Starting network…

引导进程以下消息以后似乎挂起(消息不一定完全相似,取决于所选包的列表):

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在正确的串口上启动。

11.2. Why is there no compiler on the target?

已经决定从Buildroot-2012.11版本开始停止对目标板原生编译器的支持,因为:

this feature was neither maintained nor tested, and often broken;//这个特性既没有维护也没有测试,而且经常被破坏;this feature was only available for Buildroot toolchains;// 这个特性只适用于Buildroot工具链;Buildroot mostly targets small or very small target hardware with limited resource onboard (CPU, ram, mass-storage), for which compiling on the target does not make much sense;// Buildroot主要针对小的或非常小的目标硬件,其板载资源有限(CPU、ram、大容量存储),因此在目标上编译没有多大意义;Buildroot aims at easing the cross-compilation, making native compilation on the target unnecessary.// Buildroot的目标是简化交叉编译,使目标上的本地编译变得不必要。

如果你的目标上需要一个编译器,那么Buildroot不适合你的目的。在这种情况下,你需要一个真正的发行版,你应该选择如下内容:

openembeddedyoctoemdebianFedoraopenSUSE ARMArch Linux ARM… 11.3. Why are there no development files on the target?

因为目标上没有可用的编译器(参见11.2节,“为什么目标上没有编译器?”),所以在头文件或静态库上浪费空间是没有意义的。

因此,自Buildroot-2012.11发布以来,这些文件总是从目标中删除。

11.4. Why is there no documentation on the target?

因为Buildroot主要针对有限资源(CPU、ram、大容量存储)的小型或非常小的目标硬件,所以用文档数据浪费空间是没有意义的。

如果您无论如何都需要目标上的文档数据,那么Buildroot并不适合您的目的,您应该寻找一个真正的发行版(参见11.2节,“为什么目标上没有编译器?”)。

11.5. Why are some packages not visible in the Buildroot config menu?

如果一个包存在于Buildroot树中,并且没有出现在配置菜单中,这很可能意味着该包的某些依赖项没有满足。

要了解更多关于包的依赖关系,可以在配置菜单中搜索包的符号(见8.1节“make tips”)。

然后,您可能必须递归地启用几个选项(对应于未满足的依赖项),以便最终能够选择包。

如果包因为一些未满足的工具链选项而不可见,那么您当然应该运行一个完整的重新构建(参见8.1节“make tips”以获得更多解释)。

11.6. Why not use the target directory as a chroot directory?

有很多理由不使用目标目录chroot,其中:

目标目录中的文件所有权、模式和权限没有正确设置;未在目标目录中创建设备节点。

由于这些原因,使用目标目录作为新的根,通过chroot运行的命令很可能会失败。

如果您想在chroot中运行目标文件系统,或者作为NFS根运行,那么使用images/中生成的tarball映像并将其作为根解压。

11.7. Why doesn’t Buildroot generate binary packages (.deb, .ipkg…)?

在Buildroot列表中经常讨论的一个特性是“包管理”package management的一般主题。总的来说,这个想法是添加一些跟踪哪个Buildroot包安装了什么文件,目的是:

当从菜单配置中取消选择包时,可以删除包安装的文件;能够生成可以安装在目标上的二进制包(ipk或其他格式),而不需要重新生成新的根文件系统映像。

通常,大多数人认为这很容易做到:只需跟踪哪个软件包安装了什么,并在软件包未被选中时删除它。然而,实际情况要复杂得多:

It is not only about the target/ directory, but also the sysroot in host//sysroot and the host/ directory itself. All files installed in those directories by various packages must be tracked.// 它不仅是关于target/目录,而且还涉及到host//sysroot中的sysroot和host/目录本身。必须跟踪由各种包安装在这些目录中的所有文件。When a package is unselected from the configuration, it is not sufficient to remove just the files it installed. One must also remove all its reverse dependencies (i.e. packages relying on it) and rebuild all those packages. For example, package A depends optionally on the OpenSSL library. Both are selected, and Buildroot is built. Package A is built with crypto support using OpenSSL. Later on, OpenSSL gets unselected from the configuration, but package A remains (since OpenSSL is an optional dependency, this is possible.) If only OpenSSL files are removed, then the files installed by package A are broken: they use a library that is no longer present on the target. Although this is technically doable, it adds a lot of complexity to Buildroot, which goes against the simplicity we try to stick to.// 当从配置中取消选择一个包时,仅仅删除它安装的文件是不够的。还必须删除所有反向依赖项(即依赖于它的包),并重新构建所有这些包。例如,包A可选依赖于OpenSSL库。两者都被选中,构建Buildroot。包A是使用OpenSSL构建的加密支持。稍后,从配置中取消选择OpenSSL,但是包A仍然存在(因为OpenSSL是一个可选的依赖项,所以这是可能的)。如果只删除OpenSSL文件,那么包A安装的文件就会被破坏:它们使用一个不再存在于目标上的库。虽然这在技术上是可行的,但它给Buildroot增加了很多复杂性,这与我们试图坚持的简单性背道而驰。In addition to the previous problem, there is the case where the optional dependency is not even known to Buildroot. For example, package A in version 1.0 never used OpenSSL, but in version 2.0 it automatically uses OpenSSL if available. If the Buildroot .mk file hasn’t been updated to take this into account, then package A will not be part of the reverse dependencies of OpenSSL and will not be removed and rebuilt when OpenSSL is removed. For sure, the .mk file of package A should be fixed to mention this optional dependency, but in the mean time, you can have non-reproducible behaviors.// 除了前面的问题之外,还有一种情况是,可选依赖项甚至不为Buildroot所知。例如,版本1.0中的包A从未使用过OpenSSL,但在版本2.0中,如果可用,它会自动使用OpenSSL。如果Buildroot .mk文件没有被更新以考虑到这一点,那么包A就不会成为OpenSSL的反向依赖项的一部分,也不会在OpenSSL被删除时被删除和重新生成。当然,包A的.mk文件应该被修复,以提到这个可选的依赖关系,但同时,您可能会有不可复制的行为。The request is to also allow changes in the menuconfig to be applied on the output directory without having to rebuild everything from scratch. However, this is very difficult to achieve in a reliable way: what happens when the suboptions of a package are changed (we would have to detect this, and rebuild the package from scratch and potentially all its reverse dependencies), what happens if toolchain options are changed, etc. At the moment, what Buildroot does is clear and simple so its behaviour is very reliable and it is easy to support users. If configuration changes done in menuconfig are applied after the next make, then it has to work correctly and properly in all situations, and not have some bizarre corner cases. The risk is to get bug reports like “I have enabled package A, B and C, then ran make, then disabled package C and enabled package D and ran make, then re-enabled package C and enabled package E and then there is a build failure”. Or worse “I did some configuration, then built, then did some changes, built, some more changes, built, some more changes, built, and now it fails, but I don’t remember all the changes I did and in which order”. This will be impossible to support.// 该请求还允许将menuconfig中的更改应用于输出目录,而不必从头重新构建所有内容。然而,这很难以可靠的方式实现:当包的子选项发生变化时会发生什么(我们必须检测这一点,并从头开始重新构建包和潜在的所有反向依赖项),如果工具链选项发生变化会发生什么,等等。目前,Buildroot所做的是清晰和简单的,所以它的行为是非常可靠的,并且很容易支持用户。如果在menuconfig中所做的配置更改是在下一次make之后应用的,那么它必须在所有情况下都正确地工作,而不是有一些奇怪的角落情况。风险在于获得错误报告,如“我启用了包A、B和C,然后运行make,然后禁用包C,启用包D,然后运行make,然后重新启用包C,启用包E,然后出现构建失败”。或者更糟糕的“我做了一些配置,然后构建,然后做了一些更改,再构建,再构建,再构建,再构建,现在失败了,但我不记得我做过的所有更改以及更改的顺序。”这将是不可能支持的。

由于所有这些原因,结论是,当包未被选中时,添加已安装文件的跟踪来删除它们,或者生成二进制包的存储库,是非常难以可靠地实现的,并且会增加很多复杂性。

在这个问题上,Buildroot开发者发表了如下立场声明:

Buildroot strives to make it easy to generate a root filesystem (hence the name, by the way.) That is what we want to make Buildroot good at: building root filesystems.// Buildroot努力使生成根文件系统更容易(顺便说一下,它的名字也因此而来)。这就是我们希望Buildroot擅长的:构建根文件系统。Buildroot is not meant to be a distribution (or rather, a distribution generator.) It is the opinion of most Buildroot developers that this is not a goal we should pursue. We believe that there are other tools better suited to generate a distro than Buildroot is. For example, Open Embedded, or openWRT, are such tools.// Buildroot不是一个发行版(或者更确切地说,是一个发行版生成器)。大多数Buildroot开发者都认为这不是我们应该追求的目标。我们相信有其他工具比Buildroot更适合生成发行版。例如,开放嵌入式或openWRT就是这样的工具。We prefer to push Buildroot in a direction that makes it easy (or even easier) to generate complete root filesystems. This is what makes Buildroot stands out in the crowd (among other things, of course!)// 我们倾向于将Buildroot推向一个更容易(甚至更容易)生成完整根文件系统的方向。这也是Buildroot脱颖而出的原因(当然还有其他原因!)We believe that for most embedded Linux systems, binary packages are not necessary, and potentially harmful. When binary packages are used, it means that the system can be partially upgraded, which creates an enormous number of possible combinations of package versions that should be tested before doing the upgrade on the embedded device. On the other hand, by doing complete system upgrades by upgrading the entire root filesystem image at once, the image deployed to the embedded system is guaranteed to really be the one that has been tested and validated.// 我们相信,对于大多数嵌入式Linux系统,二进制包是不必要的,而且可能是有害的。当使用二进制包时,这意味着系统可以部分升级,这将创建大量可能的包版本组合,在对嵌入式设备进行升级之前,应该对这些组合进行测试。另一方面,通过一次性升级整个根文件系统映像来完成系统升级,可以保证部署到嵌入式系统的映像确实是经过测试和验证的映像。 11.8. How to speed-up the build process?

由于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节“顶层并行构建”。 12. Known issues 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编译失败。 13. Legal notice and licensing 13.1. Complying with open source licenses

Buildroot的所有最终产品(工具链、根文件系统、内核、引导加载器)都包含开源软件,在各种许可下发布。

使用开源软件使您可以自由地构建丰富的嵌入式系统,可以从各种各样的包中进行选择,但也强加了一些您必须知道和遵守的义务。有些许可证要求您在产品文档中发布许可证文本。另一些则要求您将软件的源代码重新分发给接收您产品的人。

每个许可的确切要求都记录在每个包中,遵守这些要求是您的责任(或您的法律办公室的责任)。为了让你更容易做到这一点,Buildroot可以为你收集一些你可能需要的材料。要生成这个材料,在你用make menuconfig、make xconfig或make gconfig配置了Buildroot之后,运行:

make legal-info

Buildroot将在legal-info/子目录下的输出目录中收集与法律相关的材料。在那里你会发现:

一个README文件,它总结生成的材料,并包含有关Buildroot不能生成的材料的警告。buildroot.config:这是通常由make menuconfig生成的Buildroot配置文件,它对于重新生成构建是必要的。所有软件包的源代码;它分别保存在目标包和主机包的sources/和host-sources/子目录中。设置_REDISTRIBUTE = NO的包的源代码将不会被保存。应用的补丁也会被保存,同时还保存一个名为series的文件,该文件按照应用补丁的顺序列出了补丁。补丁与它们所修改的文件处于相同的许可证之下。注意:Buildroot对基于自动工具的软件包的Libtool脚本应用额外的补丁。这些补丁可以在Buildroot源代码的support/libtool下找到,由于技术限制,没有与包源代码一起保存。您可能需要手动收集它们。清单文件(一个用于主机,一个用于目标包)列出了配置的包、它们的版本、许可和相关信息。有些信息可能没有在Buildroot中定义;这些项目标记为“未知”。所有包的许可文本,分别位于目标包和主机包的许可/和主机许可/子目录中。如果在Buildroot中没有定义license文件,则不会生成该文件,并且README中的一个警告指出了这一点。

请注意,Buildroot的法律信息特性的目的是生成所有与软件包许可的法律遵从有关的材料。Buildroot并没有试图生产出你必须以某种方式公开的确切材料。当然,生产的材料比严格遵守法律所需要的要多。例如,它为在类似bsd的许可下发布的包生成源代码,您不需要以源代码的形式重新发布这些包。

此外,由于技术限制,Buildroot不能生成您将要或可能需要的一些材料,例如一些外部工具链的工具链源代码和Buildroot源代码本身。当您运行make legal-info时,Buildroot会在README文件中产生警告,通知您无法保存的相关材料。

最后,请记住,make legal-info的输出基于每个包recipes中的声明性语句。Buildroot开发人员尽其所能保持那些声明性语句尽可能准确,就他们所知。然而,很可能这些陈述性的陈述并不都完全准确或详尽无遗。您(或您的法律部门)在使用make legal-info作为您自己的合规交付之前,必须检查其输出。参见Buildroot发行版根目录的copy文件中的NO WARRANTY条款(第11和12条)。

13.2. Complying with the Buildroot license

Buildroot本身是一个开源软件,根据GNU通用公共许可证(General Public License)版本2或(由您选择)任何更新版本发布,除了下面详细介绍的包补丁。然而,作为一个构建系统,它通常不是最终产品的一部分:如果您为一个设备开发根文件系统、内核、引导加载程序或工具链,那么Buildroot的代码只出现在开发机器上,而不是在设备存储中。

然而,Buildroot开发人员的普遍看法是,当发布包含gpl许可软件的产品时,应该将Buildroot源代码与其他包的源代码一起发布。这是因为GNU GPL将可执行作品的“完整源代码”定义为“它包含的所有模块的所有源代码,加上任何关联的接口定义文件,加上用来控制可执行作品的编译和安装的脚本”。Buildroot是用于控制可执行文件的编译和安装的脚本的一部分,因此它被认为是必须重新分发的材料的一部分。

请记住,这只是Buildroot开发人员的意见,如果您有任何疑问,应该咨询您的法律部门或律师。

13.2.1. Patches to packages

Buildroot还捆绑补丁文件,应用于各种包的源代码。这些补丁不在Buildroot的许可范围内。相反,它们是由应用补丁的软件的许可证所覆盖的。当上述软件在多个许可下可用时,Buildroot补丁只在公共可访问的许可下提供。

技术细节请参见第19章补丁包。

14. Beyond Buildroot 14.1. Boot the generated images 14.1.1. NFS boot

要实现nfs引导,请在filesystem映像菜单中启用tar根文件系统。

完成构建后,只需运行以下命令设置nfs根目录:

sudo tar -xavf /path/to/output_dir/rootfs.tar -C /path/to/nfs_root_dir

请记住将此路径添加到/etc/exports.

然后,可以从目标执行nfs引导。

14.1.2. Live CD

要构建一个实时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 14.2. Chroot

如果你想在生成的映像中使用chroot,那么有几件事你应该注意:

you should setup the new root from the tar root filesystem image;// 您应该从tar根文件系统映像中设置新的根;either the selected target architecture is compatible with your host machine, or you should use some 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;// 选择的目标体系结构与您的主机兼容,或者您应该使用一些qemu-*二进制文件,并在binfmt属性中正确设置它,以便能够在您的主机上运行为目标构建的二进制文件;Buildroot does not currently provide host-qemu and binfmt correctly built and set for that kind of use.// Buildroot目前没有提供正确构建和设置的host-qemu和binfmt。 III. Developer guide 15. How Buildroot works

正如上面提到的,Buildroot基本上是一组makefile文件,它们使用正确的选项下载、配置和编译软件。它还包括各种软件包的补丁——主要是交叉编译工具链(gcc、binutils和uClibc)中涉及的补丁。

基本上每个软件包都有一个Makefile,它们以.mk扩展名命名。makefile被分成许多不同的部分:

The toolchain/ directory contains the Makefiles and associated files for all software related to the cross-compilation toolchain: binutils, gcc, gdb, kernel-headers and uClibc.// 包含与交叉编译工具链相关的所有软件的Makefiles和相关文件:binutils、gcc、gdb、kernel-headers和uClibc。The arch/ directory contains the definitions for all the processor architectures that are supported by Buildroot.// 包含Buildroot支持的所有处理器体系结构的定义。The 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.// 包含所有用户空间工具和库的makefile和相关文件,Buildroot可以编译这些工具和库并将它们添加到目标根文件系统中。每个包有一个子目录。The linux/ directory contains the Makefiles and associated files for the Linux kernel.// 包含linux内核的Makefiles和相关文件。The boot/ directory contains the Makefiles and associated files for the bootloaders supported by Buildroot.// 包含Buildroot支持的引导加载程序的makefile和相关文件。The system/ directory contains support for system integration, e.g. the target filesystem skeleton and the selection of an init system.// 包含对系统集成的支持,例如目标文件系统骨架和初始化系统的选择。The fs/ directory contains the Makefiles and associated files for software related to the generation of the target root filesystem image.// 包含Makefiles和与生成目标根文件系统映像相关的软件的相关文件。

每个目录至少包含2个文件:

something.mk is the Makefile that downloads, configures, compiles and installs the package something.// 是一个Makefile,用来下载,配置,编译和安装包什么的。Config.in is a part of the configuration tool description file. It describes the options related to the package.// 是配置工具描述文件的一部分。它描述了包相关的选项。

主Makefile执行以下步骤(一旦配置完成):

Create all the output directories: staging, target, build, etc. in the output directory (output/ by default, another value can be specified using O=)// 在输出目录中创建所有输出目录:staging, target, build等(默认是output/,可以使用O=指定另一个值)Generate the toolchain target. When an internal toolchain is used, this means generating the cross-compilation toolchain. When an external toolchain is used, this means checking the features of the external toolchain and importing it into the Buildroot environment.// 生成工具链目标。当使用内部工具链时,这意味着生成交叉编译工具链。当使用外部工具链时,这意味着检查外部工具链的特性并将其导入Buildroot环境。Generate all the targets listed in the TARGETS variable. This variable is filled by all the individual components’ Makefiles. Generating these targets will trigger the compilation of the userspace packages (libraries, programs), the kernel, the bootloader and the generation of the root filesystem images, depending on the configuration.// 生成targets变量中列出的所有目标。该变量由所有独立组件的makefile填充。生成这些目标将触发用户空间包(库、程序)、内核、引导加载程序的编译,以及根文件系统映像的生成,具体取决于配置。 16. Coding style

总之,这些编码风格规则可以帮助您在Buildroot中添加新文件或重构现有文件。

如果你稍微修改一些现有的文件,重要的是保持整个文件的一致性,这样你就可以:

要么遵循此文件中使用的可能被弃用的编码风格,或者完全返工以使其符合这些规则。 16.1. Config.in file

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行缩进一个制表符。帮助文本本身应该用一个制表符和两个空格缩进。帮助文本应该换行以适应72列,其中制表符计数为8,因此文本本身为62个字符。 16.2. The .mk file 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个散列组成的分隔符包围。标题后必须有一个空行: ################################################################################ # # libfoo # ################################################################################ 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 \ $(TARGET_DIR)/usr/share/man/man3/libfoo* endef

请注意,定义块中的commands应该总是以tab开始,这样make将它们识别为命令。

Optional dependency: // 选项依赖:

Prefer multi-line syntax. // 喜欢多行语法。

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,) Keep configure options and dependencies close together.// 保持配置选项和依赖项紧密相连。

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 16.3. The documentation

The documentation uses the asciidoc format.

For further details about the asciidoc syntax, refer to http://www.methods.co.nz/asciidoc/userguide.html.

16.4. Support scripts

Some scripts in the support/ and utils/ directories are written in Python and should follow the PEP8 Style Guide for Python Code.

17. Adding support for a particular board

Buildroot包含几个公开可用硬件板的基本配置,这样这样一个板的用户就可以轻松地构建一个已知可以工作的系统。你也可以在Buildroot中添加对其他板的支持。

为此,您需要创建一个普通的Buildroot配置,它为硬件构建一个基本的系统:(内部)工具链、内核、引导加载程序、文件系统和一个简单的BusyBox-only用户空间。不应该选择特定的包:配置应该尽可能少,并且应该只为目标平台构建一个可工作的基本BusyBox系统。当然,您可以为您的内部项目使用更复杂的配置,但是Buildroot项目将只集成基本的板配置。这是因为包选择是高度特定于应用程序的。

一旦您有了一个已知的工作配置,运行make savedefconfig。这将在Buildroot源树的根生成一个最小的defconfig文件。将此文件移到configs/目录中,并将其重命名为_defconfig。如果配置有点复杂,最好手动重新格式化并将其划分为多个部分,每个部分之前都有注释。典型的部分是架构、工具链选项(通常只是linux头文件版本)、固件、引导装载程序、内核和文件系统。

对于不同的组件,总是使用固定版本或提交散列,而不是“最新”版本。例如,将BR2_LINUX_KERNEL_CUSTOM_VERSION=y和BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE设置为您测试的内核版本。

建议尽可能多地使用Linux内核和引导加载程序的上游版本,并尽可能多地使用默认的内核和引导加载程序配置。如果它们对您的板不正确,或没有默认存在,我们鼓励您发送修复到相应的上游项目。

然而,与此同时,您可能希望存储特定于目标平台的内核或引导加载程序配置或补丁。为此,创建一个board/和子目录board//。然后,您可以将补丁和配置存储在这些目录中,并从主要的Buildroot配置中引用它们。有关更多细节,请参阅第9章,特定于项目的定制。

18. Adding new packages to Buildroot

本节介绍如何将新的包(用户空间库或应用程序)集成到Buildroot中。它还展示了如何集成现有的包,这是修复问题或调优其配置所需要的。

当您添加一个新的包时,请确保在各种条件下对它进行测试(参见第18.24.3节,“如何测试您的包”),并检查它的编码风格(参见第18.24.2节,“如何检查编码风格”)。

18.1. Package directory

首先,在软件package目录下为您的软件创建一个目录,例如libfoo。

有些包按主题分组在子目录中:x11r7、qt5和gstreamer。如果您的包符合其中一个类别,那么在这些类别中创建您的包目录。但是,不建议创建新的子目录。

18.2. Config files

对于要在配置工具中显示的包,您需要在您的包目录中创建一个Config文件。有两种类型:Config.in and Config.in.host。

18.2.1. 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的约定,属性的顺序如下:

The type of option: bool, string… with the prompt// 选项的类型If needed, the default value(s)// 默认值Any dependencies on the target in depends on form// depends on表单,描述对目标的依赖Any dependencies on the toolchain in depends on form// depends on表单,描述对工具链的依赖Any dependencies on other packages in depends on form// depends on表单,描述对其他包的依赖Any dependency of the select form// select表单,描述任何依赖The help keyword and help text.// 帮助关键字和帮助文本。

您可以将其他子选项添加到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" 18.2.2. 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菜单中有效。

18.2.3. Choosing depends on or select

在包的Config.in文件中还必须确保启用了依赖项。通常,Buildroot使用以下规则:

Use a 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_LIBGLIB2 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关键字用向后语义表示依赖关系。Use a 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.// 当用户真正需要知道依赖项时,使用依赖项类型。通常,Buildroot将这种类型的依赖用于目标体系结构、MMU支持和工具链选项(参见18.2.4节“目标和工具链选项的依赖”),或者用于“大”事物的依赖,如X.org系统。依赖关键字用前向语义表示依赖关系。

请注意。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 Package D, which will selectPackage B, it will not check for the dependencies ofPackage B, so it will not selectPackage 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文件中表示依赖关系。

进一步的格式化细节:参见编码风格。

18.2.4. Dependencies on target and toolchain options

许多包依赖于工具链的某些选项: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

Dependency symbol: BR2_powerpc, BR2_mips, … (see arch/Config.in)Comment string: no comment to be added

MMU support

Dependency symbol: BR2_USE_MMUComment string: no comment to be added

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:

Dependency symbol: BR2_TOOLCHAIN_HAS_SYNC_1 for 1 byte, BR2_TOOLCHAIN_HAS_SYNC_2 for 2 bytes, BR2_TOOLCHAIN_HAS_SYNC_4 for 4 bytes, BR2_TOOLCHAIN_HAS_SYNC_8 for 8 bytes.Comment string: no comment to be added

Gcc _atomic* built-ins used for atomic operations.

Dependency symbol: BR2_TOOLCHAIN_HAS_ATOMIC.Comment string: no comment to be added

Kernel headers

Dependency symbol: BR2_TOOLCHAIN_HEADERS_AT_LEAST_X_Y, (replace X_Y with the proper version, see toolchain/Config.in)Comment string: headers >= X.Y and/or headers = X.Y and/or gcc


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有