久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

yocto 編譯流程分析

 t涂鴉 2015-03-26

git clone 一份poky 的工程到本地。

source poky/oe-init-build-env your_build_path

看下 oe-init-build-env 這個(gè)shell 腳本都干了些什么:

[plain] view plaincopy

if [ -z "$ZSH_NAME" ] && [ "x$0" = "x./oe-init-build-env" ]; then  

echo "Error: This script needs to be sourced. Please run as '. ./oe-init-build-env'"  

else  

if [ -n "$BASH_SOURCE" ]; then  

OEROOT="`dirname $BASH_SOURCE`"  

elif [ -n "$ZSH_NAME" ]; then  

OEROOT="`dirname $0`"  

else  

OEROOT="`pwd`"  

fi  

OEROOT=`readlink -f "$OEROOT"`  

export OEROOT  

. $OEROOT/scripts/oe-buildenv-internal && \  

$OEROOT/scripts/oe-setup-builddir && \  

[ -n "$BUILDDIR" ] && cd $BUILDDIR  

unset OEROOT  

unset BBPATH  

fi  

轉(zhuǎn)載: OSChina 上一個(gè)博友分析的這段shell 腳本:

http://my.oschina.net/u/158589/blog/70921

第一步,,判斷該腳本是否是用source或者.的方法運(yùn)行的,。 但是

1

["x$0"="x./oe-init-build-env"]只能對(duì)./oe-init-build-env這種執(zhí)行方式報(bào)錯(cuò),,對(duì)./yocto/oe-init-build-env是不會(huì)報(bào)錯(cuò)的,。

第二步,,設(shè)置OEROOT這個(gè)變量,。當(dāng)用.或者source去執(zhí)行腳本時(shí),BASH_SOURCE這個(gè)變量會(huì)被自動(dòng)設(shè)置到源文件路徑,。于是dirname $BASH_SOURCE就獲得了腳本所在目錄。readlink -f $OEROOT獲得了絕對(duì)路徑,。

第三步,執(zhí)行oe-buildenv-internal和oe-setup-builddir這兩個(gè)腳本,,并且進(jìn)入到build目錄,。

(注意這里的oe-buildenv-internal是用.執(zhí)行的,,而oe-setup-build是fork shell執(zhí)行的。因?yàn)閛e-setup-builddir中用到了OEROOT這個(gè)變量,,所以在此之前,,OEROOT必須被export,,正如腳本中所做的那樣,。)

第四步,,unset一些變量,。因?yàn)?或者source的執(zhí)行方式是在原shell中執(zhí)行,,并不fork shell,,所以如果不unset,,會(huì)一直留在該shell中。

chenqi@chenqi-laptop ~/MyPro/ShellScript/yocto $ . ./oe-init-build-env

BASH_SOURCE = ./oe-init-build-env, OEROOT = .

OEROOT = /home/chenqi/MyPro/ShellScript/yocto

chenqi@chenqi-laptop ~/MyPro/ShellScript $ source yocto/oe-init-build-env

BASH_SOURCE = yocto/oe-init-build-env, OEROOT = yocto

OEROOT = /home/chenqi/MyPro/ShellScript/yocto

可見,,無論在哪個(gè)目錄下執(zhí)行,,最后獲得的OEROOT的絕對(duì)路徑都是一致的,。(主要利用BASH_SOURCE, dirname, readlink)。

[plain] view plaincopy

. $OEROOT/scripts/oe-buildenv-internal  

oe-buildenv-internal 這個(gè)shell 腳本主要是設(shè)置環(huán)境變量(poky/bitbake/bin/ 和 poky/scripts 這兩個(gè)路徑加入到PATH中,。bitbake 命令就在poky/bitbake/bin/路徑下面,。),,如下:

[plain] view plaincopy

PATH="${OEROOT}/scripts:$BITBAKEDIR/bin/:$PATH"  

unset BITBAKEDIR  

# Used by the runqemu script  

export BUILDDIR  

export PATH  

export BB_ENV_EXTRAWHITE="MACHINE DISTRO TCMODE TCLIBC HTTP_PROXY http_proxy \  

HTTPS_PROXY https_proxy FTP_PROXY ftp_proxy FTPS_PROXY ftps_proxy ALL_PROXY \  

all_proxy NO_PROXY no_proxy SSH_AGENT_PID SSH_AUTH_SOCK BB_SRCREV_POLICY \  

SDKMACHINE BB_NUMBER_THREADS BB_NO_NETWORK PARALLEL_MAKE GIT_PROXY_COMMAND \  

SOCKS5_PASSWD SOCKS5_USER SCREENDIR STAMPS_DIR"  

[plain] view plaincopy

$OEROOT/scripts/oe-setup-builddir  

oe-setup-builddir 這個(gè)shell 腳本,,創(chuàng)建編譯目錄,判斷當(dāng)前編譯目錄下面是否存在conf/local.conf 文件,,如果不存在local.conf 配置文件的話,,通過Template模板,sample 生成一個(gè)local.conf,。

下面這段shell 腳本的意思是首先檢查 meta-yocto 目錄下面是否存在conf/ 如果存在的話就用meta-yocto/conf/  下面的 local.conf.sample 和 bblayers.conf,, 如果不存在的話就到meta/conf 下面去找 local.conf.sample 和 bblayer.conf。

[plain] view plaincopy

TEMPLATECONF=${TEMPLATECONF:-meta-yocto/conf}  

#   

# $TEMPLATECONF can point to a directory for the template local.conf & bblayers.conf  

#  

if [ "x" != "x$TEMPLATECONF" ]; then  

if ! (test -d "$TEMPLATECONF"); then  

# Allow TEMPLATECONF=meta-xyz/conf as a shortcut  

if [ -d "$OEROOT/$TEMPLATECONF" ]; then  

TEMPLATECONF="$OEROOT/$TEMPLATECONF"  

fi  

if ! (test -d "$TEMPLATECONF"); then  

echo >&2 "Error: '$TEMPLATECONF' must be a directory containing local.conf & bblayers.conf"  

return  

fi  

fi  

OECORELAYERCONF="$TEMPLATECONF/bblayers.conf.sample"  

OECORELOCALCONF="$TEMPLATECONF/local.conf.sample"  

OECORENOTESCONF="$TEMPLATECONF/conf-notes.txt"  

fi  

if [ "x" = "x$OECORELOCALCONF" ]; then  

OECORELOCALCONF="$OEROOT/meta/conf/local.conf.sample"  

fi  

if ! (test -r "$BUILDDIR/conf/local.conf"); then  

cat <<eom  < p="">

