[What]Yocto Project --> BitBake 构建引擎

参考书籍:Embedded Linux System with the Yocto Project

  • 书籍比实际的yocto版本要低,所以yocto的详细命令需要参考其对应版本手册

运行环境:

  • ubuntu18.04 amd64
  • yocto 2.5.1

BitBake是由纯Python开发的构建工具,其灵活性、可扩展性和可移植性远远强于同类的 make 这类工具。

其metadata构建规则文件就类似于make中的Makefile。

获取和安装BitBake工具

BitBake的代码位于OpenEmbedded bitbake库,并且这是个独立的组件,可以将此工具用于其他工程构建之中。

yocto项目本身就已经包含了BitBake的下载和安装了,所以无需再来下载。

下载及安装的方式也是很简单的:

#获取源码
git clone git://git.openembedded.org/bitbake
#编译
./setup.py build
#安装于 /usr/lib/python<version>/site-packages
#也可以不安装,就在当前目录使用
./setup.py install

运行BitBake

BitBake的启动命名为:

#### 在构建环境的目录下执行命名 ###
#recipe_name 就是 recipe_name.bb 文件
bitbake <recipe_name / target_name>


#### 在构建环境的目录外执行命名 ###
#BBPATH需要是绝对路径!!!
BBPATH="/absolute/path/to/build_env" bitbake <recipe_name / target_name>

配置文件的搜寻

这个过程我感觉和Kconfig的解析流程好像

BitBake启动后会在当前目录下搜寻文件 conf/bblayers.conf 以获得一个基础构建环境。

  • 其中变量 BBLAYERS 指明了此次构建所包含的层的路径
  • 而在每个层的 conf/layer.conf 文件给出了当前层的配置文件路径
    • BBPATH 指定了包含 classesconf 文件夹的路径,多个路径通过冒号分隔
    • BBFILES 给出了当前层的具体构建配置文件(recipes files and append files)的路径。
  • BitBake会用变量 LAYERDIR 来保存层的顶级路径,BitBake便顺藤摸瓜找到各个层的配置文件。
  • BitBake在遍历过程中,会根据 BBFILE_COLLECTIONS, BBFILE_PATTERN_<name> , BBFILE_PRIORITY_<name> 来整理配置
    • BBFILE_COLLECTIONS 指定一个搜集器,将相同的文件聚集到一起
    • BBFILE_PATTERN_<name> 以正则表达式的方式指定BitBake的起始搜寻路径
    • BBFILE_PRIORITY_<name> 指定此层配置文件的优先级(1~10,数值越高优先级越高)
      • 当有同名的recipe文件,BitBake使用优先级高的
      • 当有多个append文件,BitBake先应用优先级高的append文件,再应用优先级低的
  • BitBake在解析完 bblayers.conf 文件后,还会去解析 conf/bitbake.conf 文件,以获取编译环境的设置。

BitBake命令行

BitBake的命令参数很多,下面对它们进行分类整理。

以包含依赖的方式处理构建

BitBake默认的构建任务是由变量 BB_DEFAULT_TASK 所指定的 build 任务。

build 任何在正式启动编译之前会评估好各个软件包之间的依赖和编译顺序。

一般情况下使用的 bitbake <recipe_name / target_name> 命令就是启动的 build 任务。

  • 当出现了错误时,bitbake将停止执行任务,可以使用 -k 选项让其继续执行。

当编译软件包时,默认会编译其最新版本或者是由变量 PREFERRED_VERSION 指定的版本。 可以在目标名称后加上版本名以指定编译特定版本:

bitbake editor-1.0
bitbake editor-2.0-r3

以不包含依赖的方式处理构建

可以指定只编译某个recipe文件的规则,而不进行依赖编译。

  • 当编译出错时则退出
bitbake -b <recipe_name>.bb
bitbake --buildfile=<recipe_name>.bb

执行指定的任务

有以下两种方式:

  • 包含依赖的方式执行
bitbake <packet> -c <task_name>
bitbake <packet> --cmd=<task_name>
  • 不包含依赖的方式执行
