Browse Source

bitbake/lib/bb/__init__.py:
bitbake/lib/bb/build.py:
bitbake/lib/bb/utils.py:
bitbake/lib/bb/shell.py:
bitbake/lib/bb/providers.py:
bitbake/lib/bb/msg.py:
bitbake/bin/bitbake:
bitbake/bin/bitdoc:
bitbake/classes/base.bbclass:
Start an overhaul of the message handling in bitbake:
- Introduce a new msg module to replace the existing simple calls.
- The msg module adds the conncept of message domains so ultimately we can
select which kinds of debug messages we want to see (it uses an Enum class
for this)
- Add a warn logging level for things the user should really pay attention to
as note is a little overloaded at present
- Start converting to use the new fuctions

Richard Purdie 18 years ago
parent
commit
4651e6cf84
9 changed files with 215 additions and 104 deletions
  1. 69 73
      bin/bitbake
  2. 1 1
      bin/bitdoc
  3. 1 1
      classes/base.bbclass
  4. 7 15
      lib/bb/__init__.py
  5. 5 5
      lib/bb/build.py
  6. 84 0
      lib/bb/msg.py
  7. 6 7
      lib/bb/providers.py
  8. 2 2
      lib/bb/shell.py
  9. 40 0
      lib/bb/utils.py

+ 69 - 73
bin/bitbake

@@ -24,12 +24,11 @@
 import sys, os, getopt, glob, copy, os.path, re, time
 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, debug, event, fatal, cache, providers
+from bb import utils, data, parse, event, cache, providers
 from sets import Set
 import itertools, optparse
 
 parsespin = itertools.cycle( r'|/-\\' )
-bbdebug = 0
 
 __version__ = "1.5.0"
 
@@ -229,14 +228,14 @@ class BBCooker:
             return True
         except bb.build.FuncFailed:
             self.stats.fail += 1
-            bb.error("task stack execution failed")
+            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.error("%s event exception, aborting" % bb.event.getName(event))
+            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
@@ -256,8 +255,8 @@ class BBCooker:
 
         # Error on build time dependency loops
         if build_depends and build_depends.count(fn) > 1:
-            bb.error("%s depends on itself (eventually)" % fn)
-            bb.error("upwards chain is: %s" % (" -> ".join(self.build_path)))
+            bb.msg.error(bb.msg.domain.Depends, "%s depends on itself (eventually)" % fn)
+            bb.msg.error(bb.msg.domain.Depends, "upwards chain is: %s" % (" -> ".join(self.build_path)))
             return False
 
         # See if this is a runtime dependency we've already built
@@ -274,9 +273,8 @@ class BBCooker:
 
         depends_list = (bb.data.getVar('DEPENDS', the_data, True) or "").split()
 
-        if self.configuration.verbose:
-            bb.note("current path: %s" % (" -> ".join(self.build_path)))
-            bb.note("dependencies for %s are: %s" % (item, " ".join(depends_list)))
+        bb.msg.note(2, bb.msg.domain.Depends, "current path: %s" % (" -> ".join(self.build_path)))
+        bb.msg.note(2, bb.msg.domain.Depends, "dependencies for %s are: %s" % (item, " ".join(depends_list)))
 
         try:
             failed = False
@@ -299,7 +297,7 @@ class BBCooker:
                 if not depcmd:
                     continue
                 if self.buildProvider( dependency , buildAllDeps , build_depends ) == 0:
-                    bb.error("dependency %s (for %s) not satisfied" % (dependency,item))
+                    bb.msg.error(bb.msg.domain.Depends, "dependency %s (for %s) not satisfied" % (dependency,item))
                     failed = True
                     if self.configuration.abort:
                         break
@@ -360,15 +358,15 @@ class BBCooker:
             try:
                 self.configuration.data = self.bb_cache.loadDataFull(self.configuration.buildfile, self)
             except IOError, e:
-                fatal("Unable to read %s: %s" % ( self.configuration.buildfile, e ))
+                bb.msg.fatal(bb.msg.domain.Parsing, "Unable to read %s: %s" % ( self.configuration.buildfile, e ))
             except Exception, e:
-                fatal("%s" % 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:
-            fatal("%s" % e)
+            bb.msg.fatal(bb.msg.domain.Parsing, "%s" % e)
         # emit the metadata which isnt valid shell
         for e in self.configuration.data.keys():
             if data.getVarFlag( e, 'python', self.configuration.data ):
@@ -401,7 +399,7 @@ class BBCooker:
                     pkg_pn[pn] = []
                 pkg_pn[pn].append(p)
 
-            bb.debug(1, "providers for %s are: %s" % (item, pkg_pn.keys()))
+            bb.msg.debug(1, bb.msg.domain.Provider, "providers for %s are: %s" % (item, pkg_pn.keys()))
 
             for pn in pkg_pn.keys():
                 preferred_versions[pn] = self.findBestProvider(pn, pkg_pn)[2:4]
@@ -409,11 +407,11 @@ class BBCooker:
 
             for p in eligible:
                 if p in self.build_cache_fail:
-                    bb.debug(1, "rejecting already-failed %s" % p)
+                    bb.msg.debug(1, bb.msg.domain.Provider, "rejecting already-failed %s" % p)
                     eligible.remove(p)
 
             if len(eligible) == 0:
-                bb.error("no eligible providers for %s" % item)
+                bb.msg.error(bb.msg.domain.Provider, "no eligible providers for %s" % item)
                 return 0
 
             prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, self.configuration.data, 1)
@@ -422,7 +420,7 @@ class BBCooker:
             if prefervar:
                 for p in eligible:
                     if prefervar == self.status.pkg_fn[p]:
-                        bb.note("Selecting PREFERRED_PROVIDER %s" % prefervar)
+                        bb.msg.note(1, bb.msg.domain.Provider, "Selecting PREFERRED_PROVIDER %s" % prefervar)
                         eligible.remove(p)
                         eligible = [p] + eligible
 
@@ -554,7 +552,7 @@ class BBCooker:
         discriminated = False
 
         if not item in self.status.providers:
-            bb.error("Nothing provides dependency %s" % item)
+            bb.msg.error(bb.msg.domain.Depends, "Nothing provides dependency %s" % item)
             bb.event.fire(bb.event.NoProvider(item,self.configuration.data))
             return 0
 
@@ -562,10 +560,10 @@ class BBCooker:
 
         for p in all_p:
             if p in self.build_cache:
-                bb.debug(1, "already built %s in this run\n" % p)
+                bb.msg.debug(1, bb.msg.domain.Provider, "already built %s in this run" % p)
                 return 1
 
-        eligible = bb.providers.filterProviders(all_p, item, self.configuration.data, self.status, self.build_cache_fail, self.configuration.verbose)
+        eligible = bb.providers.filterProviders(all_p, item, self.configuration.data, self.status, self.build_cache_fail)
 
         if not eligible:
             return 0
@@ -578,8 +576,7 @@ class BBCooker:
             for p in eligible:
                 pn = self.status.pkg_fn[p]
                 if self.preferred[item] == pn:
-                    if self.configuration.verbose:
-                        bb.note("selecting %s to satisfy %s due to PREFERRED_PROVIDERS" % (pn, item))
+                    bb.msg.note(2, bb.msg.domain.Provider, "selecting %s to satisfy %s due to PREFERRED_PROVIDERS" % (pn, item))
                     eligible.remove(p)
                     eligible = [p] + eligible
                     discriminated = True
@@ -590,19 +587,19 @@ class BBCooker:
                 providers_list = []
                 for fn in eligible:
                     providers_list.append(self.status.pkg_fn[fn])
-                bb.note("multiple providers are available (%s);" % ", ".join(providers_list))
-                bb.note("consider defining PREFERRED_PROVIDER_%s" % item)
+                bb.msg.note(1, bb.msg.domain.Provider, "multiple providers are available (%s);" % ", ".join(providers_list))
+                bb.msg.note(1, bb.msg.domain.Provider, "consider defining PREFERRED_PROVIDER_%s" % item)
                 bb.event.fire(bb.event.MultipleProviders(item,providers_list,self.configuration.data))
             self.consider_msgs_cache.append(item)
 
 
         # run through the list until we find one that we can build
         for fn in eligible:
-            bb.debug(2, "selecting %s to satisfy %s" % (fn, item))
+            bb.msg.debug(2, bb.msg.domain.Provider, "selecting %s to satisfy %s" % (fn, item))
             if self.tryBuild(fn, item, buildAllDeps, build_depends + [fn]):
                 return 1
 
-        bb.note("no buildable providers for %s" % item)
+        bb.msg.note(1, bb.msg.domain.Provider, "no buildable providers for %s" % item)
         bb.event.fire(bb.event.NoProvider(item,self.configuration.data))
         return 0
 
@@ -622,19 +619,19 @@ class BBCooker:
         all_p = self.getProvidersRun(item)
 
         if not all_p:
-            bb.error("Nothing provides runtime dependency %s" % (item))
+            bb.msg.error(bb.msg.domain.Provider, "Nothing provides runtime dependency %s" % (item))
             bb.event.fire(bb.event.NoProvider(item,self.configuration.data,runtime=True))
             return False
 
         for p in all_p:
             if p in self.rbuild_cache:
-                bb.debug(2, "Already built %s providing runtime %s\n" % (p,item))
+                bb.msg.debug(2, bb.msg.domain.Provider, "Already built %s providing runtime %s" % (p,item))
                 return True
             if p in self.build_cache:
-                bb.debug(2, "Already built %s but adding any further RDEPENDS for %s\n" % (p, item))
+                bb.msg.debug(2, bb.msg.domain.Provider, "Already built %s but adding any further RDEPENDS for %s" % (p, item))
                 return self.addRunDeps(p, item , buildAllDeps)
 
-        eligible = bb.providers.filterProviders(all_p, item, self.configuration.data, self.status, self.build_cache_fail, self.configuration.verbose)
+        eligible = bb.providers.filterProviders(all_p, item, self.configuration.data, self.status, self.build_cache_fail)
         if not eligible:
             return 0
 
@@ -645,8 +642,7 @@ class BBCooker:
             for provide in provides:
                 prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % provide, self.configuration.data, 1)
                 if prefervar == pn:
-                    if self.configuration.verbose:
-                        bb.note("selecting %s to satisfy runtime %s due to PREFERRED_PROVIDERS" % (pn, item))
+                    bb.msg.note(2, bb.msg.domain.Provider, "selecting %s to satisfy runtime %s due to PREFERRED_PROVIDERS" % (pn, item))
                     eligible.remove(p)
                     eligible = [p] + eligible
                     preferred.append(p)
@@ -656,8 +652,8 @@ class BBCooker:
                 providers_list = []
                 for fn in eligible:
                     providers_list.append(self.status.pkg_fn[fn])
-                bb.note("multiple providers are available (%s);" % ", ".join(providers_list))
-                bb.note("consider defining a PREFERRED_PROVIDER to match runtime %s" % item)
+                bb.msg.note(1, bb.msg.domain.Provider, "multiple providers are available (%s);" % ", ".join(providers_list))
+                bb.msg.note(1, bb.msg.domain.Provider, "consider defining a PREFERRED_PROVIDER to match runtime %s" % item)
                 bb.event.fire(bb.event.MultipleProviders(item,providers_list,self.configuration.data,runtime=True))
             self.consider_msgs_cache.append(item)
 
@@ -666,18 +662,18 @@ class BBCooker:
                 providers_list = []
                 for fn in preferred:
                     providers_list.append(self.status.pkg_fn[fn])
-                bb.note("multiple preferred providers are available (%s);" % ", ".join(providers_list))
-                bb.note("consider defining only one PREFERRED_PROVIDER to match runtime %s" % item)
+                bb.msg.note(1, bb.msg.domain.Provider, "multiple preferred providers are available (%s);" % ", ".join(providers_list))
+                bb.msg.note(1, bb.msg.domain.Provider, "consider defining only one PREFERRED_PROVIDER to match runtime %s" % item)
                 bb.event.fire(bb.event.MultipleProviders(item,providers_list,self.configuration.data,runtime=True))
             self.consider_msgs_cache.append(item)
 
         # run through the list until we find one that we can build
         for fn in eligible:
-            bb.debug(2, "selecting %s to satisfy runtime %s" % (fn, item))
+            bb.msg.debug(2, bb.msg.domain.Provider, "selecting %s to satisfy runtime %s" % (fn, item))
             if self.tryBuild(fn, item, buildAllDeps):
                 return True
 
-        bb.error("No buildable providers for runtime %s" % item)
+        bb.msg.error(bb.msg.domain.Provider, "No buildable providers for runtime %s" % item)
         bb.event.fire(bb.event.NoProvider(item,self.configuration.data))
         return False
 
@@ -724,7 +720,7 @@ class BBCooker:
         if fn in self.status.runrecs and item in self.status.runrecs[fn]:
             rdepends += self.status.runrecs[fn][item].keys()
 
-        bb.debug(2, "Additional runtime dependencies for %s are: %s" % (item, " ".join(rdepends)))
+        bb.msg.debug(2, bb.msg.domain.Provider, "Additional runtime dependencies for %s are: %s" % (item, " ".join(rdepends)))
 
         for rdepend in rdepends:
             if rdepend in self.status.ignored_dependencies:
@@ -750,7 +746,7 @@ class BBCooker:
         for p in (bb.data.getVar('PREFERRED_PROVIDERS', localdata, 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]))
+                bb.msg.error(bb.msg.domain.Provider, "conflicting preferences for %s: both %s and %s specified" % (providee, provider, self.preferred[providee]))
             self.preferred[providee] = provider
 
         # Calculate priorities for each file