You had no conf/local.conf file. This configuration file has therefore been  

created for you with some default values. You may wish to edit it to use a   

different MACHINE (target hardware) or enable parallel build options to take   

advantage of multiple cores for example. See the file for more information as   

common configuration options are commented.  

The Yocto Project has extensive documentation about OE including a reference manual  

which can be found at:  

http:///documentation  

For more information about OpenEmbedded see their website:  

http://www./  

EOM  

cp -f $OECORELOCALCONF $BUILDDIR/conf/local.conf  

fi  

if [ "x" = "x$OECORELAYERCONF" ]; then  

OECORELAYERCONF="$OEROOT/meta/conf/bblayers.conf.sample"  

fi  

if ! (test -r "$BUILDDIR/conf/bblayers.conf"); then  

cat <<eom  < p="">

You had no conf/bblayers.conf file. The configuration file has been created for  

you with some default values. To add additional metadata layers into your  

configuration please add entries to this file.  

The Yocto Project has extensive documentation about OE including a reference manual  

which can be found at:  

http:///documentation  

For more information about OpenEmbedded see their website:  

http://www./  

EOM  

# Put the abosolute path to the layers in bblayers.conf so we can run  

# bitbake without the init script after the first run  

sed "s|##COREBASE##|$OEROOT|g" $OECORELAYERCONF > $BUILDDIR/conf/bblayers.conf  

fi  

至此,, build_path 下面的conf/local.conf 以及 bblayer.conf 文件就 創(chuàng)建好了,,接下來就可以執(zhí)行 bitbake target 編譯了,。

----------------------------------------------------------------  華麗麗的分割線 ---------------------------------------------------------

現(xiàn)在開始分析bitbake 編譯流程:

bitbake --help 可以看到bitbake 后面可以跟的選項(xiàng)參數(shù):

[plain] view plaincopy

yocto_build$ bitbake --help  

Usage: bitbake [options] [package ...]  

Executes the specified task (default is 'build') for a given set of BitBake files.  

It expects that BBFILES is defined, which is a space separated list of files to  

be executed.  BBFILES does support wildcards.  

Default BBFILES are the .bb files in the current directory.  

Options:  

--version             show program's version number and exit  

-h, --help            show this help message and exit  

-b BUILDFILE, --buildfile=BUILDFILE  

execute the task against this .bb file, rather than a  

package from BBFILES. Does not handle any  

dependencies.  

-k, --continue        continue as much as possible after an error. While the  

target that failed, and those that depend on it,  

cannot be remade, the other dependencies of these  

targets can be processed all the same.  

-a, --tryaltconfigs   continue with builds by trying to use alternative  

providers where possible.  

-f, --force           force run of specified cmd, regardless of stamp status  

-c CMD, --cmd=CMD     Specify task to execute. Note that this only executes  

the specified task for the providee and the packages  

it depends on, i.e. 'compile' does not implicitly call  

stage for the dependencies (IOW: use only if you know  

what you are doing). Depending on the base.bbclass a  

listtasks tasks is defined and will show available  

tasks  

-C INVALIDATE_STAMP, --clear-stamp=INVALIDATE_STAMP  

Invalidate the stamp for the specified cmd such as  

'compile' and run the default task for the specified  

target(s)  

-r PREFILE, --read=PREFILE  

read the specified file before bitbake.conf  

-R POSTFILE, --postread=POSTFILE  

read the specified file after bitbake.conf  

-v, --verbose         output more chit-chat to the terminal  

-D, --debug           Increase the debug level. You can specify this more  

than once.  

-n, --dry-run         don't execute, just go through the motions  

-S, --dump-signatures  

don't execute, just dump out the signature  

construction information  

-p, --parse-only      quit after parsing the BB files (developers only)  

-s, --show-versions   show current and preferred versions of all recipes  

-e, --environment     show the global or per-package environment (this is  

what used to be bbread)  

-g, --graphviz        emit the dependency trees of the specified packages in  

the dot syntax, and the pn-buildlist to show the build  

list  

-I EXTRA_ASSUME_PROVIDED, --ignore-deps=EXTRA_ASSUME_PROVIDED  

Assume these dependencies don't exist and are already  

provided (equivalent to ASSUME_PROVIDED). Useful to  

make dependency graphs more appealing  

-l DEBUG_DOMAINS, --log-domains=DEBUG_DOMAINS  

Show debug logging for the specified logging domains  

-P, --profile         profile the command and print a report  

-u UI, --ui=UI        userinterface to use  

-t SERVERTYPE, --servertype=SERVERTYPE  

Choose which server to use, none, process or xmlrpc  

--revisions-changed   Set the exit code depending on whether upstream  

floating revisions have changed or not  

--server-only         Run bitbake without UI,  the frontend can connect with  

bitbake server itself  

-B BIND, --bind=BIND  The name/address for the bitbake server to bind to  

--no-setscene         Do not run any setscene tasks, forces builds  

那么,bitbake 對(duì)于這些個(gè)選項(xiàng)參數(shù)是怎么處理的呢,。bitbake target -xxx -xxxx -xx ,,這樣其實(shí)就是執(zhí)行poky/bitbake/bitbake 這個(gè)python 腳本:

這個(gè)python 腳本相對(duì)簡(jiǎn)單,,可以看下最后的這段代碼:

通過下面這個(gè) if 判斷,調(diào)用 main 函數(shù)執(zhí)行,,使用 python 庫(kù)中的

[python] view plaincopy

optparse.OptionParser  對(duì)選項(xiàng)參數(shù)進(jìn)行處理。

[python] view plaincopy

if __name__ == "__main__":  

try:  

ret = main()  

[python] view plaincopy

#!/usr/bin/env python  

# ex:ts=4:sw=4:sts=4:et  

# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-  

import os  

import sys, logging  

sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)),  

'lib'))  

import optparse  

import warnings  

from traceback import format_exception  

try:  

import bb  

except RuntimeError as exc:  

sys.exit(str(exc))  

from bb import event  

import bb.msg  

from bb import cooker  

from bb import ui  

from bb import server  

__version__ = "1.17.1"  

logger = logging.getLogger("BitBake")  

# Unbuffer stdout to avoid log truncation in the event  

# of an unorderly exit as well as to provide timely  

# updates to log files for use with tail  

try:  

if sys.stdout.name == '':  

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)  

except:  

pass  

class BBConfiguration(object):  

""" 

Manages build options and configurations for one run 

"""  

def __init__(self, options):  

for key, val in options.__dict__.items():  

setattr(self, key, val)  

self.pkgs_to_build = []  

*** ***  

def main():  

