summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitbake/ChangeLog9
-rw-r--r--bitbake/lib/bb/__init__.py9
-rw-r--r--bitbake/lib/bb/cache.py5
-rw-r--r--bitbake/lib/bb/cooker.py13
-rw-r--r--bitbake/lib/bb/fetch/svn.py2
-rw-r--r--bitbake/lib/bb/parse/parse_py/BBHandler.py2
-rw-r--r--bitbake/lib/bb/providers.py94
-rw-r--r--bitbake/lib/bb/runqueue.py26
8 files changed, 130 insertions, 30 deletions
diff --git a/bitbake/ChangeLog b/bitbake/ChangeLog
index 7b99a1b054..b8ab651aa2 100644
--- a/bitbake/ChangeLog
+++ b/bitbake/ChangeLog
@@ -1,4 +1,13 @@
1Changes in BitBake 1.8.x: 1Changes in BitBake 1.8.x:
2 - Psyco is available only for x86 - do not use it on other architectures.
3 - Fix a bug in bb.decodeurl where http://some.where.com/somefile.tgz decoded to host="" (#1530)
4 - Warn about malformed PREFERRED_PROVIDERS (#1072)
5 - Add support for BB_NICE_LEVEL option (#1627)
6 - Sort initial providers list by default preference (#1145, #2024)
7 - Improve provider sorting so prefered versions have preference over latest versions (#768)
8 - Detect builds of tasks with overlapping providers and warn (will become a fatal error) (#1359)
9 - Add MULTI_PROVIDER_WHITELIST variable to allow known safe multiple providers to be listed
10 - Handle paths in svn fetcher module parameter
2 11
3Changes in Bitbake 1.8.8: 12Changes in Bitbake 1.8.8:
4 - Rewrite svn fetcher to make adding extra operations easier 13 - Rewrite svn fetcher to make adding extra operations easier
diff --git a/bitbake/lib/bb/__init__.py b/bitbake/lib/bb/__init__.py
index 77b1255c77..0460c96ff4 100644
--- a/bitbake/lib/bb/__init__.py
+++ b/bitbake/lib/bb/__init__.py
@@ -283,10 +283,11 @@ def decodeurl(url):
283 raise MalformedUrl(url) 283 raise MalformedUrl(url)
284 user = m.group('user') 284 user = m.group('user')
285 parm = m.group('parm') 285 parm = m.group('parm')
286 m = re.compile('(?P<host>[^/;]+)(?P<path>/[^;]+)').match(location) 286
287 if m: 287 locidx = location.find('/')
288 host = m.group('host') 288 if locidx != -1:
289 path = m.group('path') 289 host = location[:locidx]
290 path = location[locidx:]
290 else: 291 else:
291 host = "" 292 host = ""
292 path = location 293 path = location
diff --git a/bitbake/lib/bb/cache.py b/bitbake/lib/bb/cache.py
index 335b221979..7d7e66ebd2 100644
--- a/bitbake/lib/bb/cache.py
+++ b/bitbake/lib/bb/cache.py
@@ -39,7 +39,7 @@ except ImportError:
39 import pickle 39 import pickle
40 bb.msg.note(1, bb.msg.domain.Cache, "Importing cPickle failed. Falling back to a very slow implementation.") 40 bb.msg.note(1, bb.msg.domain.Cache, "Importing cPickle failed. Falling back to a very slow implementation.")
41 41
42__cache_version__ = "126" 42__cache_version__ = "127"
43 43
44class Cache: 44class Cache:
45 """ 45 """
@@ -286,10 +286,12 @@ class Cache:
286 cacheData.pn_provides[pn] = Set() 286 cacheData.pn_provides[pn] = Set()
287 cacheData.pn_provides[pn] |= provides 287 cacheData.pn_provides[pn] |= provides
288 288
289 cacheData.fn_provides[file_name] = Set()
289 for provide in provides: 290 for provide in provides:
290 if provide not in cacheData.providers: 291 if provide not in cacheData.providers:
291 cacheData.providers[provide] = [] 292 cacheData.providers[provide] = []
292 cacheData.providers[provide].append(file_name) 293 cacheData.providers[provide].append(file_name)
294 cacheData.fn_provides[file_name].add(provide)
293 295
294 cacheData.deps[file_name] = Set() 296 cacheData.deps[file_name] = Set()
295 for dep in depends: 297 for dep in depends:
@@ -414,6 +416,7 @@ class CacheData:
414 self.pkg_pepvpr = {} 416 self.pkg_pepvpr = {}
415 self.pkg_dp = {} 417 self.pkg_dp = {}
416 self.pn_provides = {} 418 self.pn_provides = {}
419 self.fn_provides = {}
417 self.all_depends = Set() 420 self.all_depends = Set()
418 self.deps = {} 421 self.deps = {}
419 self.rundeps = {} 422 self.rundeps = {}
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index 2ddb590c5b..c16709e552 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -85,6 +85,13 @@ class BBCooker:
85 tcattr[3] = tcattr[3] & ~termios.TOSTOP 85 tcattr[3] = tcattr[3] & ~termios.TOSTOP
86 termios.tcsetattr(fd, termios.TCSANOW, tcattr) 86 termios.tcsetattr(fd, termios.TCSANOW, tcattr)
87 87
88 # Change nice level if we're asked to
89 nice = bb.data.getVar("BB_NICE_LEVEL", self.configuration.data, True)
90 if nice:
91 curnice = os.nice(0)
92 nice = int(nice) - curnice
93 bb.msg.note(2, bb.msg.domain.Build, "Renice to %s " % os.nice(nice))
94
88 95
89 def tryBuildPackage(self, fn, item, task, the_data, build_depends): 96 def tryBuildPackage(self, fn, item, task, the_data, build_depends):
90 """ 97 """
@@ -270,7 +277,11 @@ class BBCooker:
270 277
271 # Handle PREFERRED_PROVIDERS 278 # Handle PREFERRED_PROVIDERS
272 for p in (bb.data.getVar('PREFERRED_PROVIDERS', localdata, 1) or "").split(): 279 for p in (bb.data.getVar('PREFERRED_PROVIDERS', localdata, 1) or "").split():
273 (providee, provider) = p.split(':') 280 try:
281 (providee, provider) = p.split(':')
282 except:
283 bb.msg.error(bb.msg.domain.Provider, "Malformed option in PREFERRED_PROVIDERS variable: %s" % p)
284 continue
274 if providee in self.status.preferred and self.status.preferred[providee] != provider: 285 if providee in self.status.preferred and self.status.preferred[providee] != provider:
275 bb.msg.error(bb.msg.domain.Provider, "conflicting preferences for %s: both %s and %s specified" % (providee, provider, self.status.preferred[providee])) 286 bb.msg.error(bb.msg.domain.Provider, "conflicting preferences for %s: both %s and %s specified" % (providee, provider, self.status.preferred[providee]))
276 self.status.preferred[providee] = provider 287 self.status.preferred[providee] = provider
diff --git a/bitbake/lib/bb/fetch/svn.py b/bitbake/lib/bb/fetch/svn.py
index af8543ab34..95b21fe20c 100644
--- a/bitbake/lib/bb/fetch/svn.py
+++ b/bitbake/lib/bb/fetch/svn.py
@@ -163,7 +163,7 @@ class Svn(Fetch):
163 os.chdir(ud.pkgdir) 163 os.chdir(ud.pkgdir)
164 # tar them up to a defined filename 164 # tar them up to a defined filename
165 try: 165 try:
166 runfetchcmd("tar -czf %s %s" % (ud.localpath, os.path.basename(ud.module)), d) 166 runfetchcmd("tar -czf %s %s" % (ud.localpath, ud.module), d)
167 except: 167 except:
168 t, v, tb = sys.exc_info() 168 t, v, tb = sys.exc_info()
169 try: 169 try:
diff --git a/bitbake/lib/bb/parse/parse_py/BBHandler.py b/bitbake/lib/bb/parse/parse_py/BBHandler.py
index 0f19f9a5d5..2a30e5895a 100644
--- a/bitbake/lib/bb/parse/parse_py/BBHandler.py
+++ b/bitbake/lib/bb/parse/parse_py/BBHandler.py
@@ -161,7 +161,7 @@ def handle(fn, d, include = 0):
161 if t: 161 if t:
162 data.setVar('T', t, d) 162 data.setVar('T', t, d)
163 except Exception, e: 163 except Exception, e:
164 bb.msg.debug(1, bb.msg.domain.Parsing, "executing anonymous function: %s" % e) 164 bb.msg.debug(1, bb.msg.domain.Parsing, "Exception when executing anonymous function: %s" % e)
165 raise 165 raise
166 data.delVar("__anonqueue", d) 166 data.delVar("__anonqueue", d)
167 data.delVar("__anonfunc", d) 167 data.delVar("__anonfunc", d)
diff --git a/bitbake/lib/bb/providers.py b/bitbake/lib/bb/providers.py
index e6f08fb4bd..da762d3d5b 100644
--- a/bitbake/lib/bb/providers.py
+++ b/bitbake/lib/bb/providers.py
@@ -31,12 +31,12 @@ class NoProvider(Exception):
31class NoRProvider(Exception): 31class NoRProvider(Exception):
32 """Exception raised when no provider of a runtime dependency can be found""" 32 """Exception raised when no provider of a runtime dependency can be found"""
33 33
34def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None): 34
35def sortPriorities(pn, dataCache, pkg_pn = None):
35 """ 36 """
36 If there is a PREFERRED_VERSION, find the highest-priority bbfile 37 Reorder pkg_pn by file priority and default preference
37 providing that version. If not, find the latest version provided by
38 an bbfile in the highest-priority set.
39 """ 38 """
39
40 if not pkg_pn: 40 if not pkg_pn:
41 pkg_pn = dataCache.pkg_pn 41 pkg_pn = dataCache.pkg_pn
42 42
@@ -44,14 +44,30 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
44 priorities = {} 44 priorities = {}
45 for f in files: 45 for f in files:
46 priority = dataCache.bbfile_priority[f] 46 priority = dataCache.bbfile_priority[f]
47 preference = dataCache.pkg_dp[f]
47 if priority not in priorities: 48 if priority not in priorities:
48 priorities[priority] = [] 49 priorities[priority] = {}
49 priorities[priority].append(f) 50 if preference not in priorities[priority]:
50 p_list = priorities.keys() 51 priorities[priority][preference] = []
51 p_list.sort(lambda a, b: a - b) 52 priorities[priority][preference].append(f)
53 pri_list = priorities.keys()
54 pri_list.sort(lambda a, b: a - b)
52 tmp_pn = [] 55 tmp_pn = []
53 for p in p_list: 56 for pri in pri_list:
54 tmp_pn = [priorities[p]] + tmp_pn 57 pref_list = priorities[pri].keys()
58 pref_list.sort(lambda a, b: b - a)
59 tmp_pref = []
60 for pref in pref_list:
61 tmp_pref.extend(priorities[pri][pref])
62 tmp_pn = [tmp_pref] + tmp_pn
63
64 return tmp_pn
65
66
67def findPreferredProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
68 """
69 Find the first provider in pkg_pn with a PREFERRED_VERSION set.
70 """
55 71
56 preferred_file = None 72 preferred_file = None
57 73
@@ -76,7 +92,7 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
76 preferred_e = None 92 preferred_e = None
77 preferred_r = None 93 preferred_r = None
78 94
79 for file_set in tmp_pn: 95 for file_set in pkg_pn:
80 for f in file_set: 96 for f in file_set:
81 pe,pv,pr = dataCache.pkg_pepvpr[f] 97 pe,pv,pr = dataCache.pkg_pepvpr[f]
82 if preferred_v == pv and (preferred_r == pr or preferred_r == None) and (preferred_e == pe or preferred_e == None): 98 if preferred_v == pv and (preferred_r == pr or preferred_r == None) and (preferred_e == pe or preferred_e == None):
@@ -99,14 +115,18 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
99 else: 115 else:
100 bb.msg.debug(1, bb.msg.domain.Provider, "selecting %s as PREFERRED_VERSION %s of package %s%s" % (preferred_file, pv_str, pn, itemstr)) 116 bb.msg.debug(1, bb.msg.domain.Provider, "selecting %s as PREFERRED_VERSION %s of package %s%s" % (preferred_file, pv_str, pn, itemstr))
101 117
102 del localdata 118 return (preferred_v, preferred_file)
119
103 120
104 # get highest priority file set 121def findLatestProvider(pn, cfgData, dataCache, file_set):
105 files = tmp_pn[0] 122 """
123 Return the highest version of the providers in file_set.
124 Take default preferences into account.
125 """
106 latest = None 126 latest = None
107 latest_p = 0 127 latest_p = 0
108 latest_f = None 128 latest_f = None
109 for file_name in files: 129 for file_name in file_set:
110 pe,pv,pr = dataCache.pkg_pepvpr[file_name] 130 pe,pv,pr = dataCache.pkg_pepvpr[file_name]
111 dp = dataCache.pkg_dp[file_name] 131 dp = dataCache.pkg_dp[file_name]
112 132
@@ -114,11 +134,29 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
114 latest = (pe, pv, pr) 134 latest = (pe, pv, pr)
115 latest_f = file_name 135 latest_f = file_name
116 latest_p = dp 136 latest_p = dp
137
138 return (latest, latest_f)
139
140
141def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
142 """
143 If there is a PREFERRED_VERSION, find the highest-priority bbfile
144 providing that version. If not, find the latest version provided by
145 an bbfile in the highest-priority set.
146 """
147
148 sortpkg_pn = sortPriorities(pn, dataCache, pkg_pn)
149 # Find the highest priority provider with a PREFERRED_VERSION set
150 (preferred_ver, preferred_file) = findPreferredProvider(pn, cfgData, dataCache, sortpkg_pn, item)
151 # Find the latest version of the highest priority provider
152 (latest, latest_f) = findLatestProvider(pn, cfgData, dataCache, sortpkg_pn[0])
153
117 if preferred_file is None: 154 if preferred_file is None:
118 preferred_file = latest_f 155 preferred_file = latest_f
119 preferred_ver = latest 156 preferred_ver = latest
120 157
121 return (latest,latest_f,preferred_ver, preferred_file) 158 return (latest, latest_f, preferred_ver, preferred_file)
159
122 160
123def _filterProviders(providers, item, cfgData, dataCache): 161def _filterProviders(providers, item, cfgData, dataCache):
124 """ 162 """
@@ -127,6 +165,7 @@ def _filterProviders(providers, item, cfgData, dataCache):
127 """ 165 """
128 eligible = [] 166 eligible = []
129 preferred_versions = {} 167 preferred_versions = {}
168 sortpkg_pn = {}
130 169
131 # The order of providers depends on the order of the files on the disk 170 # The order of providers depends on the order of the files on the disk
132 # up to here. Sort pkg_pn to make dependency issues reproducible rather 171 # up to here. Sort pkg_pn to make dependency issues reproducible rather
@@ -143,15 +182,24 @@ def _filterProviders(providers, item, cfgData, dataCache):
143 182
144 bb.msg.debug(1, bb.msg.domain.Provider, "providers for %s are: %s" % (item, pkg_pn.keys())) 183 bb.msg.debug(1, bb.msg.domain.Provider, "providers for %s are: %s" % (item, pkg_pn.keys()))
145 184
185 # First add PREFERRED_VERSIONS
186 for pn in pkg_pn.keys():
187 sortpkg_pn[pn] = sortPriorities(pn, dataCache, pkg_pn)
188 preferred_versions[pn] = findPreferredProvider(pn, cfgData, dataCache, sortpkg_pn[pn], item)
189 if preferred_versions[pn][1]:
190 eligible.append(preferred_versions[pn][1])
191
192 # Now add latest verisons
146 for pn in pkg_pn.keys(): 193 for pn in pkg_pn.keys():
147 preferred_versions[pn] = bb.providers.findBestProvider(pn, cfgData, dataCache, pkg_pn, item)[2:4] 194 if pn in preferred_versions and preferred_versions[pn][1]:
195 continue
196 preferred_versions[pn] = findLatestProvider(pn, cfgData, dataCache, sortpkg_pn[pn][0])
148 eligible.append(preferred_versions[pn][1]) 197 eligible.append(preferred_versions[pn][1])
149 198
150 if len(eligible) == 0: 199 if len(eligible) == 0:
151 bb.msg.error(bb.msg.domain.Provider, "no eligible providers for %s" % item) 200 bb.msg.error(bb.msg.domain.Provider, "no eligible providers for %s" % item)
152 return 0 201 return 0
153 202
154
155 # If pn == item, give it a slight default preference 203 # If pn == item, give it a slight default preference
156 # This means PREFERRED_PROVIDER_foobar defaults to foobar if available 204 # This means PREFERRED_PROVIDER_foobar defaults to foobar if available
157 for p in providers: 205 for p in providers:
@@ -192,7 +240,7 @@ def _filterProviders(providers, item, cfgData, dataCache):
192 eligible = [fn] + eligible 240 eligible = [fn] + eligible
193 break 241 break
194 242
195 return eligible, preferred_versions 243 return eligible
196 244
197 245
198def filterProviders(providers, item, cfgData, dataCache): 246def filterProviders(providers, item, cfgData, dataCache):
@@ -202,7 +250,7 @@ def filterProviders(providers, item, cfgData, dataCache):
202 Takes a "normal" target item 250 Takes a "normal" target item
203 """ 251 """
204 252
205 eligible, pref_vers = _filterProviders(providers, item, cfgData, dataCache) 253 eligible = _filterProviders(providers, item, cfgData, dataCache)
206 254
207 prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, cfgData, 1) 255 prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, cfgData, 1)
208 if prefervar: 256 if prefervar:
@@ -219,6 +267,8 @@ def filterProviders(providers, item, cfgData, dataCache):
219 foundUnique = True 267 foundUnique = True
220 break 268 break
221 269
270 bb.msg.debug(1, bb.msg.domain.Provider, "sorted providers for %s are: %s" % (item, eligible))
271
222 return eligible, foundUnique 272 return eligible, foundUnique
223 273
224def filterProvidersRunTime(providers, item, cfgData, dataCache): 274def filterProvidersRunTime(providers, item, cfgData, dataCache):
@@ -228,7 +278,7 @@ def filterProvidersRunTime(providers, item, cfgData, dataCache):
228 Takes a "runtime" target item 278 Takes a "runtime" target item
229 """ 279 """
230 280
231 eligible, pref_vers = _filterProviders(providers, item, cfgData, dataCache) 281 eligible = _filterProviders(providers, item, cfgData, dataCache)
232 282
233 # Should use dataCache.preferred here? 283 # Should use dataCache.preferred here?
234 preferred = [] 284 preferred = []
@@ -246,6 +296,8 @@ def filterProvidersRunTime(providers, item, cfgData, dataCache):
246 296
247 numberPreferred = len(preferred) 297 numberPreferred = len(preferred)
248 298
299 bb.msg.debug(1, bb.msg.domain.Provider, "sorted providers for %s are: %s" % (item, eligible))
300
249 return eligible, numberPreferred 301 return eligible, numberPreferred
250 302
251def getRuntimeProviders(dataCache, rdepend): 303def getRuntimeProviders(dataCache, rdepend):
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index 3dfae219d2..f245fd6c1d 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -7,7 +7,7 @@ BitBake 'RunQueue' implementation
7Handles preparation and execution of a queue of tasks 7Handles preparation and execution of a queue of tasks
8""" 8"""
9 9
10# Copyright (C) 2006 Richard Purdie 10# Copyright (C) 2006-2007 Richard Purdie
11# 11#
12# This program is free software; you can redistribute it and/or modify 12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License version 2 as 13# it under the terms of the GNU General Public License version 2 as
@@ -63,6 +63,7 @@ class RunQueue:
63 self.targets = targets 63 self.targets = targets
64 64
65 self.number_tasks = int(bb.data.getVar("BB_NUMBER_THREADS", cfgData) or 1) 65 self.number_tasks = int(bb.data.getVar("BB_NUMBER_THREADS", cfgData) or 1)
66 self.multi_provider_whitelist = (bb.data.getVar("MULTI_PROVIDER_WHITELIST", cfgData) or "").split()
66 67
67 def reset_runqueue(self): 68 def reset_runqueue(self):
68 69
@@ -373,6 +374,29 @@ class RunQueue:
373 if runq_weight1[task] != 0: 374 if runq_weight1[task] != 0:
374 bb.msg.fatal(bb.msg.domain.RunQueue, "Task %s (%s) count not zero!" % (task, self.get_user_idstring(task))) 375 bb.msg.fatal(bb.msg.domain.RunQueue, "Task %s (%s) count not zero!" % (task, self.get_user_idstring(task)))
375 376
377
378 # Check for mulitple taska building the same provider
379 prov_list = {}
380 seen_fn = []
381 for task in range(len(self.runq_fnid)):
382 fn = taskData.fn_index[self.runq_fnid[task]]
383 if fn in seen_fn:
384 continue
385 seen_fn.append(fn)
386 for prov in self.dataCache.fn_provides[fn]:
387 if prov not in prov_list:
388 prov_list[prov] = [fn]
389 elif fn not in prov_list[prov]:
390 prov_list[prov].append(fn)
391 error = False
392 for prov in prov_list:
393 if len(prov_list[prov]) > 1 and prov not in self.multi_provider_whitelist:
394 error = True
395 bb.msg.error(bb.msg.domain.RunQueue, "Multiple files due to be built which all provide %s (%s)" % (prov, " ".join(prov_list[prov])))
396 #if error:
397 # bb.msg.fatal(bb.msg.domain.RunQueue, "Corrupted metadata configuration detected, aborting...")
398
399
376 # Make a weight sorted map 400 # Make a weight sorted map
377 from copy import deepcopy 401 from copy import deepcopy
378 402