bitbake -b <recipe_name>.bb -c <task>
bitbake -b <recipe_name>.bb --cmd=<task>

强制执行

BitBake会为每个完成的任务打上时间戳,以完成增量编译,用户可以取消此时间戳的判断以强制编译该任务

bitbake <packet> -C <task>
bitbake <packet> --clear-stamp=<task>
bitbake <packet> -c <task> -f
bitbake <packet> -c <task> --force

BitBake将任务的输出放在 "shared state cache"中(也就是 sstate-cache 文件夹),当任务输入并没有被改变时, BitBake直接从 sstate-cache 中取出结果,而不需要重新编译。

  • 这也是为什么建议将 sstate-cache 放在 build 之外的目的,多个 build 可以共享编译输出,减小编译时间

用户可以关闭 sstate-cache 的使用:

bitbake <packet> -c <task> --no-setscene

显示metadata

当用于调试构建过程时,需要输出BitBake所分析到的元数据文件、变量、功能等等:

#显示所有信息
bitbake -e
bitbake --environment
#仅显示关于此 <package>的信息
bitbake -e <package>
bitbake --environment <package>
#显示recipes的版本
bitbake -s
bitbake --show-versions

创建依赖图

BitBake基于graphviz表示包之间的依赖图:

#生成描述依赖的dot文件
bitbake -g <package>
bitbake --graphviz <package>

#生成描述依赖的dot文件,并忽略某个包
bitbake -g <package> -I <ignore_package>

最终会在构建目录下生成下面3种DOT语言描述文件:

  • task-depends.dot : 描述任务级之间的依赖
  • recipe-depends.dot : 包与包之间的依赖

然后使用 graphviz 生成图片即可,例如:

dot -Tpng -o pn-depends.png pn-depends.dot

注意:这张图很大,建议使用 tred去掉中间依赖

tred recipe-depends.dot > recipe-depends-notrans.dot

也可以使用BitBake所自带的依赖描述工具:

bitbake -g -u taskexp <package>

配置的设置和覆盖

用户可以在BitBake解析其他文件前后加入附加的配置文件:

  • 在解析其他文件前加入配置文件,一般用于设置环境变量
bitbake -r <prefile>.conf <target>
bitbake --read <prefile>.conf <target>
  • 在解析其他文件后加入配置文件,一般用于覆盖前面配置文件的设置
bitbake -R <postfile>.conf <target>
bitbake --postread <postfile>.conf <target>

服务器

BitBake是一个典型的CS架构下的应用程序,每次启动BitBake时它都会启动一个服务端程序(叫做 cooker ), 和一个客户端程序。

服务器会启动多个线程分析元文件,并进行编译。服务器和客户端使用pipe来交互信息。

当然,这种架构完全可以用于远程编译:小组里几个人共用一个强大的服务器,将自己客户端的代码放在服务器编译后取得结果。

  • 在服务器上启动BitBake服务端程序:
bitbake --server-only --bind=<ip>:<port>
  • 客户端连接 BitBake服务器构建:
bitbake --remote-server=<ip>:<port> <target>

BitBake元数据

BitBake通过分析元数据来控制构建过程,元数据来描述软件包该如何构建以及它的依赖关系。

BitBake将分析后的元文件放在一个缓存文件夹中,避免下次重复分析而浪费不需要的时间。

BitBake分析以下两类元数据:

  • 变量(Variables): 包括控制整体的全局变量,以及控制一小部分的局部变量
  • 可执行元数据(Executable Metadata):在recipes和classes中嵌入的功能和命令

