summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/classes/populate_sdk_ext.bbclass148
-rw-r--r--meta/lib/oe/copy_buildsystem.py59
-rw-r--r--scripts/lib/devtool/build_image.py79
-rw-r--r--scripts/lib/devtool/build_sdk.py65
4 files changed, 264 insertions, 87 deletions
diff --git a/meta/classes/populate_sdk_ext.bbclass b/meta/classes/populate_sdk_ext.bbclass
index 6079166980..6afc53d284 100644
--- a/meta/classes/populate_sdk_ext.bbclass
+++ b/meta/classes/populate_sdk_ext.bbclass
@@ -89,7 +89,14 @@ python copy_buildsystem () {
89 # Copy in all metadata layers + bitbake (as repositories) 89 # Copy in all metadata layers + bitbake (as repositories)
90 buildsystem = oe.copy_buildsystem.BuildSystem('extensible SDK', d) 90 buildsystem = oe.copy_buildsystem.BuildSystem('extensible SDK', d)
91 baseoutpath = d.getVar('SDK_OUTPUT', True) + '/' + d.getVar('SDKPATH', True) 91 baseoutpath = d.getVar('SDK_OUTPUT', True) + '/' + d.getVar('SDKPATH', True)
92 layers_copied = buildsystem.copy_bitbake_and_layers(baseoutpath + '/layers') 92
93 # Determine if we're building a derivative extensible SDK (from devtool build-sdk)
94 derivative = (d.getVar('SDK_DERIVATIVE', True) or '') == '1'
95 if derivative:
96 workspace_name = 'orig-workspace'
97 else:
98 workspace_name = None
99 layers_copied = buildsystem.copy_bitbake_and_layers(baseoutpath + '/layers', workspace_name)
93 100
94 sdkbblayers = [] 101 sdkbblayers = []
95 corebase = os.path.basename(d.getVar('COREBASE', True)) 102 corebase = os.path.basename(d.getVar('COREBASE', True))
@@ -158,75 +165,81 @@ python copy_buildsystem () {
158 f.write(' "\n') 165 f.write(' "\n')
159 166
160 # Create local.conf 167 # Create local.conf
161 local_conf_whitelist = (d.getVar('SDK_LOCAL_CONF_WHITELIST', True) or '').split()
162 local_conf_blacklist = (d.getVar('SDK_LOCAL_CONF_BLACKLIST', True) or '').split()
163 def handle_var(varname, origvalue, op, newlines):
164 if varname in local_conf_blacklist or (origvalue.strip().startswith('/') and not varname in local_conf_whitelist):
165 newlines.append('# Removed original setting of %s\n' % varname)
166 return None, op, 0, True
167 else:
168 return origvalue, op, 0, True
169 varlist = ['[^#=+ ]*']
170 builddir = d.getVar('TOPDIR', True) 168 builddir = d.getVar('TOPDIR', True)
171 with open(builddir + '/conf/local.conf', 'r') as f: 169 if derivative:
172 oldlines = f.readlines() 170 shutil.copyfile(builddir + '/conf/local.conf', baseoutpath + '/conf/local.conf')
173 (updated, newlines) = bb.utils.edit_metadata(oldlines, varlist, handle_var) 171 else:
172 local_conf_whitelist = (d.getVar('SDK_LOCAL_CONF_WHITELIST', True) or '').split()
173 local_conf_blacklist = (d.getVar('SDK_LOCAL_CONF_BLACKLIST', True) or '').split()
174 def handle_var(varname, origvalue, op, newlines):
175 if varname in local_conf_blacklist or (origvalue.strip().startswith('/') and not varname in local_conf_whitelist):
176 newlines.append('# Removed original setting of %s\n' % varname)
177 return None, op, 0, True
178 else:
179 return origvalue, op, 0, True
180 varlist = ['[^#=+ ]*']
181 with open(builddir + '/conf/local.conf', 'r') as f:
182 oldlines = f.readlines()
183 (updated, newlines) = bb.utils.edit_metadata(oldlines, varlist, handle_var)
174 184
175 with open(baseoutpath + '/conf/local.conf', 'w') as f: 185 with open(baseoutpath + '/conf/local.conf', 'w') as f:
176 f.write('# WARNING: this configuration has been automatically generated and in\n') 186 f.write('# WARNING: this configuration has been automatically generated and in\n')
177 f.write('# most cases should not be edited. If you need more flexibility than\n') 187 f.write('# most cases should not be edited. If you need more flexibility than\n')
178 f.write('# this configuration provides, it is strongly suggested that you set\n') 188 f.write('# this configuration provides, it is strongly suggested that you set\n')
179 f.write('# up a proper instance of the full build system and use that instead.\n\n') 189 f.write('# up a proper instance of the full build system and use that instead.\n\n')
180 for line in newlines: 190 for line in newlines:
181 if line.strip() and not line.startswith('#'): 191 if line.strip() and not line.startswith('#'):
182 f.write(line) 192 f.write(line)
183 # Write a newline just in case there's none at the end of the original 193 # Write a newline just in case there's none at the end of the original
184 f.write('\n') 194 f.write('\n')
185 195
186 f.write('INHERIT += "%s"\n\n' % 'uninative') 196 f.write('INHERIT += "%s"\n\n' % 'uninative')
187 f.write('CONF_VERSION = "%s"\n\n' % d.getVar('CONF_VERSION', False)) 197 f.write('CONF_VERSION = "%s"\n\n' % d.getVar('CONF_VERSION', False))
188 198
189 # Some classes are not suitable for SDK, remove them from INHERIT 199 # Some classes are not suitable for SDK, remove them from INHERIT
190 f.write('INHERIT_remove = "%s"\n' % d.getVar('SDK_INHERIT_BLACKLIST', False)) 200 f.write('INHERIT_remove = "%s"\n' % d.getVar('SDK_INHERIT_BLACKLIST', False))
191 201
192 # Bypass the default connectivity check if any 202 # Bypass the default connectivity check if any
193 f.write('CONNECTIVITY_CHECK_URIS = ""\n\n') 203 f.write('CONNECTIVITY_CHECK_URIS = ""\n\n')
194 204
195 # Ensure locked sstate cache objects are re-used without error 205 # Ensure locked sstate cache objects are re-used without error
196 f.write('SIGGEN_LOCKEDSIGS_CHECK_LEVEL = "none"\n\n') 206 f.write('SIGGEN_LOCKEDSIGS_CHECK_LEVEL = "none"\n\n')
197 207
198 # Hide the config information from bitbake output (since it's fixed within the SDK) 208 # Hide the config information from bitbake output (since it's fixed within the SDK)
199 f.write('BUILDCFG_HEADER = ""\n') 209 f.write('BUILDCFG_HEADER = ""\n')
200 210
201 # Allow additional config through sdk-extra.conf 211 # Allow additional config through sdk-extra.conf
202 fn = bb.cookerdata.findConfigFile('sdk-extra.conf', d) 212 fn = bb.cookerdata.findConfigFile('sdk-extra.conf', d)
203 if fn: 213 if fn:
204 with open(fn, 'r') as xf: 214 with open(fn, 'r') as xf:
205 for line in xf: 215 for line in xf:
206 f.write(line) 216 f.write(line)
207 217
208 # If you define a sdk_extraconf() function then it can contain additional config 218 # If you define a sdk_extraconf() function then it can contain additional config
209 # (Though this is awkward; sdk-extra.conf should probably be used instead) 219 # (Though this is awkward; sdk-extra.conf should probably be used instead)
210 extraconf = (d.getVar('sdk_extraconf', True) or '').strip() 220 extraconf = (d.getVar('sdk_extraconf', True) or '').strip()
211 if extraconf: 221 if extraconf:
212 # Strip off any leading / trailing spaces 222 # Strip off any leading / trailing spaces
213 for line in extraconf.splitlines(): 223 for line in extraconf.splitlines():
214 f.write(line.strip() + '\n') 224 f.write(line.strip() + '\n')
215 225
216 f.write('require conf/locked-sigs.inc\n') 226 f.write('require conf/locked-sigs.inc\n')
217 227
218 if os.path.exists(builddir + '/conf/auto.conf'): 228 if os.path.exists(builddir + '/conf/auto.conf'):
219 with open(builddir + '/conf/auto.conf', 'r') as f: 229 if derivative:
220 oldlines = f.readlines() 230 shutil.copyfile(builddir + '/conf/auto.conf', baseoutpath + '/conf/auto.conf')
221 (updated, newlines) = bb.utils.edit_metadata(oldlines, varlist, handle_var) 231 else:
222 with open(baseoutpath + '/conf/auto.conf', 'w') as f: 232 with open(builddir + '/conf/auto.conf', 'r') as f:
223 f.write('# WARNING: this configuration has been automatically generated and in\n') 233 oldlines = f.readlines()
224 f.write('# most cases should not be edited. If you need more flexibility than\n') 234 (updated, newlines) = bb.utils.edit_metadata(oldlines, varlist, handle_var)
225 f.write('# this configuration provides, it is strongly suggested that you set\n') 235 with open(baseoutpath + '/conf/auto.conf', 'w') as f:
226 f.write('# up a proper instance of the full build system and use that instead.\n\n') 236 f.write('# WARNING: this configuration has been automatically generated and in\n')
227 for line in newlines: 237 f.write('# most cases should not be edited. If you need more flexibility than\n')
228 if line.strip() and not line.startswith('#'): 238 f.write('# this configuration provides, it is strongly suggested that you set\n')
229 f.write(line) 239 f.write('# up a proper instance of the full build system and use that instead.\n\n')
240 for line in newlines:
241 if line.strip() and not line.startswith('#'):
242 f.write(line)
230 243
231 # Filter the locked signatures file to just the sstate tasks we are interested in 244 # Filter the locked signatures file to just the sstate tasks we are interested in
232 excluded_targets = d.getVar('SDK_TARGETS', True) 245 excluded_targets = d.getVar('SDK_TARGETS', True)
@@ -253,7 +266,24 @@ python copy_buildsystem () {
253 lockedsigs_pruned, 266 lockedsigs_pruned,
254 lockedsigs_copy) 267 lockedsigs_copy)
255 268
256 if d.getVar('SDK_EXT_TYPE', True) != 'minimal': 269 if d.getVar('SDK_EXT_TYPE', True) == 'minimal':
270 if derivative:
271 # Assume the user is not going to set up an additional sstate
272 # mirror, thus we need to copy the additional artifacts (from
273 # workspace recipes) into the derivative SDK
274 lockedsigs_orig = d.getVar('TOPDIR', True) + '/conf/locked-sigs.inc'
275 if os.path.exists(lockedsigs_orig):
276 lockedsigs_extra = d.getVar('WORKDIR', True) + '/locked-sigs-extra.inc'
277 oe.copy_buildsystem.merge_lockedsigs(None,
278 lockedsigs_orig,
279 lockedsigs_pruned,
280 None,
281 lockedsigs_extra)
282 oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_extra,
283 d.getVar('SSTATE_DIR', True),
284 sstate_out, d,
285 fixedlsbstring)
286 else:
257 oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_pruned, 287 oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_pruned,
258 d.getVar('SSTATE_DIR', True), 288 d.getVar('SSTATE_DIR', True),
259 sstate_out, d, 289 sstate_out, d,
diff --git a/meta/lib/oe/copy_buildsystem.py b/meta/lib/oe/copy_buildsystem.py
index 5074a43cb9..dd0e6641e3 100644
--- a/meta/lib/oe/copy_buildsystem.py
+++ b/meta/lib/oe/copy_buildsystem.py
@@ -20,7 +20,7 @@ class BuildSystem(object):
20 self.layerdirs = d.getVar('BBLAYERS', True).split() 20 self.layerdirs = d.getVar('BBLAYERS', True).split()
21 self.layers_exclude = (d.getVar('SDK_LAYERS_EXCLUDE', True) or "").split() 21 self.layers_exclude = (d.getVar('SDK_LAYERS_EXCLUDE', True) or "").split()
22 22
23 def copy_bitbake_and_layers(self, destdir): 23 def copy_bitbake_and_layers(self, destdir, workspace_name=None):
24 # Copy in all metadata layers + bitbake (as repositories) 24 # Copy in all metadata layers + bitbake (as repositories)
25 layers_copied = [] 25 layers_copied = []
26 bb.utils.mkdirhier(destdir) 26 bb.utils.mkdirhier(destdir)
@@ -34,6 +34,14 @@ class BuildSystem(object):
34 if layer_exclude in layers: 34 if layer_exclude in layers:
35 layers.remove(layer_exclude) 35 layers.remove(layer_exclude)
36 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
37 corebase_files = self.d.getVar('COREBASE_FILES', True).split() 45 corebase_files = self.d.getVar('COREBASE_FILES', True).split()
38 corebase_files = [corebase + '/' +x for x in corebase_files] 46 corebase_files = [corebase + '/' +x for x in corebase_files]
39 # Make sure bitbake goes in 47 # Make sure bitbake goes in
@@ -42,18 +50,24 @@ class BuildSystem(object):
42 50
43 for layer in layers: 51 for layer in layers:
44 layerconf = os.path.join(layer, 'conf', 'layer.conf') 52 layerconf = os.path.join(layer, 'conf', 'layer.conf')
53 layernewname = os.path.basename(layer)
54 workspace = False
45 if os.path.exists(layerconf): 55 if os.path.exists(layerconf):
46 with open(layerconf, 'r') as f: 56 with open(layerconf, 'r') as f:
47 if f.readline().startswith("# ### workspace layer auto-generated by devtool ###"): 57 if f.readline().startswith("# ### workspace layer auto-generated by devtool ###"):
48 bb.plain("NOTE: Excluding local workspace layer %s from %s" % (layer, self.context)) 58 if workspace_newname:
49 continue 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
50 64
51 # If the layer was already under corebase, leave it there 65 # If the layer was already under corebase, leave it there
52 # since layers such as meta have issues when moved. 66 # since layers such as meta have issues when moved.
53 layerdestpath = destdir 67 layerdestpath = destdir
54 if corebase == os.path.dirname(layer): 68 if corebase == os.path.dirname(layer):
55 layerdestpath += '/' + os.path.basename(corebase) 69 layerdestpath += '/' + os.path.basename(corebase)
56 layerdestpath += '/' + os.path.basename(layer) 70 layerdestpath += '/' + layernewname
57 71
58 layer_relative = os.path.relpath(layerdestpath, 72 layer_relative = os.path.relpath(layerdestpath,
59 destdir) 73 destdir)
@@ -73,6 +87,38 @@ class BuildSystem(object):
73 else: 87 else:
74 _smart_copy(layer, layerdestpath) 88 _smart_copy(layer, layerdestpath)
75 89
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
76 return layers_copied 122 return layers_copied
77 123
78def generate_locked_sigs(sigfile, d): 124def generate_locked_sigs(sigfile, d):
@@ -123,7 +169,7 @@ def merge_lockedsigs(copy_tasks, lockedsigs_main, lockedsigs_extra, merged_outpu
123 if line.endswith('\\\n'): 169 if line.endswith('\\\n'):
124 if not line in merged[invalue]: 170 if not line in merged[invalue]:
125 target, task = line.strip().split(':')[:2] 171 target, task = line.strip().split(':')[:2]
126 if task in copy_tasks: 172 if not copy_tasks or task in copy_tasks:
127 tocopy[invalue].append(line) 173 tocopy[invalue].append(line)
128 merged[invalue].append(line) 174 merged[invalue].append(line)
129 else: 175 else:
@@ -150,7 +196,8 @@ def merge_lockedsigs(copy_tasks, lockedsigs_main, lockedsigs_extra, merged_outpu
150 f.write('SIGGEN_LOCKEDSIGS_TYPES = "%s"\n' % ' '.join(fulltypes)) 196 f.write('SIGGEN_LOCKEDSIGS_TYPES = "%s"\n' % ' '.join(fulltypes))
151 197
152 write_sigs_file(copy_output, tocopy.keys(), tocopy) 198 write_sigs_file(copy_output, tocopy.keys(), tocopy)
153 write_sigs_file(merged_output, arch_order, merged) 199 if merged_output:
200 write_sigs_file(merged_output, arch_order, merged)
154 201
155def create_locked_sstate_cache(lockedsigs, input_sstate_cache, output_sstate_cache, d, fixedlsbstring=""): 202def create_locked_sstate_cache(lockedsigs, input_sstate_cache, output_sstate_cache, d, fixedlsbstring=""):
156 bb.note('Generating sstate-cache...') 203 bb.note('Generating sstate-cache...')
diff --git a/scripts/lib/devtool/build_image.py b/scripts/lib/devtool/build_image.py
index ff764fa833..e51d766474 100644
--- a/scripts/lib/devtool/build_image.py
+++ b/scripts/lib/devtool/build_image.py
@@ -25,6 +25,9 @@ from devtool import exec_build_env_command, setup_tinfoil, parse_recipe, Devtool
25 25
26logger = logging.getLogger('devtool') 26logger = logging.getLogger('devtool')
27 27
28class TargetNotImageError(Exception):
29 pass
30
28def _get_packages(tinfoil, workspace, config): 31def _get_packages(tinfoil, workspace, config):
29 """Get list of packages from recipes in the workspace.""" 32 """Get list of packages from recipes in the workspace."""
30 result = [] 33 result = []
@@ -51,6 +54,24 @@ def build_image(args, config, basepath, workspace):
51 if not image: 54 if not image:
52 raise DevtoolError('Unable to determine image to build, please specify one') 55 raise DevtoolError('Unable to determine image to build, please specify one')
53 56
57 try:
58 if args.add_packages:
59 add_packages = args.add_packages.split(',')
60 else:
61 add_packages = None
62 result, outputdir = build_image_task(config, basepath, workspace, image, add_packages)
63 except TargetNotImageError:
64 if auto_image:
65 raise DevtoolError('Unable to determine image to build, please specify one')
66 else:
67 raise DevtoolError('Specified recipe %s is not an image recipe' % image)
68
69 if result == 0:
70 logger.info('Successfully built %s. You can find output files in %s'
71 % (image, outputdir))
72 return result
73
74def build_image_task(config, basepath, workspace, image, add_packages=None, task=None, extra_append=None):
54 appendfile = os.path.join(config.workspace_path, 'appends', 75 appendfile = os.path.join(config.workspace_path, 'appends',
55 '%s.bbappend' % image) 76 '%s.bbappend' % image)
56 77
@@ -63,46 +84,60 @@ def build_image(args, config, basepath, workspace):
63 rd = parse_recipe(config, tinfoil, image, True) 84 rd = parse_recipe(config, tinfoil, image, True)
64 if not rd: 85 if not rd:
65 # Error already shown 86 # Error already shown
66 return 1 87 return (1, None)
67 if not bb.data.inherits_class('image', rd): 88 if not bb.data.inherits_class('image', rd):
68 if auto_image: 89 raise TargetNotImageError()
69 raise DevtoolError('Unable to determine image to build, please specify one')
70 else:
71 raise DevtoolError('Specified recipe %s is not an image recipe' % image)
72 90
91 outputdir = None
73 try: 92 try:
74 if workspace or args.add_packages: 93 if workspace or add_packages:
75 if args.add_packages: 94 if add_packages:
76 packages = args.add_packages.split(',') 95 packages = add_packages
77 else: 96 else:
78 packages = _get_packages(tinfoil, workspace, config) 97 packages = _get_packages(tinfoil, workspace, config)
79 if packages: 98 else:
80 with open(appendfile, 'w') as afile: 99 packages = None
100 if not task:
101 if not packages and not add_packages and workspace:
102 logger.warning('No recipes in workspace, building image %s unmodified', image)
103 elif not packages:
104 logger.warning('No packages to add, building image %s unmodified', image)
105
106 if packages or extra_append:
107 bb.utils.mkdirhier(os.path.dirname(appendfile))
108 with open(appendfile, 'w') as afile:
109 if packages:
81 # include packages from workspace recipes into the image 110 # include packages from workspace recipes into the image
82 afile.write('IMAGE_INSTALL_append = " %s"\n' % ' '.join(packages)) 111 afile.write('IMAGE_INSTALL_append = " %s"\n' % ' '.join(packages))
83 logger.info('Building image %s with the following ' 112 if not task:
84 'additional packages: %s', image, ' '.join(packages)) 113 logger.info('Building image %s with the following '
85 else: 114 'additional packages: %s', image, ' '.join(packages))
86 logger.warning('No packages to add, building image %s unmodified', image) 115 if extra_append:
116 for line in extra_append:
117 afile.write('%s\n' % line)
118
119 if task in ['populate_sdk', 'populate_sdk_ext']:
120 outputdir = rd.getVar('SDK_DEPLOY', True)
87 else: 121 else:
88 logger.warning('No recipes in workspace, building image %s unmodified', image) 122 outputdir = rd.getVar('DEPLOY_DIR_IMAGE', True)
89
90 deploy_dir_image = tinfoil.config_data.getVar('DEPLOY_DIR_IMAGE', True)
91 123
92 tinfoil.shutdown() 124 tinfoil.shutdown()
93 125
94 # run bitbake to build image 126 options = ''
127 if task:
128 options += '-c %s' % task
129
130 # run bitbake to build image (or specified task)
95 try: 131 try:
96 exec_build_env_command(config.init_path, basepath, 132 exec_build_env_command(config.init_path, basepath,
97 'bitbake %s' % image, watch=True) 133 'bitbake %s %s' % (options, image), watch=True)
98 except ExecutionError as err: 134 except ExecutionError as err:
99 return err.exitcode 135 return (err.exitcode, None)
100 finally: 136 finally:
101 if os.path.isfile(appendfile): 137 if os.path.isfile(appendfile):
102 os.unlink(appendfile) 138 os.unlink(appendfile)
139 return (0, outputdir)
103 140
104 logger.info('Successfully built %s. You can find output files in %s'
105 % (image, deploy_dir_image))
106 141
107def register_commands(subparsers, context): 142def register_commands(subparsers, context):
108 """Register devtool subcommands from the build-image plugin""" 143 """Register devtool subcommands from the build-image plugin"""
diff --git a/scripts/lib/devtool/build_sdk.py b/scripts/lib/devtool/build_sdk.py
new file mode 100644
index 0000000000..b89d65b0cb
--- /dev/null
+++ b/scripts/lib/devtool/build_sdk.py
@@ -0,0 +1,65 @@
1# Development tool - build-sdk command plugin
2#
3# Copyright (C) 2015-2016 Intel Corporation
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as
7# published by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program; if not, write to the Free Software Foundation, Inc.,
16# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18import os
19import subprocess
20import logging
21import glob
22import shutil
23import errno
24import sys
25import tempfile
26from devtool import exec_build_env_command, setup_tinfoil, parse_recipe, DevtoolError
27from devtool import build_image
28
29logger = logging.getLogger('devtool')
30
31
32def build_sdk(args, config, basepath, workspace):
33 """Entry point for the devtool build-sdk command"""
34
35 sdk_targets = config.get('SDK', 'sdk_targets', '').split()
36 if sdk_targets:
37 image = sdk_targets[0]
38 else:
39 raise DevtoolError('Unable to determine image to build SDK for')
40
41 extra_append = ['SDK_DERIVATIVE = "1"']
42 try:
43 result, outputdir = build_image.build_image_task(config,
44 basepath,
45 workspace,
46 image,
47 task='populate_sdk_ext',
48 extra_append=extra_append)
49 except build_image.TargetNotImageError:
50 raise DevtoolError('Unable to determine image to build SDK for')
51
52 if result == 0:
53 logger.info('Successfully built SDK. You can find output files in %s'
54 % outputdir)
55 return result
56
57
58def register_commands(subparsers, context):
59 """Register devtool subcommands"""
60 if context.fixed_setup:
61 parser_build_sdk = subparsers.add_parser('build-sdk',
62 help='Build a derivative SDK of this one',
63 description='Builds an extensible SDK based upon this one and the items in your workspace',
64 group='advanced')
65 parser_build_sdk.set_defaults(func=build_sdk)