Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | # This class should provide easy access to the different aspects of the |
| 2 | # buildsystem such as layers, bitbake location, etc. |
| 3 | import stat |
| 4 | import shutil |
| 5 | |
| 6 | def _smart_copy(src, dest): |
| 7 | # smart_copy will choose the correct function depending on whether the |
| 8 | # source is a file or a directory. |
| 9 | mode = os.stat(src).st_mode |
| 10 | if stat.S_ISDIR(mode): |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 11 | shutil.copytree(src, dest, symlinks=True, ignore=shutil.ignore_patterns('.git')) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 12 | else: |
| 13 | shutil.copyfile(src, dest) |
| 14 | shutil.copymode(src, dest) |
| 15 | |
| 16 | class BuildSystem(object): |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame] | 17 | def __init__(self, context, d): |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 18 | self.d = d |
Patrick Williams | f1e5d69 | 2016-03-30 15:21:19 -0500 | [diff] [blame] | 19 | self.context = context |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 20 | self.layerdirs = d.getVar('BBLAYERS', True).split() |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 21 | self.layers_exclude = (d.getVar('SDK_LAYERS_EXCLUDE', True) or "").split() |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 22 | |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 23 | def copy_bitbake_and_layers(self, destdir, workspace_name=None): |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 24 | # Copy in all metadata layers + bitbake (as repositories) |
| 25 | layers_copied = [] |
| 26 | bb.utils.mkdirhier(destdir) |
| 27 | layers = list(self.layerdirs) |
| 28 | |
| 29 | corebase = self.d.getVar('COREBASE', True) |
| 30 | layers.append(corebase) |
| 31 | |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 32 | # Exclude layers |
| 33 | for layer_exclude in self.layers_exclude: |
| 34 | if layer_exclude in layers: |
| 35 | layers.remove(layer_exclude) |
| 36 | |
| 37 | workspace_newname = workspace_name |
| 38 | if workspace_newname: |
| 39 | layernames = [os.path.basename(layer) for layer in layers] |
| 40 | extranum = 0 |
| 41 | while workspace_newname in layernames: |
| 42 | extranum += 1 |
| 43 | workspace_newname = '%s-%d' % (workspace_name, extranum) |
| 44 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 45 | corebase_files = self.d.getVar('COREBASE_FILES', True).split() |
| 46 | corebase_files = [corebase + '/' +x for x in corebase_files] |
| 47 | # Make sure bitbake goes in |
| 48 | bitbake_dir = bb.__file__.rsplit('/', 3)[0] |
| 49 | corebase_files.append(bitbake_dir) |
| 50 | |
| 51 | for layer in layers: |
| 52 | layerconf = os.path.join(layer, 'conf', 'layer.conf') |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 53 | layernewname = os.path.basename(layer) |
| 54 | workspace = False |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 55 | if os.path.exists(layerconf): |
| 56 | with open(layerconf, 'r') as f: |
| 57 | if f.readline().startswith("# ### workspace layer auto-generated by devtool ###"): |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 58 | if workspace_newname: |
| 59 | layernewname = workspace_newname |
| 60 | workspace = True |
| 61 | else: |
| 62 | bb.plain("NOTE: Excluding local workspace layer %s from %s" % (layer, self.context)) |
| 63 | continue |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 64 | |
| 65 | # If the layer was already under corebase, leave it there |
| 66 | # since layers such as meta have issues when moved. |
| 67 | layerdestpath = destdir |
| 68 | if corebase == os.path.dirname(layer): |
| 69 | layerdestpath += '/' + os.path.basename(corebase) |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 70 | layerdestpath += '/' + layernewname |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 71 | |
| 72 | layer_relative = os.path.relpath(layerdestpath, |
| 73 | destdir) |
| 74 | layers_copied.append(layer_relative) |
| 75 | |
| 76 | # Treat corebase as special since it typically will contain |
| 77 | # build directories or other custom items. |
| 78 | if corebase == layer: |
| 79 | bb.utils.mkdirhier(layerdestpath) |
| 80 | for f in corebase_files: |
| 81 | f_basename = os.path.basename(f) |
| 82 | destname = os.path.join(layerdestpath, f_basename) |
| 83 | _smart_copy(f, destname) |
| 84 | else: |
| 85 | if os.path.exists(layerdestpath): |
| 86 | bb.note("Skipping layer %s, already handled" % layer) |
| 87 | else: |
| 88 | _smart_copy(layer, layerdestpath) |
| 89 | |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 90 | if workspace: |
| 91 | # Make some adjustments original workspace layer |
| 92 | # Drop sources (recipe tasks will be locked, so we don't need them) |
| 93 | srcdir = os.path.join(layerdestpath, 'sources') |
| 94 | if os.path.isdir(srcdir): |
| 95 | shutil.rmtree(srcdir) |
| 96 | # Drop all bbappends except the one for the image the SDK is being built for |
| 97 | # (because of externalsrc, the workspace bbappends will interfere with the |
| 98 | # locked signatures if present, and we don't need them anyway) |
| 99 | image_bbappend = os.path.splitext(os.path.basename(self.d.getVar('FILE', True)))[0] + '.bbappend' |
| 100 | appenddir = os.path.join(layerdestpath, 'appends') |
| 101 | if os.path.isdir(appenddir): |
| 102 | for fn in os.listdir(appenddir): |
| 103 | if fn == image_bbappend: |
| 104 | continue |
| 105 | else: |
| 106 | os.remove(os.path.join(appenddir, fn)) |
| 107 | # Drop README |
| 108 | readme = os.path.join(layerdestpath, 'README') |
| 109 | if os.path.exists(readme): |
| 110 | os.remove(readme) |
| 111 | # Filter out comments in layer.conf and change layer name |
| 112 | layerconf = os.path.join(layerdestpath, 'conf', 'layer.conf') |
| 113 | with open(layerconf, 'r') as f: |
| 114 | origlines = f.readlines() |
| 115 | with open(layerconf, 'w') as f: |
| 116 | for line in origlines: |
| 117 | if line.startswith('#'): |
| 118 | continue |
| 119 | line = line.replace('workspacelayer', workspace_newname) |
| 120 | f.write(line) |
| 121 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 122 | return layers_copied |
| 123 | |
| 124 | def generate_locked_sigs(sigfile, d): |
| 125 | bb.utils.mkdirhier(os.path.dirname(sigfile)) |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 126 | depd = d.getVar('BB_TASKDEPDATA', False) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 127 | tasks = ['%s.%s' % (v[2], v[1]) for v in depd.itervalues()] |
| 128 | bb.parse.siggen.dump_lockedsigs(sigfile, tasks) |
| 129 | |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 130 | def prune_lockedsigs(excluded_tasks, excluded_targets, lockedsigs, pruned_output): |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 131 | with open(lockedsigs, 'r') as infile: |
| 132 | bb.utils.mkdirhier(os.path.dirname(pruned_output)) |
| 133 | with open(pruned_output, 'w') as f: |
| 134 | invalue = False |
| 135 | for line in infile: |
| 136 | if invalue: |
| 137 | if line.endswith('\\\n'): |
| 138 | splitval = line.strip().split(':') |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 139 | if not splitval[1] in excluded_tasks and not splitval[0] in excluded_targets: |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 140 | f.write(line) |
| 141 | else: |
| 142 | f.write(line) |
| 143 | invalue = False |
| 144 | elif line.startswith('SIGGEN_LOCKEDSIGS'): |
| 145 | invalue = True |
| 146 | f.write(line) |
| 147 | |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 148 | def merge_lockedsigs(copy_tasks, lockedsigs_main, lockedsigs_extra, merged_output, copy_output): |
| 149 | merged = {} |
| 150 | arch_order = [] |
| 151 | with open(lockedsigs_main, 'r') as f: |
| 152 | invalue = None |
| 153 | for line in f: |
| 154 | if invalue: |
| 155 | if line.endswith('\\\n'): |
| 156 | merged[invalue].append(line) |
| 157 | else: |
| 158 | invalue = None |
| 159 | elif line.startswith('SIGGEN_LOCKEDSIGS_t-'): |
| 160 | invalue = line[18:].split('=', 1)[0].rstrip() |
| 161 | merged[invalue] = [] |
| 162 | arch_order.append(invalue) |
| 163 | |
| 164 | with open(lockedsigs_extra, 'r') as f: |
| 165 | invalue = None |
| 166 | tocopy = {} |
| 167 | for line in f: |
| 168 | if invalue: |
| 169 | if line.endswith('\\\n'): |
| 170 | if not line in merged[invalue]: |
| 171 | target, task = line.strip().split(':')[:2] |
| 172 | if not copy_tasks or task in copy_tasks: |
| 173 | tocopy[invalue].append(line) |
| 174 | merged[invalue].append(line) |
| 175 | else: |
| 176 | invalue = None |
| 177 | elif line.startswith('SIGGEN_LOCKEDSIGS_t-'): |
| 178 | invalue = line[18:].split('=', 1)[0].rstrip() |
| 179 | if not invalue in merged: |
| 180 | merged[invalue] = [] |
| 181 | arch_order.append(invalue) |
| 182 | tocopy[invalue] = [] |
| 183 | |
| 184 | def write_sigs_file(fn, types, sigs): |
| 185 | fulltypes = [] |
| 186 | bb.utils.mkdirhier(os.path.dirname(fn)) |
| 187 | with open(fn, 'w') as f: |
| 188 | for typename in types: |
| 189 | lines = sigs[typename] |
| 190 | if lines: |
| 191 | f.write('SIGGEN_LOCKEDSIGS_%s = "\\\n' % typename) |
| 192 | for line in lines: |
| 193 | f.write(line) |
| 194 | f.write(' "\n') |
| 195 | fulltypes.append(typename) |
| 196 | f.write('SIGGEN_LOCKEDSIGS_TYPES = "%s"\n' % ' '.join(fulltypes)) |
| 197 | |
| 198 | write_sigs_file(copy_output, tocopy.keys(), tocopy) |
| 199 | if merged_output: |
| 200 | write_sigs_file(merged_output, arch_order, merged) |
| 201 | |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 202 | def create_locked_sstate_cache(lockedsigs, input_sstate_cache, output_sstate_cache, d, fixedlsbstring=""): |
| 203 | bb.note('Generating sstate-cache...') |
| 204 | |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 205 | nativelsbstring = d.getVar('NATIVELSBSTRING', True) |
| 206 | bb.process.run("gen-lockedsig-cache %s %s %s %s" % (lockedsigs, input_sstate_cache, output_sstate_cache, nativelsbstring)) |
Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 207 | if fixedlsbstring: |
Patrick Williams | d8c66bc | 2016-06-20 12:57:21 -0500 | [diff] [blame] | 208 | nativedir = output_sstate_cache + '/' + nativelsbstring |
| 209 | if os.path.isdir(nativedir): |
| 210 | destdir = os.path.join(output_sstate_cache, fixedlsbstring) |
| 211 | bb.utils.mkdirhier(destdir) |
| 212 | |
| 213 | dirlist = os.listdir(nativedir) |
| 214 | for i in dirlist: |
| 215 | src = os.path.join(nativedir, i) |
| 216 | dest = os.path.join(destdir, i) |
| 217 | os.rename(src, dest) |