元数据文件由以下5种文件组成:

  • 配置文件(.conf):配置文件中的变量都是全局变量,所以它们会影响全局。
    • 如果多个配置文件中有多个相同的变量,那么使用优先级最高的那个。
      • bitbake.conf 优先级最低,而构建目录下的 local.conf 优先级最高
  • recipe文件(.bb):recipe文件用于描述软件包以及该如何构建此软件包
    • 对包的操作命令通常有:下载、解压缩、打补丁、编译、打包、安装
  • class文件(.bbclass):类文件主要包含很多recipe文件所共有的设置,以便它们继承。
    • BitBake会搜寻当前层下的 classes 子文件以获取类文件
    • recipe中使用 inherit 指令来继承类文件
      • 类文件是全局的,所以recipe可以在任何位置继承
  • append 文件(.bbappend) : 附加文件是对recipe文件的扩展,附加文件的前缀名称必须与recipe文件一致
    • append文件中包含的层路径也要与recipe文件一致
    • 当不同层中有一样的append文件时,由层的优先级来决定使用哪一个
  • include 文件(.inc): 每中元数据文件都可以使用 include, require 指令包含其他文件,include文件表示其他元文件所共同包含的元文件
    • 包含执行指令的元文件只能被 recipes,append,classes文件包含

元数据的语法

元数据的语法类似 Makefile和shell 脚本。

注释

使用 # 作为注释开头, 但注释分为普通注释和功能函数注释

  • 普通注释(在函数之外)的 # 必须在 行的第一列 才符合语法规则
  • 元文件中可以包含 shell 和 python 功能函数,在函数内部的注释就比较随意了。

变量

元数据中的变量对于BitBake来说都是字符串,并且其和Makefile一样,引用变量使用 ${} 实现。

变量名

变量名中可以包含:大小写字母、数字、下划线(_)、横线(-)、点(.)、加号(+)、波浪线(~)

为了与Makefile和shell保持一致的习惯,一般还是使用大写字母和下划线的形式来组成变量名。

变量的作用域

  • 在配置文件(.conf)中定义的变量都是全局变量,所有的recipes文件可见
  • 在recipes文件中定义的变量是局部变量,当其修改全局变量时,其作用也是局部的

变量的赋值

变量的赋值是使用单引号或双引号包含的字符串(一般都使用双引号),具有以下几种赋值类型:

  • 直接赋值( = ) : 在使用时才真正赋值
#在双引号字符串中的其他引号字符可以使用转义字符(\)或单引号来表示
VAR1 = "This is a \"quotation\" inside a variable assignment"
VAR2 = "This is a second 'quotation' inside a variable assignment"

VAR3 = "jumps over"
VAR4 = "${VAR3} the lazy dog."
VAR3 = "falls on"
#在真正使用VAR4的时候,其值为 "falls on the lazy dog."
  • 默认赋值( ?= ): 当变量为空时,为其指定一个默认值
#如果A之前没有被赋值,那么A的值就是 value1
A ?= "value1"
#如果B之前没有被赋值,那么B的值就是 value2
B ?= "value2"
B ?= "value3"
#无论C之前有没有被赋值,其值都是 value5
C ?= "value4"
C = "value5"
  • 弱赋值 ( ??= ) : 如果变量之前没有被赋值,那么其值在分析时被确定,其优先级 < 默认赋值 < 直接赋值
#如果A之前没有被默认赋值和直接赋值,那么其值就是 value1
A ??= "value1"
#如果B之前没有被默认赋值和直接赋值,那么其值就是 value3
B ??= "value2"
B ??= "value3"
#如果C之前没有被默认赋值和直接赋值,那么其值就是 value4
C ?= "value4"
C ??= "value5"
#D的值就是 value6
D = "value6"
D ??= "value7"
  • 立即赋值( := ) : 立即为变量设置值
VAR1 = "jump over"
VAR2 := "${VAR1} the lazy dog"
VAR1 = "falls on"

#在使用VAR2时其值为 "jump over the lazy dog"


#BitBake可以解析python语法,在表达式前面加 @即可
DATE = "${@time.strftime('%A %B %d, %Y', time.gettime())}"
TODAY := "Today is: ${DATE}."
  • 值的追加:
    • "+=" : 在现有值的后面增加值,并自动添加空格
    • "=+" : 在现有值的前面增加值,并自动添加空格
    • ".=" : 在现有值的后面增加值,不会添加空格
    • "=." : 在现有值的前面增加值,不会添加空格
    • "_append" : 在名称后增加 "_append" 表示在值后面添加值,不会添加空格
    • "_prepend" : 在名称后增加 "_prepend" 表示在值前面添加值,不会添加空格
  • 值的去除:在名称后加 "_remove" ,代表在原值中去掉以空格做分隔的哪部分