parser = optparse.OptionParser(  

version = "BitBake Build Tool Core version %s, %%prog version %s" % (bb.__version__, __version__),  

usage = """%prog [options] [package ...] 

Executes the specified task (default is 'build') for a given set of BitBake files. 

It expects that BBFILES is defined, which is a space separated list of files to 

be executed.  BBFILES does support wildcards. 

Default BBFILES are the .bb files in the current directory.""")  

parser.add_option("-b", "--buildfile", help = "execute the task against this .bb file, rather than a package from BBFILES. Does not handle any dependencies.",  

action = "store", dest = "buildfile", default = None)  

parser.add_option("-k", "--continue", help = "continue as much as possible after an error. While the target that failed, and those that depend on it, cannot be remade, the other dependencies of these targets can be processed all the same.",  

action = "store_false", dest = "abort", default = True)  

parser.add_option("-a", "--tryaltconfigs", help = "continue with builds by trying to use alternative providers where possible.",  

action = "store_true", dest = "tryaltconfigs", default = False)  

parser.add_option("-f", "--force", help = "force run of specified cmd, regardless of stamp status",  

action = "store_true", dest = "force", default = False)  

parser.add_option("-c", "--cmd", help = "Specify task to execute. Note that this only executes the specified task for the providee and the packages it depends on, i.e. 'compile' does not implicitly call stage for the dependencies (IOW: use only if you know what you are doing). Depending on the base.bbclass a listtasks tasks is defined and will show available tasks",  

action = "store", dest = "cmd")  

parser.add_option("-C", "--clear-stamp", help = "Invalidate the stamp for the specified cmd such as 'compile' and run the default task for the specified target(s)",  

action = "store", dest = "invalidate_stamp")  

parser.add_option("-r", "--read", help = "read the specified file before bitbake.conf",  

action = "append", dest = "prefile", default = [])  

parser.add_option("-R", "--postread", help = "read the specified file after bitbake.conf",  

action = "append", dest = "postfile", default = [])  

parser.add_option("-v", "--verbose", help = "output more chit-chat to the terminal",  

action = "store_true", dest = "verbose", default = False)  

parser.add_option("-D", "--debug", help = "Increase the debug level. You can specify this more than once.",  

action = "count", dest="debug", default = 0)  

parser.add_option("-n", "--dry-run", help = "don't execute, just go through the motions",  

action = "store_true", dest = "dry_run", default = False)  

parser.add_option("-S", "--dump-signatures", help = "don't execute, just dump out the signature construction information",  

action = "store_true", dest = "dump_signatures", default = False)  

parser.add_option("-p", "--parse-only", help = "quit after parsing the BB files (developers only)",  

action = "store_true", dest = "parse_only", default = False)  

parser.add_option("-s", "--show-versions", help = "show current and preferred versions of all recipes",  

action = "store_true", dest = "show_versions", default = False)  

parser.add_option("-e", "--environment", help = "show the global or per-package environment (this is what used to be bbread)",  

action = "store_true", dest = "show_environment", default = False)  

parser.add_option("-g", "--graphviz", help = "emit the dependency trees of the specified packages in the dot syntax, and the pn-buildlist to show the build list",  

action = "store_true", dest = "dot_graph", default = False)  

parser.add_option("-I", "--ignore-deps", help = """Assume these dependencies don't exist and are already provided (equivalent to ASSUME_PROVIDED). Useful to make dependency graphs more appealing""",  

action = "append", dest = "extra_assume_provided", default = [])  

parser.add_option("-l", "--log-domains", help = """Show debug logging for the specified logging domains""",  

action = "append", dest = "debug_domains", default = [])  

parser.add_option("-P", "--profile", help = "profile the command and print a report",  

action = "store_true", dest = "profile", default = False)  

parser.add_option("-u", "--ui", help = "userinterface to use",  

action = "store", dest = "ui")  

parser.add_option("-t", "--servertype", help = "Choose which server to use, none, process or xmlrpc",  

action = "store", dest = "servertype")  

parser.add_option("", "--revisions-changed", help = "Set the exit code depending on whether upstream floating revisions have changed or not",  

action = "store_true", dest = "revisions_changed", default = False)  

parser.add_option("", "--server-only", help = "Run bitbake without UI,  the frontend can connect with bitbake server itself",  

action = "store_true", dest = "server_only", default = False)  

parser.add_option("-B", "--bind", help = "The name/address for the bitbake server to bind to",  

action = "store", dest = "bind", default = False)  

parser.add_option("", "--no-setscene", help = "Do not run any setscene tasks, forces builds",  

action = "store_true", dest = "nosetscene", default = False)  

options, args = parser.parse_args(sys.argv)  

print "+++++ qc test +++++ options:", options  

print "+++++ qc test +++++ args:", args  

configuration = BBConfiguration(options)  

configuration.pkgs_to_build.extend(args[1:])  

print "+++++ qc test +++++ pkgs_to_build:",configuration.pkgs_to_build  

*** ***  

# Ensure logging messages get sent to the UI as events  

handler = bb.event.LogHandler()  

logger.addHandler(handler)  

# Before we start modifying the environment we should take a pristine  

# copy for possible later use  

initialenv = os.environ.copy()  

# Clear away any spurious environment variables while we stoke up the cooker  

cleanedvars = bb.utils.clean_environment()  

server = server.BitBakeServer()  

if configuration.bind:  

server.initServer((configuration.bind, 0))  

else:  

server.initServer()  

idle = server.getServerIdleCB()  

cooker = bb.cooker.BBCooker(configuration, idle, initialenv)  

cooker.parseCommandLine()  

server.addcooker(cooker)  

server.saveConnectionDetails()  

server.detach()  

# Should no longer need to ever reference cooker  

del cooker  

logger.removeHandler(handler)  

if not configuration.server_only:  

# Setup a connection to the server (cooker)  

server_connection = server.establishConnection()  

# Restore the environment in case the UI needs it  

for k in cleanedvars:  

os.environ[k] = cleanedvars[k]  

try:  

return server.launchUI(ui_main, server_connection.connection, server_connection.events)  

finally:  

bb.event.ui_queue = []  

server_connection.terminate()  

else:  

print("server address: %s, server port: %s" % (server.serverinfo.host, server.serverinfo.port))  

return 1  

if __name__ == "__main__":  

try:  

ret = main()  

except Exception:  

ret = 1  

import traceback  

traceback.print_exc(5)  

sys.exit(ret)  

