这也是behind the code重要的事情,为了达到这个理解,在没有manual,资料缺乏的情况下,是很困难的,但是一旦达到了这个境界,很多事情就好办了,我也就可以安心做其它的事情了,继续研究behind the code的故事了
bitbake demo
程序是从 bitbake/bin/bitbake开始,其中会调用 lib/bb/下的相关模块
BBCooker.cook()这是开始的函数
一开始是对bitbake 的一些参数进行处理,比如:
if not self.configuration.cmd:
self.configuration.cmd = "build"
|
就是说如果没有指定task,那么就默认为build,比如我
那么 self.configure.cmd就为空,所以就相当于
继续下走
self.parseConfigurationFile( os.path.join( "conf", "bitbake.conf" ) )
|
这是分析一些conf文件和继承的bbclass,并cache住,这个其实就是 __depends的值,一旦这个值有改动,那么就会重新parse所有的文件
if not bb.data.getVar("BUILDNAME", self.configuration.data):
bb.data.setVar("BUILDNAME", os.popen('date +%Y%m%d%H%M').readline().strip(), self.configuration.data)
|
这个就是设置BUILDNAME,比如
NOTE: build 200710201006: started
OE Build Configuration:
BB_VERSION = "1.6.2"
OE_REVISION = "<unknown>"
TARGET_ARCH = "powerpc"
TARGET_OS = "linux-uclibc"
MACHINE = "test"
DISTRO = "test2-uclibc"
DISTRO_VERSION = "20071020"
TARGET_FPU = ""
NOTE: build 200710201006: completed
BUILDNAME的值每次在这里出现。
if (not self.configuration.show_environment) and (self.configuration.buildfile is not None):
...
self.tryBuildPackage( bf, item, bbfile_data )
|
如果你不想parse所有的bb file,(可以节约时间),直接 build package,你就可以使用 bitbake -b
这是真实的,因为你当现在可以发现,还没有程序去parse所有的bbfile
go on....
self.status = BBParsingStatus()
|
这就实例化了一个 BBParsingStatus Class,这个class很重要,记录了处理每一个pacakge的一些变量
def __init__(self):
self.providers = {} // package提供的providers,默认是3个
self.rproviders = {}// packages提供的run providers
self.packages = {} // PACKAGES变量的值
self.packages_dynamic = {} // 动态 PACKAGES的值
self.bbfile_priority = {} // bbfile的优先级
self.bbfile_config_priorities = [] //多个分支的匹配模式和优先级
self.ignored_dependencies = None //忽略的依赖关系
self.possible_world = [] //
self.world_target = Set()// 分支里所有的package
self.pkg_pn = {} // package->bb filename
self.pkg_fn = {} // filename-> package
self.pkg_pvpr = {}// pv pr
self.pkg_dp = {} // default_perference
self.pn_provides = {}
self.all_depends = Set()// 所有package总的依赖
self.build_all = {} // BUILD_ALL_DEPS
self.deps = {} // depends list
self.rundeps = {} // rundeps list
self.runrecs = {} // run reccommend
self.task_queues = {} //task 队列
self.task_deps = {} // task 的依赖关系
self.stamp = {} // stamp file
self.preferred = {} // 优先选择的 virtual/package
|
在处理每个bbfile的时候,都会调用 handle_bb_data去填充上面成员变量,理解上面这些成员变量,对理解整个bitbake sources code 有着非常重要的意思,这些变量的意义,我是通过若干次的反复,才得到的。
好,我接着走
ignore = bb.data.getVar("ASSUME_PROVIDED", self.configuration.data, 1) or ""
self.status.ignored_dependencies = Set( ignore.split() )
|
看到这里,我们就能明白在local.conf.sample,里ASSUME_PROVIDED的意思了吧,如果你一旦定义了ASSUME_PROVIDED的时候,bitbake就会把它放入 ignored_dependencies,也就是说,不会再编译这些package了。
self.handleCollections( bb.data.getVar("BBFILE_COLLECTIONS", self.configuration.data, 1) )
|
这个就是为了填充bbfile_config_priority,关于这个,可以参考以前的日志,有详细的解释
pkgs_to_build = None
if args:
if not pkgs_to_build:
pkgs_to_build = []
pkgs_to_build.extend(args)
if not pkgs_to_build:
bbpkgs = bb.data.getVar('BBPKGS', self.configuration.data, 1)
if bbpkgs:
pkgs_to_build = bbpkgs.split()
if not pkgs_to_build and not self.configuration.show_versions \
and not self.configuration.interactive \
and not self.configuration.show_environment:
print "Nothing to do. Use 'bitbake world' to build everything, or run 'bitbake --help'"
print "for usage information."
sys.exit(0)
|
pkg_to_build 就是 bitbake package1 package2 ...,这也是通过args传递过来的,如果我们只执行
那么就会提示红色的信息
下面是关于psyco,是可以加快python速度的一个东东,python是解释性的语言,当然有解释性语言的通病,慢,一旦处理数量很大的时候,有些难以忍受.
if not self.configuration.disable_psyco:
|
如果没有安装 psyco,那么就走到
self.collect_bbfiles( self.myProgressCallback )
|
这个函数很重要,尽管意思很明了,就是收集所有分支的bbfile,然后parse,当然里面也包含这cache机制,参数是一个回调函数,为了不影响大的路线,我现在还不深入这个函数,等理解了整个bitbake流程,再进入看看
到了这里,我们就parse了所有的bbfile
这个函数做2个方面的事情,一个是 PREFERRED_PROVIDERS,填充 self.preferred,二是计算上面所搜集的每个bbfile的优先级
下面是一个有趣的变量
if 'world' in pkgs_to_build:
self.buildWorldTargetList()
pkgs_to_build.remove('world')
for t in self.status.world_target:
pkgs_to_build.append(t)
|
就是说如果你 bitbake world,那么就会build 所有分支里面的package,我想这个变量也来源于gentoo,
下面终于来到了build package,结束了前面的预处理工作
for k in pkgs_to_build:
failed = False
try:
self.pkg_to_build = k
if self.buildProvider( k , False ) == 0:
|
pkgs_to_build,就是build package列表,我们就假设bitbake 一个package,首先调用的是
buildProvider,我一开始没有理解这个意思,到现在才明白,其实走到现在,我们还没有到去compile package的时候,首先是要找到一个provider 提供 pkgs_to_build,然后才走到compile package 包括dependency,如前面一样,我们现在还不分析里面的东东,继续往下走
走,其实到这里 bitbake run one time就结束了
主要的流程就这样