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