這里調(diào)用到了 parseConfigurationFiles() 函數(shù),,這個(gè)函數(shù)用于解析 prefiles, postfiles (這兩個(gè)變量都是空,需要通過執(zhí)行bitbake -r -R 指定才行),,解析 layer.conf, bblayer.conf, bitbake.conf, 以及 bb 文件中 inherit 的 bbclass,,以及包含base.bbclass,。

[python] view plaincopy

def parseConfigurationFiles(self, prefiles, postfiles):  

data = self.configuration.data  

bb.parse.init_parser(data)  

# Parse files for loading *before* bitbake.conf and any includes  

for f in prefiles:  

data = _parse(f, data)  

layerconf = self._findLayerConf()  

if layerconf:  

parselog.debug(2, "Found bblayers.conf (%s)", layerconf)  

data = _parse(layerconf, data)  

layers = (data.getVar('BBLAYERS', True) or "").split()  

data = bb.data.createCopy(data)  

for layer in layers:  

parselog.debug(2, "Adding layer %s", layer)  

data.setVar('LAYERDIR', layer)  

data = _parse(os.path.join(layer, "conf", "layer.conf"), data)  

data.expandVarref('LAYERDIR')  

data.delVar('LAYERDIR')  

if not data.getVar("BBPATH", True):  

raise SystemExit("The BBPATH variable is not set")  

data = _parse(os.path.join("conf", "bitbake.conf"), data)  

# Parse files for loading *after* bitbake.conf and any includes  

for p in postfiles:  

data = _parse(p, data)  

# Handle any INHERITs and inherit the base class  

bbclasses  = ["base"] + (data.getVar('INHERIT', True) or "").split()  

for bbclass in bbclasses:  

data = _inherit(bbclass, data)  

# Nomally we only register event handlers at the end of parsing .bb files  

# We register any handlers we've found so far here...  

for var in data.getVar('__BBHANDLERS') or []:  

bb.event.register(var, data.getVar(var))  

if data.getVar("BB_WORKERCONTEXT", False) is None:  

bb.fetch.fetcher_init(data)  

bb.codeparser.parser_cache_init(data)  

bb.event.fire(bb.event.ConfigParsed(), data)  

if data.getVar("BB_INVALIDCONF") is True:  

data.setVar("BB_INVALIDCONF", False)  

self.parseConfigurationFiles(self.configuration.prefile,  

self.configuration.postfile)  

else:  

bb.parse.init_parser(data)  

data.setVar('BBINCLUDED',bb.parse.get_file_depends(data))  

self.configuration.data = data  

self.configuration.data_hash = data.get_hash()  

將所有的conf, bb, bbclass, etc 文件解析完畢之后,處理一下這些數(shù)據(jù),,提取出task list ,之后就是執(zhí)行這些task 了,。

下面以linux-yocto 為例看下如何找到這些task 的先后關(guān)系:

yocto_build/tmp/work/qemuppc-poky-linux/linux-yocto/3.4.36+gitAUTOINC+80b4b5110dca5184b57e85f1e775fb006a2e85ad_ddbc382cbc45a009e9ce17f7d448fcfd050ab5fc-r4.3/temp/log.task_order

這個(gè)文件顯示了編譯 linux-yocto 執(zhí)行的task 以及 task 的執(zhí)行順序。

do_fetch (24333): log.do_fetch.24333

do_unpack (24359): log.do_unpack.24359

do_kernel_checkout (24371): log.do_kernel_checkout.24371

do_validate_branches (24399): log.do_validate_branches.24399

do_patch (24438): log.do_patch.24438

do_populate_lic (7751): log.do_populate_lic.7751

do_kernel_configme (7750): log.do_kernel_configme.7750

do_configure (18091): log.do_configure.18091

do_kernel_configcheck (18191): log.do_kernel_configcheck.18191

do_compile (23327): log.do_compile.23327

do_compile_kernelmodules (11394): log.do_compile_kernelmodules.11394

do_uboot_mkimage (11396): log.do_uboot_mkimage.11396

do_kernel_link_vmlinux (11397): log.do_kernel_link_vmlinux.11397

do_sizecheck (11395): log.do_sizecheck.11395

do_install (24128): log.do_install.24128

do_package (13631): log.do_package.13631

do_deploy (13632): log.do_deploy.13632

do_populate_sysroot (13633): log.do_populate_sysroot.13633

do_packagedata (16431): log.do_packagedata.16431

do_package_write_rpm (16452): log.do_package_write_rpm.16452

do_listtasks (7391): log.do_listtasks.7391

接下來介紹如何驗(yàn)證這些task 以及順序:

poky/meta/recipes-kernel/linux/linux-yocto_3.4.bb

require recipes-kernel/linux/linux-yocto.inc

KBRANCH_DEFAULT = "standard/base"

KBRANCH = "${KBRANCH_DEFAULT}"

SRCREV_machine_qemuarm ?= "7cc80532306889b75619f8a1b713048e25f59e19"

SRCREV_machine_qemumips  ?= "debce6677988e03b50c369aba5861d4f9b2e557d"

SRCREV_machine_qemuppc ?= "ddbc382cbc45a009e9ce17f7d448fcfd050ab5fc"

SRCREV_machine_qemux86 ?= "c994390cfa28339cbc1ec3b56eeec83a5fa75bb7"

SRCREV_machine_qemux86-64 ?= "c994390cfa28339cbc1ec3b56eeec83a5fa75bb7"

SRCREV_machine ?= "c994390cfa28339cbc1ec3b56eeec83a5fa75bb7"

SRCREV_meta ?= "80b4b5110dca5184b57e85f1e775fb006a2e85ad"

SRC_URI = "git://git./linux-yocto-3.4.git;protocol=git;bareclone=1;branch=${KBRANCH},${KMETA};name=machine,meta"

LINUX_VERSION ?= "3.4.36"

PR = "${INC_PR}.3"

PV = "${LINUX_VERSION}+git${SRCPV}"

KMETA = "meta"

COMPATIBLE_MACHINE = "qemuarm|qemux86|qemuppc|qemumips|qemux86-64"

# Functionality flags

KERNEL_FEATURES_append = " features/netfilter/netfilter.scc"

KERNEL_FEATURES_append_qemux86=" cfg/sound.scc"

KERNEL_FEATURES_append_qemux86-64=" cfg/sound.scc"

KERNEL_FEATURES_append_qemux86=" cfg/paravirt_kvm.scc"

KERNEL_FEATURES_append = " ${@bb.utils.contains("TUNE_FEATURES", "mx32", " cfg/x32.scc", "" ,d)}"

poky/meta/recipes-kernel/linux/linux-yocto.inc

DESCRIPTION = "Yocto Kernel"

SECTION = "kernel"

LICENSE = "GPLv2"

LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7"

