From f5665d5bfcfb13d01da9e4c7d5046453e80f7baf Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Mon, 8 Jan 2007 23:53:01 +0000 Subject: bitbake: Sync with upstream. * File licence headers were sanitised causing most of the diff. * cooker.py was created from bin/bitbake. * cvs fetcher port option was added * The -f force option was fixed to work correctly * Multiple entries in rrecrdeps are now handled correctly (allows adding do_deploy to image depends) git-svn-id: https://svn.o-hand.com/repos/poky/trunk@1129 311d38ba-8fff-0310-9ca6-ca027cbcb966 --- bitbake/bin/bbimage | 24 +- bitbake/bin/bitbake | 679 ++-------------------------------------------------- bitbake/bin/bitdoc | 28 +-- 3 files changed, 41 insertions(+), 690 deletions(-) (limited to 'bitbake/bin') diff --git a/bitbake/bin/bbimage b/bitbake/bin/bbimage index 9adedbfc63..fdc417617b 100755 --- a/bitbake/bin/bbimage +++ b/bitbake/bin/bbimage @@ -4,18 +4,18 @@ # # Copyright (C) 2003 Chris Larson # -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 59 Temple -# Place, Suite 330, Boston, MA 02111-1307 USA. +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import sys, os sys.path.insert(0,os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib')) diff --git a/bitbake/bin/bitbake b/bitbake/bin/bitbake index 33e8933c90..001f229331 100755 --- a/bitbake/bin/bitbake +++ b/bitbake/bin/bitbake @@ -9,54 +9,26 @@ # Copyright (C) 2005 ROAD GmbH # Copyright (C) 2006 Richard Purdie # -# This program is free software; you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. # -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 59 Temple -# Place, Suite 330, Boston, MA 02111-1307 USA. +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -import sys, os, getopt, glob, copy, os.path, re, time +import sys, os, getopt, re, time, optparse sys.path.insert(0,os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib')) import bb -from bb import utils, data, parse, event, cache, providers, taskdata, runqueue -from sets import Set -import itertools, optparse - -parsespin = itertools.cycle( r'|/-\\' ) +from bb import cooker __version__ = "1.7.4" -#============================================================================# -# BBStatistics -#============================================================================# -class BBStatistics: - """ - Manage build statistics for one run - """ - def __init__(self ): - self.attempt = 0 - self.success = 0 - self.fail = 0 - self.deps = 0 - - def show( self ): - print "Build statistics:" - print " Attempted builds: %d" % self.attempt - if self.fail: - print " Failed builds: %d" % self.fail - if self.deps: - print " Dependencies not satisfied: %d" % self.deps - if self.fail or self.deps: return 1 - else: return 0 - - #============================================================================# # BBOptions #============================================================================# @@ -68,622 +40,6 @@ class BBConfiguration( object ): for key, val in options.__dict__.items(): setattr( self, key, val ) -#============================================================================# -# BBCooker -#============================================================================# -class BBCooker: - """ - Manages one bitbake build run - """ - - Statistics = BBStatistics # make it visible from the shell - - def __init__( self ): - self.build_cache_fail = [] - self.build_cache = [] - self.stats = BBStatistics() - self.status = None - - self.cache = None - self.bb_cache = None - - def tryBuildPackage(self, fn, item, task, the_data, build_depends): - """ - Build one task of a package, optionally build following task depends - """ - bb.event.fire(bb.event.PkgStarted(item, the_data)) - try: - self.stats.attempt += 1 - if self.configuration.force: - bb.data.setVarFlag('do_%s' % task, 'force', 1, the_data) - if not build_depends: - bb.data.setVarFlag('do_%s' % task, 'dontrundeps', 1, the_data) - if not self.configuration.dry_run: - bb.build.exec_task('do_%s' % task, the_data) - bb.event.fire(bb.event.PkgSucceeded(item, the_data)) - self.build_cache.append(fn) - return True - except bb.build.FuncFailed: - self.stats.fail += 1 - bb.msg.error(bb.msg.domain.Build, "task stack execution failed") - bb.event.fire(bb.event.PkgFailed(item, the_data)) - self.build_cache_fail.append(fn) - raise - except bb.build.EventException, e: - self.stats.fail += 1 - event = e.args[1] - bb.msg.error(bb.msg.domain.Build, "%s event exception, aborting" % bb.event.getName(event)) - bb.event.fire(bb.event.PkgFailed(item, the_data)) - self.build_cache_fail.append(fn) - raise - - def tryBuild( self, fn, build_depends): - """ - Build a provider and its dependencies. - build_depends is a list of previous build dependencies (not runtime) - If build_depends is empty, we're dealing with a runtime depends - """ - - the_data = self.bb_cache.loadDataFull(fn, self.configuration.data) - - item = self.status.pkg_fn[fn] - - if bb.build.stamp_is_current('do_%s' % self.configuration.cmd, the_data) and not self.configuration.force: - self.build_cache.append(fn) - return True - - return self.tryBuildPackage(fn, item, self.configuration.cmd, the_data, build_depends) - - def showVersions( self ): - pkg_pn = self.status.pkg_pn - preferred_versions = {} - latest_versions = {} - - # Sort by priority - for pn in pkg_pn.keys(): - (last_ver,last_file,pref_ver,pref_file) = bb.providers.findBestProvider(pn, self.configuration.data, self.status) - preferred_versions[pn] = (pref_ver, pref_file) - latest_versions[pn] = (last_ver, last_file) - - pkg_list = pkg_pn.keys() - pkg_list.sort() - - for p in pkg_list: - pref = preferred_versions[p] - latest = latest_versions[p] - - if pref != latest: - prefstr = pref[0][0] + "-" + pref[0][1] - else: - prefstr = "" - - print "%-30s %20s %20s" % (p, latest[0][0] + "-" + latest[0][1], - prefstr) - - - def showEnvironment( self ): - """Show the outer or per-package environment""" - if self.configuration.buildfile: - self.cb = None - self.bb_cache = bb.cache.init(self) - try: - self.configuration.data = self.bb_cache.loadDataFull(self.configuration.buildfile, self.configuration.data) - except IOError, e: - bb.msg.fatal(bb.msg.domain.Parsing, "Unable to read %s: %s" % ( self.configuration.buildfile, e )) - except Exception, e: - bb.msg.fatal(bb.msg.domain.Parsing, "%s" % e) - # emit variables and shell functions - try: - data.update_data( self.configuration.data ) - data.emit_env(sys.__stdout__, self.configuration.data, True) - except Exception, e: - bb.msg.fatal(bb.msg.domain.Parsing, "%s" % e) - # emit the metadata which isnt valid shell - data.expandKeys( self.configuration.data ) - for e in self.configuration.data.keys(): - if data.getVarFlag( e, 'python', self.configuration.data ): - sys.__stdout__.write("\npython %s () {\n%s}\n" % (e, data.getVar(e, self.configuration.data, 1))) - - def generateDotGraph( self, pkgs_to_build, ignore_deps ): - """ - Generate a task dependency graph. - - pkgs_to_build A list of packages that needs to be built - ignore_deps A list of names where processing of dependencies - should be stopped. e.g. dependencies that get - """ - - for dep in ignore_deps: - self.status.ignored_dependencies.add(dep) - - localdata = data.createCopy(self.configuration.data) - bb.data.update_data(localdata) - bb.data.expandKeys(localdata) - taskdata = bb.taskdata.TaskData(self.configuration.abort) - - runlist = [] - try: - for k in pkgs_to_build: - taskdata.add_provider(localdata, self.status, k) - runlist.append([k, "do_%s" % self.configuration.cmd]) - taskdata.add_unresolved(localdata, self.status) - except bb.providers.NoProvider: - sys.exit(1) - rq = bb.runqueue.RunQueue() - rq.prepare_runqueue(self.configuration.data, self.status, taskdata, runlist) - - seen_fnids = [] - depends_file = file('depends.dot', 'w' ) - tdepends_file = file('task-depends.dot', 'w' ) - print >> depends_file, "digraph depends {" - print >> tdepends_file, "digraph depends {" - rq.prio_map.reverse() - for task1 in range(len(rq.runq_fnid)): - task = rq.prio_map[task1] - taskname = rq.runq_task[task] - fnid = rq.runq_fnid[task] - fn = taskdata.fn_index[fnid] - pn = self.status.pkg_fn[fn] - version = self.bb_cache.getVar('PV', fn, True ) + '-' + self.bb_cache.getVar('PR', fn, True) - print >> tdepends_file, '"%s.%s" [label="%s %s\\n%s\\n%s"]' % (pn, taskname, pn, taskname, version, fn) - for dep in rq.runq_depends[task]: - depfn = taskdata.fn_index[rq.runq_fnid[dep]] - deppn = self.status.pkg_fn[depfn] - print >> tdepends_file, '"%s.%s" -> "%s.%s"' % (pn, rq.runq_task[task], deppn, rq.runq_task[dep]) - if fnid not in seen_fnids: - seen_fnids.append(fnid) - packages = [] - print >> depends_file, '"%s" [label="%s %s\\n%s"]' % (pn, pn, version, fn) - for depend in self.status.deps[fn]: - print >> depends_file, '"%s" -> "%s"' % (pn, depend) - rdepends = self.status.rundeps[fn] - for package in rdepends: - for rdepend in rdepends[package]: - print >> depends_file, '"%s" -> "%s" [style=dashed]' % (package, rdepend) - packages.append(package) - rrecs = self.status.runrecs[fn] - for package in rrecs: - for rdepend in rrecs[package]: - print >> depends_file, '"%s" -> "%s" [style=dashed]' % (package, rdepend) - if not package in packages: - packages.append(package) - for package in packages: - if package != pn: - print >> depends_file, '"%s" [label="%s(%s) %s\\n%s"]' % (package, package, pn, version, fn) - for depend in self.status.deps[fn]: - print >> depends_file, '"%s" -> "%s"' % (package, depend) - # Prints a flattened form of the above where subpackages of a package are merged into the main pn - #print >> depends_file, '"%s" [label="%s %s\\n%s\\n%s"]' % (pn, pn, taskname, version, fn) - #for rdep in taskdata.rdepids[fnid]: - # print >> depends_file, '"%s" -> "%s" [style=dashed]' % (pn, taskdata.run_names_index[rdep]) - #for dep in taskdata.depids[fnid]: - # print >> depends_file, '"%s" -> "%s"' % (pn, taskdata.build_names_index[dep]) - print >> depends_file, "}" - print >> tdepends_file, "}" - bb.msg.note(1, bb.msg.domain.Collection, "Dependencies saved to 'depends.dot'") - bb.msg.note(1, bb.msg.domain.Collection, "Task dependencies saved to 'task-depends.dot'") - - def buildDepgraph( self ): - all_depends = self.status.all_depends - pn_provides = self.status.pn_provides - - localdata = data.createCopy(self.configuration.data) - bb.data.update_data(localdata) - bb.data.expandKeys(localdata) - - def calc_bbfile_priority(filename): - for (regex, pri) in self.status.bbfile_config_priorities: - if regex.match(filename): - return pri - return 0 - - # Handle PREFERRED_PROVIDERS - for p in (bb.data.getVar('PREFERRED_PROVIDERS', localdata, 1) or "").split(): - (providee, provider) = p.split(':') - if providee in self.status.preferred and self.status.preferred[providee] != provider: - bb.msg.error(bb.msg.domain.Provider, "conflicting preferences for %s: both %s and %s specified" % (providee, provider, self.status.preferred[providee])) - self.status.preferred[providee] = provider - - # Calculate priorities for each file - for p in self.status.pkg_fn.keys(): - self.status.bbfile_priority[p] = calc_bbfile_priority(p) - - def buildWorldTargetList(self): - """ - Build package list for "bitbake world" - """ - all_depends = self.status.all_depends - pn_provides = self.status.pn_provides - bb.msg.debug(1, bb.msg.domain.Parsing, "collating packages for \"world\"") - for f in self.status.possible_world: - terminal = True - pn = self.status.pkg_fn[f] - - for p in pn_provides[pn]: - if p.startswith('virtual/'): - bb.msg.debug(2, bb.msg.domain.Parsing, "World build skipping %s due to %s provider starting with virtual/" % (f, p)) - terminal = False - break - for pf in self.status.providers[p]: - if self.status.pkg_fn[pf] != pn: - bb.msg.debug(2, bb.msg.domain.Parsing, "World build skipping %s due to both us and %s providing %s" % (f, pf, p)) - terminal = False - break - if terminal: - self.status.world_target.add(pn) - - # drop reference count now - self.status.possible_world = None - self.status.all_depends = None - - def myProgressCallback( self, x, y, f, from_cache ): - """Update any tty with the progress change""" - if os.isatty(sys.stdout.fileno()): - sys.stdout.write("\rNOTE: Handling BitBake files: %s (%04d/%04d) [%2d %%]" % ( parsespin.next(), x, y, x*100/y ) ) - sys.stdout.flush() - else: - if x == 1: - sys.stdout.write("Parsing .bb files, please wait...") - sys.stdout.flush() - if x == y: - sys.stdout.write("done.") - sys.stdout.flush() - - def interactiveMode( self ): - """Drop off into a shell""" - try: - from bb import shell - except ImportError, details: - bb.msg.fatal(bb.msg.domain.Parsing, "Sorry, shell not available (%s)" % details ) - else: - bb.data.update_data( self.configuration.data ) - bb.data.expandKeys( self.configuration.data ) - shell.start( self ) - sys.exit( 0 ) - - def parseConfigurationFile( self, afile ): - try: - self.configuration.data = bb.parse.handle( afile, self.configuration.data ) - - # Add the handlers we inherited by INHERIT - # we need to do this manually as it is not guranteed - # we will pick up these classes... as we only INHERIT - # on .inc and .bb files but not on .conf - data = bb.data.createCopy( self.configuration.data ) - inherits = ["base"] + (bb.data.getVar('INHERIT', data, True ) or "").split() - for inherit in inherits: - data = bb.parse.handle( os.path.join('classes', '%s.bbclass' % inherit ), data, True ) - - # FIXME: This assumes that we included at least one .inc file - for var in bb.data.keys(data): - if bb.data.getVarFlag(var, 'handler', data): - bb.event.register(var,bb.data.getVar(var, data)) - - except IOError: - bb.msg.fatal(bb.msg.domain.Parsing, "Unable to open %s" % afile ) - except bb.parse.ParseError, details: - bb.msg.fatal(bb.msg.domain.Parsing, "Unable to parse %s (%s)" % (afile, details) ) - - def handleCollections( self, collections ): - """Handle collections""" - if collections: - collection_list = collections.split() - for c in collection_list: - regex = bb.data.getVar("BBFILE_PATTERN_%s" % c, self.configuration.data, 1) - if regex == None: - bb.msg.error(bb.msg.domain.Parsing, "BBFILE_PATTERN_%s not defined" % c) - continue - priority = bb.data.getVar("BBFILE_PRIORITY_%s" % c, self.configuration.data, 1) - if priority == None: - bb.msg.error(bb.msg.domain.Parsing, "BBFILE_PRIORITY_%s not defined" % c) - continue - try: - cre = re.compile(regex) - except re.error: - bb.msg.error(bb.msg.domain.Parsing, "BBFILE_PATTERN_%s \"%s\" is not a valid regular expression" % (c, regex)) - continue - try: - pri = int(priority) - self.status.bbfile_config_priorities.append((cre, pri)) - except ValueError: - bb.msg.error(bb.msg.domain.Parsing, "invalid value for BBFILE_PRIORITY_%s: \"%s\"" % (c, priority)) - - - def cook( self, configuration, args ): - """ - We are building stuff here. We do the building - from here. By default we try to execute task - build. - """ - - self.configuration = configuration - - if self.configuration.verbose: - bb.msg.set_verbose(True) - - if self.configuration.debug: - bb.msg.set_debug_level(self.configuration.debug) - else: - bb.msg.set_debug_level(0) - - if self.configuration.debug_domains: - bb.msg.set_debug_domains(self.configuration.debug_domains) - - self.configuration.data = bb.data.init() - - for f in self.configuration.file: - self.parseConfigurationFile( f ) - - self.parseConfigurationFile( os.path.join( "conf", "bitbake.conf" ) ) - - if not self.configuration.cmd: - self.configuration.cmd = bb.data.getVar("BB_DEFAULT_TASK", self.configuration.data) - - # For backwards compatibility - REMOVE ME - if not self.configuration.cmd: - self.configuration.cmd = "build" - - # - # Special updated configuration we use for firing events - # - self.configuration.event_data = bb.data.createCopy(self.configuration.data) - bb.data.update_data(self.configuration.event_data) - - if self.configuration.show_environment: - self.showEnvironment() - sys.exit( 0 ) - - # inject custom variables - 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) - bb.data.setVar("BUILDSTART", time.strftime('%m/%d/%Y %H:%M:%S',time.gmtime()),self.configuration.data) - - buildname = bb.data.getVar("BUILDNAME", self.configuration.data) - - if self.configuration.interactive: - self.interactiveMode() - - if self.configuration.buildfile is not None: - bf = os.path.abspath( self.configuration.buildfile ) - try: - os.stat(bf) - except OSError: - (filelist, masked) = self.collect_bbfiles() - regexp = re.compile(self.configuration.buildfile) - matches = [] - for f in filelist: - if regexp.search(f) and os.path.isfile(f): - bf = f - matches.append(f) - if len(matches) != 1: - bb.msg.error(bb.msg.domain.Parsing, "Unable to match %s (%s matches found):" % (self.configuration.buildfile, len(matches))) - for f in matches: - bb.msg.error(bb.msg.domain.Parsing, " %s" % f) - sys.exit(1) - bf = matches[0] - - bbfile_data = bb.parse.handle(bf, self.configuration.data) - - item = bb.data.getVar('PN', bbfile_data, 1) - try: - self.tryBuildPackage(bf, item, self.configuration.cmd, bbfile_data, True) - except bb.build.EventException: - bb.msg.error(bb.msg.domain.Build, "Build of '%s' failed" % item ) - - sys.exit( self.stats.show() ) - - # initialise the parsing status now we know we will need deps - self.status = bb.cache.CacheData() - - ignore = bb.data.getVar("ASSUME_PROVIDED", self.configuration.data, 1) or "" - self.status.ignored_dependencies = Set( ignore.split() ) - - self.handleCollections( bb.data.getVar("BBFILE_COLLECTIONS", self.configuration.data, 1) ) - - 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) - - # Import Psyco if available and not disabled - if not self.configuration.disable_psyco: - try: - import psyco - except ImportError: - bb.msg.note(1, bb.msg.domain.Collection, "Psyco JIT Compiler (http://psyco.sf.net) not available. Install it to increase performance.") - else: - psyco.bind( self.parse_bbfiles ) - else: - bb.msg.note(1, bb.msg.domain.Collection, "You have disabled Psyco. This decreases performance.") - - try: - bb.msg.debug(1, bb.msg.domain.Collection, "collecting .bb files") - (filelist, masked) = self.collect_bbfiles() - self.parse_bbfiles(filelist, masked, self.myProgressCallback) - bb.msg.debug(1, bb.msg.domain.Collection, "parsing complete") - print - if self.configuration.parse_only: - bb.msg.note(1, bb.msg.domain.Collection, "Requested parsing .bb files only. Exiting.") - return - - - self.buildDepgraph() - - if self.configuration.show_versions: - self.showVersions() - sys.exit( 0 ) - 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) - - if self.configuration.dot_graph: - self.generateDotGraph( pkgs_to_build, self.configuration.ignored_dot_deps ) - sys.exit( 0 ) - - bb.event.fire(bb.event.BuildStarted(buildname, pkgs_to_build, self.configuration.event_data)) - - localdata = data.createCopy(self.configuration.data) - bb.data.update_data(localdata) - bb.data.expandKeys(localdata) - - taskdata = bb.taskdata.TaskData(self.configuration.abort) - - runlist = [] - try: - for k in pkgs_to_build: - taskdata.add_provider(localdata, self.status, k) - runlist.append([k, "do_%s" % self.configuration.cmd]) - taskdata.add_unresolved(localdata, self.status) - except bb.providers.NoProvider: - sys.exit(1) - - rq = bb.runqueue.RunQueue() - rq.prepare_runqueue(self.configuration.data, self.status, taskdata, runlist) - try: - failures = rq.execute_runqueue(self, self.configuration.data, self.status, taskdata, runlist) - except runqueue.TaskFailure, fnids: - for fnid in fnids: - bb.msg.error(bb.msg.domain.Build, "'%s' failed" % taskdata.fn_index[fnid]) - sys.exit(1) - bb.event.fire(bb.event.BuildCompleted(buildname, pkgs_to_build, self.configuration.event_data, failures)) - - sys.exit( self.stats.show() ) - - except KeyboardInterrupt: - bb.msg.note(1, bb.msg.domain.Collection, "KeyboardInterrupt - Build not completed.") - sys.exit(1) - - def get_bbfiles( self, path = os.getcwd() ): - """Get list of default .bb files by reading out the current directory""" - contents = os.listdir(path) - bbfiles = [] - for f in contents: - (root, ext) = os.path.splitext(f) - if ext == ".bb": - bbfiles.append(os.path.abspath(os.path.join(os.getcwd(),f))) - return bbfiles - - def find_bbfiles( self, path ): - """Find all the .bb files in a directory (uses find)""" - findcmd = 'find ' + path + ' -name *.bb | grep -v SCCS/' - try: - finddata = os.popen(findcmd) - except OSError: - return [] - return finddata.readlines() - - def collect_bbfiles( self ): - """Collect all available .bb build files""" - parsed, cached, skipped, masked = 0, 0, 0, 0 - self.bb_cache = bb.cache.init(self) - - files = (data.getVar( "BBFILES", self.configuration.data, 1 ) or "").split() - data.setVar("BBFILES", " ".join(files), self.configuration.data) - - if not len(files): - files = self.get_bbfiles() - - if not len(files): - bb.msg.error(bb.msg.domain.Collection, "no files to build.") - - newfiles = [] - for f in files: - if os.path.isdir(f): - dirfiles = self.find_bbfiles(f) - if dirfiles: - newfiles += dirfiles - continue - newfiles += glob.glob(f) or [ f ] - - bbmask = bb.data.getVar('BBMASK', self.configuration.data, 1) - - if not bbmask: - return (newfiles, 0) - - try: - bbmask_compiled = re.compile(bbmask) - except sre_constants.error: - bb.msg.fatal(bb.msg.domain.Collection, "BBMASK is not a valid regular expression.") - - finalfiles = [] - for i in xrange( len( newfiles ) ): - f = newfiles[i] - if bbmask and bbmask_compiled.search(f): - bb.msg.debug(1, bb.msg.domain.Collection, "skipping masked file %s" % f) - masked += 1 - continue - finalfiles.append(f) - - return (finalfiles, masked) - - def parse_bbfiles(self, filelist, masked, progressCallback = None): - parsed, cached, skipped = 0, 0, 0 - for i in xrange( len( filelist ) ): - f = filelist[i] - - bb.msg.debug(1, bb.msg.domain.Collection, "parsing %s" % f) - - # read a file's metadata - try: - fromCache, skip = self.bb_cache.loadData(f, self.configuration.data) - if skip: - skipped += 1 - bb.msg.debug(2, bb.msg.domain.Collection, "skipping %s" % f) - self.bb_cache.skip(f) - continue - elif fromCache: cached += 1 - else: parsed += 1 - deps = None - - # Disabled by RP as was no longer functional - # allow metadata files to add items to BBFILES - #data.update_data(self.pkgdata[f]) - #addbbfiles = self.bb_cache.getVar('BBFILES', f, False) or None - #if addbbfiles: - # for aof in addbbfiles.split(): - # if not files.count(aof): - # if not os.path.isabs(aof): - # aof = os.path.join(os.path.dirname(f),aof) - # files.append(aof) - - self.bb_cache.handle_data(f, self.status) - - # now inform the caller - if progressCallback is not None: - progressCallback( i + 1, len( filelist ), f, fromCache ) - - except IOError, e: - self.bb_cache.remove(f) - bb.msg.error(bb.msg.domain.Collection, "opening %s: %s" % (f, e)) - pass - except KeyboardInterrupt: - self.bb_cache.sync() - raise - except Exception, e: - self.bb_cache.remove(f) - bb.msg.error(bb.msg.domain.Collection, "%s while parsing %s" % (e, f)) - except: - self.bb_cache.remove(f) - raise - - if progressCallback is not None: - print "\r" # need newline after Handling Bitbake files message - bb.msg.note(1, bb.msg.domain.Collection, "Parsing finished. %d cached, %d parsed, %d skipped, %d masked." % ( cached, parsed, skipped, masked )) - - self.bb_cache.sync() #============================================================================# # main @@ -747,12 +103,13 @@ Default BBFILES are the .bb files in the current directory.""" ) action = "append", dest = "debug_domains", default = [] ) - options, args = parser.parse_args( sys.argv ) - - cooker = BBCooker() - cooker.cook( BBConfiguration( options ), args[1:] ) + options, args = parser.parse_args(sys.argv) + configuration = BBConfiguration(options) + configuration.pkgs_to_build = [] + configuration.pkgs_to_build.extend(args[1:]) + bb.cooker.BBCooker().cook(configuration) if __name__ == "__main__": main() @@ -761,4 +118,6 @@ if __name__ == "__main__": profile.run('main()', "profile.log") import pstats p = pstats.Stats('profile.log') + p.sort_stats('time') p.print_stats() + p.print_callers() diff --git a/bitbake/bin/bitdoc b/bitbake/bin/bitdoc index e865e1b998..3bcc9b344b 100755 --- a/bitbake/bin/bitdoc +++ b/bitbake/bin/bitdoc @@ -4,26 +4,18 @@ # # Copyright (C) 2005 Holger Hans Peter Freyther # +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. # -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR -# THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import optparse, os, sys -- cgit v1.2.3-54-g00ecf