buildroot官方教材
buildroot官方的教程training
下载Buildroot的底层源码或者二进制文件
Buildroot是如何从第三方的项目中获取源码或者二进制文件的呢?
每一个Buildroot的包都由一个.mk文件来指定下载链接。
可以下载压缩包,补丁、二进制文件等。
下载一个文件时,Buildroot将会以下面的顺序查找文件:
- 本地的$(DL_DIR)文件夹(用来保存下载文件);
- primary site,在BR2_PRIMARY_SITE中指定;
- original site在包的.mk文件中指定;
- backup Buildroot mirror,在BR2_BACKUP_SITE中指定。
BR2_PRIMARY_SITE中可以指定HTTP或者FTP的链接地址,默认为空。
BR2_PRIMARY_SITE可以覆盖.mk文件中的位置。
如果选项 BR2_PRIMARY_SITE_ONLY使能,则只使用primary site作为下载地址。
在前面的链接失效的情况下,设置BR2_BACKUP_SITE选项可以保证备份的服务可用。
BR2_BACKUP_SITE默认的链接地址为:http://sources.buildroot.net
该服务由buildroot社区维护,在每一个Buildroot发布时将进行更新。
然而它不可能保存了所有配置选项指定的包的版本。
Buildroot默认的下载文件夹在:
$(DL_DIR)
可以通过选项BR2_DL_DIR进行配置,默认为:$(TOP_DIR)/dl文件夹。
注意!:该文件夹不会进行清理,下载的文件永远也不会删除,即使是对包进行版本的更新。
Buildroot使用版本控制系统专用的方式来下载Git、Subversion等版本控制系统的源码。
DL_DIR中将克隆和保存源码的压缩包,而不是版本控制的历史数据或者元数据。
GNU Make介绍
因为Buildroot是基于GNU Make执行的,所以这里对GNU Make进行一个简单的语法的介绍,详细的教程请参考:
http://www.gnu.org/software/make/manual/make.html
或
http://www.nostarch.comgnumake
GNU Make语法的核心是通过Makefile来定义创建目标的规则。
最简单的语法如下:
TARGET …: PREREQUISITES …
RECIPE
…
TARGET为生成的目标文件名,也可以为任意的行为,如clean,此时clean为一个伪目标文件。
PREREQUISITES为依赖文件列表。
RECIPE,为从依赖文件创建目标文件的shell命令列表。
一个简单的伪目标文件的Makefile如下:
clean:
rm -rf $(TARGET_DIR) $(BINARIES_DIR) $(HOST_DIR) \
$(BUILD_DIR) $(BASE_DIR)/staging \
$(LEGAL_INFO_DIR)
distclean: clean
[...]
rm -rf $(BR2_CONFIG) $(CONFIG_DIR)/.config.old \
$(CONFIG_DIR)/.auto.deps
Makefile中有如下的定义宏变量的方法:
FOOBAR =值,使用时展开
FOOBAR: =值,分配时展开
FOOBAR + =值,扩展变量
FOOBAR ? =值,只有在未定义定义该变量
使用多行格式定义变量时,使用define NAME … endef的格式:
define FOOBAR
line 1
line 2
endef
ifeq或者ifneq的语法如下:
ifeq ($(BR2_CCACHE),y)
CCACHE := $(HOST_DIR)/bin/ccache
endif
distclean: clean
ifeq ($(DL_DIR),$(TOPDIR)/dl)
rm -rf $(DL_DIR)
endif
if的语法如下:
HOSTAPD_LIBS += $(if $(BR2_STATIC_LIBS),-lcrypto -lz)
定义函数的语法如下:
MESSAGE = echo "$(TERM_BOLD)>>> $($(PKG)_NAME) $($(PKG)_VERSION) $(call qstrip,$(1))$(TERM_RESET)"
define legal-license-header # pkg, license-file, {HOST|TARGET}
printf "$(LEGAL_INFO_SEPARATOR)\n\t$(1):\
$(2)\n$(LEGAL_INFO_SEPARATOR)\n\n\n" >>$(LEGAL_LICENSES_TXT_$(3))
endef
调用函数的语法如下:
$(BUILD_DIR)/%/.stamp_extracted:
[...]
@$(call MESSAGE,"Extracting")
define legal-license-nofiles # pkg, {HOST|TARGET}
$(call legal-license-header,$(1),unknown license file(s),$(2))
endef
其中参数的传递为, $(1),第一个参数; $(2),第二个参数;等等。
调用函数的语法为: $(call func, arg1, arg2)
subst和patsubst用来替代文本:
ICU_SOURCE = icu4c-$(subst .,_,$(ICU_VERSION))-src.tgz
filter和filter-out用来过滤。
foreach用来执行循环:
$(foreach incdir,$(TI_GFX_HDR_DIRS),
$(INSTALL) -d $(STAGING_DIR)/usr/include/$(notdir $(incdir)); \
$(INSTALL) -D -m 0644 $(@D)/include/$(incdir)/*.h \
$(STAGING_DIR)/usr/include/$(notdir $(incdir))/
)
foreach的语法定义为:$(foreach ,,
意思为将list中的每一个单词逐个地放入变量var中,并执行text中定义的命令。
dir,notdir,addsuffix,addprefix为用来操作文件名的命令。
参见GNU Make手册。
编写RECIPIES
recipes就是一些shell的命令,
每一行必须插入一个Tab符。
每一行的shell命令之间相互独立,且变量不能共享。
单行可以通过’'符号,分为多行。
Shell命令的变量通过$$name引用。
如在package/pppd/pppd.mk文件中,有如下代码:
define PPPD_INSTALL_RADIUS
...
for m in $(PPPD_RADIUS_CONF); do \
$(INSTALL) -m 644 -D $(PPPD_DIR)/pppd/plugins/radius/etc/$$m \
$(TARGET_DIR)/etc/ppp/radius/$$m; \
done
...
endef
Buildroot中添加新的包
Buildroot所说的包,代表着一套用来自动构建系统某个组件的所有的元数据信息。
可以是开源,第三方的组件或用户内部的组件。
可用于用户空间的组件(如:库和应用等),但也可以用于固件,内核驱动,bootloader,等。
注意:不要与常规的Linux发行版本的二进制包相混淆。
Buildroot包的基本元素有:
一个文件夹,如:package/foo
一个Config.in文件,该文件为包的配置选项(kconfig语言)。
一个< pkg >.mk文件,定义了源代码的获取路径,构建和安装方式等(make语言)。
一些.patch文件(可选的),构建前对源码打补丁。
其它的文件(可选),init脚本,配置文件示例,等。
Config.in文件
该文件定义了包的配置选项。
其中一个选项用来使能/禁用包,该选项必须使用如下的命名方式:
BR2_PACKAGE_< PACKAGE >
配置选项的定义如下:
config BR2_PACKAGE_STRACE
bool "strace"
help
A useful diagnostic, instructional, and debugging tool.
Allows you to track what system calls a program makes
while it is running.
http://sourceforge.net/projects/strace/
在menuconfig中,将可以看到"strace"这个bool量的选项,用来使能/禁用"trace"包。
所有的Config.in文件将include到一个顶层的Config.in文件中,menuconfig通过读取这个顶层的Config.in文件将这些配置选项以菜单的形式呈现出来,方便用户进行系统构建。
所有的package/< pkg >/Config.in文件都包含了package/Config.in文件。该文件定义了包的子菜单。
package/Config.in文件内容如下:
menu "Target packages"
menu "Audio and video applications"
source "package/alsa-utils/Config.in"
...
endmenu
...
menu "Libraries"
menu "Audio/Sound"
source "package/alsa-lib/Config.in"
...
endmenu
...
Config.in的依赖关系
kconfig允许使用select或depends语句来表达依赖关系
-
select,自动依赖:如果 A select B,则当A使能时,B自动使能。
-
depends on,手动依赖:如果A depends on B,则只有在B使能以后,A才可见,并需要手动进行使能。
-
depends on一般用于架构,工具链或者大的依赖关系。比如一个只能在x86架构使用的包,或者依赖于Python的包等。
-
select通常为构建当前包时使能所需要的其它包时使用。
以下为一个btrfs-progs包的依赖关系:
config BR2_PACKAGE_BTRFS_PROGS
bool "btrfs-progs"
depends on BR2_USE_WCHAR # util-linux
depends on BR2_USE_MMU # util-linux
depends on BR2_TOOLCHAIN_HAS_THREADS
select BR2_PACKAGE_ACL
select BR2_PACKAGE_ATTR
select BR2_PACKAGE_E2FSPROGS
select BR2_PACKAGE_LZO
select BR2_PACKAGE_UTIL_LINUX
select BR2_PACKAGE_UTIL_LINUX_LIBBLKID
select BR2_PACKAGE_UTIL_LINUX_LIBUUID
select BR2_PACKAGE_ZLIB
help
Btrfs filesystem utilities
https://btrfs.wiki.kernel.org/in...
comment "btrfs-progs needs a toolchain w/ wchar, threads"
depends on BR2_USE_MMU
depends on !BR2_USE_WCHAR || \
!BR2_TOOLCHAIN_HAS_THREADS
依赖的继承关系
kconfig不能够通过select来继承下一层的depends on的依赖关系。
比如:A depends on F00,B select A,B需要手动复制depends on F00,而不能自动的继承A的依赖关系。
大多数的包为目标硬件上的包,它们通过交叉编译,并运行于目标硬件平台。
然后一些包仍然有主机版本,可以构建并运行在主机上,这些包通常用来构建其它包。
大多数的host包在menuconfig的菜单中都是找不到的,因为它们只是作为其它包的依赖包,用户可以不必知道它们。
但也有很少的一部分的host包可以直接为用户所使用,比如Flash的烧录工具等。它们可以在menuconfig的Host utilities中找到。
这些包的配置选项在Config.in.host文件中,该文件包含了package/Config.in.host文件,选项名必须命名为:BR2_PACKAGE_HOST_< PACKAGE >。
文件package/Config.in.host的内容如下:
menu "Host utilities"
source "package/genimage/Config.in.host"
source "package/lpc3250loader/Config.in.host"
source "package/openocd/Config.in.host"
source "package/qemu/Config.in.host"
endmenu
openocd包的配置文件package/openocd/Config.in.host的内容如下:
config BR2_PACKAGE_HOST_OPENOCD
bool "host openocd"
help
OpenOCD - Open On-Chip Debugger
http://openocd.org
可以定义附加的子选项来进一步配置包,以启用或禁用附加功能,再从包的.mk文件中获取这些选项的值,从而相应地调整构建。
如package/pppd/Config.in文件中:
config BR2_PACKAGE_PPPD
bool "pppd"
depends on !BR2_STATIC_LIBS
depends on BR2_USE_MMU
...
if BR2_PACKAGE_PPPD
config BR2_PACKAGE_PPPD_FILTER
bool "filtering"
select BR2_PACKAGE_LIBPCAP
help
Packet filtering abilities for pppd. If enabled,
the pppd active-filter and pass-filter options
are available.
config BR2_PACKAGE_PPPD_RADIUS
bool "radius"
help
Install RADIUS support for pppd
endif
Buildroot要构建的每个软件组件,它们都有自己的构建系统。
Buildroot不会更改每个组件的构建系统,而只是简单地去使用它本身的构建系统。
这些组件本身的构建系统可能为:手写makefile或shell脚本,autotools,CMake和一些特定于语言:如Python、Perl、 Lua、Erlang等等。
为了避免复制代码,Buildroot采用了包的infrastructures的机制来使用这些通用的构建系统。
下面为一个使用非标准构建系统的通用的包的infrastructure。
转载请注明出处!