@@ -763,19 +759,19 @@ class BBCooker:
         """
         all_depends = self.status.all_depends
         pn_provides = self.status.pn_provides
-        bb.debug(1, "collating packages for \"world\"")
+        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.debug(2, "skipping %s due to %s provider starting with virtual/" % (f, p))
+                    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.debug(2, "skipping %s due to both us and %s providing %s" % (f, pf, p))
+                        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:
@@ -790,8 +786,6 @@ class BBCooker:
 
         self.status.handle_bb_data(f, bb_cache, from_cache)
 
-        if bbdebug > 0:
-            return
         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()
@@ -808,7 +802,7 @@ class BBCooker:
         try:
             from bb import shell
         except ImportError, details:
-            bb.fatal("Sorry, shell not available (%s)" % details )
+            bb.msg.fatal(bb.msg.domain.Parsing, "Sorry, shell not available (%s)" % details )
         else:
             bb.data.update_data( self.configuration.data )
             shell.start( self )
@@ -833,9 +827,9 @@ class BBCooker:
                     bb.event.register(var,bb.data.getVar(var, data))
 
         except IOError:
-            bb.fatal( "Unable to open %s" % afile )
+            bb.msg.fatal(bb.msg.domain.Parsing, "Unable to open %s" % afile )
         except bb.parse.ParseError, details:
-            bb.fatal( "Unable to parse %s (%s)" % (afile, details) )
+            bb.msg.fatal(bb.msg.domain.Parsing, "Unable to parse %s (%s)" % (afile, details) )
 
     def handleCollections( self, collections ):
         """Handle collections"""
@@ -844,22 +838,22 @@ class BBCooker:
             for c in collection_list:
                 regex = bb.data.getVar("BBFILE_PATTERN_%s" % c, self.configuration.data, 1)
                 if regex == None:
-                    bb.error("BBFILE_PATTERN_%s not defined" % c)
+                    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.error("BBFILE_PRIORITY_%s not defined" % c)
+                    bb.msg.error(bb.msg.domain.Parsing, "BBFILE_PRIORITY_%s not defined" % c)
                     continue
                 try:
                     cre = re.compile(regex)
                 except re.error:
-                    bb.error("BBFILE_PATTERN_%s \"%s\" is not a valid regular expression" % (c, regex))
+                    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.error("invalid value for BBFILE_PRIORITY_%s: \"%s\"" % (c, priority))
+                    bb.msg.error(bb.msg.domain.Parsing, "invalid value for BBFILE_PRIORITY_%s: \"%s\"" % (c, priority))
 
 
     def cook( self, configuration, args ):
@@ -871,11 +865,14 @@ class BBCooker:
 
         self.configuration = configuration
 
+        if self.configuration.verbose:
+            bb.msg.set_verbose(True)
+
         if not self.configuration.cmd:
             self.configuration.cmd = "build"
 
         if self.configuration.debug:
-            bb.debug_level = self.configuration.debug
+            bb.msg.set_debug_level(self.configuration.debug)
 
         self.configuration.data = bb.data.init()
 
@@ -910,13 +907,13 @@ class BBCooker:
             try:
                 bbfile_data = bb.parse.handle(bf, self.configuration.data)
             except IOError:
-                bb.fatal("Unable to open %s" % bf)
+                bb.msg.fatal(bb.msg.domain.Parsing, "Unable to open %s" % bf)
 
             item = bb.data.getVar('PN', bbfile_data, 1)
             try:
                 self.tryBuildPackage( bf, item, bbfile_data )
             except bb.build.EventException:
-                bb.error( "Build of '%s' failed" % item )
+                bb.msg.error(bb.msg.domain.Build,  "Build of '%s' failed" % item )
 
             sys.exit( self.stats.show() )
 
@@ -949,21 +946,19 @@ class BBCooker:
             try:
                 import psyco
             except ImportError:
-                if bbdebug == 0:
-                    bb.note("Psyco JIT Compiler (http://psyco.sf.net) not available. Install it to increase performance.")
+                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.collect_bbfiles )
         else:
-            bb.note("You have disabled Psyco. This decreases performance.")
+            bb.msg.note(1, bb.msg.domain.Collection, "You have disabled Psyco. This decreases performance.")
 
         try:
-            bb.debug(1, "collecting .bb files")
+            bb.msg.debug(1, bb.msg.domain.Collection, "collecting .bb files")
             self.collect_bbfiles( self.myProgressCallback )
-            bb.debug(1, "parsing complete")
-            if bbdebug == 0:
-                print
+            bb.msg.debug(1, bb.msg.domain.Collection, "parsing complete")
+            print
             if self.configuration.parse_only:
-                print "Requested parsing .bb files only.  Exiting."
+                bb.msg.note(1, bb.msg.domain.Collection, "Requested parsing .bb files only.  Exiting.")
                 return
 
 
@@ -993,7 +988,7 @@ class BBCooker:
                         # already diagnosed
                         failed = True
                 except bb.build.EventException:
-                    bb.error("Build of " + k + " failed")
+                    bb.msg.error(bb.msg.domain.Build, "Build of " + k + " failed")
                     failed = True
 
                 if failed:
@@ -1006,7 +1001,7 @@ class BBCooker:
             sys.exit( self.stats.show() )
 
         except KeyboardInterrupt:
-            print "\nNOTE: KeyboardInterrupt - Build not completed."
+            bb.msg.note(1, bb.msg.domain.Collection, "KeyboardInterrupt - Build not completed.")
             sys.exit(1)
 
     def get_bbfiles( self, path = os.getcwd() ):
@@ -1041,7 +1036,7 @@ class BBCooker:
             files = self.get_bbfiles()
 
         if not len(files):
-            bb.error("no files to build.")
+            bb.msg.error(bb.msg.domain.Collection, "no files to build.")
 
         newfiles = []
         for f in files:
@@ -1056,22 +1051,22 @@ class BBCooker:
         try:
             bbmask_compiled = re.compile(bbmask)
         except sre_constants.error:
-            bb.fatal("BBMASK is not a valid regular expression.")
+            bb.msg.fatal(bb.msg.domain.Collection, "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)
+                bb.msg.debug(1, bb.msg.domain.Collection, "bbmake: skipping %s" % f, f)
                 masked += 1
                 continue
-            debug(1, "bbmake: parsing %s" % f)
+            bb.msg.debug(1, bb.msg.domain.Collection, "bbmake: parsing %s" % f, f)
 
             # read a file's metadata
             try:
                 fromCache, skip = self.bb_cache.loadData(f, self)
                 if skip:
                     skipped += 1
-                    #bb.note("Skipping %s" % f)
+                    bb.msg.debug(2, bb.msg.domain.Collection, "Skipping %s" % f, f)
                     self.bb_cache.skip(f)
                     continue
                 elif fromCache: cached += 1
@@ -1094,20 +1089,21 @@ class BBCooker:
 
             except IOError, e:
                 self.bb_cache.remove(f)
-                bb.error("opening %s: %s" % (f, e))
+                bb.msg.error(bb.msg.domain.Collection, "opening %s: %s" % (f, e), f)
                 pass
             except KeyboardInterrupt:
                 self.bb_cache.sync()
                 raise
             except Exception, e:
                 self.bb_cache.remove(f)
-                bb.error("%s while parsing %s" % (e, f))
+                bb.msg.error(bb.msg.domain.Collection, "%s while parsing %s" % (e, f), f)
             except:
                 self.bb_cache.remove(f)
                 raise
 
         if self.cb is not None:
-            print "\rNOTE: Parsing finished. %d cached, %d parsed, %d skipped, %d masked." % ( cached, parsed, skipped, masked ),
+            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()
 

+ 1 - 1
bin/bitdoc

@@ -442,7 +442,7 @@ Create a set of html pages (documentation) for a bitbake.conf....
     options, args = parser.parse_args( sys.argv )
 
     if options.debug:
-        bb.debug_level = options.debug
+        bb.msg.set_debug_level(options.debug)
 
     return options.config, options.output
 

+ 1 - 1
classes/base.bbclass

@@ -41,7 +41,7 @@ bbdebug() {
 		exit 1
 	}
 
-	test ${@bb.debug_level} -ge $1 && {
+	test ${@bb.msg.debug_level} -ge $1 && {
 		shift
 		echo "DEBUG:" $*
 	}

+ 7 - 15
lib/bb/__init__.py

@@ -69,19 +69,16 @@ __all__ = [
 whitespace = '\t\n\x0b\x0c\r '
 lowercase = 'abcdefghijklmnopqrstuvwxyz'
 
-import sys, os, types, re, string
+import sys, os, types, re, string, bb
+from bb import msg
 
 #projectdir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
 projectdir = os.getcwd()
 
-debug_level = 0
-
 if "BBDEBUG" in os.environ:
     level = int(os.environ["BBDEBUG"])
     if level:
-        debug_level = level
-    else:
-        debug_level = 0
+        bb.msg.set_debug_level(level)
 
 class VarExpandError(Exception):
     pass
@@ -100,22 +97,17 @@ class MalformedUrl(Exception):
 #######################################################################
 #######################################################################
 
-debug_prepend = ''
-
-
 def debug(lvl, *args):
-    if debug_level >= lvl:
-        print debug_prepend + 'DEBUG:', ''.join(args)
+    bb.msg.std_debug(lvl, ''.join(args))
 
 def note(*args):
-    print debug_prepend + 'NOTE:', ''.join(args)
+    bb.msg.std_note(''.join(args))
 
 def error(*args):
-    print debug_prepend + 'ERROR:', ''.join(args)
+    bb.msg.std_error(''.join(args))
 
 def fatal(*args):
-    print debug_prepend + 'ERROR:', ''.join(args)
-    sys.exit(1)
+    bb.msg.std_fatal(''.join(args))
 
 
 #######################################################################

+ 5 - 5
lib/bb/build.py

@@ -25,7 +25,7 @@ You should have received a copy of the GNU General Public License along with
 Based on functions from the base bb module, Copyright 2003 Holger Schurig
 """
 