INC_PR = "r4"

# A KMACHINE is the mapping of a yocto $MACHINE to what is built

# by the kernel. This is typically the branch that should be built,

# and it can be specific to the machine or shared

# KMACHINE = "UNDEFINED"

LINUX_KERNEL_TYPE ?= "standard"

# KMETA ?= ""

KBRANCH ?= "master"

KMACHINE ?= "${MACHINE}"

SRCREV_FORMAT ?= "meta_machine"

LINUX_VERSION_EXTENSION ?= "-yocto-${LINUX_KERNEL_TYPE}"

do_patch[depends] = "kern-tools-native:do_populate_sysroot"

addtask kernel_configme before do_configure after do_patch

# Pick up shared functions

inherit kernel

inherit kernel-yocto

require linux-dtb.inc

B = "${WORKDIR}/linux-${MACHINE}-${LINUX_KERNEL_TYPE}-build"

do_install_append(){

if [ -n "${KMETA}" ]; then

rm -rf ${STAGING_KERNEL_DIR}/${KMETA}

fi

}

# extra tasks

addtask kernel_link_vmlinux after do_compile before do_install

addtask validate_branches before do_patch after do_kernel_checkout

addtask kernel_configcheck after do_configure before do_compile

poky/meta/classes/base.bbclass

poky/meta/classes/kernel.bbclass

poky/meta/classes/kernel-yocto.bbclass

這是 linux-yocto 所有相關(guān)的bb, bbclass 文件,,所有的task 都是通過addtasks 關(guān)鍵字添加的,,它們之間先后關(guān)系構(gòu)成了所謂的依賴關(guān)系,,第一個(gè)task,,在這幾個(gè)bb, bbclass 文件里面肯定沒有 addtask before the_1st_task 這樣的語(yǔ)句,。

poky/meta/classes$ grep -nr "addtask . | grep "patch"

就按照上面這樣的方法不斷的grep 就能驗(yàn)證出log.task_order 里面顯示的task,,以及 正確的執(zhí)行順序。

ex. $ bitbake linux-yocto -c cleanall 執(zhí)行 cleanall task 需要運(yùn)行的tasklist:

poky/meta/classes$ grep -nr "addtask" . | grep "clean"

./base.bbclass:636:addtask cleansstate after do_clean

./base.bbclass:637:addtask qc_test after do_cleansstate

./base.bbclass:648:addtask cleanall after do_cleansstate

./utility-tasks.bbclass:16:addtask clean

其中,,qc_test task 是我自己加的測(cè)試 task:

addtask cleansstate after do_clean

addtask qc_test after do_cleansstate

do_qc_test() {

echo "qc hello base.bbclass !"

echo "qc   test !!!!!~~~~ "

}

這樣,,構(gòu)建起來的tasklist 如下:

clean

clean

cleansstate

cleansstate

cleanall

qc_test

如此,,可以看出,執(zhí)行 cleanall task 的話,,clean, cleansstate task 都要執(zhí)行,,因?yàn)榫哂幸蕾囮P(guān)系,相反,,qc_test 和 cleanall 雖然都是 after do_cleansstate ,,但是二者之間沒有依賴關(guān)系,。其它的task 的 runqueue list 也是這樣得到。

bitbake 如果不刻意指定要執(zhí)行的task 的話,,默認(rèn)執(zhí)行的是build 操作,而這個(gè)操作是針對(duì)一系列的bb 文件,,這些文件是在BBFILES定義的??匆幌翨BFILES 這個(gè)變量的來歷,方法如下

/poky/bitbake$ grep -nr "BBFILES" .

直接在bitbake 目錄下面搜索有誰(shuí)對(duì)BBFILES 這個(gè)變量進(jìn)行了賦值操作,,這樣就能定位到./lib/bb/cooker.py

反向推理一下:

搜集bbfiles 函數(shù):

[plain] view plaincopy

def collect_bbfiles( self ):  

"""Collect all available .bb build files"""  

parsed, cached, skipped, masked = 0, 0, 0, 0  

collectlog.debug(1, "collecting .bb files")  

files = (data.getVar( "BBFILES", self.configuration.data, True) or "").split()  

data.setVar("BBFILES", " ".join(files), self.configuration.data)  

# Sort files by priority  

files.sort( key=lambda fileitem: self.calc_bbfile_priority(fileitem) )  

[plain] view plaincopy

def matchFile(self, buildfile):  

"""  

Find the .bb file which matches the expression in 'buildfile'.  

Raise an error if multiple files  

"""  

matches = self.matchFiles(buildfile)  

[plain] view plaincopy

def buildFile(self, buildfile, task):  

"""  

Build the file matching regexp buildfile  

"""  

# Too many people use -b because they think it's how you normally  

# specify a target to be built, so show a warning  

bb.warn("Buildfile specified, dependencies will not be handled. If this is not what you want, do not use -b / --buildfile.")  

# Parse the configuration here. We need to do it explicitly here since  

# buildFile() doesn't use the cache  

self.parseConfiguration()  

# If we are told to do the None task then query the default task  

if (task == None):  

task = self.configuration.cmd  

fn, cls = bb.cache.Cache.virtualfn2realfn(buildfile)  

fn = self.matchFile(fn)  

self.buildSetVars()  

[plain] view plaincopy

def parseCommandLine(self):  

# Parse any commandline into actions  

self.commandlineAction = {'action':None, 'msg':None}  

if self.configuration.show_environment:  

if 'world' in self.configuration.pkgs_to_build:  

self.commandlineAction['msg'] = "'world' is not a valid target for --environment."  

elif 'universe' in self.configuration.pkgs_to_build:  

self.commandlineAction['msg'] = "'universe' is not a valid target for --environment."  

elif len(self.configuration.pkgs_to_build) > 1:  

self.commandlineAction['msg'] = "Only one target can be used with the --environment option."  

elif self.configuration.buildfile and len(self.configuration.pkgs_to_build) > 0:  

self.commandlineAction['msg'] = "No target should be used with the --environment and --buildfile options."  

elif len(self.configuration.pkgs_to_build) > 0:  

self.commandlineAction['action'] = ["showEnvironmentTarget", self.configuration.pkgs_to_build]  

self.configuration.data.setVar("BB_CONSOLELOG", None)  

else:  

self.commandlineAction['action'] = ["showEnvironment", self.configuration.buildfile]  

self.configuration.data.setVar("BB_CONSOLELOG", None)  

elif self.configuration.buildfile is not None:  

self.commandlineAction['action'] = ["buildFile", self.configuration.buildfile, self.configuration.cmd]  

elif self.configuration.revisions_changed:  

