目录
Buildroot介绍
Buildroot工作原理
路径含义
根文件系统配置
工具链配置
内核、busybox等配置
实用命令
编译
定制自己的工程
1.Buildroot工具诞生的缘由是:Making Embedded Linux y,
网址:http://buildroot.uclibc.org/
2.Buildroot发布
Buildroot每年发布4次, 3个月一次,2,5,8,11月份。格式YYYY.MM。 2015.02.
3、builtroot的优势:
*文件系统搭建,强烈建议直接用buildroot。文件系统通常要包含很多第三方软件,比如busybox, udhcpc,tftp,apache,sqlite,PHP,iptable,DNS等,为了避免繁杂的移植工作。buildroot应运而生。
通过menuconfig配置我们需要的功能,不需要的功能去掉,再执行make指令编译,buildroot就会自动
从指定的服务器上下载源码包,自动编译,自动搭建成我们所需要的嵌入式根文件系统。让我们的工作效率成
百倍的提升。
* 能处理嵌入式开发包的任何事情交叉编译工具链,根文件系统, 内核镜像文件和 bootloader编译。
* Buildroot高效、灵活处理其中的每步或者多步。
* 基于她的menuconfig, gconfig and xconfig configuration interfaces非常容易构建
* 建立一个linux嵌入式系统只需15-30分钟。
* 支持上百个应用程序包和库 X.org stack, Gtk2, Qt, DirectFB, SDL, GStreamer and a large number of network-related and system-related utilities and libraries.
* 支持多种根文件系统:JFFS2, UBIFS, tarballs, romfs, cramfs, sqhfs .
* 能生成(e)glibc 或者 uClibc 交叉编译工具链, 或者重构已有的 glibc, eglibc or uClibc 交叉编译工具链
* 非常简单的结构便于理解和扩展
* 基于Makefile语言编写。
arch/
存放CPU架构相关的配置脚本,如arm/mips/x86 ,这些CPU相关的配置,在制作工具链,编译boot和内核时很关键。
board/
存放各种board 特有的一些配置脚本,在构建系统时,board默认的boot和Linux kernel配置文件,以及一些板相关特殊构建流程的脚本,都在该目录下,等待自动构建时调用。
boot/
存在各种boot软件的自动构建脚本,不只是u-boot,还有grub等,也可以通过Buildroot来构建。
configs/
存放这每种方案上层的全局配置文件,之前的make mini2440_defconfig实际上就是调用了该目录下的mini2440方案的配置。该目录下的配置文件记录着该机器平台或者方案使用的工具栏,boot, kernel,各种应用软件包的配置和是否编译选择的状态,某个特殊开发板整个系统的配置文件,就在configs/目录下。
dl/
存放从官网上下载的开源软件包。第一次下载后,下次就不会再去从官网下载了,而是从dl/目录下拿开源包,以节约时间,也可以自己下载放到这里。
buildroot 在make时,会在顶层目录创建dl目录,然后在dl目录寻找需要的安装包,如果找不到需要的安装包就会从网
上下载安装包到dl目录,再解压到output/build目录下,再编译安装;或者在你指定的工作目录,拷贝源文件到output/build目录下,再编译安装。
docs/
存放相关的参考文档。
fs/
存放着各种文件系统的自动构建脚本。
linux/
存放着Linux kernel的自动构建脚本。
output/
编译出来的输出文件夹,里面的build/目录存放着解压后的各种软件包编译完后的现场。
build/ 所有源码包(dl路径)解压出来的文件存放地和编译的发生地。
host/ 制作好的主机工具。
host/usr:主机工具(交叉编译工具链等)
host/< tuple >/sysroot/或host/usr/< tuple >/sysroot/:根文件系统所需库和基本目录
staging/ 软链接到host/< tuple >/sysroot/ 。就是上面说到的文件系统需要的库等目录,方便查看。
target/ 存放rootfs的。里面放着Linux系统基本的目录结构,以及各种编译好的应用库和bin可执行文件。
Images/ 内核镜像、uboot、压缩的根文件系统等。
package/
用户空间包,busybox/, gcc/, qt5/等
pkg-generic.mk、pkg-cmake.mk, pkg-autotools.mk, pkg-perl.mk,等构建脚本
support/
固定的流程脚本,以备构建时调用执行。
system/
根目录的主要骨架和相关的启动初始化配置。当制作根目录时就是将此处的文件拷贝到output里去,然后再安装toolchain的动态库和你勾选的package的可执行文件之类的。
toolchain/
各种制作工具链的脚本,buildroot可以选择从0开始,用gcc和linux 内核,glibc、uclibc库等原材料制作一个自己工具链,也可以下载第三方制作好的开源工具。
package/, toolchain/ , boot/ , fs/ , linux/。这几个路径下边每个软件包都有自己的Makefile文件,并以.mk文件结束。每个软件包必须至少包含something.mk和config.in:
* config.in : 是否选择此软件包。(linux的config语法完全一致)
* something.mk:编译软件包的步骤。包括:
软件版本、软件包名字、下载网址、编译选项、安装命令(把软件包装到output/target/相应路径)等
生成根文件系统流程
配置项 |
路径 |
顶层.config选项 |
构建完根文件系统前执行的脚本。可执行自己的脚本 |
System configuration ---> ( ) Custom scripts to run before creating filesystem images |
BR2_ROOTFS_POST_BUILD_SCRIPT="" |
构建完根文件系统后执行的脚本。可执行自己的脚本 |
System configuration ---> ( ) Custom scripts to run after creating files |
BR2_ROOTFS_POST_IMAGE_SCRIPT= "/mt7620/postimage.sh" |
添加或者覆盖文件 | System configuration ---> () Root filesystem overlay directories |
BR2_ROOTFS_OVERLAY="" |
设置权限和属组关系 | System configuration ---> () Path to the permission tables 有时找不到,只能改config文件 |
BR2_ROOTFS_DEVICE_TABLE="" |
添加指定的设备节点 | System configuration ---> () Path to the device tables 有时找不到,只能改config文件 |
BR2_ROOTFS_STATIC_DEVICE_TABLE |
添加用户账户 | System configuration ---> () Path to the users tables |
BR2_ROOTFS_USERS_TABLES |
给指定的package打补丁 | BR2_GLOBAL_PATCH_DIR | |
使能init进程 | BR2_INIT_BUSYBOX |
其他配置
/dev management
1.Static using device table (不能动态生成dev/节点,文件系统有什么就是什么)
2.Dynamic using devtmpfs only (在启动时能动态生成,后面就不行了)
3.Dynamic using devtmpfs + mdev (嵌入式选择这个,当有新设备时能动态生成或删除节点文件,
/etc/mdev.conf它的配置文件)
4.Dynamic using devtmpfs + eudev(比mdev要大要耗费资源,但…肯定要好些了)
要想能Dynamic using还要内核配置上CONFIG_DEVTMPFS 和 CONFIG_DEVTMPFS_MOUNT.如果是使用buildroot编译内核,它会根所你的选择自动检测这两项。
[] tar the root filesystem
仅打包,而不制作镜像。做目录版的文件系统,可以用来nfs mount的,就选中此,然后解压出来就是了。
Toolchain menu
–>Toolchain Type
Buildroot toolchain //buildroot自己编译生成的
external toolchain //非buildroot编译生成的
external toolchain
( ) Sourcery CodeBench ARM 2014.05
( ) Musl 1.1.12 toolchain
(X) Custom toolchain(用户自己定义的交叉工具)
输入路径示例:/work/tools/usr/local/arm/4.3.2
Toolchain origin(工具来源):
() Toolchain to be downloaded and installed //选中后,需要在下一项中填交叉工具的下载地址–Toolchain URL)
(X) Pre-installed toolchain(以安装的) //配置好本地的Toolchain path,和Toolchain prefix
配置项 |
路径 |
顶层.config选项 |
备注 |
自己的内核源码、busybox、c库 |
Build options ---> ( )location of a package override file |
BR2_PACKAGE_OVERRIDE_ FILE="/mt7620/local.mk" |
local.mk配置文件需要自己编写 |
全局补丁目录 | Build options ---> ( ) global patch directories |
BR2_GLOBAL_PATCH_DIR= "/mt7620/patch" |
|
指定uClibc配置文件 | Toolchain ---> file to use? |
BR2_UCLIBC_CONFIG= "/mt7620/uclibc.config" |
第一次make的时候,buildroot将该配置文件拷贝到output/build/目录下uClibc自己的目录,成为.config,运行该配置,后续自己改动的配置是保存在.config |
target/下根文件系统的母本的目录 | System configuration ---> Root FS skeleton (custom target skeleton) ---> ( ) custom target skeleton path |
BR2_ROOTFS_SKELETON _CUSTOM_PATH= "/mt7620/skeleton" |
默认使用的是system/路径下的 |
内核配置文件。
|
Kernel ---> Kernel configuration (Using a custom config file) ---> ( ) Configuration file path
|
BR2_LINUX_KERNEL_ CUSTOM_CONFIG_FILE= "/mt7620/linux.config" |
第一次make时,buildroot将该配置文件拷贝到output/build/linux-custom /目录为.config,运行该配置,后续自己改动的配置是保存在.config |
busybox配置文件 |
Target packages ---> ( ) BusyBox configuration file to use? |
BR2_PACKAGE_ BUSYBOX_CONFIG= "/mt7620/busybox.config" |
第一次make时,buildroot将该配置文件拷贝到output/build/busybox目录(一般是busybox-head),成为.config,运行该配置,后续自己改动的配置是保存在.config |
uboot配置文件 | BR2_TARGET_UBOOT _USE_CUSTOM_CONFIG'= "mt7620/uboot.config" |
local.mk文件格式
格式:XXXXXX_OVERRIDE_SRCDIR = /.../my_xxxxxx
参考例子如下:
//指定自己的内核源代码工作目录,buildroot里的内核源代码设置就会被自动替换
//然后将其源文件拷贝到output/build/目录下,buildroot最后是编译output/build/目录下各子目录的代码
LINUX_OVERRIDE_SRCDIR = /mt7620/my_linux
// 指定自己的内核头工作目录,buildroot里的内核头设置就会被自动替换
// 然后将其源文件拷贝到output/build/目录下,buildroot最后是编译output/build/目录下各子目录的代码
LINUX_HEADERS_OVERRIDE_SRCDIR = /mt7620/my_linux
//指定自己的busybox工作目录,buildroot里的busybox设置就会被自动替换
//然后将其源文件拷贝到output/build/目录下,buildroot最后是编译output/build/目录下各子目录的代码
BUSYBOX_OVERRIDE_SRCDIR = /mt7620/my_busybox
//指定自己的 C library工作目录,buildroot里的C library设置就会被自动替换
//然后将其源文件拷贝到output/build/目录下,buildroot最后是编译output/build/目录下各子目录的代码
UCLIBC_OVERRIDE_SRCDIR = /mt7620/my_uclibc
命令 |
含义 |
帮助 |
|
make help |
显示编译命令 |
清除 |
|
make clean |
删除编译产生的文件 |
make distclean |
删除所有非源码文件(包括.config) |
编译 |
|
make all |
编译所有 |
make linux | 编译内核 |
make busybox | 编译busybox |
make toolchain |
编译工具链 |
make sdk |
编译可移动sdk |
配置 |
|
make xxx_defconfig | 拷贝configs/xxx_defconfig到顶层.config |
make menuconfig |
配置buildroot |
make oldconfig |
解决所有.config中未解决的符号(symbols) |
make syncconfig |
和oldconfig一样。但安静地,额外地更新依赖 |
make olddefconfig |
和syncconfig一样。但把新的symbols设为默认值 |
make defconfig |
对所有选项使用默认回答来配置。如果定义了BR2_DEFCONFIG,则使用它配置 |
make savedefconfig |
把当前配置保存到BR2_DEFCONFIG |
make update-defconfig |
和savedefconfig一样 |
make alldefconfig |
把所有新选项配置为默认 |
包相关 |
|
make |
单独编译和安装某个pkg模块以及其依赖的模块,比如make demo_app |
make |
只下载某pkg,然后不做任何事情 |
make |
只解压pkg,不编译,pkg解压后放在 output/build/目录对应的pkg-dir目录下 |
make |
给pkg打补丁 |
make |
编译pkg的依赖 |
make |
编译pkg到配置这一步 |
make |
编译pkg到构造这一步 |
make |
产生pkg的info |
make |
显示pkg的依赖包 |
make |
显示有哪些包依赖于本pkg |
make |
递归显示pkg的依赖包 |
make |
递归显示有哪些包依赖于本pkg |
make |
图形化查看某个package的依赖文件 |
make |
图形化查看哪些包依赖于本pkg |
make |
移除pkg的build路径。再make时它就会重新解压配置编译了 |
make |
从配置这一步开始重新编译pkg |
make |
从构造这一步开始重新编译pkg |
其他配置 |
|
make busybox-menuconfig |
配置busybox。会使用BR2_PACKAGE_BUSYBOX_CONFIG指定的文件配置。 |
make busybox-update-config | 保存配置文件到BR2_PACKAGE_BUSYBOX_CONFIG指定的路径 |
make uclibc-menuconfig |
配置uclibc。会使用BR2_UCLIBC_CONFIG指定的文件配置。 |
make uclibc-update-config | 保存配置到BR2_UCLIBC_CONFIG指定的路径 |
make linux-menuconfig |
配置linux内核。会使用BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE指定的文件配置。 |
make linux-savedefconfig |
保存linux内核配置 |
make linux-update-defconfig |
保存linux内核配置到BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE指定文件。linux-2.6.33之后的版本使用此命令 |
make linux-update-config | 保存linux内核配置到BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE指定文件。linux-2.6.33之前的版本使用此命令 |
make barebox-menuconfig | 配置barebox。会使用BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE指定的文件配置。 进入output/build目录下的barebox路径执行Makefile文件。 |
make barebox-update-defconfig | 保存配置文件到BR2_TARGET_BAREBOX_CUSTOM_CONFIG_FILE指定的文件 |
make uboot-update-defconfig | 保存配置文件到BR2_TARGET_UBOOT_CUSTOM_CONFIG_FILE指定的文件 |
make linux-clean make linux-distclean make busybox-clean make busybox-distclean make uclibc-clean make uclibc-distclean |
|
Doc |
|
make manual |
生成帮助手册,当前在docs/manual下,编译生成的在output/dosc/manual下。 |
make graph-build |
图形化查看编译时间 |
make graph-depends |
图形化查看所有依赖 |
graph-size |
图形化查看文件系统大小 |
make list-defconfigs |
显示拥有默认配置的单板列表 |
其他命令 |
|
make source |
下载所有要离线编译的源码到dl路径 |
make external-deps |
列出使用的所有外部包。当不知道要下载哪个包时可以查询等 |
make legal-info |
列出许可证合规性 |
make show-info |
产生包信息(作为JSON blurb) |
make printvars |
打印内部变量。(“VARS=”指定的) |
make V=0|1 |
0 => 安静编译 (default), 1 => 打印信息编译 |
make O=dir |
指定输出目录。在原先的架构之外进行编译,可通过命令 make O=dir 来指定输出的目录。这样编译出来的.config文件和Makefile文件都是在指定的输出目录,可以直接去到输出的目录去进行编译。 |
make show-targets |
显示出本次配置所要编译所有的目标,这些目标可以单独作为模块,用 make |
make UCLIBC_CONFIG_FILE =/my/uClibc.config |
指定uClibc配置 |
make BUSYBOX_CONFIG_FILE =/my/busybox.config |
指定busybox配置 |
1.多核编译
make -JN 不适用于builtroot,但是可以通过BR2_JLEVEL的配置选项来指定每个可用的Makefile文件使用N核编译。
2.全编译
builtroot何时需要全编译,何时不需要?主要有对以下几种情况进行一个说明:
- builtroot的配置文件(系统架构的配置)发生了变化需要全编译
- 工具链的配置有改动需要全编译
- 外部包新增进来的时候(若这个包是一个被编译过的库)
- 移除一个包的配置需要全编译
- 根文件系统的框架发生了变动
- 只增加一个包的子选项不必进行全编译
3.单独编译
若要对某个package单独进行编译,有:
- 最简单的办法是去到对应的output/builtroot目录删除对应的单独编译文件夹。
- 先执行make -rebuild 再make
- 若修改了包的配置,可以通过make -reconfigure ,再make来进行单独编译
以上,builtroot会在对应的package中产生stamp文件用于追踪编译、安装过程的,通过上述命令修改stamp文件来达到重新编译某个包的目的。
4.高级用法
- ccache是编译缓存( compiler cache),编译的时候都会使用此工具,用于加速下一次编译的工具。
- 若源码有一个小的改动,需要进行编译时,开发者不希望进行整个包进行改动,而又不能在build目录下进行改动(执行make clean的时候会被删除掉的);
* 这种情况下可以通过修改源码然后通过rsync同步来实现,rsync只会同步有改动的地方,也只会重新编译有改动的包。、
* 例子:在linux源码码中进行源码的修改,到output目录下使用make linux-rebuild all命令,系统就会先同步linux改动的源码,然后进行内核编译。
其他
buildroot在编译之前会根据.config 文件来检查output/build/package 的6个文件,做相应的步骤:
.stamp_configured, 此文件表示已经配置过
.stamp_downloaded, 此文件表示源码已经下载过,没有此文件会重新下载
.stamp_patched, 此文件表示已经打过补丁
.stamp_extracted 此文件表示已经压过
.stamp_builted 此文件表示源码已经编译过
.stamp_target_installed 此文件表示软件已经安装过
想要从新执行哪一步,就把对应的.stamp_文件删除就行
* 首先配置builtroot(包括编译选项、工具链、bootloader、kernel、package和根文件系统类型)
* 对内核和busybox的的内容配置
* 定制根文件系统
* 在目标文件系统中增加或覆盖文件(using BR2_ROOTFS_OVERLAY)
* 改动或者删除目标文件系统(using BR2_ROOTFS_POST_BUILD_SCRIPT )
* 生成跟文件系统之前运行任意命令(using BR2_ROOTFS_POST_BUILD_SCRIPT )
* 设置文件属性权限(using BR2_ROOTFS_DEVICE_TABLE )
* 增加定制设备节点 (using BR2_ROOTFS_STATIC_DEVICE_TABLE )
* 增加用户个数 (using BR2_ROOTFS_USERS_TABLES )
* 生成根文件系统之后运行任意指令 (using BR2_ROOTFS_POST_IMAGE_SCRIPT )
* 增加工程patch到平package (using BR2_GLOBAL_PATCH_DIR )
* 增加工程package (using BR2_GLOBAL_PATCH_DIR )
根据以下建议使用方法,可以定制出独特的工程出来。
1.目录结构
构建工程目录结构时,既可以放在builtroot原有的目录结构内,也可以放在原有的目录结构外。放在目录结构外,则需要使用BR2_EXTERNAL参数。
推荐的目录结构如下:+-- board/
| +-- /
| +-- /
| +-- linux.config
| +-- busybox .config
| +--
| +-- post_build.sh
| +-- post_image.sh
| +-- rootfs_overlay /
| | +-- etc /
| | +--
| +-- patches /
| +-- foo /
| | +-- < some patch>
| +-- libbar/
| +--
|
+-- configs/
| +-- _defconfig
|
+-- package/
| +-- /
| +-- Config.in (if not using BR2_EXTERNAL)
| +-- .mk (if not using BR2_EXTERNAL)
| +-- package1 /
| | +-- Config.in
| | +-- package1 .mk
| +-- package2 /
| +-- Config.in
| +-- package2 .mk
|
+-- Config.in (if using BR2_EXTERNAL)
+-- external .mk (if using BR2_EXTERNAL)
2.外部builtroot的自定义
FIXME
3.保存builtroot配置文件
make savedefconfig
4.保存其他部分的配置文件
a. 内核的配置和保存
- make linux-menuconfig
- make linux-update-defconfig(2.6.33版本之前的话,make linux-update-config)
b.busybox的配置和保存
- make busybox-menuconfig
- make busybox-update-config
c. uclibc的配置和保存
- make uclibc-update-config
5.自定义目标文件系统
除了以上提及的修改配置文件的方法,还有以下两种方法可以使用。可以同时使用。分别是 root lesystem overlay(s) and post build script(s).
- 覆盖根文件系统
- 传递构建脚本
* 在系统所有软件编译完成之后rootfs images组装之前,执行shell 脚本去修改跟文件系统
* 推荐的路径是 board///post_build.sh.
以下两种方法不推荐,但是可以使用:
- 在output目录下临时修改进行编译
- 修改rootfs框架skeleton
6.设置权限和增加设备节点
假如某个文件需要root的权限,若使用脚本,则需要借助fakeroot命令,但是builtroot可以根据BR2_ROOTFS_DEVICE_TABLE 空格隔开的权限列表,根据makedev 语法来实现txt文件。
7.增加用户个数
FIXME
根据makeuser的语法使用选项BR2_ROOTFS_USERS_TABLES来配置用户列表
8.镜像文件生成之后自定义
9.builtroot的编码风格
总的来说,编码风格的统一有助于新增文件包或者重构已有的文件包。
10.config.in
Config.in 文件包含所有builtroot的配置信息。
风格样式: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.
http:// foosoftware .org /libfoo /
11. .mk
与Makefile文件风格一致。
文件头部说明的样式,说明样式之后强制空一行:#############################################################
#
# s3c2440_message_framework
#
#############################################################
=号前后加一个空格,样式为:LIBFOO_VERSION = 1.0
LIBFOO_CONF_OPTS += --without -python- support
定义使用TAB键
define LIBFOO_REMOVE_DOC
$(RM) - fr $(TARGET_DIR)/usr / share/ libfoo / doc \
$(TARGET_DIR)/usr /share/ man / man3/ libfoo *
endef
12. 对一个板子进行支持
13. 增加新的package
- 首先在package目录下增加一个需要增加的类型子文件夹。子文件夹里面存放两个文件config.in(config.in.host)和.mk。
* menuconfig BR2_PACKAGE_MYTEST
bool "My test"
default y 需要注意,命令行首加TAB键,帮助内容的行首加tab键和两个空格。
* 这样来看的话,可以在buildroot的menuconfig中发现这列。
* 示例图:{{:tool:mytestmenuconfig.jpg?900|}}
- 通过在builtroot中的config.in文件中source好config.in文件,即可完成新增。source "package/mytest/Config.in"
* 若有依赖关系,则还需依赖相关。
* 如是否依赖目标系统和工具链,是否依赖内核,是否依赖udev规则FIXME
- .mk文件
* 这部分最难,指定这个package如何下载,配置,编译,安装
* .mk的各个参数含义
* xxx_VERSION指定版本
* xxx_SOURCE指定名称,缺省就是xxx
* xxx_PATCH指定补丁的文件名
* xxx_SITE指定包的位置,有
* loacl
* cvs
* svn
* git
* xxx_DEPENDENCIES指定依赖关系
* xxx_INSTALL_STAGING指定安装到到根目录
* xxx__INSTALL_TARGET指定安装到目标目录
* xxx_INSTALL_IMAGES指定安装到镜像目录
* 以下几点是可选选项:
* xxx_DEVICES设备文件
* xxx_PERMISSIONS设备文件权限
* xxx_USERS指定用户
* ...
* $(@D) 用于指定未压缩的源码路径
* 示例:
1 #############################################################
2 #
3 # mytest
4 #
5 #############################################################
6
7 pkg = MYTEST
8
9 $(pkg)_VERSION = 1.0
10 $(pkg)_SITE_METHOD = local
11 $(pkg)_SITE = $(AMBARELLA_PKG_DIR)/mytest
12 $(pkg)_SOURCE =
13 $(pkg)_DEPENDENCIES =
14 $(pkg)_INSTALL_STAGING = NO
15 $(pkg)_INSTALL_IMAGES = NO
16 $(pkg)_INSTALL_TARGET = YES
17 $(pkg)_LICENSE = Ambarella
18 $(pkg)_LICENSE_FILES = License_Ambarella.txt
19
20 define MYTEST_INSTALL_STAGING_CMDS
21 $(TARGET_CONFIGURE_OPTS) $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) -f br.mk DESTDIR=$(STAGING_DIR) install_staging
22 endef
23
24 define MYTEST_INSTALL_TARGET_CMDS
25 $(TARGET_CONFIGURE_OPTS) $(TARGET_MAKE_ENV) $(MAKE) -C $(@D) -f br.mk
26 endef
27
28 define MYTEST_BUILD_CMDS
29 $(TARGET_CONFIGURE_OPTS) $(TARGET_MAKE_EVN) $(MAKE) -C $(@D) -f br.mk
30 endef
32 $(eval $(generic-package))
* 1-6行通用做法,程序包名称的说明
* 7行是变量赋值
* 9行是版本号信息
* 10、11、12是指定源码的来源(本地寻找还是网络下载)
* 13是依赖
* 14、15、16是安装到根目录,镜像文件,安装(YES / NO 来选)
* 17 18是许可证信息
* 20-30分别对应14 15 16指令执行的内容
* 32 generic-package是指使用普通的mk,不像autotools 或者cmake工具一样简单,需要用户自己定义好,如上所述。同时最后的宏还可以支持:
* autotools-ed
* CMake-ed
* Python
* Perl
* ...