buildroot官方教材7(笔记)

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。
包的infrastructures机制

转载请注明出处!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_43354598

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值