self.commandlineAction['action'] = ["compareRevisions"]  

elif self.configuration.show_versions:  

self.commandlineAction['action'] = ["showVersions"]  

elif self.configuration.parse_only:  

self.commandlineAction['action'] = ["parseFiles"]  

elif self.configuration.dot_graph:  

if self.configuration.pkgs_to_build:  

self.commandlineAction['action'] = ["generateDotGraph", self.configuration.pkgs_to_build, self.configuration.cmd]  

else:  

self.commandlineAction['msg'] = "Please specify a package name for dependency graph generation."  

else:  

if self.configuration.pkgs_to_build:  

self.commandlineAction['action'] = ["buildTargets", self.configuration.pkgs_to_build, self.configuration.cmd]  

else:  

#self.commandlineAction['msg'] = "Nothing to do.  Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information."  

self.commandlineAction = None  

仔細(xì)看下上面這個(gè)函數(shù),,是不是和最初在bitbake 這個(gè)python 根腳本中定義的main 函數(shù)有很多相似之處,,這樣就能猜到 bitbake -b xxx 這個(gè)指令回執(zhí)行到buildFile 這個(gè)python 函數(shù),。同樣可以知道 bitbake -e 可以看到所有的環(huán)境變量,,包括BBFILES 變量的值,因?yàn)樗鼒?zhí)行了 showEnvrioment 這個(gè)python 函數(shù),。

強(qiáng)烈建議把 bitbake -e > ~/bitbake_-e.txt  重定向到文件中好好看看,。

[plain] view plaincopy

def main():  

parser = optparse.OptionParser(  

version = "BitBake Build Tool Core version %s, %%prog version %s" % (bb.__version__, __version__),  

usage = """%prog [options] [package ...]  

Executes the specified task (default is 'build') for a given set of BitBake files.  

It expects that BBFILES is defined, which is a space separated list of files to  

be executed.  BBFILES does support wildcards.  

Default BBFILES are the .bb files in the current directory.""")  

parser.add_option("-b", "--buildfile", help = "execute the task against this .bb file, rather than a package from BBFILES. Does not handle any dependencies.",  

action = "store", dest = "buildfile", default = None)  

parser.add_option("-k", "--continue", help = "continue as much as possible after an error. While the target that failed, and those that depend on it, cannot be remade, the other dependencies of these targets can be processed all the same.",  

action = "store_false", dest = "abort", default = True)  

parser.add_option("-a", "--tryaltconfigs", help = "continue with builds by trying to use alternative providers where possible.",  

action = "store_true", dest = "tryaltconfigs", default = False)  

parser.add_option("-f", "--force", help = "force run of specified cmd, regardless of stamp status",  

action = "store_true", dest = "force", default = False)  

parser.add_option("-c", "--cmd", help = "Specify task to execute. Note that this only executes the specified task for the providee and the packages it depends on, i.e. 'compile' does not implicitly call stage for the dependencies (IOW: use only if you know what you are doing). Depending on the base.bbclass a listtasks tasks is defined and will show available tasks",  

action = "store", dest = "cmd")  

OK.

再看一下 parseCommandLine 這個(gè)函數(shù)if elif elif ,,, else 通過不斷的探測(cè)bitbake 的選項(xiàng)參數(shù),如果沒有選項(xiàng)參數(shù),,只有target 走到buildTargets 這個(gè)else 里面,,接下來要執(zhí)行的函數(shù)是buildTargets.

[plain] view plaincopy

def parseCommandLine(self):  

# Parse any commandline into actions  

self.commandlineAction = {'action':None, 'msg':None}  

if self.configuration.show_environment:  

if 'world' in self.configuration.pkgs_to_build:  

self.commandlineAction['msg'] = "'world' is not a valid target for --environment."  

elif 'universe' in self.configuration.pkgs_to_build:  

self.commandlineAction['msg'] = "'universe' is not a valid target for --environment."  

elif len(self.configuration.pkgs_to_build) > 1:  

self.commandlineAction['msg'] = "Only one target can be used with the --environment option."  

elif self.configuration.buildfile and len(self.configuration.pkgs_to_build) > 0:  

self.commandlineAction['msg'] = "No target should be used with the --environment and --buildfile options."  

elif len(self.configuration.pkgs_to_build) > 0:  

self.commandlineAction['action'] = ["showEnvironmentTarget", self.configuration.pkgs_to_build]  

self.configuration.data.setVar("BB_CONSOLELOG", None)  

else:  

self.commandlineAction['action'] = ["showEnvironment", self.configuration.buildfile]  

self.configuration.data.setVar("BB_CONSOLELOG", None)  

elif self.configuration.buildfile is not None:  

self.commandlineAction['action'] = ["buildFile", self.configuration.buildfile, self.configuration.cmd]  

elif self.configuration.revisions_changed:  

self.commandlineAction['action'] = ["compareRevisions"]  

elif self.configuration.show_versions:  

self.commandlineAction['action'] = ["showVersions"]  

elif self.configuration.parse_only:  

self.commandlineAction['action'] = ["parseFiles"]  

elif self.configuration.dot_graph:  

if self.configuration.pkgs_to_build:  

self.commandlineAction['action'] = ["generateDotGraph", self.configuration.pkgs_to_build, self.configuration.cmd]  

else:  

self.commandlineAction['msg'] = "Please specify a package name for dependency graph generation."  

else:  

if self.configuration.pkgs_to_build:  

self.commandlineAction['action'] = ["buildTargets", self.configuration.pkgs_to_build, self.configuration.cmd]  

else:  

#self.commandlineAction['msg'] = "Nothing to do.  Use 'bitbake world' to build everything, or run 'bitbake --help' for usage information."  

self.commandlineAction = None  

看一個(gè)特定的package 編譯流程,拿kernel 看吧:

從bitbake_-e.txt 環(huán)境中搜到:

PREFERRED_PROVIDER_virtual/kernel="linux-yocto"

PREFERRED_VERSION_linux-yocto="3.4%"

這樣就可以在poky 目錄下面搜索 名字為 linux-yocto*.bb* 的 bb和bbappend, 搜出來以后再取 3.4版本的那些bb 和 bbappend,。

/poky$ find -name "linux-yocto*.bb*"

./meta/recipes-kernel/linux/linux-yocto_3.8.bb

./meta/recipes-kernel/linux/linux-yocto-dev.bb

./meta/recipes-kernel/linux/linux-yocto-rt_3.4.bb

./meta/recipes-kernel/linux/linux-yocto-rt_3.8.bb

./meta/recipes-kernel/linux/linux-yocto-rt_3.2.bb