-from bb import debug, data, fetch, fatal, error, note, event, mkdirhier, utils
+from bb import data, fetch, fatal, error, note, event, mkdirhier, utils
 import bb, os
 
 # events
@@ -146,7 +146,7 @@ def exec_func_shell(func, d):
 
     f = open(runfile, "w")
     f.write("#!/bin/sh -e\n")
-    if bb.debug_level > 0: f.write("set -x\n")
+    if bb.msg.debug_level > 0: f.write("set -x\n")
     data.emit_env(f, d)
 
     f.write("cd %s\n" % os.getcwd())
@@ -160,7 +160,7 @@ def exec_func_shell(func, d):
     # open logs
     si = file('/dev/null', 'r')
     try:
-        if bb.debug_level > 0:
+        if bb.msg.debug_level > 0:
             so = os.popen("tee \"%s\"" % logfile, "w")
         else:
             so = file(logfile, 'w')
@@ -208,7 +208,7 @@ def exec_func_shell(func, d):
     os.close(ose[0])
 
     if ret==0:
-        if bb.debug_level > 0:
+        if bb.msg.debug_level > 0:
             os.remove(runfile)
 #            os.remove(logfile)
         return
@@ -265,7 +265,7 @@ def exec_task(task, d):
                 return 1
 
             try:
-                debug(1, "Executing task %s" % item)
+                bb.msg.debug(1, bb.msg.domain.Build, "Executing task %s" % item)
                 old_overrides = data.getVar('OVERRIDES', d, 0)
                 localdata = data.createCopy(d)
                 data.setVar('OVERRIDES', 'task_%s:%s' % (item, old_overrides), localdata)

+ 84 - 0
lib/bb/msg.py

@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+"""
+BitBake 'msg' implementation
+
+Message handling infrastructure for bitbake
+
+# 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 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.
+
+"""
+
+import os, re, bb
+from bb import utils
+
+debug_level = 0
+
+verbose = False
+
+domain = bb.utils.Enum('Depends', 'Provider', 'Build', 'Parsing', 'Collection')
+
+#
+# Message control functions
+#
+
+def set_debug_level(level):
+    bb.msg.debug_level = level
+
+def set_verbose(level):
+    bb.msg.verbose = level
+
+#
+# Message handling functions
+#
+
+def debug(level, domain, msg, fn = None):
+    std_debug(level, msg)
+
+def note(level, domain, msg, fn = None):
+    if level == 1 or verbose:
+        std_note(msg)
+
+def warn(domain, msg, fn = None):
+    std_warn(msg)
+
+def error(domain, msg, fn = None):
+    std_error(msg)
+
+def fatal(domain, msg, fn = None):
+    std_fatal(msg)
+
+#
+# Compatibility functions for the original message interface
+#
+def std_debug(lvl, msg):
+    if debug_level >= lvl:
+        print 'DEBUG: ' + msg
+
+def std_note(msg):
+    print 'NOTE: ' + msg
+
+def std_warn(msg):
+    print 'WARNING: ' + msg
+
+def std_error(msg):
+    print 'ERROR: ' + msg
+
+def std_fatal(msg):
+    print 'ERROR: ' + msg
+    sys.exit(1)
+

+ 6 - 7
lib/bb/providers.py

@@ -76,9 +76,9 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None):
         else:
             pv_str = preferred_v
         if preferred_file is None:
-            bb.note("preferred version %s of %s not available" % (pv_str, pn))
+            bb.msg.note(1, bb.msg.domain.Provider, "preferred version %s of %s not available" % (pv_str, pn))
         else:
-            bb.debug(1, "selecting %s as PREFERRED_VERSION %s of package %s" % (preferred_file, pv_str, pn))
+            bb.msg.debug(1, bb.msg.domain.Provider, "selecting %s as PREFERRED_VERSION %s of package %s" % (preferred_file, pv_str, pn))
 
     del localdata
 
@@ -101,7 +101,7 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None):
 
     return (latest,latest_f,preferred_ver, preferred_file)
 
