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: |