VAR1 = "123 456 789 123456789 789 456 123 123 456"
VAR1_remove = "123"
VAR1_remove = "456"

#最终VAR1的值为 "789 123456789"
  • 条件赋值:可以为变量的赋值设定一定的条件,当满足该条件值才可以被改变。这在构建过程常用
#OVERRIDES变量中包含了赋值的条件,条件使用冒号分隔,条件优先级从左到右依次升高
#也就是说最后边的优先级是最高的,其中默认的 "append" 和 "prepend" 具有最高优先级
OVERRIDES = "sun:rain:snow"

#变量使用后缀来确定使用哪个条件
#最终变量 PROTECTION中的值为 "sweater" 因为snow的优先级高于 "rain"
PROTECTION = "unknown"
PROTECTION_snow = "sweater"
PROTECTION_rain = "umbrella"

#也可以附加值
PROTECTION_append_rain = "umbrella"

包含

metadata 文件可以包含其他文件可以获取它们的设置,BitBake使用以下两种命令包含其他文件:

  • include : 可选包含,当BitBake没有找到该文件时会继续执行不会报错
  • required : 必须包含,当BitBake没有找到该文件时会报错并停止执行

recipes 和 classes 文件可以包含配置设置和命令设置文件,而配置文件只能包含仅有配置设置的文件!

.inc 文件可以包含其他文件,当包含形成一个环形包含时,BitBake会给出报错信息

当有多个同名文件时,BitBake以找到的第一个文件为准。

#两个命令都可以使用绝对路径和相对路径
#当使用相对路径时,它是相对于变量 BBPATH 的路径
include file1.inc
include meta-test/recipes-core/images/file2.inc
required /home/build/yocto/file3.inc

和预编译处理过程一样,包含的文件会在包含指令的位置处展开。

继承

recipes,append,classes文件可以继承classes文件,继承使用命令 inherit <class_name>

BitBake继承class文件的流程为:

  1. 通过 inherit 命令中的 <class_name> 找到 <class_name>.bbclass 文件。
    • <class_name>.bbclass 文件位于 classes 文件夹中, class_name 需要是独一无二的
  2. 在解析完配置文件之后以及recipes文件之前,BitBake开始分析classes文件
  3. 在分析classes文件中遇到了文件包含,则顺序展开即可
  4. BitBake使用写时复制(copy on write, COW),来保持class副本

可执行语句

可执行语句可以存在于 recipes,append,classes 文件中,可以是 shell 或 python 功能函数。

BitBake将功能函数名作为变量名,将其函数体作为右值,所以这些功能函数也可以像其他普通变量一样被扩展。

在classes中的功能函数为全局作用域,而在recipes和append中的功能函数为局部作用域。

shell函数

BitBake调用的解释器路径为 /bin/shshell函数的定义和标准shell(bash)一模一样:

function_name () { 
command...
}

python本地函数

python本地函数的定义有些许不同,需要使用 python 关键字来提示BitBake使用python解释器来执行:

  • 在函数内的就可以按照标准的python语法来实现了
python printdate () {
    import time
    print time strftime(‘%Y%m%d’, time.gettime())
}

python全局函数

当使用标准语法来定义函数时,此函数就是一个全局的函数,可以被其他的metadata所使用

python匿名函数

匿名函数在当前文件被解析完后自动执行,有以下两种定义方式:

python __anonymous () {
# Anonymous function using the __anonymous keyword
...
}
python () {
# Anonymous function omitting the function name
...
}

任务(tasks)

上面所讲述的几种函数,将他们名称前加上 do_ 就被称为任务(tasks),BitBake使用 addtask 命令来讲此任务加入任务列表。