./meta/recipes-kernel/linux/linux-yocto-tiny_3.2.bb

./meta/recipes-kernel/linux/linux-yocto_3.4.bb

./meta/recipes-kernel/linux/linux-yocto_3.2.bb

./meta/recipes-kernel/linux/linux-yocto-tiny_3.4.bb

./meta/recipes-kernel/linux/linux-yocto-tiny_3.8.bb

./meta-yocto-bsp/recipes-kernel/linux/linux-yocto_3.8.bbappend

./meta-yocto-bsp/recipes-kernel/linux/linux-yocto_3.2.bbappend

./meta-yocto-bsp/recipes-kernel/linux/linux-yocto_3.4.bbappend

./meta-skeleton/recipes-kernel/linux/linux-yocto-custom.bb

查看./meta/recipes-kernel/linux/linux-yocto_3.4.bb

[plain] view plaincopy

require recipes-kernel/linux/linux-yocto.inc  

KBRANCH_DEFAULT = "standard/base"  

KBRANCH = "${KBRANCH_DEFAULT}"  

SRCREV_machine_qemuarm ?= "7cc80532306889b75619f8a1b713048e25f59e19"  

SRCREV_machine_qemumips  ?= "debce6677988e03b50c369aba5861d4f9b2e557d"  

SRCREV_machine_qemuppc ?= "ddbc382cbc45a009e9ce17f7d448fcfd050ab5fc"  

SRCREV_machine_qemux86 ?= "c994390cfa28339cbc1ec3b56eeec83a5fa75bb7"  

SRCREV_machine_qemux86-64 ?= "c994390cfa28339cbc1ec3b56eeec83a5fa75bb7"  

SRCREV_machine ?= "c994390cfa28339cbc1ec3b56eeec83a5fa75bb7"  

SRCREV_meta ?= "80b4b5110dca5184b57e85f1e775fb006a2e85ad"  

SRC_URI = "git://git./linux-yocto-3.4.git;protocol=git;bareclone=1;branch=${KBRANCH},${KMETA};name=machine,meta"  

LINUX_VERSION ?= "3.4.36"  

PR = "${INC_PR}.3"  

PV = "${LINUX_VERSION}+git${SRCPV}"  

KMETA = "meta"  

COMPATIBLE_MACHINE = "qemuarm|qemux86|qemuppc|qemumips|qemux86-64"  

# Functionality flags  

KERNEL_FEATURES_append = " features/netfilter/netfilter.scc"  

KERNEL_FEATURES_append_qemux86=" cfg/sound.scc"  

KERNEL_FEATURES_append_qemux86-64=" cfg/sound.scc"  

KERNEL_FEATURES_append_qemux86=" cfg/paravirt_kvm.scc"  

KERNEL_FEATURES_append = " ${@bb.utils.contains("TUNE_FEATURES", "mx32", " cfg/x32.scc", "" ,d)}"  

先查看下 linux-yocto_3.4.bb require 的 recipes-kernel/linux/linux-yocto.inc

[plain] view plaincopy

DESCRIPTION = "Yocto Kernel"  

SECTION = "kernel"  

LICENSE = "GPLv2"  

LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7"  

INC_PR = "r4"  

# A KMACHINE is the mapping of a yocto $MACHINE to what is built  

# by the kernel. This is typically the branch that should be built,  

# and it can be specific to the machine or shared  

# KMACHINE = "UNDEFINED"  

LINUX_KERNEL_TYPE ?= "standard"  

# KMETA ?= ""  

KBRANCH ?= "master"  

KMACHINE ?= "${MACHINE}"  

SRCREV_FORMAT ?= "meta_machine"  

LINUX_VERSION_EXTENSION ?= "-yocto-${LINUX_KERNEL_TYPE}"  

do_patch[depends] = "kern-tools-native:do_populate_sysroot"  

addtask kernel_configme before do_configure after do_patch  

# Pick up shared functions  

inherit kernel  

inherit kernel-yocto  

require linux-dtb.inc  

B = "${WORKDIR}/linux-${MACHINE}-${LINUX_KERNEL_TYPE}-build"  

do_install_append(){  

if [ -n "${KMETA}" ]; then  

rm -rf ${STAGING_KERNEL_DIR}/${KMETA}  

fi  

}  

# extra tasks  

addtask kernel_link_vmlinux after do_compile before do_install  

addtask validate_branches before do_patch after do_kernel_checkout  

addtask kernel_configcheck after do_configure before do_compile  這里inherit kernel, inherit kernel-yocto, 在meta/class 里面可以看到 kernel.class ,kernel-yocto.class 文件,里面有kernel 公共的base 函數(shù),。

http://blog./uid-7652108-id-2047290.html

bitbake parse 的機(jī)理分析:

Bitbake 這個(gè) task execute tool的第一步就是parsing,,也就是對(duì)BBFILES所定義的變量的內(nèi)容,也就是bbfiles 進(jìn)行讀取data,,然后分析,,相關(guān)數(shù)據(jù)進(jìn)行緩存(cache)

出發(fā)是從 conf/bitbake.conf 這個(gè)文件開始,這個(gè)文件本身的內(nèi)容處理是一部分,,另外一部分是這個(gè)文件會(huì)include一些其它的conf文件,,比如很重要的 conf/local.conf,分析處理的數(shù)據(jù)都會(huì)寫到 CACHEDATA的文件中(bb_cache.dat) ,,當(dāng)然前提是你開啟了cache機(jī)制

處理完conf文件后,,就是bbclass文件,,這個(gè)時(shí)候是從 class/base.bbclass開始,,然后分析其inherit的一些class。

這兩部分?jǐn)?shù)據(jù)很重要,,后來所有的bbfile 都依賴于這些conf 文件和class文件,,當(dāng)然這些文件中的變量也會(huì)實(shí)施到所有的bb file上,所以只要這些conf文件和class文件有改變,,那么bitbake 就會(huì)重新parse

那么,,到現(xiàn)在,,就開始進(jìn)入parsing bb file了,當(dāng)然第一次肯定要parse所有的bbfile了,,這部分是最耗時(shí)的,,第一次完了之后,,那么就可以利用cache機(jī)制來判斷是否重新parse了

上面就是bitbake version 1版本parsing的機(jī)制,,理解了code背后的故事,才能讓我們更游刃有余地工作

膜拜這個(gè)大神,,早在07年就把 bitbake 一個(gè)package 的流程分析的這么透徹了:

http://blog./uid-7652108-id-2047247.html

