summaryrefslogtreecommitdiffstats
path: root/import-layers/yocto-poky/bitbake/lib/bb/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'import-layers/yocto-poky/bitbake/lib/bb/utils.py')
-rw-r--r--import-layers/yocto-poky/bitbake/lib/bb/utils.py102
1 files changed, 77 insertions, 25 deletions
diff --git a/import-layers/yocto-poky/bitbake/lib/bb/utils.py b/import-layers/yocto-poky/bitbake/lib/bb/utils.py
index 3544bbe17..729848a1c 100644
--- a/import-layers/yocto-poky/bitbake/lib/bb/utils.py
+++ b/import-layers/yocto-poky/bitbake/lib/bb/utils.py
@@ -27,6 +27,8 @@ import bb
import bb.msg
import multiprocessing
import fcntl
+import imp
+import itertools
import subprocess
import glob
import fnmatch
@@ -34,12 +36,15 @@ import traceback
import errno
import signal
import ast
-from commands import getstatusoutput
+import collections
+import copy
+from subprocess import getstatusoutput
from contextlib import contextmanager
from ctypes import cdll
-
logger = logging.getLogger("BitBake.Util")
+python_extensions = [e for e, _, _ in imp.get_suffixes()]
+
def clean_context():
return {
@@ -71,7 +76,7 @@ def explode_version(s):
r.append((0, int(m.group(1))))
s = m.group(2)
continue
- if s[0] in string.letters:
+ if s[0] in string.ascii_letters:
m = alpha_regexp.match(s)
r.append((1, m.group(1)))
s = m.group(2)
@@ -188,7 +193,7 @@ def explode_dep_versions2(s):
"DEPEND1 (optional version) DEPEND2 (optional version) ..."
and return a dictionary of dependencies and versions.
"""
- r = {}
+ r = collections.OrderedDict()
l = s.replace(",", "").split()
lastdep = None
lastcmp = ""
@@ -245,6 +250,7 @@ def explode_dep_versions2(s):
if not (i in r and r[i]):
r[lastdep] = []
+ r = collections.OrderedDict(sorted(r.items(), key=lambda x: x[0]))
return r
def explode_dep_versions(s):
@@ -369,6 +375,12 @@ def _print_exception(t, value, tb, realfile, text, context):
level = level + 1
error.append("Exception: %s" % ''.join(exception))
+
+ # If the exception is from spwaning a task, let's be helpful and display
+ # the output (which hopefully includes stderr).
+ if isinstance(value, subprocess.CalledProcessError):
+ error.append("Subprocess output:")
+ error.append(value.output.decode("utf-8", errors="ignore"))
finally:
logger.error("\n".join(error))
@@ -403,8 +415,13 @@ def better_exec(code, context, text = None, realfile = "<code>", pythonexception
def simple_exec(code, context):
exec(code, get_context(), context)
-def better_eval(source, locals):
- return eval(source, get_context(), locals)
+def better_eval(source, locals, extraglobals = None):
+ ctx = get_context()
+ if extraglobals:
+ ctx = copy.copy(ctx)
+ for g in extraglobals:
+ ctx[g] = extraglobals[g]
+ return eval(source, ctx, locals)
@contextmanager
def fileslocked(files):
@@ -563,6 +580,8 @@ def preserved_envvars_exported():
'SHELL',
'TERM',
'USER',
+ 'LC_ALL',
+ 'BBSERVER',
]
def preserved_envvars():
@@ -582,14 +601,19 @@ def filter_environment(good_vars):
"""
removed_vars = {}
- for key in os.environ.keys():
+ for key in list(os.environ):
if key in good_vars:
continue
removed_vars[key] = os.environ[key]
- os.unsetenv(key)
del os.environ[key]
+ # If we spawn a python process, we need to have a UTF-8 locale, else python's file
+ # access methods will use ascii. You can't change that mode once the interpreter is
+ # started so we have to ensure a locale is set. Ideally we'd use C.UTF-8 but not all
+ # distros support that and we need to set something.
+ os.environ["LC_ALL"] = "en_US.UTF-8"
+
if removed_vars:
logger.debug(1, "Removed the following variables from the environment: %s", ", ".join(removed_vars.keys()))
@@ -629,7 +653,7 @@ def empty_environment():
"""
Remove all variables from the environment.
"""
- for s in os.environ.keys():
+ for s in list(os.environ.keys()):
os.unsetenv(s)
del os.environ[s]
@@ -818,7 +842,7 @@ def copyfile(src, dest, newmtime = None, sstat = None):
if not sstat:
sstat = os.lstat(src)
except Exception as e:
- logger.warn("copyfile: stat of %s failed (%s)" % (src, e))
+ logger.warning("copyfile: stat of %s failed (%s)" % (src, e))
return False
destexists = 1
@@ -845,7 +869,7 @@ def copyfile(src, dest, newmtime = None, sstat = None):
#os.lchown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID])
return os.lstat(dest)
except Exception as e:
- logger.warn("copyfile: failed to create symlink %s to %s (%s)" % (dest, target, e))
+ logger.warning("copyfile: failed to create symlink %s to %s (%s)" % (dest, target, e))
return False
if stat.S_ISREG(sstat[stat.ST_MODE]):
@@ -860,7 +884,7 @@ def copyfile(src, dest, newmtime = None, sstat = None):
shutil.copyfile(src, dest + "#new")
os.rename(dest + "#new", dest)
except Exception as e:
- logger.warn("copyfile: copy %s to %s failed (%s)" % (src, dest, e))
+ logger.warning("copyfile: copy %s to %s failed (%s)" % (src, dest, e))
return False
finally:
if srcchown:
@@ -871,13 +895,13 @@ def copyfile(src, dest, newmtime = None, sstat = None):
#we don't yet handle special, so we need to fall back to /bin/mv
a = getstatusoutput("/bin/cp -f " + "'" + src + "' '" + dest + "'")
if a[0] != 0:
- logger.warn("copyfile: failed to copy special file %s to %s (%s)" % (src, dest, a))
+ logger.warning("copyfile: failed to copy special file %s to %s (%s)" % (src, dest, a))
return False # failure
try:
os.lchown(dest, sstat[stat.ST_UID], sstat[stat.ST_GID])
os.chmod(dest, stat.S_IMODE(sstat[stat.ST_MODE])) # Sticky is reset on chown
except Exception as e:
- logger.warn("copyfile: failed to chown/chmod %s (%s)" % (dest, e))
+ logger.warning("copyfile: failed to chown/chmod %s (%s)" % (dest, e))
return False
if newmtime:
@@ -946,7 +970,7 @@ def contains(variable, checkvalues, truevalue, falsevalue, d):
if not val:
return falsevalue
val = set(val.split())
- if isinstance(checkvalues, basestring):
+ if isinstance(checkvalues, str):
checkvalues = set(checkvalues.split())
else:
checkvalues = set(checkvalues)
@@ -959,7 +983,7 @@ def contains_any(variable, checkvalues, truevalue, falsevalue, d):
if not val:
return falsevalue
val = set(val.split())
- if isinstance(checkvalues, basestring):
+ if isinstance(checkvalues, str):
checkvalues = set(checkvalues.split())
else:
checkvalues = set(checkvalues)
@@ -1028,7 +1052,7 @@ def exec_flat_python_func(func, *args, **kwargs):
aidx += 1
# Handle keyword arguments
context.update(kwargs)
- funcargs.extend(['%s=%s' % (arg, arg) for arg in kwargs.iterkeys()])
+ funcargs.extend(['%s=%s' % (arg, arg) for arg in kwargs.keys()])
code = 'retval = %s(%s)' % (func, ', '.join(funcargs))
comp = bb.utils.better_compile(code, '<string>', '<string>')
bb.utils.better_exec(comp, context, code, '<string>')
@@ -1057,7 +1081,7 @@ def edit_metadata(meta_lines, variables, varfunc, match_overrides=False):
newlines: list of lines up to this point. You can use
this to prepend lines before this variable setting
if you wish.
- and should return a three-element tuple:
+ and should return a four-element tuple:
newvalue: new value to substitute in, or None to drop
the variable setting entirely. (If the removal
results in two consecutive blank lines, one of the
@@ -1071,6 +1095,8 @@ def edit_metadata(meta_lines, variables, varfunc, match_overrides=False):
multi-line value to continue on the same line as
the assignment, False to indent before the first
element.
+ To clarify, if you wish not to change the value, then you
+ would return like this: return origvalue, None, 0, True
match_overrides: True to match items with _overrides on the end,
False otherwise
Returns a tuple:
@@ -1115,7 +1141,7 @@ def edit_metadata(meta_lines, variables, varfunc, match_overrides=False):
else:
varset_new = varset_start
- if isinstance(indent, (int, long)):
+ if isinstance(indent, int):
if indent == -1:
indentspc = ' ' * (len(varset_new) + 2)
else:
@@ -1183,7 +1209,7 @@ def edit_metadata(meta_lines, variables, varfunc, match_overrides=False):
in_var = None
else:
skip = False
- for (varname, var_re) in var_res.iteritems():
+ for (varname, var_re) in var_res.items():
res = var_re.match(line)
if res:
isfunc = varname.endswith('()')
@@ -1361,7 +1387,7 @@ def get_file_layer(filename, d):
# Use longest path so we handle nested layers
matchlen = 0
match = None
- for collection, regex in collection_res.iteritems():
+ for collection, regex in collection_res.items():
if len(regex) > matchlen and re.match(regex, path):
matchlen = len(regex)
match = collection
@@ -1427,9 +1453,8 @@ def set_process_name(name):
# This is nice to have for debugging, not essential
try:
libc = cdll.LoadLibrary('libc.so.6')
- buff = create_string_buffer(len(name)+1)
- buff.value = name
- libc.prctl(15, byref(buff), 0, 0, 0)
+ buf = create_string_buffer(bytes(name, 'utf-8'))
+ libc.prctl(15, byref(buf), 0, 0, 0)
except:
pass
@@ -1438,7 +1463,8 @@ def export_proxies(d):
import os
variables = ['http_proxy', 'HTTP_PROXY', 'https_proxy', 'HTTPS_PROXY',
- 'ftp_proxy', 'FTP_PROXY', 'no_proxy', 'NO_PROXY']
+ 'ftp_proxy', 'FTP_PROXY', 'no_proxy', 'NO_PROXY',
+ 'GIT_PROXY_COMMAND']
exported = False
for v in variables:
@@ -1451,3 +1477,29 @@ def export_proxies(d):
exported = True
return exported
+
+
+def load_plugins(logger, plugins, pluginpath):
+ def load_plugin(name):
+ logger.debug('Loading plugin %s' % name)
+ fp, pathname, description = imp.find_module(name, [pluginpath])
+ try:
+ return imp.load_module(name, fp, pathname, description)
+ finally:
+ if fp:
+ fp.close()
+
+ logger.debug('Loading plugins from %s...' % pluginpath)
+
+ expanded = (glob.glob(os.path.join(pluginpath, '*' + ext))
+ for ext in python_extensions)
+ files = itertools.chain.from_iterable(expanded)
+ names = set(os.path.splitext(os.path.basename(fn))[0] for fn in files)
+ for name in names:
+ if name != '__init__':
+ plugin = load_plugin(name)
+ if hasattr(plugin, 'plugin_init'):
+ obj = plugin.plugin_init(plugins)
+ plugins.append(obj or plugin)
+ else:
+ plugins.append(plugin)
OpenPOWER on IntegriCloud