python do_clean () {
# task to clean remove build output...
}
addtask clean
do_build () {
# task to build the software package
...
}
addtask build
do_download () {
# task to download sources
...
}
addtask download before do_build
do_unpack () {
# task to unpack sources
...
}
addtask unpack before do_build after do_download
do_compile () {
# task to compile software package
...
}
addtask compile before do_build after do_unpack
do_install () {
# task to install binaries, libraries, and documentation
...
}
addtask install after do_build
  • 上述定义了任务 do_clean() ,然后使用 addtask clean 将其加入任务列表,BitBake可以使用命令行的方式来指定执行此任务(比如recipe文件的名称为 myrecipe.bb)
    • bitbake myrecipe -c clean
  • 上面的 addtask download before do_build , addtask unpack beofre do_build after do_download , addtask compile before do_build after do_unpack , addtask install after do_build
    • 当执行 bitbake myrecipe -c build 时,其执行函数顺序依次为 do_download -> do_unpack -> do_compile -> do_build -> do_install
      • 也就是说将这些任务串联起来了
  • 当recipe中调用 BitBake时没有为其指定任务时,则其使用 BB_DEFAULT_TASK 所定义的任务,默认为 build
BB_DEFAULT_TASK ?= "build"

在函数中访问BitBake变量

  • 在shell函数中访问:直接使用变量引用访问即可
    • shell中改变了变量,其作用域在函数内
BPN = "myapp-v1"
MAKE = "make"
EXTRA_OEMAKE = "CFLAGS='-W -Wall -Werror -Wundef -Wshadow ${CFLAGS}'"
do_compile () {
bbnote ${MAKE} ${EXTRA_OEMAKE} "$@"
${MAKE} ${EXTRA_OEMAKE} "$@" || die "oe_runmake failed"
}
do_install () {
BPN = "myapp"
docdir = "docs"
install -d ${D}${docdir}/${BPN}
}
  • 在python函数中访问:需要使用方法才可以
    • 使用全局变量中的 d 方法 getVar()setVar 来获取和设置此值
      • getVar() 参数2用于表示是否要使用此变量被扩展后的值(当变量值中包含其他变量时,是使用其他变量的值还是按照原字符串返回)
    • 注意: 使用这种方式修改的变量则是全局修改的,为了局部修改可以使用 createCopy() 方法来创建变量副本,也是使用COW的方式
      • localdata = d.createCopy()
HELLO = "Hello, World!"
DATE = ""
python printhello () {
hello = d.getVar('HELLO', True)
print hello
}
python setdate () {
import timedate = time.strftime('%A %B %d, %Y', time.gettime())
d.setVar('DATE', date)
}

有些变量是由分隔符所组成的字符串列表,python中也有对应的方法将其拆开来:

python do_download () {
#SRC_URI中以空格作为分隔,所以split中使用 " " 作为分离符
# or 是为了避免 SRC_URI 没有找到而出错
uris = (d.getVar('SRC_URI', True) or "").split(" ")
for uri in uris:
# process the source URIs
...
}

功能函数的扩展

函数也可以像变量那样通过 _append_prepend 来扩展函数体:

python printdate () {
import time
print time.strftime('%A %B %d, %Y', time.gettime())
}
python printdate_prepend () {
print ('Today is: ')
}
python printdate_append () {
print('MOTD: A good day for the Yocto Project.')
}

#最终的函数为
python printdate () {
print ('Today is: ')
import time
print time strftime('%A %B %d, %Y', time.gettime())
print('MOTD: A good day for the Yocto Project.')
}

metadata 的属性

变量的属性是由变量名后的方括号所表示的,并且属性也可以被扩展:

VAR[flag] = "flagvalue"

在Python中也可以获取和修改属性:

func[run] = "1"
python func () {
run = d.getVarFlag('func', 'run')
if run == 1:
# do some work
...
d.setVarFlag('func', 'run', 0)
else:
# do not run at this time
}

变量名的扩展

变量名也可以被扩展:

A${B} = "foo"
B = "2"
A2 = "bar"

#在整个文件解析完毕之后, A2 的值为 "foo"

源码的下载

链接获取及其格式

