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