summaryrefslogtreecommitdiff
path: root/bitbake/lib/bb/providers.py
diff options
context:
space:
mode:
authorRichard Purdie <richard@openedhand.com>2006-11-16 15:02:15 +0000
committerRichard Purdie <richard@openedhand.com>2006-11-16 15:02:15 +0000
commit306b7c7a9757ead077363074e7bbac2e5c03e7c5 (patch)
tree6935017a9af749c46816881c86258f514384ba1c /bitbake/lib/bb/providers.py
parent65930a38e415ae4a0182e1cea1be838e0ada50ee (diff)
downloadopenembedded-core-306b7c7a9757ead077363074e7bbac2e5c03e7c5.tar.gz
openembedded-core-306b7c7a9757ead077363074e7bbac2e5c03e7c5.tar.bz2
openembedded-core-306b7c7a9757ead077363074e7bbac2e5c03e7c5.zip
bitbake: Upgrade from 1.4 -> 1.7.4ish
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@863 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'bitbake/lib/bb/providers.py')
-rw-r--r--bitbake/lib/bb/providers.py209
1 files changed, 209 insertions, 0 deletions
diff --git a/bitbake/lib/bb/providers.py b/bitbake/lib/bb/providers.py
new file mode 100644
index 0000000000..3cb7cc1f07
--- /dev/null
+++ b/bitbake/lib/bb/providers.py
@@ -0,0 +1,209 @@
+#!/usr/bin/env python
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Copyright (C) 2003, 2004 Chris Larson
+# Copyright (C) 2003, 2004 Phil Blundell
+# Copyright (C) 2003 - 2005 Michael 'Mickey' Lauer
+# Copyright (C) 2005 Holger Hans Peter Freyther
+# Copyright (C) 2005 ROAD GmbH
+# Copyright (C) 2006 Richard Purdie
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA.
+
+import os, re
+from bb import data, utils
+import bb
+
+class NoProvider(Exception):
+ """Exception raised when no provider of a build dependency can be found"""
+
+class NoRProvider(Exception):
+ """Exception raised when no provider of a runtime dependency can be found"""
+
+def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None):
+ """
+ If there is a PREFERRED_VERSION, find the highest-priority bbfile
+ providing that version. If not, find the latest version provided by
+ an bbfile in the highest-priority set.
+ """
+ if not pkg_pn:
+ pkg_pn = dataCache.pkg_pn
+
+ files = pkg_pn[pn]
+ priorities = {}
+ for f in files:
+ priority = dataCache.bbfile_priority[f]
+ if priority not in priorities:
+ priorities[priority] = []
+ priorities[priority].append(f)
+ p_list = priorities.keys()
+ p_list.sort(lambda a, b: a - b)
+ tmp_pn = []
+ for p in p_list:
+ tmp_pn = [priorities[p]] + tmp_pn
+
+ preferred_file = None
+
+ localdata = data.createCopy(cfgData)
+ bb.data.setVar('OVERRIDES', "%s:%s" % (pn, data.getVar('OVERRIDES', localdata)), localdata)
+ bb.data.update_data(localdata)
+
+ preferred_v = bb.data.getVar('PREFERRED_VERSION_%s' % pn, localdata, True)
+ if preferred_v:
+ m = re.match('(.*)_(.*)', preferred_v)
+ if m:
+ preferred_v = m.group(1)
+ preferred_r = m.group(2)
+ else:
+ preferred_r = None
+
+ for file_set in tmp_pn:
+ for f in file_set:
+ pv,pr = dataCache.pkg_pvpr[f]
+ if preferred_v == pv and (preferred_r == pr or preferred_r == None):
+ preferred_file = f
+ preferred_ver = (pv, pr)
+ break
+ if preferred_file:
+ break;
+ if preferred_r:
+ pv_str = '%s-%s' % (preferred_v, preferred_r)
+ else:
+ pv_str = preferred_v
+ itemstr = ""
+ if item:
+ itemstr = " (for item %s)" % item
+ if preferred_file is None:
+ bb.msg.note(1, bb.msg.domain.Provider, "preferred version %s of %s not available%s" % (pv_str, pn, itemstr))
+ else:
+ bb.msg.debug(1, bb.msg.domain.Provider, "selecting %s as PREFERRED_VERSION %s of package %s%s" % (preferred_file, pv_str, pn, itemstr))
+
+ del localdata
+
+ # get highest priority file set
+ files = tmp_pn[0]
+ latest = None
+ latest_p = 0
+ latest_f = None
+ for file_name in files:
+ pv,pr = dataCache.pkg_pvpr[file_name]
+ dp = dataCache.pkg_dp[file_name]
+
+ if (latest is None) or ((latest_p == dp) and (utils.vercmp(latest, (pv, pr)) < 0)) or (dp > latest_p):
+ latest = (pv, pr)
+ latest_f = file_name
+ latest_p = dp
+ if preferred_file is None:
+ preferred_file = latest_f
+ preferred_ver = latest
+
+ return (latest,latest_f,preferred_ver, preferred_file)
+
+#
+# RP - build_cache_fail needs to move elsewhere
+#
+def filterProviders(providers, item, cfgData, dataCache, build_cache_fail = {}):
+ """
+ Take a list of providers and filter/reorder according to the
+ environment variables and previous build results
+ """
+ eligible = []
+ preferred_versions = {}
+
+ # Collate providers by PN
+ pkg_pn = {}
+ for p in providers:
+ pn = dataCache.pkg_fn[p]
+ if pn not in pkg_pn:
+ pkg_pn[pn] = []
+ pkg_pn[pn].append(p)
+
+ bb.msg.debug(1, bb.msg.domain.Provider, "providers for %s are: %s" % (item, pkg_pn.keys()))
+
+ for pn in pkg_pn.keys():
+ preferred_versions[pn] = bb.providers.findBestProvider(pn, cfgData, dataCache, pkg_pn, item)[2:4]
+ eligible.append(preferred_versions[pn][1])
+
+
+ for p in eligible:
+ if p in build_cache_fail:
+ bb.msg.debug(1, bb.msg.domain.Provider, "rejecting already-failed %s" % p)
+ eligible.remove(p)
+
+ if len(eligible) == 0:
+ bb.msg.error(bb.msg.domain.Provider, "no eligible providers for %s" % item)
+ return 0
+
+
+ # If pn == item, give it a slight default preference
+ # This means PREFERRED_PROVIDER_foobar defaults to foobar if available
+ for p in providers:
+ pn = dataCache.pkg_fn[p]
+ if pn != item:
+ continue
+ (newvers, fn) = preferred_versions[pn]
+ if not fn in eligible:
+ continue
+ eligible.remove(fn)
+ eligible = [fn] + eligible
+
+ # look to see if one of them is already staged, or marked as preferred.
+ # if so, bump it to the head of the queue
+ for p in providers:
+ pn = dataCache.pkg_fn[p]
+ pv, pr = dataCache.pkg_pvpr[p]
+
+ stamp = '%s.do_populate_staging' % dataCache.stamp[p]
+ if os.path.exists(stamp):
+ (newvers, fn) = preferred_versions[pn]
+ if not fn in eligible:
+ # package was made ineligible by already-failed check
+ continue
+ oldver = "%s-%s" % (pv, pr)
+ newver = '-'.join(newvers)
+ if (newver != oldver):
+ extra_chat = "%s (%s) already staged but upgrading to %s to satisfy %s" % (pn, oldver, newver, item)
+ else:
+ extra_chat = "Selecting already-staged %s (%s) to satisfy %s" % (pn, oldver, item)
+
+ bb.msg.note(2, bb.msg.domain.Provider, "%s" % extra_chat)
+ eligible.remove(fn)
+ eligible = [fn] + eligible
+ break
+
+ return eligible
+
+def getRuntimeProviders(dataCache, rdepend):
+ """
+ Return any providers of runtime dependency
+ """
+ rproviders = []
+
+ if rdepend in dataCache.rproviders:
+ rproviders += dataCache.rproviders[rdepend]
+
+ if rdepend in dataCache.packages:
+ rproviders += dataCache.packages[rdepend]
+
+ if rproviders:
+ return rproviders
+
+ # Only search dynamic packages if we can't find anything in other variables
+ for pattern in dataCache.packages_dynamic:
+ regexp = re.compile(pattern)
+ if regexp.match(rdepend):
+ rproviders += dataCache.packages_dynamic[pattern]
+
+ return rproviders