在进行正式构建前的第一步就是源码的获取,BitBake是从上游库(Upstream repositories)获取源码。

上游库可以是本地路径、远程文件服务器、git库等等,而BitBake会根据库的路径来自动使用合适的协议获取源码。

同时源码也可能以各种不同的格式被压缩,而BitBake也会根据源码的压缩格式来自动使用合适的工具解压缩。

BitBake提供 fetch2 库(位于 bitbake/lib/bb/fetch2),使用Python其 Fetch 类来实现源码的智能获取。

描述链接的格式为:

<scheme>://[<user>[:<pwd>]@]<host>[:<port>]/<path>[;<key>=<value>;..]
  • 对于本地路径,支持绝对路径和相对路径两种方式:
file:///absolute/path/to/file
file://relative/path/to/file

使用 Fetch 类

为了可以获取源码,需要使用 Fetch 类来触发源码的下载:

  • 最终的下载会指向 DL_DIR 所指定的目录
python do_fetch() {
bb.note(“Downloading sources from ${SRC_URI} ...”)

src_uri = (d.getVar(‘SRC_URI’, True) or "").split()
if len(src_uri) == 0:
bb.fatal("Empty URI")
try:
fetcher = bb.fetch2.Fetch(src_uri, d)
fetcher.download()
except bb.fetch2.BBFetchException:
bb.fatal("Could not fetch source tarball.")

bb.note("Download successful.")
}
addtask fetch before do_build

实际上OE Core的 base.bbclass已经提供了此任务,无需用户实现

源码获取的具体实现

本地源码的获取

本地源码的获取支持绝对路径和相对路径两种格式:

  • 本地源码的下载其实就是将路径中的文件复制到 DL_DIR 指定的路径中
  • 本地文件获取的执行源码位于 bitbake/lib/bb/fetch2/local.py
SRC_URI = "file:///absolute/path/to/file"
SRC_URI = "file://relative/path/to/file"

相对路径使用 FILESPATHFILESDIR 来定位文件的位置:

  • FILESPATH : 此变量使用冒号分隔多个路径,提取器(fetcher)依次搜寻这些目录直到找到匹配的文件
    • 当有多个路径下有同名文件时,提取器下载第一个找到的文件
  • FILESDIR : 当 FILESPATH 中没有路径时,提取器会检查变量 FILESDIR 中的路径

如果没有找到对应的文件,提取器就会报错。

HTTP/HTTPS/FTP 源码的获取

BitBake默认使用wget来完成http,https,ftp协议的文件下载。

  • 源码脚本位于 bitbake/lib/bb/fetch2/wget.py

可以通过设置变量 FETCHCMD_wget 来设置 wget 的选项,可设置的值有:

  • md5sum : 使用md5校验,如果与提供的校验码不匹配则报错
  • sha256sum : 使用sha256sum校验,如果与提供的校验码不匹配则报错
  • downloadfilename : 将下载好的文件重命名为当前设定的文件名
  • name : 链接地址的别名

其中 md5sumsha256sum 至少需要提供其中一个!

SRC_URI	=	"http://host.site.org/downloads/srcpkg.tar.gz;md5sum=12345"
SRC_URI	=	"https://host.site.org/downloads/srcpkg.tar.gz;sha256sum=6789"
SRC_URI	=	"ftp://user:pwd@host.site.org/repo/srcpkg.tar.gz;md5sum=12345"
SRC_URI	=	"ftp://host.site.org/srcpkg.tar.tgz;md5sum=12345;downloadfilename=file.tgz"

校验码一般都比较长,所以可以分离URL和校验码:

#当只有一个下载包时
SRC_URI	=	"http://host.site.org/downloads/srcpkg.tar.gz"
SRC_URI[md5sum]	=	"12345"
SRC_URI[sha256sum]	=	"6789"

#当有多个下载包时,通过名称来区分
SRC_URI	=	"http://host.site.org/downloads/srcpkg1.tar.gz;name=pkg1
           ftp://host.anothersite.org/downloads/srcpkg2.tgz;name=pkg2"
