bitbake 流程 run one time


                    这也是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,比如我
bitbake demo
那么 self.configure.cmd就为空,所以就相当于
bitbake -c build demo
继续下走
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    = ""
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
bitbake -b path/demo.bb
这是真实的,因为你当现在可以发现,还没有程序去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传递过来的,如果我们只执行
bitbake
那么就会提示红色的信息
下面是关于psyco,是可以加快python速度的一个东东,python是解释性的语言,当然有解释性语言的通病,慢,一旦处理数量很大的时候,有些难以忍受.
if not self.configuration.disable_psyco:
如果没有安装 psyco,那么就走到
self.collect_bbfiles( self.myProgressCallback )
这个函数很重要,尽管意思很明了,就是收集所有分支的bbfile,然后parse,当然里面也包含这cache机制,参数是一个回调函数,为了不影响大的路线,我现在还不深入这个函数,等理解了整个bitbake流程,再进入看看
到了这里,我们就parse了所有的bbfile
self.buildDepgraph()
这个函数做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就结束了
主要的流程就这样