-def filterProviders(providers, item, cfgData, dataCache, build_cache_fail, verbose):
+def filterProviders(providers, item, cfgData, dataCache, build_cache_fail):
     """
     Take a list of providers and filter/reorder according to the 
     environment variables and previous build results
@@ -117,7 +117,7 @@ def filterProviders(providers, item, cfgData, dataCache, build_cache_fail, verbo
             pkg_pn[pn] = []
         pkg_pn[pn].append(p)
 
-    bb.debug(1, "providers for %s are: %s" % (item, pkg_pn.keys()))
+    bb.msg.debug(1, bb.msg.domain.Provider, "providers for %s are: %s" % (item, pkg_pn.keys()))
 
     for pn in pkg_pn.keys():
         preferred_versions[pn] = bb.providers.findBestProvider(pn, cfgData, dataCache, pkg_pn)[2:4]
@@ -126,7 +126,7 @@ def filterProviders(providers, item, cfgData, dataCache, build_cache_fail, verbo
 
     for p in eligible:
         if p in build_cache_fail:
-            bb.debug(1, "rejecting already-failed %s" % p)
+            bb.msg.debug(1, bb.msg.domain.Provider, "rejecting already-failed %s" % p)
             eligible.remove(p)
 
     if len(eligible) == 0:
@@ -152,8 +152,7 @@ def filterProviders(providers, item, cfgData, dataCache, build_cache_fail, verbo
             else:
                 extra_chat = "Selecting already-staged %s (%s) to satisfy %s" % (pn, oldver, item)
 
-            if verbose:
-                bb.note("%s" % extra_chat)
+            bb.msg.note(2, bb.msg.domain.Provider, "%s" % extra_chat)
             eligible.remove(fn)
             eligible = [fn] + eligible
             discriminated = True

+ 2 - 2
lib/bb/shell.py

@@ -107,7 +107,7 @@ class BitBakeShellCommands:
         preferred = data.getVar( "PREFERRED_PROVIDER_%s" % item, cooker.configuration.data, 1 )
         if not preferred: preferred = item
         try:
-            lv, lf, pv, pf = bb.providers.findBestProvider(preferred, cooker.configuration.data, cooker.status, cooker.build_cache_fail, cooker.configuration.verbose)
+            lv, lf, pv, pf = bb.providers.findBestProvider(preferred, cooker.configuration.data, cooker.status, cooker.build_cache_fail)
         except KeyError:
             if item in cooker.status.providers:
                 pf = cooker.status.providers[item][0]
@@ -537,7 +537,7 @@ SRC_URI = ""
         if not preferred: preferred = item
 
         try:
-            lv, lf, pv, pf = bb.providers.findBestProvider(preferred, cooker.configuration.data, cooker.status, cooker.build_cache_fail, cooker.configuration.verbose)
+            lv, lf, pv, pf = bb.providers.findBestProvider(preferred, cooker.configuration.data, cooker.status, cooker.build_cache_fail)
         except KeyError:
             lv, lf, pv, pf = (None,)*4
 

+ 40 - 0
lib/bb/utils.py

@@ -160,3 +160,43 @@ def better_exec(code, context, text, realfile):
         _print_trace( text.split('\n'), line )
         
         raise
+
+def Enum(*names):
+   """
+   A simple class to give Enum support
+   """
+
+   assert names, "Empty enums are not supported"
+
+   class EnumClass(object):
+      __slots__ = names
+      def __iter__(self):        return iter(constants)
+      def __len__(self):         return len(constants)
+      def __getitem__(self, i):  return constants[i]
+      def __repr__(self):        return 'Enum' + str(names)
+      def __str__(self):         return 'enum ' + str(constants)
+
+   class EnumValue(object):
+      __slots__ = ('__value')
+      def __init__(self, value): self.__value = value
+      Value = property(lambda self: self.__value)
+      EnumType = property(lambda self: EnumType)
+      def __hash__(self):        return hash(self.__value)
+      def __cmp__(self, other):
+         # C fans might want to remove the following assertion
+         # to make all enums comparable by ordinal value {;))
+         assert self.EnumType is other.EnumType, "Only values from the same enum are comparable"
+         return cmp(self.__value, other.__value)
+      def __invert__(self):      return constants[maximum - self.__value]
+      def __nonzero__(self):     return bool(self.__value)
+      def __repr__(self):        return str(names[self.__value])
+
+   maximum = len(names) - 1
+   constants = [None] * len(names)
+   for i, each in enumerate(names):
+      val = EnumValue(i)
+      setattr(EnumClass, each, val)
+      constants[i] = val
+   constants = tuple(constants)
+   EnumType = EnumClass()
+   return EnumType