diff options
Diffstat (limited to 'meta/lib/oe/copy_buildsystem.py')
-rw-r--r-- | meta/lib/oe/copy_buildsystem.py | 105 |
1 files changed, 81 insertions, 24 deletions
diff --git a/meta/lib/oe/copy_buildsystem.py b/meta/lib/oe/copy_buildsystem.py index 4d3faf6681..a0d829054e 100644 --- a/meta/lib/oe/copy_buildsystem.py +++ b/meta/lib/oe/copy_buildsystem.py @@ -1,14 +1,30 @@ +# +# Copyright OpenEmbedded Contributors +# +# SPDX-License-Identifier: GPL-2.0-only +# # This class should provide easy access to the different aspects of the # buildsystem such as layers, bitbake location, etc. +# +# SDK_LAYERS_EXCLUDE: Layers which will be excluded from SDK layers. +# SDK_LAYERS_EXCLUDE_PATTERN: The simiar to SDK_LAYERS_EXCLUDE, this supports +# python regular expression, use space as separator, +# e.g.: ".*-downloads closed-.*" +# + import stat import shutil def _smart_copy(src, dest): + import subprocess # smart_copy will choose the correct function depending on whether the # source is a file or a directory. mode = os.stat(src).st_mode if stat.S_ISDIR(mode): - shutil.copytree(src, dest, symlinks=True, ignore=shutil.ignore_patterns('.git')) + bb.utils.mkdirhier(dest) + cmd = "tar --exclude='.git' --exclude='__pycache__' --xattrs --xattrs-include='*' -chf - -C %s -p . \ + | tar --xattrs --xattrs-include='*' -xf - -C %s" % (src, dest) + subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT) else: shutil.copyfile(src, dest) shutil.copymode(src, dest) @@ -17,23 +33,39 @@ class BuildSystem(object): def __init__(self, context, d): self.d = d self.context = context - self.layerdirs = d.getVar('BBLAYERS', True).split() - self.layers_exclude = (d.getVar('SDK_LAYERS_EXCLUDE', True) or "").split() + self.layerdirs = [os.path.abspath(pth) for pth in d.getVar('BBLAYERS').split()] + self.layers_exclude = (d.getVar('SDK_LAYERS_EXCLUDE') or "").split() + self.layers_exclude_pattern = d.getVar('SDK_LAYERS_EXCLUDE_PATTERN') def copy_bitbake_and_layers(self, destdir, workspace_name=None): + import re # Copy in all metadata layers + bitbake (as repositories) + copied_corebase = None layers_copied = [] bb.utils.mkdirhier(destdir) layers = list(self.layerdirs) - corebase = self.d.getVar('COREBASE', True) + corebase = os.path.abspath(self.d.getVar('COREBASE')) layers.append(corebase) + # The bitbake build system uses the meta-skeleton layer as a layout + # for common recipies, e.g: the recipetool script to create kernel recipies + # Add the meta-skeleton layer to be included as part of the eSDK installation + layers.append(os.path.join(corebase, 'meta-skeleton')) # Exclude layers for layer_exclude in self.layers_exclude: if layer_exclude in layers: + bb.note('Excluded %s from sdk layers since it is in SDK_LAYERS_EXCLUDE' % layer_exclude) layers.remove(layer_exclude) + if self.layers_exclude_pattern: + layers_cp = layers[:] + for pattern in self.layers_exclude_pattern.split(): + for layer in layers_cp: + if re.match(pattern, layer): + bb.note('Excluded %s from sdk layers since matched SDK_LAYERS_EXCLUDE_PATTERN' % layer) + layers.remove(layer) + workspace_newname = workspace_name if workspace_newname: layernames = [os.path.basename(layer) for layer in layers] @@ -42,7 +74,7 @@ class BuildSystem(object): extranum += 1 workspace_newname = '%s-%d' % (workspace_name, extranum) - corebase_files = self.d.getVar('COREBASE_FILES', True).split() + corebase_files = self.d.getVar('COREBASE_FILES').split() corebase_files = [corebase + '/' +x for x in corebase_files] # Make sure bitbake goes in bitbake_dir = bb.__file__.rsplit('/', 3)[0] @@ -67,22 +99,30 @@ class BuildSystem(object): layerdestpath = destdir if corebase == os.path.dirname(layer): layerdestpath += '/' + os.path.basename(corebase) + # If the layer is located somewhere under the same parent directory + # as corebase we keep the layer structure. + elif os.path.commonpath([layer, corebase]) == os.path.dirname(corebase): + layer_relative = os.path.relpath(layer, os.path.dirname(corebase)) + if os.path.dirname(layer_relative) != layernewname: + layerdestpath += '/' + os.path.dirname(layer_relative) + layerdestpath += '/' + layernewname layer_relative = os.path.relpath(layerdestpath, destdir) - layers_copied.append(layer_relative) - # Treat corebase as special since it typically will contain # build directories or other custom items. if corebase == layer: + copied_corebase = layer_relative bb.utils.mkdirhier(layerdestpath) for f in corebase_files: f_basename = os.path.basename(f) destname = os.path.join(layerdestpath, f_basename) _smart_copy(f, destname) else: - if os.path.exists(layerdestpath): + layers_copied.append(layer_relative) + + if os.path.exists(os.path.join(layerdestpath, 'conf/layer.conf')): bb.note("Skipping layer %s, already handled" % layer) else: _smart_copy(layer, layerdestpath) @@ -96,7 +136,7 @@ class BuildSystem(object): # Drop all bbappends except the one for the image the SDK is being built for # (because of externalsrc, the workspace bbappends will interfere with the # locked signatures if present, and we don't need them anyway) - image_bbappend = os.path.splitext(os.path.basename(self.d.getVar('FILE', True)))[0] + '.bbappend' + image_bbappend = os.path.splitext(os.path.basename(self.d.getVar('FILE')))[0] + '.bbappend' appenddir = os.path.join(layerdestpath, 'appends') if os.path.isdir(appenddir): for fn in os.listdir(appenddir): @@ -119,15 +159,23 @@ class BuildSystem(object): line = line.replace('workspacelayer', workspace_newname) f.write(line) - return layers_copied + # meta-skeleton layer is added as part of the build system + # but not as a layer included in the build, therefore it is + # not reported to the function caller. + for layer in layers_copied: + if layer.endswith('/meta-skeleton'): + layers_copied.remove(layer) + break + + return copied_corebase, layers_copied def generate_locked_sigs(sigfile, d): bb.utils.mkdirhier(os.path.dirname(sigfile)) depd = d.getVar('BB_TASKDEPDATA', False) - tasks = ['%s.%s' % (v[2], v[1]) for v in depd.values()] + tasks = ['%s:%s' % (v[2], v[1]) for v in depd.values()] bb.parse.siggen.dump_lockedsigs(sigfile, tasks) -def prune_lockedsigs(excluded_tasks, excluded_targets, lockedsigs, pruned_output): +def prune_lockedsigs(excluded_tasks, excluded_targets, lockedsigs, onlynative, pruned_output): with open(lockedsigs, 'r') as infile: bb.utils.mkdirhier(os.path.dirname(pruned_output)) with open(pruned_output, 'w') as f: @@ -137,7 +185,11 @@ def prune_lockedsigs(excluded_tasks, excluded_targets, lockedsigs, pruned_output if line.endswith('\\\n'): splitval = line.strip().split(':') if not splitval[1] in excluded_tasks and not splitval[0] in excluded_targets: - f.write(line) + if onlynative: + if 'nativesdk' in splitval[0]: + f.write(line) + else: + f.write(line) else: f.write(line) invalue = False @@ -201,21 +253,25 @@ def merge_lockedsigs(copy_tasks, lockedsigs_main, lockedsigs_extra, merged_outpu write_sigs_file(merged_output, arch_order, merged) def create_locked_sstate_cache(lockedsigs, input_sstate_cache, output_sstate_cache, d, fixedlsbstring="", filterfile=None): + import shutil bb.note('Generating sstate-cache...') - nativelsbstring = d.getVar('NATIVELSBSTRING', True) - bb.process.run("gen-lockedsig-cache %s %s %s %s %s" % (lockedsigs, input_sstate_cache, output_sstate_cache, nativelsbstring, filterfile or '')) - if fixedlsbstring: + nativelsbstring = d.getVar('NATIVELSBSTRING') + bb.process.run("PYTHONDONTWRITEBYTECODE=1 gen-lockedsig-cache %s %s %s %s %s" % (lockedsigs, input_sstate_cache, output_sstate_cache, nativelsbstring, filterfile or '')) + if fixedlsbstring and nativelsbstring != fixedlsbstring: nativedir = output_sstate_cache + '/' + nativelsbstring if os.path.isdir(nativedir): destdir = os.path.join(output_sstate_cache, fixedlsbstring) - bb.utils.mkdirhier(destdir) - - dirlist = os.listdir(nativedir) - for i in dirlist: - src = os.path.join(nativedir, i) - dest = os.path.join(destdir, i) - os.rename(src, dest) + for root, _, files in os.walk(nativedir): + for fn in files: + src = os.path.join(root, fn) + dest = os.path.join(destdir, os.path.relpath(src, nativedir)) + if os.path.exists(dest): + # Already exists, and it'll be the same file, so just delete it + os.unlink(src) + else: + bb.utils.mkdirhier(os.path.dirname(dest)) + shutil.move(src, dest) def check_sstate_task_list(d, targets, filteroutfile, cmdprefix='', cwd=None, logfile=None): import subprocess @@ -228,9 +284,10 @@ def check_sstate_task_list(d, targets, filteroutfile, cmdprefix='', cwd=None, lo logparam = '-l %s' % logfile else: logparam = '' - cmd = "%sBB_SETSCENE_ENFORCE=1 PSEUDO_DISABLED=1 oe-check-sstate %s -s -o %s %s" % (cmdprefix, targets, filteroutfile, logparam) + cmd = "%sPYTHONDONTWRITEBYTECODE=1 BB_SETSCENE_ENFORCE=1 PSEUDO_DISABLED=1 oe-check-sstate %s -s -o %s %s" % (cmdprefix, targets, filteroutfile, logparam) env = dict(d.getVar('BB_ORIGENV', False)) env.pop('BUILDDIR', '') + env.pop('BBPATH', '') pathitems = env['PATH'].split(':') env['PATH'] = ':'.join([item for item in pathitems if not item.endswith('/bitbake/bin')]) bb.process.run(cmd, stderr=subprocess.STDOUT, env=env, cwd=cwd, executable='/bin/bash') |