import sys, os, getopt, glob, copy, os.path, re
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
import bb
-from bb import make
+from bb import utils, data, parse, debug, event, fatal
from sets import Set
import itertools, optparse
parsespin = itertools.cycle( r'|/-\\' )
bbdebug = 0
-__version__ = "1.3.1"
+__version__ = "1.3.2"
#============================================================================#
# BBParsingStatus
#============================================================================#
+# BBOptions
+#============================================================================#
+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.data = data.init()
+
+#============================================================================#
# BBCooker
#============================================================================#
class BBCooker:
self.stats = BBStatistics()
self.status = None
+ self.pkgdata = None
+ self.cache = None
+
def tryBuildPackage( self, fn, item, the_data ):
"""Build one package"""
bb.event.fire(bb.event.PkgStarted(item, the_data))
try:
self.stats.attempt += 1
- if make.options.force:
- bb.data.setVarFlag('do_%s' % make.options.cmd, 'force', 1, the_data)
- if not make.options.dry_run:
- bb.build.exec_task('do_%s' % make.options.cmd, the_data)
+ if self.configuration.force:
+ bb.data.setVarFlag('do_%s' % self.configuration.cmd, 'force', 1, the_data)
+ if not self.configuration.dry_run:
+ bb.build.exec_task('do_%s' % self.configuration.cmd, the_data)
bb.event.fire(bb.event.PkgSucceeded(item, the_data))
self.build_cache.append(fn)
return True
bb.error("upwards chain is: %s" % (" -> ".join(self.build_path)))
return False
- the_data = make.pkgdata[fn]
+ the_data = self.pkgdata[fn]
item = self.status.pkg_fn[fn]
self.building_list.append(fn)
self.build_path.append(pathstr)
depends_list = (bb.data.getVar('DEPENDS', the_data, 1) or "").split()
- if make.options.verbose:
+ if self.configuration.verbose:
bb.note("current path: %s" % (" -> ".join(self.build_path)))
bb.note("dependencies for %s are: %s" % (item, " ".join(depends_list)))
try:
failed = False
- depcmd = make.options.cmd
- bbdepcmd = bb.data.getVarFlag('do_%s' % make.options.cmd, 'bbdepcmd', the_data)
+ depcmd = self.configuration.cmd
+ bbdepcmd = bb.data.getVarFlag('do_%s' % self.configuration.cmd, 'bbdepcmd', the_data)
if bbdepcmd is not None:
if bbdepcmd == "":
depcmd = None
depcmd = bbdepcmd
if depcmd:
- oldcmd = make.options.cmd
- make.options.cmd = depcmd
+ oldcmd = self.configuration.cmd
+ self.configuration.cmd = depcmd
for dependency in depends_list:
if dependency in self.status.ignored_dependencies:
if self.buildProvider( dependency ) == 0:
bb.error("dependency %s (for %s) not satisfied" % (dependency,item))
failed = True
- if make.options.abort:
+ if self.configuration.abort:
break
if depcmd:
- make.options.cmd = oldcmd
+ self.configuration.cmd = oldcmd
if failed:
self.stats.deps += 1
return False
- if bb.build.stamp_is_current('do_%s' % make.options.cmd, the_data):
+ if bb.build.stamp_is_current('do_%s' % self.configuration.cmd, the_data):
self.build_cache.append(fn)
return True
preferred_file = None
- preferred_v = bb.data.getVar('PREFERRED_VERSION_%s' % pn, make.cfg, 1)
+ preferred_v = bb.data.getVar('PREFERRED_VERSION_%s' % pn, self.configuration.data, 1)
if preferred_v:
m = re.match('(.*)_(.*)', preferred_v)
if m:
pv,pr = self.status.pkg_pvpr[file_name]
dp = self.status.pkg_dp[file_name]
- if (latest is None) or ((latest_p == dp) and (make.vercmp(latest, (pv, pr)) < 0)) or (dp > latest_p):
+ if (latest is None) or ((latest_p == dp) and (utils.vercmp(latest, (pv, pr)) < 0)) or (dp > latest_p):
latest = (pv, pr)
latest_f = file_name
latest_p = dp
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:
+ try:
+ self.configuration.data, fromCache = self.load_bbfile( self.configuration.buildfile )
+ except IOError, e:
+ fatal("Unable to read %s: %s" % ( self.configuration.buildfile, e ))
+ except Exception, e:
+ fatal("%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:
+ fatal("%s" % e)
+ # emit the metadata which isnt valid shell
+ 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 buildProvider( self, item ):
fn = None
# look to see if one of them is already staged, or marked as preferred.
# if so, bump it to the head of the queue
for p in all_p:
- the_data = make.pkgdata[p]
+ the_data = self.pkgdata[p]
pn = bb.data.getVar('PN', the_data, 1)
pv = bb.data.getVar('PV', the_data, 1)
pr = bb.data.getVar('PR', the_data, 1)
extra_chat = "; upgrading from %s to %s" % (oldver, newver)
else:
extra_chat = ""
- if make.options.verbose:
+ if self.configuration.verbose:
bb.note("selecting already-staged %s to satisfy %s%s" % (pn, item, extra_chat))
eligible.remove(fn)
eligible = [fn] + eligible
discriminated = True
break
- prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, make.cfg, 1)
+ prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, self.configuration.data, 1)
if prefervar:
self.preferred[item] = prefervar
for p in eligible:
pn = self.status.pkg_fn[p]
if self.preferred[item] == pn:
- if make.options.verbose:
+ if self.configuration.verbose:
bb.note("selecting %s to satisfy %s due to PREFERRED_PROVIDERS" % (pn, item))
eligible.remove(p)
eligible = [p] + eligible
return 0
# Handle PREFERRED_PROVIDERS
- for p in (bb.data.getVar('PREFERRED_PROVIDERS', make.cfg, 1) or "").split():
+ for p in (bb.data.getVar('PREFERRED_PROVIDERS', self.configuration.data, 1) or "").split():
(providee, provider) = p.split(':')
if providee in self.preferred and self.preferred[providee] != provider:
bb.error("conflicting preferences for %s: both %s and %s specified" % (providee, provider, self.preferred[providee]))
self.preferred[providee] = provider
# Calculate priorities for each file
- for p in make.pkgdata.keys():
+ for p in self.pkgdata.keys():
self.status.bbfile_priority[p] = calc_bbfile_priority(p)
# Build package list for "bitbake world"
def parseConfigurationFile( self, afile ):
try:
- make.cfg = bb.parse.handle( afile, make.cfg )
+ self.configuration.data = bb.parse.handle( afile, self.configuration.data )
except IOError:
bb.fatal( "Unable to open %s" % afile )
except bb.parse.ParseError, details:
if collections:
collection_list = collections.split()
for c in collection_list:
- regex = bb.data.getVar("BBFILE_PATTERN_%s" % c, make.cfg, 1)
+ regex = bb.data.getVar("BBFILE_PATTERN_%s" % c, self.configuration.data, 1)
if regex == None:
bb.error("BBFILE_PATTERN_%s not defined" % c)
continue
- priority = bb.data.getVar("BBFILE_PRIORITY_%s" % c, make.cfg, 1)
+ priority = bb.data.getVar("BBFILE_PRIORITY_%s" % c, self.configuration.data, 1)
if priority == None:
bb.error("BBFILE_PRIORITY_%s not defined" % c)
continue
bb.error("invalid value for BBFILE_PRIORITY_%s: \"%s\"" % (c, priority))
- def cook( self, args ):
- if not make.options.cmd:
- make.options.cmd = "build"
+ def cook( self, configuration, args ):
+ self.configuration = configuration
- if make.options.debug:
- bb.debug_level = make.options.debug
+ if not self.configuration.cmd:
+ self.configuration.cmd = "build"
- make.cfg = bb.data.init()
+ if self.configuration.debug:
+ bb.debug_level = self.configuration.debug
- for f in make.options.file:
+ 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 bb.data.getVar("BUILDNAME", make.cfg):
- bb.data.setVar("BUILDNAME", os.popen('date +%Y%m%d%H%M').readline().strip(), make.cfg)
+ if self.configuration.show_environment:
+ self.showEnvironment()
+ sys.exit( 0 )
- buildname = bb.data.getVar("BUILDNAME", make.cfg)
+ 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)
- if make.options.interactive:
+ buildname = bb.data.getVar("BUILDNAME", self.configuration.data)
+
+ if self.configuration.interactive:
self.interactiveMode()
- if make.options.buildfile is not None:
- bf = os.path.abspath( make.options.buildfile )
+ if self.configuration.buildfile is not None:
+ bf = os.path.abspath( self.configuration.buildfile )
try:
- bbfile_data = bb.parse.handle(bf, make.cfg)
+ bbfile_data = bb.parse.handle(bf, self.configuration.data)
except IOError:
bb.fatal("Unable to open %s" % bf)
# initialise the parsing status now we know we will need deps
self.status = BBParsingStatus()
- ignore = bb.data.getVar("ASSUME_PROVIDED", make.cfg, 1) or ""
+ 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", make.cfg, 1) )
+ self.handleCollections( bb.data.getVar("BBFILE_COLLECTIONS", self.configuration.data, 1) )
pkgs_to_build = None
if args:
pkgs_to_build = []
pkgs_to_build.extend(args)
if not pkgs_to_build:
- bbpkgs = bb.data.getVar('BBPKGS', make.cfg, 1)
+ bbpkgs = bb.data.getVar('BBPKGS', self.configuration.data, 1)
if bbpkgs:
pkgs_to_build = bbpkgs.split()
- if not pkgs_to_build and not make.options.show_versions and not make.options.interactive:
+ 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 make.options.disable_psyco:
+ if not self.configuration.disable_psyco:
try:
import psyco
except ImportError:
if bbdebug == 0:
bb.note("Psyco JIT Compiler (http://psyco.sf.net) not available. Install it to increase performance.")
else:
- psyco.bind( make.collect_bbfiles )
+ psyco.bind( self.collect_bbfiles )
else:
bb.note("You have disabled Psyco. This decreases performance.")
try:
bb.debug(1, "collecting .bb files")
- make.collect_bbfiles( self.myProgressCallback )
+ self.collect_bbfiles( self.myProgressCallback )
bb.debug(1, "parsing complete")
if bbdebug == 0:
print
- if make.options.parse_only:
+ if self.configuration.parse_only:
print "Requested parsing .bb files only. Exiting."
return
- bb.data.update_data( make.cfg )
+ bb.data.update_data( self.configuration.data )
self.buildDepgraph()
- if make.options.show_versions:
+ if self.configuration.show_versions:
self.showVersions()
sys.exit( 0 )
if 'world' in pkgs_to_build:
for t in self.status.world_target:
pkgs_to_build.append(t)
- bb.event.fire(bb.event.BuildStarted(buildname, pkgs_to_build, make.cfg))
+ bb.event.fire(bb.event.BuildStarted(buildname, pkgs_to_build, self.configuration.data))
for k in pkgs_to_build:
failed = False
failed = True
if failed:
- if make.options.abort:
+ if self.configuration.abort:
sys.exit(1)
- bb.event.fire(bb.event.BuildCompleted(buildname, pkgs_to_build, make.cfg))
+ bb.event.fire(bb.event.BuildCompleted(buildname, pkgs_to_build, self.configuration.data))
sys.exit( self.stats.show() )
print "\nNOTE: 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 deps_clean(self, d):
+ depstr = data.getVar('__depends', d)
+ if depstr:
+ deps = depstr.split(" ")
+ for dep in deps:
+ (f,old_mtime_s) = dep.split("@")
+ old_mtime = int(old_mtime_s)
+ new_mtime = parse.cached_mtime(f)
+ if (new_mtime > old_mtime):
+ return False
+ return True
+
+ def load_bbfile( self, bbfile ):
+ """Load and parse one .bb build file"""
+
+ if not self.cache in [None, '']:
+ # get the times
+ cache_mtime = data.init_db_mtime(self.cache, bbfile)
+ file_mtime = parse.cached_mtime(bbfile)
+
+ if file_mtime > cache_mtime:
+ #print " : '%s' dirty. reparsing..." % bbfile
+ pass
+ else:
+ #print " : '%s' clean. loading from cache..." % bbfile
+ cache_data = data.init_db( self.cache, bbfile, False )
+ if self.deps_clean(cache_data):
+ return cache_data, True
+
+ topdir = data.getVar('TOPDIR', self.configuration.data)
+ if not topdir:
+ topdir = os.path.abspath(os.getcwd())
+ # set topdir to here
+ data.setVar('TOPDIR', topdir, self.configuration)
+ bbfile = os.path.abspath(bbfile)
+ bbfile_loc = os.path.abspath(os.path.dirname(bbfile))
+ # expand tmpdir to include this topdir
+ data.setVar('TMPDIR', data.getVar('TMPDIR', self.configuration.data, 1) or "", self.configuration.data)
+ # set topdir to location of .bb file
+ topdir = bbfile_loc
+ #data.setVar('TOPDIR', topdir, cfg)
+ # go there
+ oldpath = os.path.abspath(os.getcwd())
+ os.chdir(topdir)
+ bb = data.init_db(self.cache,bbfile, True, self.configuration.data)
+ try:
+ parse.handle(bbfile, bb) # read .bb data
+ if not self.cache in [None, '']:
+ bb.commit(parse.cached_mtime(bbfile)) # write cache
+ os.chdir(oldpath)
+ return bb, False
+ finally:
+ os.chdir(oldpath)
+
+ def collect_bbfiles( self, progressCallback ):
+ """Collect all available .bb build files"""
+ self.cb = progressCallback
+ parsed, cached, skipped, masked = 0, 0, 0, 0
+ self.cache = bb.data.getVar( "CACHE", self.configuration.data, 1 )
+ self.pkgdata = data.pkgdata( not self.cache in [None, ''], self.cache )
+
+ if not self.cache in [None, '']:
+ if self.cb is not None:
+ print "NOTE: Using cache in '%s'" % self.cache
+ try:
+ os.stat( self.cache )
+ except OSError:
+ bb.mkdirhier( self.cache )
+ else:
+ if self.cb is not None:
+ print "NOTE: Not using a cache. Set CACHE = <directory> to enable."
+ files = (data.getVar( "BBFILES", self.configuration.data, 1 ) or "").split()
+ data.setVar("BBFILES", " ".join(files), self.configuration.data)
+
+ if not len(files):
+ files = get_bbfiles()
+
+ if not len(files):
+ bb.error("no files to build.")
+
+ newfiles = []
+ for f in files:
+ if os.path.isdir(f):
+ dirfiles = find_bbfiles(f)
+ if dirfiles:
+ newfiles += dirfiles
+ continue
+ newfiles += glob.glob(f) or [ f ]
+
+ bbmask = bb.data.getVar('BBMASK', self.configuration.data, 1) or ""
+ try:
+ bbmask_compiled = re.compile(bbmask)
+ except sre_constants.error:
+ bb.fatal("BBMASK is not a valid regular expression.")
+
+ for i in xrange( len( newfiles ) ):
+ f = newfiles[i]
+ if bbmask and bbmask_compiled.search(f):
+ bb.debug(1, "bbmake: skipping %s" % f)
+ masked += 1
+ continue
+ debug(1, "bbmake: parsing %s" % f)
+
+ # read a file's metadata
+ try:
+ bb_data, fromCache = self.load_bbfile(f)
+ if fromCache: cached += 1
+ else: parsed += 1
+ deps = None
+ if bb_data is not None:
+ # allow metadata files to add items to BBFILES
+ #data.update_data(self.pkgdata[f])
+ addbbfiles = data.getVar('BBFILES', bb_data) 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)
+ for var in bb_data.keys():
+ if data.getVarFlag(var, "handler", bb_data) and data.getVar(var, bb_data):
+ event.register(data.getVar(var, bb_data))
+ self.pkgdata[f] = bb_data
+
+ # now inform the caller
+ if self.cb is not None:
+ self.cb( i + 1, len( newfiles ), f, bb_data, fromCache )
+
+ except IOError, e:
+ bb.error("opening %s: %s" % (f, e))
+ pass
+ except bb.parse.SkipPackage:
+ skipped += 1
+ pass
+ except KeyboardInterrupt:
+ raise
+ except Exception, e:
+ bb.error("%s while parsing %s" % (e, f))
+
+ if self.cb is not None:
+ print "\rNOTE: Parsing finished. %d cached, %d parsed, %d skipped, %d masked." % ( cached, parsed, skipped, masked ),
+
#============================================================================#
# main
#============================================================================#
parser.add_option( "-i", "--interactive", help = "drop into the interactive mode.",
action = "store_true", dest = "interactive", default = False )
- parser.add_option( "-c", "--cmd", help = "Specify task to execute",
+ 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)",
action = "store", dest = "cmd", default = "build" )
parser.add_option( "-r", "--read", help = "read the specified file before bitbake.conf",
parser.add_option( "-s", "--show-versions", help = "show current and preferred versions of all packages",
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 )
+
options, args = parser.parse_args( sys.argv )
- make.options = options
cooker = BBCooker()
- cooker.cook( args[1:] )
+ cooker.cook( BBConfiguration( options ), args[1:] )
+++ /dev/null
-# ex:ts=4:sw=4:sts=4:et
-# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
-"""
-BitBake 'Make' implementations
-
-Functions for reading BB files, building a dependency graph and
-building a set of BB files while walking along the dependency graph.
-
-Copyright (C) 2003, 2004 Mickey Lauer
-Copyright (C) 2003, 2004 Phil Blundell
-Copyright (C) 2003, 2004 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 file is part of the BitBake build tools.
-"""
-
-from bb import debug, digraph, data, fetch, fatal, error, note, event, parse
-import copy, bb, re, sys, os, glob, sre_constants
-
-pkgdata = None
-cfg = data.init()
-cache = None
-digits = "0123456789"
-ascii_letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
-mtime_cache = {}
-
-def get_bbfiles( 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( 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 deps_clean(d):
- depstr = data.getVar('__depends', d)
- if depstr:
- deps = depstr.split(" ")
- for dep in deps:
- (f,old_mtime_s) = dep.split("@")
- old_mtime = int(old_mtime_s)
- new_mtime = parse.cached_mtime(f)
- if (new_mtime > old_mtime):
- return False
- return True
-
-def load_bbfile( bbfile ):
- """Load and parse one .bb build file"""
-
- if not cache in [None, '']:
- # get the times
- cache_mtime = data.init_db_mtime(cache, bbfile)
- file_mtime = parse.cached_mtime(bbfile)
-
- if file_mtime > cache_mtime:
- #print " : '%s' dirty. reparsing..." % bbfile
- pass
- else:
- #print " : '%s' clean. loading from cache..." % bbfile
- cache_data = data.init_db( cache, bbfile, False )
- if deps_clean(cache_data):
- return cache_data, True
-
- topdir = data.getVar('TOPDIR', cfg)
- if not topdir:
- topdir = os.path.abspath(os.getcwd())
- # set topdir to here
- data.setVar('TOPDIR', topdir, cfg)
- bbfile = os.path.abspath(bbfile)
- bbfile_loc = os.path.abspath(os.path.dirname(bbfile))
- # expand tmpdir to include this topdir
- data.setVar('TMPDIR', data.getVar('TMPDIR', cfg, 1) or "", cfg)
- # set topdir to location of .bb file
- topdir = bbfile_loc
- #data.setVar('TOPDIR', topdir, cfg)
- # go there
- oldpath = os.path.abspath(os.getcwd())
- os.chdir(topdir)
- bb = data.init_db(cache,bbfile, True, cfg)
- try:
- parse.handle(bbfile, bb) # read .bb data
- if not cache in [None, '']:
- bb.commit(parse.cached_mtime(bbfile)) # write cache
- os.chdir(oldpath)
- return bb, False
- finally:
- os.chdir(oldpath)
-
-def collect_bbfiles( progressCallback ):
- """Collect all available .bb build files"""
- collect_bbfiles.cb = progressCallback
- parsed, cached, skipped, masked = 0, 0, 0, 0
- global cache, pkgdata
- cache = bb.data.getVar( "CACHE", cfg, 1 )
- pkgdata = data.pkgdata( not cache in [None, ''], cache )
-
- if not cache in [None, '']:
- if collect_bbfiles.cb is not None:
- print "NOTE: Using cache in '%s'" % cache
- try:
- os.stat( cache )
- except OSError:
- bb.mkdirhier( cache )
- else:
- if collect_bbfiles.cb is not None:
- print "NOTE: Not using a cache. Set CACHE = <directory> to enable."
- files = (data.getVar( "BBFILES", cfg, 1 ) or "").split()
- data.setVar("BBFILES", " ".join(files), cfg)
-
- if not len(files):
- files = get_bbfiles()
-
- if not len(files):
- bb.error("no files to build.")
-
- newfiles = []
- for f in files:
- if os.path.isdir(f):
- dirfiles = find_bbfiles(f)
- if dirfiles:
- newfiles += dirfiles
- continue
- newfiles += glob.glob(f) or [ f ]
-
- bbmask = bb.data.getVar('BBMASK', cfg, 1) or ""
- try:
- bbmask_compiled = re.compile(bbmask)
- except sre_constants.error:
- bb.fatal("BBMASK is not a valid regular expression.")
-
- for i in xrange( len( newfiles ) ):
- f = newfiles[i]
- if bbmask and bbmask_compiled.search(f):
- bb.debug(1, "bbmake: skipping %s" % f)
- masked += 1
- continue
- debug(1, "bbmake: parsing %s" % f)
-
- # read a file's metadata
- try:
- bb_data, fromCache = load_bbfile(f)
- if fromCache: cached += 1
- else: parsed += 1
- deps = None
- if bb_data is not None:
- # allow metadata files to add items to BBFILES
- #data.update_data(pkgdata[f])
- addbbfiles = data.getVar('BBFILES', bb_data) 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)
- for var in bb_data.keys():
- if data.getVarFlag(var, "handler", bb_data) and data.getVar(var, bb_data):
- event.register(data.getVar(var, bb_data))
- pkgdata[f] = bb_data
-
- # now inform the caller
- if collect_bbfiles.cb is not None:
- collect_bbfiles.cb( i + 1, len( newfiles ), f, bb_data, fromCache )
-
- except IOError, e:
- bb.error("opening %s: %s" % (f, e))
- pass
- except bb.parse.SkipPackage:
- skipped += 1
- pass
- except KeyboardInterrupt:
- raise
- except Exception, e:
- bb.error("%s while parsing %s" % (e, f))
-
- if collect_bbfiles.cb is not None:
- print "\rNOTE: Parsing finished. %d cached, %d parsed, %d skipped, %d masked." % ( cached, parsed, skipped, masked ),
-
-def explode_version(s):
- import string
- r = []
- alpha_regexp = re.compile('^([a-zA-Z]+)(.*)$')
- numeric_regexp = re.compile('^(\d+)(.*)$')
- while (s != ''):
- if s[0] in digits:
- m = numeric_regexp.match(s)
- r.append(int(m.group(1)))
- s = m.group(2)
- continue
- if s[0] in ascii_letters:
- m = alpha_regexp.match(s)
- r.append(m.group(1))
- s = m.group(2)
- continue
- s = s[1:]
- return r
-
-def vercmp_part(a, b):
- va = explode_version(a)
- vb = explode_version(b)
- while True:
- if va == []:
- ca = None
- else:
- ca = va.pop(0)
- if vb == []:
- cb = None
- else:
- cb = vb.pop(0)
- if ca == None and cb == None:
- return 0
- if ca > cb:
- return 1
- if ca < cb:
- return -1
-
-def vercmp(ta, tb):
- (va, ra) = ta
- (vb, rb) = tb
-
- r = vercmp_part(va, vb)
- if (r == 0):
- r = vercmp_part(ra, rb)
- return r
* ncurses interface
* read some initial commands from startup file (batch)
-MAYBE WORKING:
- * poke doesn't work at all (outcommented atm.)
-
PROBLEMS:
* force doesn't always work
* readline completion for commands with more than one parameters
from sets import Set as set
import sys, os, imp, readline, socket, httplib, urllib, commands, popen2
imp.load_source( "bitbake", os.path.dirname( sys.argv[0] )+"/bitbake" )
-from bb import data, parse, build, make, fatal
+from bb import data, parse, build, fatal
-__version__ = "0.5.0"
+__version__ = "0.5.1"
__credits__ = """BitBake Shell Version %s (C) 2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
Type 'help' for more information, press CTRL-D to exit.""" % __version__
def _findProvider( self, item ):
self._checkParsed()
- preferred = data.getVar( "PREFERRED_PROVIDER_%s" % item, make.cfg, 1 )
+ preferred = data.getVar( "PREFERRED_PROVIDER_%s" % item, cooker.configuration.data, 1 )
if not preferred: preferred = item
try:
lv, lf, pv, pf = cooker.findBestProvider( preferred )
"""Build a providee"""
name = params[0]
- oldcmd = make.options.cmd
- make.options.cmd = cmd
+ oldcmd = cooker.configuration.cmd
+ cooker.configuration.cmd = cmd
cooker.build_cache = []
cooker.build_cache_fail = []
global last_exception
last_exception = e
- make.options.cmd = oldcmd
+ cooker.configuration.cmd = oldcmd
build.usage = "<providee>"
def clean( self, params ):
def environment( self, params ):
"""Dump out the outer BitBake environment (see bbread)"""
- data.emit_env(sys.__stdout__, make.cfg, True)
+ data.emit_env(sys.__stdout__, cooker.configuration.data, True)
def exit_( self, params ):
"""Leave the BitBake Shell"""
bf = completeFilePath( name )
print "SHELL: Calling '%s' on '%s'" % ( cmd, bf )
- oldcmd = make.options.cmd
- make.options.cmd = cmd
+ oldcmd = cooker.configuration.cmd
+ cooker.configuration.cmd = cmd
cooker.build_cache = []
cooker.build_cache_fail = []
try:
- bbfile_data = parse.handle( bf, make.cfg )
+ bbfile_data = parse.handle( bf, cooker.configuration.data )
except parse.ParseError:
print "ERROR: Unable to open or parse '%s'" % bf
else:
global last_exception
last_exception = e
- make.options.cmd = oldcmd
+ cooker.configuration.cmd = oldcmd
fileBuild.usage = "<bbfile>"
def fileClean( self, params ):
def force( self, params ):
"""Toggle force task execution flag (see bitbake -f)"""
- make.options.force = not make.options.force
- print "SHELL: Force Flag is now '%s'" % repr( make.options.force )
+ cooker.configuration.force = not cooker.configuration.force
+ print "SHELL: Force Flag is now '%s'" % repr( cooker.configuration.force )
def help( self, params ):
"""Show a comprehensive list of commands and their purpose"""
def new( self, params ):
"""Create a new .bb file and open the editor"""
dirname, filename = params
- packages = '/'.join( data.getVar( "BBFILES", make.cfg, 1 ).split('/')[:-2] )
+ packages = '/'.join( data.getVar( "BBFILES", cooker.configuration.data, 1 ).split('/')[:-2] )
fulldirname = "%s/%s" % ( packages, dirname )
if not os.path.exists( fulldirname ):
def parse( self, params ):
"""(Re-)parse .bb files and calculate the dependency graph"""
cooker.status = cooker.ParsingStatus()
- ignore = data.getVar("ASSUME_PROVIDED", make.cfg, 1) or ""
+ ignore = data.getVar("ASSUME_PROVIDED", cooker.configuration.data, 1) or ""
cooker.status.ignored_dependencies = set( ignore.split() )
- cooker.handleCollections( data.getVar("BBFILE_COLLECTIONS", make.cfg, 1) )
+ cooker.handleCollections( data.getVar("BBFILE_COLLECTIONS", cooker.configuration.data, 1) )
- make.collect_bbfiles( cooker.myProgressCallback )
+ cooker.collect_bbfiles( cooker.myProgressCallback )
cooker.buildDepgraph()
global parsed
parsed = True
def getvar( self, params ):
"""Dump the contents of an outer BitBake environment variable"""
var = params[0]
- value = data.getVar( var, make.cfg, 1 )
+ value = data.getVar( var, cooker.configuration.data, 1 )
print value
getvar.usage = "<variable>"
name, var = params
bbfile = self._findProvider( name )
if bbfile is not None:
- value = make.pkgdata[bbfile].getVar( var, 1 )
+ value = cooker.pkgdata[bbfile].getVar( var, 1 )
print value
else:
print "ERROR: Nothing provides '%s'" % name
"""Set contents of variable defined in providee's metadata"""
name, var, value = params
bbfile = self._findProvider( name )
- d = make.pkgdata[bbfile]
+ d = cooker.pkgdata[bbfile]
if bbfile is not None:
data.setVar( var, value, d )
# mark the change semi persistant
- make.pkgdata.setDirty(bbfile, d)
+ cooker.pkgdata.setDirty(bbfile, d)
print "OK"
else:
print "ERROR: Nothing provides '%s'" % name
what = params[0]
if what == "files":
self._checkParsed()
- for key in make.pkgdata.keys(): print key
+ for key in cooker.pkgdata.keys(): print key
elif what == "providers":
self._checkParsed()
for key in cooker.status.providers.keys(): print key
def setVar( self, params ):
"""Set an outer BitBake environment variable"""
var, value = params
- data.setVar( var, value, make.cfg )
+ data.setVar( var, value, cooker.configuration.data )
print "OK"
setVar.usage = "<variable> <value>"
self._checkParsed()
- preferred = data.getVar( "PREFERRED_PROVIDER_%s" % item, make.cfg, 1 )
+ preferred = data.getVar( "PREFERRED_PROVIDER_%s" % item, cooker.configuration.data, 1 )
if not preferred: preferred = item
try:
def completeFilePath( bbfile ):
"""Get the complete bbfile path"""
- if not make.pkgdata: return bbfile
- for key in make.pkgdata.keys():
+ if not cooker.pkgdata: return bbfile
+ for key in cooker.pkgdata.keys():
if key.endswith( bbfile ):
return key
return bbfile
if line[0] in cmds and hasattr( cmds[line[0]][0], "usage" ): # known command and usage
u = getattr( cmds[line[0]][0], "usage" ).split()[0]
if u == "<variable>":
- allmatches = make.cfg.keys()
+ allmatches = cooker.configuration.data.keys()
elif u == "<bbfile>":
- if make.pkgdata is None: allmatches = [ "(No Matches Available. Parsed yet?)" ]
- else: allmatches = [ x.split("/")[-1] for x in make.pkgdata.keys() ]
+ if cooker.pkgdata is None: allmatches = [ "(No Matches Available. Parsed yet?)" ]
+ else: allmatches = [ x.split("/")[-1] for x in cooker.pkgdata.keys() ]
elif u == "<providee>":
- if make.pkgdata is None: allmatches = [ "(No Matches Available. Parsed yet?)" ]
+ if cooker.pkgdata is None: allmatches = [ "(No Matches Available. Parsed yet?)" ]
else: allmatches = cooker.status.providers.iterkeys()
else: allmatches = [ "(No tab completion available for this command)" ]
else: allmatches = [ "(No tab completion available for this command)" ]