diff options
Diffstat (limited to 'lib/bb/providers.py')
-rw-r--r-- | lib/bb/providers.py | 120 |
1 files changed, 72 insertions, 48 deletions
diff --git a/lib/bb/providers.py b/lib/bb/providers.py index f80963cb4..e11a4637d 100644 --- a/lib/bb/providers.py +++ b/lib/bb/providers.py @@ -38,16 +38,17 @@ def findProviders(cfgData, dataCache, pkg_pn = None): localdata = data.createCopy(cfgData) bb.data.expandKeys(localdata) + required = {} preferred_versions = {} latest_versions = {} for pn in pkg_pn: - (last_ver, last_file, pref_ver, pref_file) = findBestProvider(pn, localdata, dataCache, pkg_pn) + (last_ver, last_file, pref_ver, pref_file, req) = findBestProvider(pn, localdata, dataCache, pkg_pn) preferred_versions[pn] = (pref_ver, pref_file) latest_versions[pn] = (last_ver, last_file) + required[pn] = req - return (latest_versions, preferred_versions) - + return (latest_versions, preferred_versions, required) def allProviders(dataCache): """ @@ -59,7 +60,6 @@ def allProviders(dataCache): all_providers[pn].append((ver, fn)) return all_providers - def sortPriorities(pn, dataCache, pkg_pn = None): """ Reorder pkg_pn by file priority and default preference @@ -87,34 +87,58 @@ def sortPriorities(pn, dataCache, pkg_pn = None): return tmp_pn +def versionVariableMatch(cfgData, keyword, pn): + """ + Return the value of the <keyword>_VERSION variable if set. + """ + + # pn can contain '_', e.g. gcc-cross-x86_64 and an override cannot + # hence we do this manually rather than use OVERRIDES + ver = cfgData.getVar("%s_VERSION:pn-%s" % (keyword, pn)) + if not ver: + ver = cfgData.getVar("%s_VERSION_%s" % (keyword, pn)) + if not ver: + ver = cfgData.getVar("%s_VERSION" % keyword) + + return ver + def preferredVersionMatch(pe, pv, pr, preferred_e, preferred_v, preferred_r): """ Check if the version pe,pv,pr is the preferred one. If there is preferred version defined and ends with '%', then pv has to start with that version after removing the '%' """ - if (pr == preferred_r or preferred_r == None): - if (pe == preferred_e or preferred_e == None): + if pr == preferred_r or preferred_r is None: + if pe == preferred_e or preferred_e is None: if preferred_v == pv: return True - if preferred_v != None and preferred_v.endswith('%') and pv.startswith(preferred_v[:len(preferred_v)-1]): + if preferred_v is not None and preferred_v.endswith('%') and pv.startswith(preferred_v[:len(preferred_v)-1]): return True return False def findPreferredProvider(pn, cfgData, dataCache, pkg_pn = None, item = None): """ - Find the first provider in pkg_pn with a PREFERRED_VERSION set. + Find the first provider in pkg_pn with REQUIRED_VERSION or PREFERRED_VERSION set. """ preferred_file = None preferred_ver = None + required = False - # pn can contain '_', e.g. gcc-cross-x86_64 and an override cannot - # hence we do this manually rather than use OVERRIDES - preferred_v = cfgData.getVar("PREFERRED_VERSION_pn-%s" % pn) - if not preferred_v: - preferred_v = cfgData.getVar("PREFERRED_VERSION_%s" % pn) - if not preferred_v: - preferred_v = cfgData.getVar("PREFERRED_VERSION") + required_v = versionVariableMatch(cfgData, "REQUIRED", pn) + preferred_v = versionVariableMatch(cfgData, "PREFERRED", pn) + + itemstr = "" + if item: + itemstr = " (for item %s)" % item + + if required_v is not None: + if preferred_v is not None: + logger.warning("REQUIRED_VERSION and PREFERRED_VERSION for package %s%s are both set using REQUIRED_VERSION %s", pn, itemstr, required_v) + else: + logger.debug("REQUIRED_VERSION is set for package %s%s", pn, itemstr) + # REQUIRED_VERSION always takes precedence over PREFERRED_VERSION + preferred_v = required_v + required = True if preferred_v: m = re.match(r'(\d+:)*(.*)(_.*)*', preferred_v) @@ -147,11 +171,9 @@ def findPreferredProvider(pn, cfgData, dataCache, pkg_pn = None, item = None): pv_str = preferred_v if not (preferred_e is None): pv_str = '%s:%s' % (preferred_e, pv_str) - itemstr = "" - if item: - itemstr = " (for item %s)" % item if preferred_file is None: - logger.info("preferred version %s of %s not available%s", pv_str, pn, itemstr) + if not required: + logger.warning("preferred version %s of %s not available%s", pv_str, pn, itemstr) available_vers = [] for file_set in pkg_pn: for f in file_set: @@ -163,12 +185,16 @@ def findPreferredProvider(pn, cfgData, dataCache, pkg_pn = None, item = None): available_vers.append(ver_str) if available_vers: available_vers.sort() - logger.info("versions of %s available: %s", pn, ' '.join(available_vers)) + logger.warning("versions of %s available: %s", pn, ' '.join(available_vers)) + if required: + logger.error("required version %s of %s not available%s", pv_str, pn, itemstr) else: - logger.debug(1, "selecting %s as PREFERRED_VERSION %s of package %s%s", preferred_file, pv_str, pn, itemstr) - - return (preferred_ver, preferred_file) + if required: + logger.debug("selecting %s as REQUIRED_VERSION %s of package %s%s", preferred_file, pv_str, pn, itemstr) + else: + logger.debug("selecting %s as PREFERRED_VERSION %s of package %s%s", preferred_file, pv_str, pn, itemstr) + return (preferred_ver, preferred_file, required) def findLatestProvider(pn, cfgData, dataCache, file_set): """ @@ -189,7 +215,6 @@ def findLatestProvider(pn, cfgData, dataCache, file_set): return (latest, latest_f) - def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None): """ If there is a PREFERRED_VERSION, find the highest-priority bbfile @@ -198,17 +223,16 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None): """ sortpkg_pn = sortPriorities(pn, dataCache, pkg_pn) - # Find the highest priority provider with a PREFERRED_VERSION set - (preferred_ver, preferred_file) = findPreferredProvider(pn, cfgData, dataCache, sortpkg_pn, item) + # Find the highest priority provider with a REQUIRED_VERSION or PREFERRED_VERSION set + (preferred_ver, preferred_file, required) = findPreferredProvider(pn, cfgData, dataCache, sortpkg_pn, item) # Find the latest version of the highest priority provider (latest, latest_f) = findLatestProvider(pn, cfgData, dataCache, sortpkg_pn[0]) - if preferred_file is None: + if not required and preferred_file is None: preferred_file = latest_f preferred_ver = latest - return (latest, latest_f, preferred_ver, preferred_file) - + return (latest, latest_f, preferred_ver, preferred_file, required) def _filterProviders(providers, item, cfgData, dataCache): """ @@ -232,12 +256,15 @@ def _filterProviders(providers, item, cfgData, dataCache): pkg_pn[pn] = [] pkg_pn[pn].append(p) - logger.debug(1, "providers for %s are: %s", item, list(sorted(pkg_pn.keys()))) + logger.debug("providers for %s are: %s", item, list(sorted(pkg_pn.keys()))) - # First add PREFERRED_VERSIONS + # First add REQUIRED_VERSIONS or PREFERRED_VERSIONS for pn in sorted(pkg_pn): sortpkg_pn[pn] = sortPriorities(pn, dataCache, pkg_pn) - preferred_versions[pn] = findPreferredProvider(pn, cfgData, dataCache, sortpkg_pn[pn], item) + preferred_ver, preferred_file, required = findPreferredProvider(pn, cfgData, dataCache, sortpkg_pn[pn], item) + if required and preferred_file is None: + return eligible + preferred_versions[pn] = (preferred_ver, preferred_file) if preferred_versions[pn][1]: eligible.append(preferred_versions[pn][1]) @@ -248,9 +275,8 @@ def _filterProviders(providers, item, cfgData, dataCache): preferred_versions[pn] = findLatestProvider(pn, cfgData, dataCache, sortpkg_pn[pn][0]) eligible.append(preferred_versions[pn][1]) - if len(eligible) == 0: - logger.error("no eligible providers for %s", item) - return 0 + if not eligible: + return eligible # If pn == item, give it a slight default preference # This means PREFERRED_PROVIDER_foobar defaults to foobar if available @@ -266,7 +292,6 @@ def _filterProviders(providers, item, cfgData, dataCache): return eligible - def filterProviders(providers, item, cfgData, dataCache): """ Take a list of providers and filter/reorder according to the @@ -291,7 +316,7 @@ def filterProviders(providers, item, cfgData, dataCache): foundUnique = True break - logger.debug(1, "sorted providers for %s are: %s", item, eligible) + logger.debug("sorted providers for %s are: %s", item, eligible) return eligible, foundUnique @@ -333,7 +358,7 @@ def filterProvidersRunTime(providers, item, cfgData, dataCache): provides = dataCache.pn_provides[pn] for provide in provides: prefervar = cfgData.getVar('PREFERRED_PROVIDER_%s' % provide) - #logger.debug(1, "checking PREFERRED_PROVIDER_%s (value %s) against %s", provide, prefervar, pns.keys()) + #logger.debug("checking PREFERRED_PROVIDER_%s (value %s) against %s", provide, prefervar, pns.keys()) if prefervar in pns and pns[prefervar] not in preferred: var = "PREFERRED_PROVIDER_%s = %s" % (provide, prefervar) logger.verbose("selecting %s to satisfy runtime %s due to %s", prefervar, item, var) @@ -349,7 +374,7 @@ def filterProvidersRunTime(providers, item, cfgData, dataCache): if numberPreferred > 1: logger.error("Trying to resolve runtime dependency %s resulted in conflicting PREFERRED_PROVIDER entries being found.\nThe providers found were: %s\nThe PREFERRED_PROVIDER entries resulting in this conflict were: %s. You could set PREFERRED_RPROVIDER_%s" % (item, preferred, preferred_vars, item)) - logger.debug(1, "sorted runtime providers for %s are: %s", item, eligible) + logger.debug("sorted runtime providers for %s are: %s", item, eligible) return eligible, numberPreferred @@ -371,8 +396,8 @@ def getRuntimeProviders(dataCache, rdepend): return rproviders # Only search dynamic packages if we can't find anything in other variables - for pattern in dataCache.packages_dynamic: - pattern = pattern.replace(r'+', r"\+") + for pat_key in dataCache.packages_dynamic: + pattern = pat_key.replace(r'+', r"\+") if pattern in regexp_cache: regexp = regexp_cache[pattern] else: @@ -383,12 +408,11 @@ def getRuntimeProviders(dataCache, rdepend): raise regexp_cache[pattern] = regexp if regexp.match(rdepend): - rproviders += dataCache.packages_dynamic[pattern] - logger.debug(1, "Assuming %s is a dynamic package, but it may not exist" % rdepend) + rproviders += dataCache.packages_dynamic[pat_key] + logger.debug("Assuming %s is a dynamic package, but it may not exist" % rdepend) return rproviders - def buildWorldTargetList(dataCache, task=None): """ Build package list for "bitbake world" @@ -396,22 +420,22 @@ def buildWorldTargetList(dataCache, task=None): if dataCache.world_target: return - logger.debug(1, "collating packages for \"world\"") + logger.debug("collating packages for \"world\"") for f in dataCache.possible_world: terminal = True pn = dataCache.pkg_fn[f] if task and task not in dataCache.task_deps[f]['tasks']: - logger.debug(2, "World build skipping %s as task %s doesn't exist", f, task) + logger.debug2("World build skipping %s as task %s doesn't exist", f, task) terminal = False for p in dataCache.pn_provides[pn]: if p.startswith('virtual/'): - logger.debug(2, "World build skipping %s due to %s provider starting with virtual/", f, p) + logger.debug2("World build skipping %s due to %s provider starting with virtual/", f, p) terminal = False break for pf in dataCache.providers[p]: if dataCache.pkg_fn[pf] != pn: - logger.debug(2, "World build skipping %s due to both us and %s providing %s", f, pf, p) + logger.debug2("World build skipping %s due to both us and %s providing %s", f, pf, p) terminal = False break if terminal: |