fix building of one .bb file (-b parametr) - fix by pb
[vuplus_bitbake] / bin / bitbake
1 #!/usr/bin/env python
2 # ex:ts=4:sw=4:sts=4:et
3 # -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4 #
5 # Copyright (C) 2003, 2004  Chris Larson
6 # Copyright (C) 2003, 2004  Phil Blundell
7 #
8 # This program is free software; you can redistribute it and/or modify it under
9 # the terms of the GNU General Public License as published by the Free Software
10 # Foundation; either version 2 of the License, or (at your option) any later
11 # version.
12
13 # This program is distributed in the hope that it will be useful, but WITHOUT
14 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16
17 # You should have received a copy of the GNU General Public License along with
18 # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 # Place, Suite 330, Boston, MA 02111-1307 USA. 
20
21 import sys, os, getopt, glob, copy, os.path, re
22 sys.path.append(os.path.join(os.path.dirname(os.path.dirname(sys.argv[0])), 'lib'))
23 import bb
24 from bb import make
25 from sets import Set
26 import itertools, optparse
27
28 parsespin = itertools.cycle( r'|/-\\' )
29
30 __version__ = 1.2
31 __build_cache_fail = []
32 __build_cache = []
33 __building_list = []
34 __build_path = []
35
36 __preferred = {}
37 __world_target = Set()
38 __ignored_dependencies = Set()
39
40 __stats = {}
41
42 bbfile_config_priorities = []
43 bbfile_priority = {}
44 bbdebug = 0
45
46 def handle_options( args ):
47     parser = optparse.OptionParser( version = "BitBake Build Tool Core version %s, %%prog version %s" % ( bb.__version__, __version__ ),
48     usage = """%prog [options] [package ...]
49
50 Executes the specified task (default is 'build') for a given set of BitBake files.
51 It expects that BBFILES is defined, which is a space seperated list of files to
52 be executed.  BBFILES does support wildcards.
53 Default BBFILES are the .bb files in the current directory.""" )
54
55     parser.add_option( "-b", "--buildfile", help = "execute the task against this .bb file, rather than a package from BBFILES.",
56                action = "store", dest = "buildfile", default = None )
57
58     parser.add_option( "-k", "--continue", help = "continue as much as possible after an error. While the target that failed, and those that depend on it, cannot be remade, the other dependencies of these targets can be processed all the same.",
59                action = "store_false", dest = "abort", default = True )
60
61     parser.add_option( "-f", "--force", help = "force run of specified cmd, regardless of stamp status",
62                action = "store_true", dest = "force", default = False )
63
64
65     parser.add_option( "-c", "--cmd", help = "Specify task to execute",
66                action = "store", dest = "cmd", default = "build" )
67
68     parser.add_option( "-r", "--read", help = "read the specified file before bitbake.conf",
69                action = "append", dest = "file", default = [] )
70
71     parser.add_option( "-v", "--verbose", help = "output more chit-chat to the terminal",
72                action = "store_true", dest = "verbose", default = False )
73     parser.add_option( "-D", "--debug", help = "Increase the debug level",
74                action = "count", dest="debug", default = 0)
75
76     parser.add_option( "-n", "--dry-run", help = "don't execute, just go through the motions",
77                action = "store_true", dest = "dry_run", default = False )
78
79     parser.add_option( "-p", "--parse-only", help = "quit after parsing the BB files (developers only)",
80                action = "store_true", dest = "parse_only", default = False )
81
82     parser.add_option( "-d", "--disable-psyco", help = "disable using the psyco just-in-time compiler (not recommended)",
83                action = "store_true", dest = "disable_psyco", default = False )
84
85     parser.add_option( "-s", "--show-versions", help = "show current and preferred versions of all packages",
86                action = "store_true", dest = "show_versions", default = False )
87
88     options, args = parser.parse_args( args )
89     return options, args[1:]
90
91 def try_build(fn, virtual):
92     if fn in __building_list:
93         bb.error("%s depends on itself (eventually)" % fn)
94         bb.error("upwards chain is: %s" % (" -> ".join(__build_path)))
95         return False
96
97     __building_list.append(fn)
98
99     the_data = make.pkgdata[fn]
100     item = bb.data.getVar('PN', the_data, 1)
101     pathstr = "%s (%s)" % (item, virtual)
102     __build_path.append(pathstr)
103
104     depends_list = (bb.data.getVar('DEPENDS', the_data, 1) or "").split()
105     if make.options.verbose:
106         bb.note("current path: %s" % (" -> ".join(__build_path)))
107         bb.note("dependencies for %s are: %s" % (item, " ".join(depends_list)))
108
109     try:
110         failed = False
111
112         depcmd = make.options.cmd
113         bbdepcmd = bb.data.getVarFlag('do_%s' % make.options.cmd, 'bbdepcmd', make.pkgdata[fn])
114         if bbdepcmd is not None:
115             if bbdepcmd == "":
116                 depcmd = None
117             else:
118                 depcmd = bbdepcmd
119
120         if depcmd:
121             oldcmd = make.options.cmd
122             make.options.cmd = depcmd
123
124         for d in depends_list:
125             if d in __ignored_dependencies:
126                 continue
127             if not depcmd:
128                 continue
129             if buildPackage(d) == 0:
130                 bb.error("dependency %s (for %s) not satisfied" % (d,item))
131                 failed = True
132                 if make.options.abort:
133                     break
134
135         if depcmd:
136             make.options.cmd = oldcmd
137
138         if failed:
139             __stats["deps"] += 1
140             return False
141
142         bb.event.fire(bb.event.PkgStarted(item, make.pkgdata[fn]))
143         try:
144             __stats["attempt"] += 1
145             if not make.options.dry_run:
146                 bb.build.exec_task('do_%s' % make.options.cmd, make.pkgdata[fn])
147             bb.event.fire(bb.event.PkgSucceeded(item, make.pkgdata[fn]))
148             __build_cache.append(fn)
149             return True
150         except bb.build.FuncFailed:
151             __stats["fail"] += 1
152             bb.error("task stack execution failed")
153             bb.event.fire(bb.event.PkgFailed(item, make.pkgdata[fn]))
154             __build_cache_fail.append(fn)
155             raise
156         except bb.build.EventException:
157             __stats["fail"] += 1
158             (type, value, traceback) = sys.exc_info()
159             e = value.event
160             bb.error("%s event exception, aborting" % bb.event.getName(e))
161             bb.event.fire(bb.event.PkgFailed(item, make.pkgdata[fn]))
162             __build_cache_fail.append(fn)
163             raise
164     finally:
165         __building_list.remove(fn)
166         __build_path.remove(pathstr)
167
168 def showVersions():
169     pkg_pn = {}
170     preferred_versions = {}
171     latest_versions = {}
172
173     for p in make.pkgdata.keys():
174         pn = bb.data.getVar('PN', make.pkgdata[p], 1)
175         if not pkg_pn.has_key(pn):
176             pkg_pn[pn] = []
177         pkg_pn[pn].append(p)
178     
179     # Sort by priority
180     for pn in pkg_pn.keys():
181         files = pkg_pn[pn]
182         priorities = {}
183         for f in files:
184             priority = bbfile_priority[f]
185             if not priorities.has_key(priority):
186                 priorities[priority] = []
187             priorities[priority].append(f)
188         p_list = priorities.keys()
189         p_list.sort(lambda a, b: a - b)
190         pkg_pn[pn] = []
191         for p in p_list:
192             pkg_pn[pn] = [ priorities[p] ] + pkg_pn[pn]
193
194     # If there is a PREFERRED_VERSION, find the highest-priority bbfile providing that
195     # version.  If not, find the latest version provided by an bbfile in the
196     # highest-priority set.
197     for pn in pkg_pn.keys():
198         preferred_file = None
199         
200         preferred_v = bb.data.getVar('PREFERRED_VERSION_%s' % pn, make.cfg, 1)
201         if preferred_v:
202             preferred_r = None
203             m = re.match('(.*)_(.*)', preferred_v)
204             if m:
205                 preferred_v = m.group(1)
206                 preferred_r = m.group(2)
207                 
208             for file_set in pkg_pn[pn]:
209                 for f in file_set:
210                     the_data = make.pkgdata[f]
211                     pv = bb.data.getVar('PV', the_data, 1)
212                     pr = bb.data.getVar('PR', the_data, 1)
213                     if preferred_v == pv and (preferred_r == pr or preferred_r == None):
214                         preferred_file = f
215                         preferred_ver = (pv, pr)
216                         break
217                 if preferred_file:
218                     break
219             if preferred_r:
220                 pv_str = '%s-%s' % (preferred_v, preferred_r)
221             else:
222                 pv_str = preferred_v
223             if preferred_file is None:
224                 bb.note("preferred version %s of %s not available" % (pv_str, pn))
225             else:
226                 bb.debug(1, "selecting %s as PREFERRED_VERSION %s of package %s" % (preferred_file, pv_str, pn))
227                
228         # get highest priority file set
229         files = pkg_pn[pn][0]
230         latest = None
231         latest_p = 0
232         latest_f = None
233         for f in files:
234             the_data = make.pkgdata[f]
235             pv = bb.data.getVar('PV', the_data, 1)
236             pr = bb.data.getVar('PR', the_data, 1)
237             dp = int(bb.data.getVar('DEFAULT_PREFERENCE', the_data, 1) or "0")
238
239             if (latest is None) or ((latest_p == dp) and (make.vercmp(latest, (pv, pr)) < 0)) or (dp > latest_p):
240                 latest = (pv, pr)
241                 latest_f = f
242                 latest_p = dp
243         if preferred_file is None:
244             preferred_file = latest_f
245             preferred_ver = latest
246             
247         preferred_versions[pn] = (preferred_ver, preferred_file)
248         latest_versions[pn] = (latest, latest_f)
249
250     pkg_list = pkg_pn.keys()
251     pkg_list.sort()
252     
253     for p in pkg_list:
254         pref = preferred_versions[p]
255         latest = latest_versions[p]
256
257         if pref != latest:
258             prefstr = pref[0][0] + "-" + pref[0][1]
259         else:
260             prefstr = ""
261
262         print "%-30s %20s %20s" % (p, latest[0][0] + "-" + latest[0][1],
263                                    prefstr)
264
265 def buildPackage(item):
266     fn = None
267
268     discriminated = False
269
270     if not providers.has_key(item):
271         bb.error("Nothing provides %s" % item)
272         return 0
273
274     all_p = providers[item]
275
276     for p in all_p:
277         if p in __build_cache:
278             bb.debug(1, "already built %s in this run\n" % p)
279             return 1
280
281     eligible = []
282     preferred_versions = {}
283
284     # Collate providers by PN
285     pkg_pn = {}
286     for p in all_p:
287         the_data = make.pkgdata[p]
288         pn = bb.data.getVar('PN', the_data, 1)
289         if not pkg_pn.has_key(pn):
290             pkg_pn[pn] = []
291         pkg_pn[pn].append(p)
292
293     bb.debug(1, "providers for %s are: %s" % (item, pkg_pn.keys()))
294
295     # Sort by priority
296     for pn in pkg_pn.keys():
297         files = pkg_pn[pn]
298         priorities = {}
299         for f in files:
300             priority = bbfile_priority[f]
301             if not priorities.has_key(priority):
302                 priorities[priority] = []
303             priorities[priority].append(f)
304         p_list = priorities.keys()
305         p_list.sort(lambda a, b: a - b)
306         pkg_pn[pn] = []
307         for p in p_list:
308             pkg_pn[pn] = [ priorities[p] ] + pkg_pn[pn]
309
310     # If there is a PREFERRED_VERSION, find the highest-priority bbfile providing that
311     # version.  If not, find the latest version provided by an bbfile in the
312     # highest-priority set.
313     for pn in pkg_pn.keys():
314         preferred_file = None
315         
316         preferred_v = bb.data.getVar('PREFERRED_VERSION_%s' % pn, make.cfg, 1)
317         if preferred_v:
318             preferred_r = None
319             m = re.match('(.*)_(.*)', preferred_v)
320             if m:
321                 preferred_v = m.group(1)
322                 preferred_r = m.group(2)
323                 
324             for file_set in pkg_pn[pn]:
325                 for f in file_set:
326                     the_data = make.pkgdata[f]
327                     pv = bb.data.getVar('PV', the_data, 1)
328                     pr = bb.data.getVar('PR', the_data, 1)
329                     if preferred_v == pv and (preferred_r == pr or preferred_r == None):
330                         preferred_file = f
331                         preferred_ver = (pv, pr)
332                         break
333                 if preferred_file:
334                     break
335             if preferred_r:
336                 pv_str = '%s-%s' % (preferred_v, preferred_r)
337             else:
338                 pv_str = preferred_v
339             if preferred_file is None:
340                 bb.note("preferred version %s of %s not available" % (pv_str, pn))
341             else:
342                 bb.debug(1, "selecting %s as PREFERRED_VERSION %s of package %s" % (preferred_file, pv_str, pn))
343                 
344         if preferred_file is None:
345             # get highest priority file set
346             files = pkg_pn[pn][0]
347             latest = None
348             latest_p = 0
349             latest_f = None
350             for f in files:
351                 the_data = make.pkgdata[f]
352                 pv = bb.data.getVar('PV', the_data, 1)
353                 pr = bb.data.getVar('PR', the_data, 1)
354                 dp = int(bb.data.getVar('DEFAULT_PREFERENCE', the_data, 1) or "0")
355
356                 if (latest is None) or ((latest_p == dp) and (make.vercmp(latest, (pv, pr)) < 0)) or (dp > latest_p):
357                     latest = (pv, pr)
358                     latest_f = f
359                     latest_p = dp
360             preferred_file = latest_f
361             preferred_ver = latest
362             
363             bb.debug(1, "selecting %s as latest version of provider %s" % (preferred_file, pn))
364
365         preferred_versions[pn] = (preferred_ver, preferred_file)
366         eligible.append(preferred_file)
367
368     for p in eligible:
369         if p in __build_cache_fail:
370             bb.debug(1, "rejecting already-failed %s" % p)
371             eligible.remove(p)
372
373     if len(eligible) == 0:
374         bb.error("no eligible providers for %s" % item)
375         return 0
376
377     # look to see if one of them is already staged, or marked as preferred.
378     # if so, bump it to the head of the queue
379     for p in all_p:
380         the_data = make.pkgdata[p]
381         pn = bb.data.getVar('PN', the_data, 1)
382         pv = bb.data.getVar('PV', the_data, 1)
383         pr = bb.data.getVar('PR', the_data, 1)
384         tmpdir = bb.data.getVar('TMPDIR', the_data, 1)
385         stamp = '%s/stamps/%s-%s-%s.do_populate_staging' % (tmpdir, pn, pv, pr)
386         if os.path.exists(stamp):
387             (newvers, fn) = preferred_versions[pn]
388             if not fn in eligible:
389                 # package was made ineligible by already-failed check
390                 continue
391             oldver = "%s-%s" % (pv, pr)
392             newver = '-'.join(newvers)
393             if (newver != oldver):
394                 extra_chat = "; upgrading from %s to %s" % (oldver, newver)
395             else:
396                 extra_chat = ""
397             if make.options.verbose:
398                 bb.note("selecting already-staged %s to satisfy %s%s" % (pn, item, extra_chat))
399             eligible.remove(fn)
400             eligible = [fn] + eligible
401             discriminated = True
402             break
403
404     prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, make.cfg, 1)
405     if prefervar:
406         __preferred[item] = prefervar
407
408     if __preferred.has_key(item):
409         for p in eligible:
410             the_data = make.pkgdata[p]
411             pn = bb.data.getVar('PN', the_data, 1)
412             if __preferred[item] == pn:
413                 if make.options.verbose:
414                     bb.note("selecting %s to satisfy %s due to PREFERRED_PROVIDERS" % (pn, item))
415                 eligible.remove(p)
416                 eligible = [p] + eligible
417                 discriminated = True
418                 break
419
420     if len(eligible) > 1 and discriminated == False:
421         providers_list = []
422         for fn in eligible:
423             providers_list.append(bb.data.getVar('PN', make.pkgdata[fn], 1))
424         bb.note("multiple providers are available (%s);" % ", ".join(providers_list))
425         bb.note("consider defining PREFERRED_PROVIDER_%s" % item)
426
427     # run through the list until we find one that we can build
428     for fn in eligible:
429         bb.debug(2, "selecting %s to satisfy %s" % (fn, item))
430         if try_build(fn, item):
431             return 1
432
433     bb.note("no buildable providers for %s" % item)
434     return 0
435
436 def build_depgraph():
437     all_depends = Set()
438     pn_provides = {}
439
440     def progress(p):
441         if bbdebug or progress.p == p: return 
442         progress.p = p
443         if os.isatty(sys.stdout.fileno()):
444             sys.stdout.write("\rNOTE: Building provider hash: [%s%s] (%02d%%)" % ( "#" * (p/5), " " * ( 20 - p/5 ), p ) )
445             sys.stdout.flush()
446         else:
447             if p == 0:
448                 sys.stdout.write("NOTE: Building provider hash, please wait...\n")
449             if p == 100:
450                 sys.stdout.write("done.\n")
451     progress.p = 0
452
453     def calc_bbfile_priority(filename):
454         for (regex, pri) in bbfile_config_priorities:
455             if regex.match(filename):
456                 return pri
457         return 0
458
459     # Handle PREFERRED_PROVIDERS
460     for p in (bb.data.getVar('PREFERRED_PROVIDERS', make.cfg, 1) or "").split():
461         (providee, provider) = p.split(':')
462         if __preferred.has_key(providee) and __preferred[providee] != provider:
463             bb.error("conflicting preferences for %s: both %s and %s specified" % (providee, provider, __preferred[providee]))
464         __preferred[providee] = provider
465
466     # Calculate priorities for each file
467     for p in make.pkgdata.keys():
468         bbfile_priority[p] = calc_bbfile_priority(p)
469     
470     n = len(make.pkgdata.keys())
471     i = 0
472
473     op = -1
474
475     bb.debug(1, "BBMAKE building providers hashes")
476
477     # Build forward and reverse provider hashes
478     # Forward: virtual -> [filenames]
479     # Reverse: PN -> [virtuals]
480     for f in make.pkgdata.keys():
481         d = make.pkgdata[f]
482
483         pn = bb.data.getVar('PN', d, 1)
484         provides = Set([pn] + (bb.data.getVar("PROVIDES", d, 1) or "").split())
485
486         if not pn_provides.has_key(pn):
487             pn_provides[pn] = Set()
488         pn_provides[pn] |= provides
489
490         for provide in provides:
491             if not providers.has_key(provide):
492                 providers[provide] = []
493             providers[provide].append(f)
494
495         deps = (bb.data.getVar("DEPENDS", d, 1) or "").split()
496         for dep in deps:
497             all_depends.add(dep)
498
499         i += 1
500         p = (100 * i) / n
501         if p != op:
502             op = p
503             progress(p)
504
505     if bbdebug == 0:
506         sys.stdout.write("\n")
507
508     # Build package list for "bitbake world"
509     bb.debug(1, "BBMAKE collating packages for \"world\"")
510     for f in make.pkgdata.keys():
511         d = make.pkgdata[f]
512         if bb.data.getVar('BROKEN', d, 1) or bb.data.getVar('EXCLUDE_FROM_WORLD', d, 1):
513             bb.debug(2, "BBMAKE skipping %s due to BROKEN/EXCLUDE_FROM_WORLD" % f)
514             continue
515         terminal = True
516         pn = bb.data.getVar('PN', d, 1)
517         for p in pn_provides[pn]:
518             if p.startswith('virtual/'):
519                 bb.debug(2, "BBMAKE skipping %s due to %s provider starting with virtual/" % (f, p))
520                 terminal = False
521                 break
522             for pf in providers[p]:
523                 if bb.data.getVar('PN', make.pkgdata[pf], 1) != pn:
524                     bb.debug(2, "BBMAKE skipping %s due to both us and %s providing %s" % (f, pf, p))
525                     terminal = False
526                     break
527         if terminal:
528             __world_target.add(pn)
529
530 def myProgressCallback( x, y, f ):
531     if bbdebug > 0:
532         return
533     if os.isatty(sys.stdout.fileno()):
534         sys.stdout.write("\rNOTE: Handling BitBake files: %s (%04d/%04d) [%2d %%]" % ( parsespin.next(), x, y, x*100/y ) )
535         sys.stdout.flush()
536     else:
537         if x == 1:
538             sys.stdout.write("Parsing .bb files, please wait...")
539             sys.stdout.flush()
540         if x == y:
541             sys.stdout.write("done.")
542             sys.stdout.flush()
543
544 def executeOneBB( fn ):
545         try:
546             d = bb.parse.handle(fn, make.cfg)
547         except IOError:
548             bb.fatal("Unable to open %s" % fn)
549
550         name = bb.data.getVar('PN', d, 1)
551         bb.event.fire(bb.event.PkgStarted(name, d))
552         try:
553             __stats["attempt"] += 1
554             if not make.options.dry_run:
555                 bb.build.exec_task('do_%s' % make.options.cmd, d)
556             bb.event.fire(bb.event.PkgSucceeded(name, d))
557             __build_cache.append(fn)
558         except bb.build.FuncFailed:
559             __stats["fail"] += 1
560             bb.error("task stack execution failed")
561             bb.event.fire(bb.event.PkgFailed(name, d))
562             __build_cache_fail.append(fn)
563         except bb.build.EventException:
564             __stats["fail"] += 1
565             (type, value, traceback) = sys.exc_info()
566             e = value.event
567             bb.error("%s event exception, aborting" % bb.event.getName(e))
568             bb.event.fire(bb.event.PkgFailed(name, d))
569             __build_cache_fail.append(fn)
570
571 #
572 # main
573 #
574
575 __stats["attempt"] = 0
576 __stats["success"] = 0
577 __stats["fail"] = 0
578 __stats["deps"] = 0
579
580 def printStats( ):
581     print "Build statistics:"
582     print "  Attempted builds: %d" % __stats["attempt"]
583     if __stats["fail"] != 0:
584         print "  Failed builds: %d" % __stats["fail"]
585     if __stats["deps"] != 0:
586         print "  Dependencies not satisfied: %d" % __stats["deps"]
587     if __stats["fail"] != 0 or __stats["deps"] != 0:
588         sys.exit(1)
589     sys.exit(0)
590
591 if __name__ == "__main__":
592
593     make.options, args = handle_options( sys.argv )
594
595     if not make.options.cmd:
596         make.options.cmd = "build"
597
598     if make.options.debug:
599         bb.debug_level = make.options.debug
600
601     make.pkgdata = {}
602     make.cfg = bb.data.init()
603     providers = {}
604
605     for f in make.options.file:
606         try:
607             make.cfg = bb.parse.handle(f, make.cfg)
608         except IOError:
609             bb.fatal("Unable to open %s" % f)
610
611     try:
612         make.cfg = bb.parse.handle(os.path.join('conf', 'bitbake.conf'), make.cfg)
613     except IOError:
614         bb.fatal("Unable to open %s" % os.path.join('conf', 'bitbake.conf'))
615
616     if not bb.data.getVar("BUILDNAME", make.cfg):
617         bb.data.setVar("BUILDNAME", os.popen('date +%Y%m%d%H%M').readline().strip(), make.cfg)
618
619     buildname = bb.data.getVar("BUILDNAME", make.cfg)
620
621     bf = make.options.buildfile
622     if bf:
623         executeOneBB( os.path.abspath(bf) )
624         printStats()
625
626     ignore = bb.data.getVar("ASSUME_PROVIDED", make.cfg, 1) or ""
627     __ignored_dependencies = ignore.split()
628
629     collections = bb.data.getVar("BBFILE_COLLECTIONS", make.cfg, 1)
630     if collections:
631         collection_list = collections.split()
632         for c in collection_list:
633             regex = bb.data.getVar("BBFILE_PATTERN_%s" % c, make.cfg, 1)
634             if regex == None:
635                 bb.error("BBFILE_PATTERN_%s not defined" % c)
636                 continue
637             priority = bb.data.getVar("BBFILE_PRIORITY_%s" % c, make.cfg, 1)
638             if priority == None:
639                 bb.error("BBFILE_PRIORITY_%s not defined" % c)
640                 continue
641             try:
642                 cre = re.compile(regex)
643             except re.error:
644                 bb.error("BBFILE_PATTERN_%s \"%s\" is not a valid regular expression" % (c, regex))
645                 continue
646             try:
647                 pri = int(priority)
648                 bbfile_config_priorities.append((cre, pri))
649             except ValueError:
650                 bb.error("invalid value for BBFILE_PRIORITY_%s: \"%s\"" % (c, priority))
651
652     pkgs_to_build = None
653     if args:
654         if not pkgs_to_build:
655             pkgs_to_build = []
656         pkgs_to_build.extend(args)
657     if not pkgs_to_build:
658             bbpkgs = bb.data.getVar('BBPKGS', make.cfg, 1)
659             if bbpkgs:
660                     pkgs_to_build = bbpkgs.split()
661     if not pkgs_to_build and not make.options.show_versions:
662             print "Nothing to do.  Use 'bitbake world' to build everything, or run 'bitbake --help'"
663             print "for usage information."
664             sys.exit(0)
665
666
667     # Import Psyco if available and not disabled
668     if not make.options.disable_psyco:
669         try:
670             import psyco
671         except ImportError:
672             if bbdebug == 0:
673                 bb.note("Psyco JIT Compiler (http://psyco.sf.net) not available. Install it to increase performance.")
674         else:
675             psyco.bind( make.collect_bbfiles )
676     else:
677         bb.note("You have disabled Psyco. This decreases performance.")
678
679     try:
680         bb.debug(1, "BBMAKE collecting .bb files")
681         make.collect_bbfiles( myProgressCallback )
682         bb.debug(1, "BBMAKE parsing complete")
683         if bbdebug == 0:
684             print
685         if make.options.parse_only:
686             print "Requested parsing .bb files only.  Exiting."
687             sys.exit(0)
688
689         build_depgraph()
690
691         if make.options.show_versions:
692             showVersions()
693             sys.exit(0)
694             
695         if 'world' in pkgs_to_build:
696             pkgs_to_build.remove('world')
697             for t in __world_target:
698                 pkgs_to_build.append(t)
699
700         bb.event.fire(bb.event.BuildStarted(buildname, pkgs_to_build, make.cfg))
701
702         for k in pkgs_to_build:
703             failed = False
704             try:
705                 if buildPackage(k) == 0:
706                     # already diagnosed
707                     failed = True
708             except bb.build.EventException:
709                 bb.error("Build of " + k + " failed")
710                 failed = True
711
712             if failed:
713                 if make.options.abort:
714                     sys.exit(1)
715
716         bb.event.fire(bb.event.BuildCompleted(buildname, pkgs_to_build, make.cfg))
717
718         printStats()
719
720     except KeyboardInterrupt:
721         print "\nNOTE: KeyboardInterrupt - Build not completed."
722         sys.exit(1)