summaryrefslogtreecommitdiffstats
path: root/bitbake-dev/lib/bb/providers.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake-dev/lib/bb/providers.py')
-rw-r--r--bitbake-dev/lib/bb/providers.py327
1 files changed, 0 insertions, 327 deletions
diff --git a/bitbake-dev/lib/bb/providers.py b/bitbake-dev/lib/bb/providers.py
deleted file mode 100644
index 8617251ca3..0000000000
--- a/bitbake-dev/lib/bb/providers.py
+++ /dev/null
@@ -1,327 +0,0 @@
1# ex:ts=4:sw=4:sts=4:et
2# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
3#
4# Copyright (C) 2003, 2004 Chris Larson
5# Copyright (C) 2003, 2004 Phil Blundell
6# Copyright (C) 2003 - 2005 Michael 'Mickey' Lauer
7# Copyright (C) 2005 Holger Hans Peter Freyther
8# Copyright (C) 2005 ROAD GmbH
9# Copyright (C) 2006 Richard Purdie
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License version 2 as
13# published by the Free Software Foundation.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License along
21# with this program; if not, write to the Free Software Foundation, Inc.,
22# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
24import re
25from bb import data, utils
26import bb
27
28class NoProvider(Exception):
29 """Exception raised when no provider of a build dependency can be found"""
30
31class NoRProvider(Exception):
32 """Exception raised when no provider of a runtime dependency can be found"""
33
34
35def sortPriorities(pn, dataCache, pkg_pn = None):
36 """
37 Reorder pkg_pn by file priority and default preference
38 """
39
40 if not pkg_pn:
41 pkg_pn = dataCache.pkg_pn
42
43 files = pkg_pn[pn]
44 priorities = {}
45 for f in files:
46 priority = dataCache.bbfile_priority[f]
47 preference = dataCache.pkg_dp[f]
48 if priority not in priorities:
49 priorities[priority] = {}
50 if preference not in priorities[priority]:
51 priorities[priority][preference] = []
52 priorities[priority][preference].append(f)
53 pri_list = priorities.keys()
54 pri_list.sort(lambda a, b: a - b)
55 tmp_pn = []
56 for pri in pri_list:
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
66def preferredVersionMatch(pe, pv, pr, preferred_e, preferred_v, preferred_r):
67 """
68 Check if the version pe,pv,pr is the preferred one.
69 If there is preferred version defined and ends with '%', then pv has to start with that version after removing the '%'
70 """
71 if (pr == preferred_r or preferred_r == None):
72 if (pe == preferred_e or preferred_e == None):
73 if preferred_v == pv:
74 return True
75 if preferred_v != None and preferred_v.endswith('%') and pv.startswith(preferred_v[:len(preferred_v)-1]):
76 return True
77 return False
78
79def findPreferredProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
80 """
81 Find the first provider in pkg_pn with a PREFERRED_VERSION set.
82 """
83
84 preferred_file = None
85 preferred_ver = None
86
87 localdata = data.createCopy(cfgData)
88 bb.data.setVar('OVERRIDES', "pn-%s:%s:%s" % (pn, pn, data.getVar('OVERRIDES', localdata)), localdata)
89 bb.data.update_data(localdata)
90
91 preferred_v = bb.data.getVar('PREFERRED_VERSION_%s' % pn, localdata, True)
92 if preferred_v:
93 m = re.match('(\d+:)*(.*)(_.*)*', preferred_v)
94 if m:
95 if m.group(1):
96 preferred_e = int(m.group(1)[:-1])
97 else:
98 preferred_e = None
99 preferred_v = m.group(2)
100 if m.group(3):
101 preferred_r = m.group(3)[1:]
102 else:
103 preferred_r = None
104 else:
105 preferred_e = None
106 preferred_r = None
107
108 for file_set in pkg_pn:
109 for f in file_set:
110 pe,pv,pr = dataCache.pkg_pepvpr[f]
111 if preferredVersionMatch(pe, pv, pr, preferred_e, preferred_v, preferred_r):
112 preferred_file = f
113 preferred_ver = (pe, pv, pr)
114 break
115 if preferred_file:
116 break;
117 if preferred_r:
118 pv_str = '%s-%s' % (preferred_v, preferred_r)
119 else:
120 pv_str = preferred_v
121 if not (preferred_e is None):
122 pv_str = '%s:%s' % (preferred_e, pv_str)
123 itemstr = ""
124 if item:
125 itemstr = " (for item %s)" % item
126 if preferred_file is None:
127 bb.msg.note(1, bb.msg.domain.Provider, "preferred version %s of %s not available%s" % (pv_str, pn, itemstr))
128 else:
129 bb.msg.debug(1, bb.msg.domain.Provider, "selecting %s as PREFERRED_VERSION %s of package %s%s" % (preferred_file, pv_str, pn, itemstr))
130
131 return (preferred_ver, preferred_file)
132
133
134def findLatestProvider(pn, cfgData, dataCache, file_set):
135 """
136 Return the highest version of the providers in file_set.
137 Take default preferences into account.
138 """
139 latest = None
140 latest_p = 0
141 latest_f = None
142 for file_name in file_set:
143 pe,pv,pr = dataCache.pkg_pepvpr[file_name]
144 dp = dataCache.pkg_dp[file_name]
145
146 if (latest is None) or ((latest_p == dp) and (utils.vercmp(latest, (pe, pv, pr)) < 0)) or (dp > latest_p):
147 latest = (pe, pv, pr)
148 latest_f = file_name
149 latest_p = dp
150
151 return (latest, latest_f)
152
153
154def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
155 """
156 If there is a PREFERRED_VERSION, find the highest-priority bbfile
157 providing that version. If not, find the latest version provided by
158 an bbfile in the highest-priority set.
159 """
160
161 sortpkg_pn = sortPriorities(pn, dataCache, pkg_pn)
162 # Find the highest priority provider with a PREFERRED_VERSION set
163 (preferred_ver, preferred_file) = findPreferredProvider(pn, cfgData, dataCache, sortpkg_pn, item)
164 # Find the latest version of the highest priority provider
165 (latest, latest_f) = findLatestProvider(pn, cfgData, dataCache, sortpkg_pn[0])
166
167 if preferred_file is None:
168 preferred_file = latest_f
169 preferred_ver = latest
170
171 return (latest, latest_f, preferred_ver, preferred_file)
172
173
174def _filterProviders(providers, item, cfgData, dataCache):
175 """
176 Take a list of providers and filter/reorder according to the
177 environment variables and previous build results
178 """
179 eligible = []
180 preferred_versions = {}
181 sortpkg_pn = {}
182
183 # The order of providers depends on the order of the files on the disk
184 # up to here. Sort pkg_pn to make dependency issues reproducible rather
185 # than effectively random.
186 providers.sort()
187
188 # Collate providers by PN
189 pkg_pn = {}
190 for p in providers:
191 pn = dataCache.pkg_fn[p]
192 if pn not in pkg_pn:
193 pkg_pn[pn] = []
194 pkg_pn[pn].append(p)
195
196 bb.msg.debug(1, bb.msg.domain.Provider, "providers for %s are: %s" % (item, pkg_pn.keys()))
197
198 # First add PREFERRED_VERSIONS
199 for pn in pkg_pn.keys():
200 sortpkg_pn[pn] = sortPriorities(pn, dataCache, pkg_pn)
201 preferred_versions[pn] = findPreferredProvider(pn, cfgData, dataCache, sortpkg_pn[pn], item)
202 if preferred_versions[pn][1]:
203 eligible.append(preferred_versions[pn][1])
204
205 # Now add latest verisons
206 for pn in sortpkg_pn.keys():
207 if pn in preferred_versions and preferred_versions[pn][1]:
208 continue
209 preferred_versions[pn] = findLatestProvider(pn, cfgData, dataCache, sortpkg_pn[pn][0])
210 eligible.append(preferred_versions[pn][1])
211
212 if len(eligible) == 0:
213 bb.msg.error(bb.msg.domain.Provider, "no eligible providers for %s" % item)
214 return 0
215
216 # If pn == item, give it a slight default preference
217 # This means PREFERRED_PROVIDER_foobar defaults to foobar if available
218 for p in providers:
219 pn = dataCache.pkg_fn[p]
220 if pn != item:
221 continue
222 (newvers, fn) = preferred_versions[pn]
223 if not fn in eligible:
224 continue
225 eligible.remove(fn)
226 eligible = [fn] + eligible
227
228 return eligible
229
230
231def filterProviders(providers, item, cfgData, dataCache):
232 """
233 Take a list of providers and filter/reorder according to the
234 environment variables and previous build results
235 Takes a "normal" target item
236 """
237
238 eligible = _filterProviders(providers, item, cfgData, dataCache)
239
240 prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, cfgData, 1)
241 if prefervar:
242 dataCache.preferred[item] = prefervar
243
244 foundUnique = False
245 if item in dataCache.preferred:
246 for p in eligible:
247 pn = dataCache.pkg_fn[p]
248 if dataCache.preferred[item] == pn:
249 bb.msg.note(2, bb.msg.domain.Provider, "selecting %s to satisfy %s due to PREFERRED_PROVIDERS" % (pn, item))
250 eligible.remove(p)
251 eligible = [p] + eligible
252 foundUnique = True
253 break
254
255 bb.msg.debug(1, bb.msg.domain.Provider, "sorted providers for %s are: %s" % (item, eligible))
256
257 return eligible, foundUnique
258
259def filterProvidersRunTime(providers, item, cfgData, dataCache):
260 """
261 Take a list of providers and filter/reorder according to the
262 environment variables and previous build results
263 Takes a "runtime" target item
264 """
265
266 eligible = _filterProviders(providers, item, cfgData, dataCache)
267
268 # Should use dataCache.preferred here?
269 preferred = []
270 preferred_vars = []
271 for p in eligible:
272 pn = dataCache.pkg_fn[p]
273 provides = dataCache.pn_provides[pn]
274 for provide in provides:
275 bb.msg.note(2, bb.msg.domain.Provider, "checking PREFERRED_PROVIDER_%s" % (provide))
276 prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % provide, cfgData, 1)
277 if prefervar == pn:
278 var = "PREFERRED_PROVIDER_%s = %s" % (provide, prefervar)
279 bb.msg.note(2, bb.msg.domain.Provider, "selecting %s to satisfy runtime %s due to %s" % (pn, item, var))
280 preferred_vars.append(var)
281 eligible.remove(p)
282 eligible = [p] + eligible
283 preferred.append(p)
284 break
285
286 numberPreferred = len(preferred)
287
288 if numberPreferred > 1:
289 bb.msg.error(bb.msg.domain.Provider, "Conflicting PREFERRED_PROVIDER entries were found which resulted in an attempt to select multiple providers (%s) for runtime dependecy %s\nThe entries resulting in this conflict were: %s" % (preferred, item, preferred_vars))
290
291 bb.msg.debug(1, bb.msg.domain.Provider, "sorted providers for %s are: %s" % (item, eligible))
292
293 return eligible, numberPreferred
294
295regexp_cache = {}
296
297def getRuntimeProviders(dataCache, rdepend):
298 """
299 Return any providers of runtime dependency
300 """
301 rproviders = []
302
303 if rdepend in dataCache.rproviders:
304 rproviders += dataCache.rproviders[rdepend]
305
306 if rdepend in dataCache.packages:
307 rproviders += dataCache.packages[rdepend]
308
309 if rproviders:
310 return rproviders
311
312 # Only search dynamic packages if we can't find anything in other variables
313 for pattern in dataCache.packages_dynamic:
314 pattern = pattern.replace('+', "\+")
315 if pattern in regexp_cache:
316 regexp = regexp_cache[pattern]
317 else:
318 try:
319 regexp = re.compile(pattern)
320 except:
321 bb.msg.error(bb.msg.domain.Provider, "Error parsing re expression: %s" % pattern)
322 raise
323 regexp_cache[pattern] = regexp
324 if regexp.match(rdepend):
325 rproviders += dataCache.packages_dynamic[pattern]
326
327 return rproviders