diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2018-11-28 17:16:14 +1300 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2018-12-03 12:20:00 +0000 |
commit | 15fb7acb7761cd0026cb4547fa8ad216123f4a10 (patch) | |
tree | 87c348cc951bc65eac9d1065c71cbad4049b0425 /meta/lib/oe | |
parent | aeb6c44af75f9cff93f748839cabade4af5bd897 (diff) | |
download | poky-15fb7acb7761cd0026cb4547fa8ad216123f4a10.tar.gz |
lib/oe/recipeutils: patch_recipe(): fix handling of values across includes/classes
If we were setting a variable and part of the variable's value was being
set in a class or a .inc file, we were still just setting the value
outright on the assumption that it was too hard to do otherwise. With
some careful use of the variable history we can do better for certain
situations i.e. when the recipe does not currently set the value
outright.
Additionally, correctly remove _appends for variables we are changing if
we're trying to remove the value added in the _append.
Fixes [YOCTO #12623] and partially fixes [YOCTO #9360].
(From OE-Core rev: f798d963db77db66a2a5a4b8d4c157d46ede417f)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib/oe')
-rw-r--r-- | meta/lib/oe/recipeutils.py | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/meta/lib/oe/recipeutils.py b/meta/lib/oe/recipeutils.py index aa64553c06..9de291f5b5 100644 --- a/meta/lib/oe/recipeutils.py +++ b/meta/lib/oe/recipeutils.py | |||
@@ -52,6 +52,29 @@ def parse_recipe(cooker, fn, appendfiles): | |||
52 | return envdata | 52 | return envdata |
53 | 53 | ||
54 | 54 | ||
55 | def simplify_history(history, d): | ||
56 | """ | ||
57 | Eliminate any irrelevant events from a variable history | ||
58 | """ | ||
59 | ret_history = [] | ||
60 | has_set = False | ||
61 | # Go backwards through the history and remove any immediate operations | ||
62 | # before the most recent set | ||
63 | for event in reversed(history): | ||
64 | if 'flag' in event or not 'file' in event: | ||
65 | continue | ||
66 | if event['op'] == 'set': | ||
67 | if has_set: | ||
68 | continue | ||
69 | has_set = True | ||
70 | elif event['op'] in ('append', 'prepend', 'postdot', 'predot'): | ||
71 | # Reminder: "append" and "prepend" mean += and =+ respectively, NOT _append / _prepend | ||
72 | if has_set: | ||
73 | continue | ||
74 | ret_history.insert(0, event) | ||
75 | return ret_history | ||
76 | |||
77 | |||
55 | def get_var_files(fn, varlist, d): | 78 | def get_var_files(fn, varlist, d): |
56 | """Find the file in which each of a list of variables is set. | 79 | """Find the file in which each of a list of variables is set. |
57 | Note: requires variable history to be enabled when parsing. | 80 | Note: requires variable history to be enabled when parsing. |
@@ -176,7 +199,14 @@ def patch_recipe_lines(fromlines, values, trailing_newline=True): | |||
176 | def outputvalue(name, lines, rewindcomments=False): | 199 | def outputvalue(name, lines, rewindcomments=False): |
177 | if values[name] is None: | 200 | if values[name] is None: |
178 | return | 201 | return |
179 | rawtext = '%s = "%s"%s' % (name, values[name], newline) | 202 | if isinstance(values[name], tuple): |
203 | op, value = values[name] | ||
204 | if op == '+=' and value.strip() == '': | ||
205 | return | ||
206 | else: | ||
207 | value = values[name] | ||
208 | op = '=' | ||
209 | rawtext = '%s %s "%s"%s' % (name, op, value, newline) | ||
180 | addlines = [] | 210 | addlines = [] |
181 | nowrap = False | 211 | nowrap = False |
182 | for nowrap_re in nowrap_vars_res: | 212 | for nowrap_re in nowrap_vars_res: |
@@ -186,10 +216,10 @@ def patch_recipe_lines(fromlines, values, trailing_newline=True): | |||
186 | if nowrap: | 216 | if nowrap: |
187 | addlines.append(rawtext) | 217 | addlines.append(rawtext) |
188 | elif name in list_vars: | 218 | elif name in list_vars: |
189 | splitvalue = split_var_value(values[name], assignment=False) | 219 | splitvalue = split_var_value(value, assignment=False) |
190 | if len(splitvalue) > 1: | 220 | if len(splitvalue) > 1: |
191 | linesplit = ' \\\n' + (' ' * (len(name) + 4)) | 221 | linesplit = ' \\\n' + (' ' * (len(name) + 4)) |
192 | addlines.append('%s = "%s%s"%s' % (name, linesplit.join(splitvalue), linesplit, newline)) | 222 | addlines.append('%s %s "%s%s"%s' % (name, op, linesplit.join(splitvalue), linesplit, newline)) |
193 | else: | 223 | else: |
194 | addlines.append(rawtext) | 224 | addlines.append(rawtext) |
195 | else: | 225 | else: |
@@ -321,12 +351,47 @@ def patch_recipe(d, fn, varvalues, patch=False, relpath='', redirect_output=None | |||
321 | """Modify a list of variable values in the specified recipe. Handles inc files if | 351 | """Modify a list of variable values in the specified recipe. Handles inc files if |
322 | used by the recipe. | 352 | used by the recipe. |
323 | """ | 353 | """ |
354 | overrides = d.getVar('OVERRIDES').split(':') | ||
355 | def override_applicable(hevent): | ||
356 | op = hevent['op'] | ||
357 | if '[' in op: | ||
358 | opoverrides = op.split('[')[1].split(']')[0].split('_') | ||
359 | for opoverride in opoverrides: | ||
360 | if not opoverride in overrides: | ||
361 | return False | ||
362 | return True | ||
363 | |||
324 | varlist = varvalues.keys() | 364 | varlist = varvalues.keys() |
365 | fn = os.path.abspath(fn) | ||
325 | varfiles = get_var_files(fn, varlist, d) | 366 | varfiles = get_var_files(fn, varlist, d) |
326 | locs = localise_file_vars(fn, varfiles, varlist) | 367 | locs = localise_file_vars(fn, varfiles, varlist) |
327 | patches = [] | 368 | patches = [] |
328 | for f,v in locs.items(): | 369 | for f,v in locs.items(): |
329 | vals = {k: varvalues[k] for k in v} | 370 | vals = {k: varvalues[k] for k in v} |
371 | f = os.path.abspath(f) | ||
372 | if f == fn: | ||
373 | extravals = {} | ||
374 | for var, value in vals.items(): | ||
375 | if var in list_vars: | ||
376 | history = simplify_history(d.varhistory.variable(var), d) | ||
377 | recipe_set = False | ||
378 | for event in history: | ||
379 | if os.path.abspath(event['file']) == fn: | ||
380 | if event['op'] == 'set': | ||
381 | recipe_set = True | ||
382 | if not recipe_set: | ||
383 | for event in history: | ||
384 | if event['op'].startswith('_remove'): | ||
385 | continue | ||
386 | if not override_applicable(event): | ||
387 | continue | ||
388 | newvalue = value.replace(event['detail'], '') | ||
389 | if newvalue == value and os.path.abspath(event['file']) == fn and event['op'].startswith('_'): | ||
390 | op = event['op'].replace('[', '_').replace(']', '') | ||
391 | extravals[var + op] = None | ||
392 | value = newvalue | ||
393 | vals[var] = ('+=', value) | ||
394 | vals.update(extravals) | ||
330 | patchdata = patch_recipe_file(f, vals, patch, relpath, redirect_output) | 395 | patchdata = patch_recipe_file(f, vals, patch, relpath, redirect_output) |
331 | if patch: | 396 | if patch: |
332 | patches.append(patchdata) | 397 | patches.append(patchdata) |