在 linux-yocto.inc 文件中 inherit kernel-yocto,, 來看下 class/kernel-yocto.bbclass , 分析一下do_kernel_configme 這個(gè)函數(shù)。添加log語(yǔ)句打印一下這個(gè)函數(shù)中的一些變量,。 ${S} 表示linux source code 的目錄,, ${B} 表示linux build 目錄。

在 linux_source_code_path/meta/scripts/configme 執(zhí)行這個(gè)shell 腳本,。

[python] view plaincopy

do_kernel_configme[dirs] = "${S} ${B}"  

do_kernel_configme() {  

echo "[INFO] doing kernel configme"  

export KMETA=${KMETA}  

if [ -n ${KCONFIG_MODE} ]; then  

configmeflags=${KCONFIG_MODE}  

else  

# If a defconfig was passed, use =n as the baseline, which is achieved  

# via --allnoconfig  

if [ -f ${WORKDIR}/defconfig ]; then  

configmeflags="--allnoconfig"  

fi  

fi  

cd ${S}  

PATH=${PATH}:${S}/scripts/util  

configme ${configmeflags} --reconfig --output ${B} ${LINUX_KERNEL_TYPE} ${KMACHINE}  

if [ $? -ne 0 ]; then  

echo "ERROR. Could not configure ${KMACHINE}-${LINUX_KERNEL_TYPE}"  

exit 1  

fi  

#qc added log  

echo "qc variables value: ${S} ${B} ${KMETA} ${KCONFIG_MODE} ${WORKDIR} ${LINUX_KERNEL_TYPE} ${KMACHINE}."  

echo "# Global settings from linux recipe" >> ${B}/.config  

echo "CONFIG_LOCALVERSION="\"${LINUX_VERSION_EXTENSION}\" >> ${B}/.config  

}  

configme 這個(gè) shell 腳本完成 生成.config 文件的工作:

[plain] view plaincopy

# This is factored out into a function because for a given branch,  

# there may be more than one user (i.e. big endian, little endian,  

# or BSPs that use the same branch but differ only in kernel configs)  

run_board_config()  

{  

# Can't set these until we've unwound the checkpoint and have meta data.  

KVER=`cat ./$META_DIR/cfg/kernel-*cache/kver|sed 's/^v//'`  

# Look for standard defines, with compatibility fallbacks  

KARCH=`grep KARCH $SCC | awk '{print $3}'`  

KPROFILE=`grep KMACHINE $SCC | awk '{print $3}'`  

KTYPE=`grep KTYPE $SCC | awk '{print $3}'`  

META=./$META_DIR/meta-series  

META_ALT=./$META_DIR/cfg/scratch/`basename $SCC .scc`-meta  

BUILD_DIR=$out_dir  

CFGFILE=$machine-$target-config-$KVER  

kgit-meta -v -k $META  

if [ $? != 0 ]; then  

echo Error running the meta series for collecting config data  

return 1  

fi  

KTGT=`get_branch_name $META`  

mkdir -p ./$META_DIR/cfg/$KTGT  

if [ $? != 0 ]; then  

echo Failed to mkdir ./$META_DIR/cfg/$KTGT for config data  

return 1  

fi  

frags=`cat $META_DIR/cfg/$KTGT/config_frag.txt | sed 's%.?$%'$META_DIR/cfg'\1%'`  

pre_config -l $META_DIR/cfg/$KTGT/ $frags > $META_DIR/cfg/$KTGT/config.log 2>&1  

# remove any old assembled debug fragments  

rm -f $BUILD_DIR/.tmp.config*  

merge_frags=`cat $META_DIR/cfg/$KTGT/config_frag.txt | sed 's%.?$%'$META_DIR/cfg'\1.sanitized%'`  

ARCH=$KARCH O=$BUILD_DIR merge_config.sh $allnoconfig -d $merge_frags  \  

> $META_DIR/cfg/$KTGT/merge_log.txt 2>&1  

mv $BUILD_DIR/.tmp.config* $META_DIR/cfg/$KTGT/$CFGFILE  

if [ $? != 0 ]; then  

echo creation of pre-processed config data failed  

return 1  

fi  

# break the merge log down into parts that can be processed later  

grep -A2 "^Value of" $META_DIR/cfg/$KTGT/merge_log.txt > $META_DIR/cfg/$KTGT/redefinition.txt  

grep -A2 "^Value requested" $META_DIR/cfg/$KTGT/merge_log.txt > $META_DIR/cfg/$KTGT/mismatch.txt  

echo "[INFO] Pre-processed cfg file $CFGFILE created."  

拼接一系列的meta 目錄下的config_frag 文件,最終通過 merge_config.sh 生成 .config 文件。

/yocto_build/tmp/work/qemuppc-poky-linux/linux-yocto/3.4.36+gitAUTOINC+80b4b5110dca5184b57e85f1e775fb006a2e85ad_ddbc382cbc45a009e9ce17f7d448fcfd050ab5fc-r4.3/linux/meta/cfg/standard/qemuppc/config_frag.txt

這個(gè)就是要處理的所有 config 的片段,。

可以參考 config.log 和 merge_log.txt

/yocto_build/tmp/work/qemuppc-poky-linux/linux-yocto/3.4.36+gitAUTOINC+80b4b5110dca5184b57e85f1e775fb006a2e85ad_ddbc382cbc45a009e9ce17f7d448fcfd050ab5fc-r4.3/linux/meta/cfg/standard/qemuppc/config.log

/yocto_build/tmp/work/qemuppc-poky-linux/linux-yocto/3.4.36+gitAUTOINC+80b4b5110dca5184b57e85f1e775fb006a2e85ad_ddbc382cbc45a009e9ce17f7d448fcfd050ab5fc-r4.3/linux/meta/cfg/standard/qemuppc/merge_log.txt

至此,,就知道 yocto 編譯 linux kernel 的 .config 是從哪來的了!??!

了解更多關(guān)于 yocto kernel config 可以 git clone git://git./yocto-kernel-cache,查看 00-README 文檔,。

http://blog.csdn.net/fmddlmyy/article/details/325403

在 bitbake 中加入 print log語(yǔ)句,,方便調(diào)試:

[python] view plaincopy

parser.add_option("-B", "--bind", help = "The name/address for the bitbake server to bind to",  

action = "store", dest = "bind", default = False)  

parser.add_option("", "--no-setscene", help = "Do not run any setscene tasks, forces builds",  

action = "store_true", dest = "nosetscene", default = False)  

options, args = parser.parse_args(sys.argv)  

#qc test code  

print "qc test code: options:", options  

print "qc test code: args", args  

configuration = BBConfiguration(options)  

configuration.pkgs_to_build.extend(args[1:])  

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多