SRC_URI[pkg1.md5sum]	=	"12345"
SRC_URI[pkg2.sha256sum]	=	"6789"

SFTP 源码的获取

在使用SFTP前,用户需要先用ssh key提前获取权限后,再来让bitbake以sftp的方式抓取,不能直接在URI中输入密码。

  • 源码脚本位于 bitbake/lib/bb/fetch2/sftp.py
SRC_URI	=	“sftp://host.site.org/downloads/srcpkg.tgz;md5sum=12345”
SRC_URI	=	“sftp://user@host.site.org/downloads/srcpkg.tgz;md5sum=12345”

git 源码的获取

git 抓取脚本位于 bitbake/lib/bb/fetch2/git.py

抓取器提供了以下参数可以控制clone的过程:

  • protocol : 支持的协议有 git,file,ssh,http,https,rsync
    • 默认的便是 git协议
  • branch : 要切换到哪个分支
    • 默认为 master
  • name : 分支的名称
  • tag : 切换到哪个标记
    • 默认为 HEAD
  • rebaseable : 使用 "rebaseable=1" 告知上游库可能以后会有 rebase 操作,抓取器需要将当前工作目录缓存
    • 默认为 0
  • nocheckout : 使用 "nocheckout=1" 告知不要切换到抓取后的分支
    • 默认为 0
  • bareclone : 使用 "bareclone=1" 告知仅clone裸库而不释出源码
    • 默认为0
#注意:最开始的地址都是以默认的git协议写的,具体的protocol需要在后面更改
SRC_URI	=	"git://git.site.org/git/repo.git;branch=develop"
SRC_URI	=	"git://git.site/org/git/repo.git;tag=0C12ABD"
SRC_URI	=	"git://git.site.org/git/repo.git;protocol=http"

当库代码中有子模块时,提取器会在clone完基础代码后再clone子模块。 git 抓取脚本位于 bitbake/lib/bb/fetch2/gitsm.py

源码镜像

BitBake支持从镜像站点下载软件包,其访问顺序为:

  1. 根据 SRC_URI 中提供的软件包,在 DL_DIR 指向的路径中寻找是否有匹配的文件。如果存在此文件,则无需从远程下载了。
    • 当软件包使用了SCM仓库,那么BitBake会检查 DL_DIR 中的分支和tag是否对应。
  2. DL_DIR 中没有对应的软件包时,BitBake根据 PREMIRRORS 中提供的镜像站点下载文件
    • 如果不想使用此镜像站,那么将变量 PREMIRRORS 的值设置空字符串即可
  3. 如果在 PREMIRRORS 的镜像站点没有找到对应的包,BitBake则会在 SRC_URI 指向的路径下载软件包
  4. 如果在 SRC_URI 路径下载失败,那么BitBake会在 MIRRORS 指向的备用镜像站点下载文件
    • 如果不想使用此镜像站,那么将变量 MIRRORS 的值设置空字符串即可
  5. 备用镜像下载文件都失败的话,BitBake则会报错。

PREMIRRORSMIRRORS 使用正则表达式来列出各种下载协议对应的站点:

MIRRORS	=	"\
ftp://.*/.*				http://downloads.mirrorsite.org/mirror/sources/	\n	\
http://.*/.*			http://downloads.mirrorsite.org/mirror/sources/	\n	\
https://.*/.*		http://downloads.mirrorsite.org/mirror/sources/	\n	\
git://.*/.*				http://downloads.mirrorsite.org/mirror/sources/	\n	\
svn://.*/.*				http://downloads.mirrorsite.org/mirror/sources/	\n"

BitBake会根据 SRC_URI 对应的协议来找到镜像站点的链接并做替换。

yocto为 poky也提供了默认的镜像站

创建自己的镜像站

可以事先从yocto中下载好软件包,然后自己搭建一个内部局域网的ftp服务器,这样就可以小组内共享了。

Last Updated 2018-10-14 日 19:32.
Render by hexo-renderer-org with Emacs 26.1 (Org mode 9.1.14)