diff options
| -rwxr-xr-x | bitbake/bin/bitbake-layers | 75 |
1 files changed, 67 insertions, 8 deletions
diff --git a/bitbake/bin/bitbake-layers b/bitbake/bin/bitbake-layers index b2781bbd56..572487d2db 100755 --- a/bitbake/bin/bitbake-layers +++ b/bitbake/bin/bitbake-layers | |||
| @@ -139,9 +139,10 @@ Highest priority recipes are listed with the recipes they overlay as subitems. | |||
| 139 | def do_flatten(self, args): | 139 | def do_flatten(self, args): |
| 140 | """flattens layer configuration into a separate output directory. | 140 | """flattens layer configuration into a separate output directory. |
| 141 | 141 | ||
| 142 | usage: flatten <outputdir> | 142 | usage: flatten [layer1 layer2 [layer3]...] <outputdir> |
| 143 | 143 | ||
| 144 | Takes the current layer configuration and builds a "flattened" directory | 144 | Takes the specified layers (or all layers in the current layer |
| 145 | configuration if none are specified) and builds a "flattened" directory | ||
| 145 | containing the contents of all layers, with any overlayed recipes removed | 146 | containing the contents of all layers, with any overlayed recipes removed |
| 146 | and bbappends appended to the corresponding recipes. Note that some manual | 147 | and bbappends appended to the corresponding recipes. Note that some manual |
| 147 | cleanup may still be necessary afterwards, in particular: | 148 | cleanup may still be necessary afterwards, in particular: |
| @@ -149,21 +150,59 @@ cleanup may still be necessary afterwards, in particular: | |||
| 149 | * where non-recipe files (such as patches) are overwritten (the flatten | 150 | * where non-recipe files (such as patches) are overwritten (the flatten |
| 150 | command will show a warning for these) | 151 | command will show a warning for these) |
| 151 | * where anything beyond the normal layer setup has been added to | 152 | * where anything beyond the normal layer setup has been added to |
| 152 | layer.conf (only the lowest priority layer's layer.conf is used) | 153 | layer.conf (only the lowest priority number layer's layer.conf is used) |
| 153 | * overridden/appended items from bbappends will need to be tidied up | 154 | * overridden/appended items from bbappends will need to be tidied up |
| 155 | |||
| 156 | Warning: if you flatten several layers where another layer is intended to | ||
| 157 | be used "inbetween" them (in layer priority order) such that recipes / | ||
| 158 | bbappends in the layers interact, and then attempt to use the new output | ||
| 159 | layer together with that other layer, you may no longer get the same | ||
| 160 | build results (as the layer priority order has effectively changed). | ||
| 154 | """ | 161 | """ |
| 155 | arglist = args.split() | 162 | arglist = args.split() |
| 156 | if len(arglist) != 1: | 163 | if len(arglist) < 1: |
| 157 | logger.error('Please specify an output directory') | 164 | logger.error('Please specify an output directory') |
| 158 | self.do_help('flatten') | 165 | self.do_help('flatten') |
| 159 | return | 166 | return |
| 160 | 167 | ||
| 161 | if os.path.exists(arglist[0]) and os.listdir(arglist[0]): | 168 | if len(arglist) == 2: |
| 162 | logger.error('Directory %s exists and is non-empty, please clear it out first' % arglist[0]) | 169 | logger.error('If you specify layers to flatten you must specify at least two') |
| 170 | self.do_help('flatten') | ||
| 171 | return | ||
| 172 | |||
| 173 | outputdir = arglist[-1] | ||
| 174 | if os.path.exists(outputdir) and os.listdir(outputdir): | ||
| 175 | logger.error('Directory %s exists and is non-empty, please clear it out first' % outputdir) | ||
| 163 | return | 176 | return |
| 164 | 177 | ||
| 165 | self.check_prepare_cooker() | 178 | self.check_prepare_cooker() |
| 166 | layers = (self.config_data.getVar('BBLAYERS', True) or "").split() | 179 | layers = (self.config_data.getVar('BBLAYERS', True) or "").split() |
| 180 | if len(arglist) > 2: | ||
| 181 | layernames = arglist[:-1] | ||
| 182 | found_layernames = [] | ||
| 183 | found_layerdirs = [] | ||
| 184 | for layerdir in layers: | ||
| 185 | for layername, _, regex, _ in self.cooker.status.bbfile_config_priorities: | ||
| 186 | if layername in layernames: | ||
| 187 | if regex.match(os.path.join(layerdir, 'test')): | ||
| 188 | found_layerdirs.append(layerdir) | ||
| 189 | found_layernames.append(layername) | ||
| 190 | break | ||
| 191 | |||
| 192 | for layername in layernames: | ||
| 193 | if not layername in found_layernames: | ||
| 194 | logger.error('Unable to find layer %s in current configuration, please run "%s show_layers" to list configured layers' % (layername, os.path.basename(sys.argv[0]))) | ||
| 195 | return | ||
| 196 | layers = found_layerdirs | ||
| 197 | |||
| 198 | # Ensure a specified path matches our list of layers | ||
| 199 | def layer_path_match(path): | ||
| 200 | for layerdir in layers: | ||
| 201 | if path.startswith(os.path.join(layerdir, '')): | ||
| 202 | return layerdir | ||
| 203 | return None | ||
| 204 | |||
| 205 | appended_recipes = [] | ||
| 167 | for layer in layers: | 206 | for layer in layers: |
| 168 | overlayed = [] | 207 | overlayed = [] |
| 169 | for f in self.cooker.overlayed.iterkeys(): | 208 | for f in self.cooker.overlayed.iterkeys(): |
| @@ -181,7 +220,7 @@ cleanup may still be necessary afterwards, in particular: | |||
| 181 | ext = os.path.splitext(f1)[1] | 220 | ext = os.path.splitext(f1)[1] |
| 182 | if ext != '.bbappend': | 221 | if ext != '.bbappend': |
| 183 | fdest = f1full[len(layer):] | 222 | fdest = f1full[len(layer):] |
| 184 | fdest = os.path.normpath(os.sep.join([arglist[0],fdest])) | 223 | fdest = os.path.normpath(os.sep.join([outputdir,fdest])) |
| 185 | bb.utils.mkdirhier(os.path.dirname(fdest)) | 224 | bb.utils.mkdirhier(os.path.dirname(fdest)) |
| 186 | if os.path.exists(fdest): | 225 | if os.path.exists(fdest): |
| 187 | if f1 == 'layer.conf' and root.endswith('/conf'): | 226 | if f1 == 'layer.conf' and root.endswith('/conf'): |
| @@ -196,7 +235,27 @@ cleanup may still be necessary afterwards, in particular: | |||
| 196 | if appends: | 235 | if appends: |
| 197 | logger.plain(' Applying appends to %s' % fdest ) | 236 | logger.plain(' Applying appends to %s' % fdest ) |
| 198 | for appendname in appends: | 237 | for appendname in appends: |
| 199 | self.apply_append(appendname, fdest) | 238 | if layer_path_match(appendname): |
| 239 | self.apply_append(appendname, fdest) | ||
| 240 | appended_recipes.append(f1) | ||
| 241 | |||
| 242 | # Take care of when some layers are excluded and yet we have included bbappends for those recipes | ||
| 243 | for recipename in self.cooker_data.appends.iterkeys(): | ||
| 244 | if recipename not in appended_recipes: | ||
| 245 | appends = self.cooker_data.appends[recipename] | ||
| 246 | first_append = None | ||
| 247 | for appendname in appends: | ||
| 248 | layer = layer_path_match(appendname) | ||
| 249 | if layer: | ||
| 250 | if first_append: | ||
| 251 | self.apply_append(appendname, first_append) | ||
| 252 | else: | ||
| 253 | fdest = appendname[len(layer):] | ||
| 254 | fdest = os.path.normpath(os.sep.join([outputdir,fdest])) | ||
| 255 | bb.utils.mkdirhier(os.path.dirname(fdest)) | ||
| 256 | bb.utils.copyfile(appendname, fdest) | ||
| 257 | first_append = fdest | ||
| 258 | |||
| 200 | 259 | ||
| 201 | def get_append_layer(self, appendname): | 260 | def get_append_layer(self, appendname): |
| 202 | for layer, _, regex, _ in self.cooker.status.bbfile_config_priorities: | 261 | for layer, _, regex, _ in self.cooker.status.bbfile_config_priorities: |
