blob: 0f0525d7648a08848bb020b3987c546c979a5e8f [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001# Extensible SDK
2
3inherit populate_sdk_base
4
5# NOTE: normally you cannot use task overrides for this kind of thing - this
6# only works because of get_sdk_ext_rdepends()
7
8TOOLCHAIN_HOST_TASK_task-populate-sdk-ext = " \
9 meta-environment-extsdk-${MACHINE} \
10 "
11
12TOOLCHAIN_TARGET_TASK_task-populate-sdk-ext = ""
13
14SDK_RDEPENDS_append_task-populate-sdk-ext = " ${SDK_TARGETS}"
15
16SDK_RELOCATE_AFTER_INSTALL_task-populate-sdk-ext = "0"
17
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050018SDK_EXT = ""
19SDK_EXT_task-populate-sdk-ext = "-ext"
20
21# Options are full or minimal
22SDK_EXT_TYPE ?= "full"
Patrick Williamsc0f7c042017-02-23 20:41:17 -060023SDK_INCLUDE_PKGDATA ?= "0"
24SDK_INCLUDE_TOOLCHAIN ?= "${@'1' if d.getVar('SDK_EXT_TYPE', True) == 'full' else '0'}"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050025
26SDK_RECRDEP_TASKS ?= ""
27
Patrick Williamsc124f4f2015-09-15 14:41:29 -050028SDK_LOCAL_CONF_WHITELIST ?= ""
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050029SDK_LOCAL_CONF_BLACKLIST ?= "CONF_VERSION \
30 BB_NUMBER_THREADS \
Patrick Williamsc0f7c042017-02-23 20:41:17 -060031 BB_NUMBER_PARSE_THREADS \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050032 PARALLEL_MAKE \
33 PRSERV_HOST \
34 SSTATE_MIRRORS \
Patrick Williamsc0f7c042017-02-23 20:41:17 -060035 DL_DIR \
36 SSTATE_DIR \
37 TMPDIR \
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050038 "
Patrick Williamsc124f4f2015-09-15 14:41:29 -050039SDK_INHERIT_BLACKLIST ?= "buildhistory icecc"
40SDK_UPDATE_URL ?= ""
41
42SDK_TARGETS ?= "${PN}"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050043
Patrick Williamsc0f7c042017-02-23 20:41:17 -060044def get_sdk_install_targets(d, images_only=False):
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050045 sdk_install_targets = ''
Patrick Williamsc0f7c042017-02-23 20:41:17 -060046 if images_only or d.getVar('SDK_EXT_TYPE', True) != 'minimal':
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050047 sdk_install_targets = d.getVar('SDK_TARGETS', True)
48
49 depd = d.getVar('BB_TASKDEPDATA', False)
Patrick Williamsc0f7c042017-02-23 20:41:17 -060050 for v in depd.values():
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050051 if v[1] == 'do_image_complete':
52 if v[0] not in sdk_install_targets:
53 sdk_install_targets += ' {}'.format(v[0])
54
Patrick Williamsc0f7c042017-02-23 20:41:17 -060055 if not images_only:
56 if d.getVar('SDK_INCLUDE_PKGDATA', True) == '1':
57 sdk_install_targets += ' meta-world-pkgdata:do_allpackagedata'
58 if d.getVar('SDK_INCLUDE_TOOLCHAIN', True) == '1':
59 sdk_install_targets += ' meta-extsdk-toolchain:do_populate_sysroot'
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050060
61 return sdk_install_targets
62
63get_sdk_install_targets[vardepsexclude] = "BB_TASKDEPDATA"
64
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065OE_INIT_ENV_SCRIPT ?= "oe-init-build-env"
66
67# The files from COREBASE that you want preserved in the COREBASE copied
68# into the sdk. This allows someone to have their own setup scripts in
69# COREBASE be preserved as well as untracked files.
70COREBASE_FILES ?= " \
71 oe-init-build-env \
72 oe-init-build-env-memres \
73 scripts \
74 LICENSE \
75 .templateconf \
76"
77
78SDK_DIR_task-populate-sdk-ext = "${WORKDIR}/sdk-ext"
79B_task-populate-sdk-ext = "${SDK_DIR}"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050080TOOLCHAINEXT_OUTPUTNAME = "${SDK_NAME}-toolchain-ext-${SDK_VERSION}"
81TOOLCHAIN_OUTPUTNAME_task-populate-sdk-ext = "${TOOLCHAINEXT_OUTPUTNAME}"
82
83SDK_EXT_TARGET_MANIFEST = "${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.target.manifest"
84SDK_EXT_HOST_MANIFEST = "${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.host.manifest"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050085
86SDK_TITLE_task-populate-sdk-ext = "${@d.getVar('DISTRO_NAME', True) or d.getVar('DISTRO', True)} Extensible SDK"
87
Patrick Williamsc0f7c042017-02-23 20:41:17 -060088def clean_esdk_builddir(d, sdkbasepath):
89 """Clean up traces of the fake build for create_filtered_tasklist()"""
90 import shutil
91 cleanpaths = 'cache conf/sanity_info conf/templateconf.cfg tmp'.split()
92 for pth in cleanpaths:
93 fullpth = os.path.join(sdkbasepath, pth)
94 if os.path.isdir(fullpth):
95 shutil.rmtree(fullpth)
96 elif os.path.isfile(fullpth):
97 os.remove(fullpth)
98
99def create_filtered_tasklist(d, sdkbasepath, tasklistfile, conf_initpath):
100 """
101 Create a filtered list of tasks. Also double-checks that the build system
102 within the SDK basically works and required sstate artifacts are available.
103 """
104 import tempfile
105 import shutil
106 import oe.copy_buildsystem
107
108 # Create a temporary build directory that we can pass to the env setup script
109 shutil.copyfile(sdkbasepath + '/conf/local.conf', sdkbasepath + '/conf/local.conf.bak')
110 try:
111 with open(sdkbasepath + '/conf/local.conf', 'a') as f:
112 # Force the use of sstate from the build system
113 f.write('\nSSTATE_DIR_forcevariable = "%s"\n' % d.getVar('SSTATE_DIR', True))
114 f.write('SSTATE_MIRRORS_forcevariable = ""\n')
115 # Ensure TMPDIR is the default so that clean_esdk_builddir() can delete it
116 f.write('TMPDIR_forcevariable = "${TOPDIR}/tmp"\n')
117 # Drop uninative if the build isn't using it (or else NATIVELSBSTRING will
118 # be different and we won't be able to find our native sstate)
119 if not bb.data.inherits_class('uninative', d):
120 f.write('INHERIT_remove = "uninative"\n')
121
122 # Unfortunately the default SDKPATH (or even a custom value) may contain characters that bitbake
123 # will not allow in its COREBASE path, so we need to rename the directory temporarily
124 temp_sdkbasepath = d.getVar('SDK_OUTPUT', True) + '/tmp-renamed-sdk'
125 # Delete any existing temp dir
126 try:
127 shutil.rmtree(temp_sdkbasepath)
128 except FileNotFoundError:
129 pass
130 os.rename(sdkbasepath, temp_sdkbasepath)
131 try:
132 cmdprefix = '. %s .; ' % conf_initpath
133 logfile = d.getVar('WORKDIR', True) + '/tasklist_bb_log.txt'
134 try:
135 oe.copy_buildsystem.check_sstate_task_list(d, get_sdk_install_targets(d), tasklistfile, cmdprefix=cmdprefix, cwd=temp_sdkbasepath, logfile=logfile)
136 except bb.process.ExecutionError as e:
137 msg = 'Failed to generate filtered task list for extensible SDK:\n%s' % e.stdout.rstrip()
138 if 'attempted to execute unexpectedly and should have been setscened' in e.stdout:
139 msg += '\n----------\n\nNOTE: "attempted to execute unexpectedly and should have been setscened" errors indicate this may be caused by missing sstate artifacts that were likely produced in earlier builds, but have been subsequently deleted for some reason.\n'
140 bb.fatal(msg)
141 finally:
142 os.rename(temp_sdkbasepath, sdkbasepath)
143 # Clean out residue of running bitbake, which check_sstate_task_list()
144 # will effectively do
145 clean_esdk_builddir(d, sdkbasepath)
146 finally:
147 os.replace(sdkbasepath + '/conf/local.conf.bak', sdkbasepath + '/conf/local.conf')
148
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500149python copy_buildsystem () {
150 import re
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500151 import shutil
152 import glob
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500153 import oe.copy_buildsystem
154
155 oe_init_env_script = d.getVar('OE_INIT_ENV_SCRIPT', True)
156
157 conf_bbpath = ''
158 conf_initpath = ''
159 core_meta_subdir = ''
160
161 # Copy in all metadata layers + bitbake (as repositories)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500162 buildsystem = oe.copy_buildsystem.BuildSystem('extensible SDK', d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500163 baseoutpath = d.getVar('SDK_OUTPUT', True) + '/' + d.getVar('SDKPATH', True)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500164
165 # Determine if we're building a derivative extensible SDK (from devtool build-sdk)
166 derivative = (d.getVar('SDK_DERIVATIVE', True) or '') == '1'
167 if derivative:
168 workspace_name = 'orig-workspace'
169 else:
170 workspace_name = None
171 layers_copied = buildsystem.copy_bitbake_and_layers(baseoutpath + '/layers', workspace_name)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500172
173 sdkbblayers = []
174 corebase = os.path.basename(d.getVar('COREBASE', True))
175 for layer in layers_copied:
176 if corebase == os.path.basename(layer):
177 conf_bbpath = os.path.join('layers', layer, 'bitbake')
178 else:
179 sdkbblayers.append(layer)
180
181 for path in os.listdir(baseoutpath + '/layers'):
182 relpath = os.path.join('layers', path, oe_init_env_script)
183 if os.path.exists(os.path.join(baseoutpath, relpath)):
184 conf_initpath = relpath
185
186 relpath = os.path.join('layers', path, 'scripts', 'devtool')
187 if os.path.exists(os.path.join(baseoutpath, relpath)):
188 scriptrelpath = os.path.dirname(relpath)
189
190 relpath = os.path.join('layers', path, 'meta')
191 if os.path.exists(os.path.join(baseoutpath, relpath, 'lib', 'oe')):
192 core_meta_subdir = relpath
193
194 d.setVar('oe_init_build_env_path', conf_initpath)
195 d.setVar('scriptrelpath', scriptrelpath)
196
197 # Write out config file for devtool
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600198 import configparser
199 config = configparser.SafeConfigParser()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500200 config.add_section('General')
201 config.set('General', 'bitbake_subdir', conf_bbpath)
202 config.set('General', 'init_path', conf_initpath)
203 config.set('General', 'core_meta_subdir', core_meta_subdir)
204 config.add_section('SDK')
205 config.set('SDK', 'sdk_targets', d.getVar('SDK_TARGETS', True))
206 updateurl = d.getVar('SDK_UPDATE_URL', True)
207 if updateurl:
208 config.set('SDK', 'updateserver', updateurl)
209 bb.utils.mkdirhier(os.path.join(baseoutpath, 'conf'))
210 with open(os.path.join(baseoutpath, 'conf', 'devtool.conf'), 'w') as f:
211 config.write(f)
212
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500213 unlockedsigs = os.path.join(baseoutpath, 'conf', 'unlocked-sigs.inc')
214 with open(unlockedsigs, 'w') as f:
215 pass
216
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500217 # Create a layer for new recipes / appends
218 bbpath = d.getVar('BBPATH', True)
219 bb.process.run(['devtool', '--bbpath', bbpath, '--basepath', baseoutpath, 'create-workspace', '--create-only', os.path.join(baseoutpath, 'workspace')])
220
221 # Create bblayers.conf
222 bb.utils.mkdirhier(baseoutpath + '/conf')
223 with open(baseoutpath + '/conf/bblayers.conf', 'w') as f:
224 f.write('# WARNING: this configuration has been automatically generated and in\n')
225 f.write('# most cases should not be edited. If you need more flexibility than\n')
226 f.write('# this configuration provides, it is strongly suggested that you set\n')
227 f.write('# up a proper instance of the full build system and use that instead.\n\n')
228
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500229 # LCONF_VERSION may not be set, for example when using meta-poky
230 # so don't error if it isn't found
231 lconf_version = d.getVar('LCONF_VERSION', False)
232 if lconf_version is not None:
233 f.write('LCONF_VERSION = "%s"\n\n' % lconf_version)
234
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500235 f.write('BBPATH = "$' + '{TOPDIR}"\n')
236 f.write('SDKBASEMETAPATH = "$' + '{TOPDIR}"\n')
237 f.write('BBLAYERS := " \\\n')
238 for layerrelpath in sdkbblayers:
239 f.write(' $' + '{SDKBASEMETAPATH}/layers/%s \\\n' % layerrelpath)
240 f.write(' $' + '{SDKBASEMETAPATH}/workspace \\\n')
241 f.write(' "\n')
242
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600243 # Copy uninative tarball
244 # For now this is where uninative.bbclass expects the tarball
245 uninative_file = d.expand('${SDK_DEPLOY}/${BUILD_ARCH}-nativesdk-libc.tar.bz2')
246 uninative_checksum = bb.utils.sha256_file(uninative_file)
247 uninative_outdir = '%s/downloads/uninative/%s' % (baseoutpath, uninative_checksum)
248 bb.utils.mkdirhier(uninative_outdir)
249 shutil.copy(uninative_file, uninative_outdir)
250
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500251 env_whitelist = (d.getVar('BB_ENV_EXTRAWHITE', True) or '').split()
252 env_whitelist_values = {}
253
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500254 # Create local.conf
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500255 builddir = d.getVar('TOPDIR', True)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500256 if derivative:
257 shutil.copyfile(builddir + '/conf/local.conf', baseoutpath + '/conf/local.conf')
258 else:
259 local_conf_whitelist = (d.getVar('SDK_LOCAL_CONF_WHITELIST', True) or '').split()
260 local_conf_blacklist = (d.getVar('SDK_LOCAL_CONF_BLACKLIST', True) or '').split()
261 def handle_var(varname, origvalue, op, newlines):
262 if varname in local_conf_blacklist or (origvalue.strip().startswith('/') and not varname in local_conf_whitelist):
263 newlines.append('# Removed original setting of %s\n' % varname)
264 return None, op, 0, True
265 else:
266 if varname in env_whitelist:
267 env_whitelist_values[varname] = origvalue
268 return origvalue, op, 0, True
269 varlist = ['[^#=+ ]*']
270 with open(builddir + '/conf/local.conf', 'r') as f:
271 oldlines = f.readlines()
272 (updated, newlines) = bb.utils.edit_metadata(oldlines, varlist, handle_var)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500273
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500274 with open(baseoutpath + '/conf/local.conf', 'w') as f:
275 f.write('# WARNING: this configuration has been automatically generated and in\n')
276 f.write('# most cases should not be edited. If you need more flexibility than\n')
277 f.write('# this configuration provides, it is strongly suggested that you set\n')
278 f.write('# up a proper instance of the full build system and use that instead.\n\n')
279 for line in newlines:
280 if line.strip() and not line.startswith('#'):
281 f.write(line)
282 # Write a newline just in case there's none at the end of the original
283 f.write('\n')
284
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600285 f.write('DL_DIR = "${TOPDIR}/downloads"\n')
286
287 f.write('INHERIT += "%s"\n' % 'uninative')
288 f.write('UNINATIVE_CHECKSUM[%s] = "%s"\n\n' % (d.getVar('BUILD_ARCH', True), uninative_checksum))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500289 f.write('CONF_VERSION = "%s"\n\n' % d.getVar('CONF_VERSION', False))
290
291 # Some classes are not suitable for SDK, remove them from INHERIT
292 f.write('INHERIT_remove = "%s"\n' % d.getVar('SDK_INHERIT_BLACKLIST', False))
293
294 # Bypass the default connectivity check if any
295 f.write('CONNECTIVITY_CHECK_URIS = ""\n\n')
296
297 # This warning will come out if reverse dependencies for a task
298 # don't have sstate as well as the task itself. We already know
299 # this will be the case for the extensible sdk, so turn off the
300 # warning.
301 f.write('SIGGEN_LOCKEDSIGS_SSTATE_EXISTS_CHECK = "none"\n\n')
302
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600303 # Warn if the sigs in the locked-signature file don't match
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500304 # the sig computed from the metadata.
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600305 f.write('SIGGEN_LOCKEDSIGS_TASKSIG_CHECK = "warn"\n\n')
306
307 # Set up whitelist for run on install
308 f.write('BB_SETSCENE_ENFORCE_WHITELIST = "%:* *:do_shared_workdir *:do_rm_work"\n\n')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500309
310 # Hide the config information from bitbake output (since it's fixed within the SDK)
311 f.write('BUILDCFG_HEADER = ""\n')
312
313 # Allow additional config through sdk-extra.conf
314 fn = bb.cookerdata.findConfigFile('sdk-extra.conf', d)
315 if fn:
316 with open(fn, 'r') as xf:
317 for line in xf:
318 f.write(line)
319
320 # If you define a sdk_extraconf() function then it can contain additional config
321 # (Though this is awkward; sdk-extra.conf should probably be used instead)
322 extraconf = (d.getVar('sdk_extraconf', True) or '').strip()
323 if extraconf:
324 # Strip off any leading / trailing spaces
325 for line in extraconf.splitlines():
326 f.write(line.strip() + '\n')
327
328 f.write('require conf/locked-sigs.inc\n')
329 f.write('require conf/unlocked-sigs.inc\n')
330
331 if os.path.exists(builddir + '/conf/auto.conf'):
332 if derivative:
333 shutil.copyfile(builddir + '/conf/auto.conf', baseoutpath + '/conf/auto.conf')
334 else:
335 with open(builddir + '/conf/auto.conf', 'r') as f:
336 oldlines = f.readlines()
337 (updated, newlines) = bb.utils.edit_metadata(oldlines, varlist, handle_var)
338 with open(baseoutpath + '/conf/auto.conf', 'w') as f:
339 f.write('# WARNING: this configuration has been automatically generated and in\n')
340 f.write('# most cases should not be edited. If you need more flexibility than\n')
341 f.write('# this configuration provides, it is strongly suggested that you set\n')
342 f.write('# up a proper instance of the full build system and use that instead.\n\n')
343 for line in newlines:
344 if line.strip() and not line.startswith('#'):
345 f.write(line)
346
347 # Ensure any variables set from the external environment (by way of
348 # BB_ENV_EXTRAWHITE) are set in the SDK's configuration
349 extralines = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600350 for name, value in env_whitelist_values.items():
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500351 actualvalue = d.getVar(name, True) or ''
352 if value != actualvalue:
353 extralines.append('%s = "%s"\n' % (name, actualvalue))
354 if extralines:
355 with open(baseoutpath + '/conf/local.conf', 'a') as f:
356 f.write('\n')
357 f.write('# Extra settings from environment:\n')
358 for line in extralines:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500359 f.write(line)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500360 f.write('\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500361
362 # Filter the locked signatures file to just the sstate tasks we are interested in
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600363 excluded_targets = get_sdk_install_targets(d, images_only=True)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500364 sigfile = d.getVar('WORKDIR', True) + '/locked-sigs.inc'
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500365 lockedsigs_pruned = baseoutpath + '/conf/locked-sigs.inc'
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500366 oe.copy_buildsystem.prune_lockedsigs([],
367 excluded_targets.split(),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500368 sigfile,
369 lockedsigs_pruned)
370
371 sstate_out = baseoutpath + '/sstate-cache'
372 bb.utils.remove(sstate_out, True)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500373 # uninative.bbclass sets NATIVELSBSTRING to 'universal'
374 fixedlsbstring = 'universal'
375
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600376 sdk_include_toolchain = (d.getVar('SDK_INCLUDE_TOOLCHAIN', True) == '1')
377 sdk_ext_type = d.getVar('SDK_EXT_TYPE', True)
378 if sdk_ext_type != 'minimal' or sdk_include_toolchain or derivative:
379 # Create the filtered task list used to generate the sstate cache shipped with the SDK
380 tasklistfn = d.getVar('WORKDIR', True) + '/tasklist.txt'
381 create_filtered_tasklist(d, baseoutpath, tasklistfn, conf_initpath)
382 else:
383 tasklistfn = None
384
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500385 # Add packagedata if enabled
386 if d.getVar('SDK_INCLUDE_PKGDATA', True) == '1':
387 lockedsigs_base = d.getVar('WORKDIR', True) + '/locked-sigs-base.inc'
388 lockedsigs_copy = d.getVar('WORKDIR', True) + '/locked-sigs-copy.inc'
389 shutil.move(lockedsigs_pruned, lockedsigs_base)
390 oe.copy_buildsystem.merge_lockedsigs(['do_packagedata'],
391 lockedsigs_base,
392 d.getVar('STAGING_DIR_HOST', True) + '/world-pkgdata/locked-sigs-pkgdata.inc',
393 lockedsigs_pruned,
394 lockedsigs_copy)
395
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600396 if sdk_include_toolchain:
397 lockedsigs_base = d.getVar('WORKDIR', True) + '/locked-sigs-base2.inc'
398 lockedsigs_toolchain = d.getVar('STAGING_DIR_HOST', True) + '/locked-sigs/locked-sigs-extsdk-toolchain.inc'
399 shutil.move(lockedsigs_pruned, lockedsigs_base)
400 oe.copy_buildsystem.merge_lockedsigs([],
401 lockedsigs_base,
402 lockedsigs_toolchain,
403 lockedsigs_pruned)
404 oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_toolchain,
405 d.getVar('SSTATE_DIR', True),
406 sstate_out, d,
407 fixedlsbstring,
408 filterfile=tasklistfn)
409
410 if sdk_ext_type == 'minimal':
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500411 if derivative:
412 # Assume the user is not going to set up an additional sstate
413 # mirror, thus we need to copy the additional artifacts (from
414 # workspace recipes) into the derivative SDK
415 lockedsigs_orig = d.getVar('TOPDIR', True) + '/conf/locked-sigs.inc'
416 if os.path.exists(lockedsigs_orig):
417 lockedsigs_extra = d.getVar('WORKDIR', True) + '/locked-sigs-extra.inc'
418 oe.copy_buildsystem.merge_lockedsigs(None,
419 lockedsigs_orig,
420 lockedsigs_pruned,
421 None,
422 lockedsigs_extra)
423 oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_extra,
424 d.getVar('SSTATE_DIR', True),
425 sstate_out, d,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600426 fixedlsbstring,
427 filterfile=tasklistfn)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500428 else:
429 oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_pruned,
430 d.getVar('SSTATE_DIR', True),
431 sstate_out, d,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600432 fixedlsbstring,
433 filterfile=tasklistfn)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500434
435 # We don't need sstate do_package files
436 for root, dirs, files in os.walk(sstate_out):
437 for name in files:
438 if name.endswith("_package.tgz"):
439 f = os.path.join(root, name)
440 os.remove(f)
441
442 # Write manifest file
443 # Note: at the moment we cannot include the env setup script here to keep
444 # it updated, since it gets modified during SDK installation (see
445 # sdk_ext_postinst() below) thus the checksum we take here would always
446 # be different.
447 manifest_file_list = ['conf/*']
448 manifest_file = os.path.join(baseoutpath, 'conf', 'sdk-conf-manifest')
449 with open(manifest_file, 'w') as f:
450 for item in manifest_file_list:
451 for fn in glob.glob(os.path.join(baseoutpath, item)):
452 if fn == manifest_file:
453 continue
454 chksum = bb.utils.sha256_file(fn)
455 f.write('%s\t%s\n' % (chksum, os.path.relpath(fn, baseoutpath)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500456}
457
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600458def get_current_buildtools(d):
459 """Get the file name of the current buildtools installer"""
460 import glob
461 btfiles = glob.glob(os.path.join(d.getVar('SDK_DEPLOY', True), '*-buildtools-nativesdk-standalone-*.sh'))
462 btfiles.sort(key=os.path.getctime)
463 return os.path.basename(btfiles[-1])
464
465def get_sdk_required_utilities(buildtools_fn, d):
466 """Find required utilities that aren't provided by the buildtools"""
467 sanity_required_utilities = (d.getVar('SANITY_REQUIRED_UTILITIES', True) or '').split()
468 sanity_required_utilities.append(d.expand('${BUILD_PREFIX}gcc'))
469 sanity_required_utilities.append(d.expand('${BUILD_PREFIX}g++'))
470 buildtools_installer = os.path.join(d.getVar('SDK_DEPLOY', True), buildtools_fn)
471 filelist, _ = bb.process.run('%s -l' % buildtools_installer)
472 localdata = bb.data.createCopy(d)
473 localdata.setVar('SDKPATH', '.')
474 sdkpathnative = localdata.getVar('SDKPATHNATIVE', True)
475 sdkbindirs = [localdata.getVar('bindir_nativesdk', True),
476 localdata.getVar('sbindir_nativesdk', True),
477 localdata.getVar('base_bindir_nativesdk', True),
478 localdata.getVar('base_sbindir_nativesdk', True)]
479 for line in filelist.splitlines():
480 splitline = line.split()
481 if len(splitline) > 5:
482 fn = splitline[5]
483 if not fn.startswith('./'):
484 fn = './%s' % fn
485 if fn.startswith(sdkpathnative):
486 relpth = '/' + os.path.relpath(fn, sdkpathnative)
487 for bindir in sdkbindirs:
488 if relpth.startswith(bindir):
489 relpth = os.path.relpath(relpth, bindir)
490 if relpth in sanity_required_utilities:
491 sanity_required_utilities.remove(relpth)
492 break
493 return ' '.join(sanity_required_utilities)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500494
495install_tools() {
496 install -d ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600497 scripts="devtool recipetool oe-find-native-sysroot runqemu*"
498 for script in $scripts; do
499 for scriptfn in `find ${SDK_OUTPUT}/${SDKPATH}/${scriptrelpath} -maxdepth 1 -executable -name "$script"`; do
500 lnr ${scriptfn} ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}/`basename $scriptfn`
501 done
502 done
503 # We can't use the same method as above because files in the sysroot won't exist at this point
504 # (they get populated from sstate on installation)
505 if [ "${SDK_INCLUDE_TOOLCHAIN}" == "1" ] ; then
506 binrelpath=${@os.path.relpath(d.getVar('STAGING_BINDIR_NATIVE',True), d.getVar('TOPDIR', True))}
507 lnr ${SDK_OUTPUT}/${SDKPATH}/$binrelpath/unfsd ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}/unfsd
508 fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500509 touch ${SDK_OUTPUT}/${SDKPATH}/.devtoolbase
510
511 # find latest buildtools-tarball and install it
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600512 install ${SDK_DEPLOY}/${SDK_BUILDTOOLS_INSTALLER} ${SDK_OUTPUT}/${SDKPATH}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500513
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500514 install -m 0644 ${COREBASE}/meta/files/ext-sdk-prepare.py ${SDK_OUTPUT}/${SDKPATH}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500515}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500516do_populate_sdk_ext[file-checksums] += "${COREBASE}/meta/files/ext-sdk-prepare.py:True"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500517
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500518sdk_ext_preinst() {
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600519 # Since bitbake won't run as root it doesn't make sense to try and install
520 # the extensible sdk as root.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500521 if [ "`id -u`" = "0" ]; then
522 echo "ERROR: The extensible sdk cannot be installed as root."
523 exit 1
524 fi
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600525 if ! command -v locale > /dev/null; then
526 echo "ERROR: The installer requires the locale command, please install it first"
527 exit 1
528 fi
529 # Check setting of LC_ALL set above
530 canonicalised_locale=`echo $LC_ALL | sed 's/UTF-8/utf8/'`
531 if ! locale -a | grep -q $canonicalised_locale ; then
532 echo "ERROR: the installer requires the $LC_ALL locale to be installed (but not selected), please install it first"
533 exit 1
534 fi
535 # The relocation script used by buildtools installer requires python
536 if ! command -v python > /dev/null; then
537 echo "ERROR: The installer requires python, please install it first"
538 exit 1
539 fi
540 missing_utils=""
541 for util in ${SDK_REQUIRED_UTILITIES}; do
542 if ! command -v $util > /dev/null; then
543 missing_utils="$missing_utils $util"
544 fi
545 done
546 if [ -n "$missing_utils" ] ; then
547 echo "ERROR: the SDK requires the following missing utilities, please install them: $missing_utils"
548 exit 1
549 fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500550 SDK_EXTENSIBLE="1"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500551 if [ "$publish" = "1" ] ; then
552 EXTRA_TAR_OPTIONS="$EXTRA_TAR_OPTIONS --exclude=ext-sdk-prepare.py"
553 if [ "${SDK_EXT_TYPE}" = "minimal" ] ; then
554 EXTRA_TAR_OPTIONS="$EXTRA_TAR_OPTIONS --exclude=sstate-cache"
555 fi
556 fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500557}
558SDK_PRE_INSTALL_COMMAND_task-populate-sdk-ext = "${sdk_ext_preinst}"
559
560# FIXME this preparation should be done as part of the SDK construction
561sdk_ext_postinst() {
562 printf "\nExtracting buildtools...\n"
563 cd $target_sdk_dir
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600564 env_setup_script="$target_sdk_dir/environment-setup-${REAL_MULTIMACH_TARGET_SYS}"
565 printf "buildtools\ny" | ./${SDK_BUILDTOOLS_INSTALLER} > buildtools.log || { printf 'ERROR: buildtools installation failed:\n' ; cat buildtools.log ; echo "printf 'ERROR: this SDK was not fully installed and needs reinstalling\n'" >> $env_setup_script ; exit 1 ; }
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500566
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500567 # Delete the buildtools tar file since it won't be used again
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600568 rm -f ./${SDK_BUILDTOOLS_INSTALLER}
569 # We don't need the log either since it succeeded
570 rm -f buildtools.log
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500571
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500572 # Make sure when the user sets up the environment, they also get
573 # the buildtools-tarball tools in their path.
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500574 echo ". $target_sdk_dir/buildtools/environment-setup*" >> $env_setup_script
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500575
576 # Allow bitbake environment setup to be ran as part of this sdk.
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500577 echo "export OE_SKIP_SDK_CHECK=1" >> $env_setup_script
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500578
579 # A bit of another hack, but we need this in the path only for devtool
580 # so put it at the end of $PATH.
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500581 echo "export PATH=$target_sdk_dir/sysroots/${SDK_SYS}${bindir_nativesdk}:\$PATH" >> $env_setup_script
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500582
583 echo "printf 'SDK environment now set up; additionally you may now run devtool to perform development tasks.\nRun devtool --help for further details.\n'" >> $env_setup_script
584
585 # Warn if trying to use external bitbake and the ext SDK together
586 echo "(which bitbake > /dev/null 2>&1 && echo 'WARNING: attempting to use the extensible SDK in an environment set up to run bitbake - this may lead to unexpected results. Please source this script in a new shell session instead.') || true" >> $env_setup_script
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500587
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500588 if [ "$prepare_buildsystem" != "no" ]; then
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500589 printf "Preparing build system...\n"
590 # dash which is /bin/sh on Ubuntu will not preserve the
591 # current working directory when first ran, nor will it set $1 when
592 # sourcing a script. That is why this has to look so ugly.
593 LOGFILE="$target_sdk_dir/preparing_build_system.log"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600594 sh -c ". buildtools/environment-setup* > $LOGFILE && cd $target_sdk_dir/`dirname ${oe_init_build_env_path}` && set $target_sdk_dir && . $target_sdk_dir/${oe_init_build_env_path} $target_sdk_dir >> $LOGFILE && python $target_sdk_dir/ext-sdk-prepare.py $LOGFILE '${SDK_INSTALL_TARGETS}'" || { echo "printf 'ERROR: this SDK was not fully installed and needs reinstalling\n'" >> $env_setup_script ; exit 1 ; }
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500595 rm $target_sdk_dir/ext-sdk-prepare.py
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500596 fi
597 echo done
598}
599
600SDK_POST_INSTALL_COMMAND_task-populate-sdk-ext = "${sdk_ext_postinst}"
601
602SDK_POSTPROCESS_COMMAND_prepend_task-populate-sdk-ext = "copy_buildsystem; install_tools; "
603
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500604SDK_INSTALL_TARGETS = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500605fakeroot python do_populate_sdk_ext() {
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500606 # FIXME hopefully we can remove this restriction at some point, but uninative
607 # currently forces this upon us
608 if d.getVar('SDK_ARCH', True) != d.getVar('BUILD_ARCH', True):
609 bb.fatal('The extensible SDK can currently only be built for the same architecture as the machine being built on - SDK_ARCH is set to %s (likely via setting SDKMACHINE) which is different from the architecture of the build machine (%s). Unable to continue.' % (d.getVar('SDK_ARCH', True), d.getVar('BUILD_ARCH', True)))
610
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500611 d.setVar('SDK_INSTALL_TARGETS', get_sdk_install_targets(d))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600612 buildtools_fn = get_current_buildtools(d)
613 d.setVar('SDK_REQUIRED_UTILITIES', get_sdk_required_utilities(buildtools_fn, d))
614 d.setVar('SDK_BUILDTOOLS_INSTALLER', buildtools_fn)
615 d.setVar('SDKDEPLOYDIR', '${SDKEXTDEPLOYDIR}')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500616
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600617 populate_sdk_common(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500618}
619
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500620def get_ext_sdk_depends(d):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600621 # Note: the deps varflag is a list not a string, so we need to specify expand=False
622 deps = d.getVarFlag('do_image_complete', 'deps', False)
623 pn = d.getVar('PN', True)
624 deplist = ['%s:%s' % (pn, dep) for dep in deps]
625 for task in ['do_image_complete', 'do_rootfs', 'do_build']:
626 deplist.extend((d.getVarFlag(task, 'depends', True) or '').split())
627 return ' '.join(deplist)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500628
629python do_sdk_depends() {
630 # We have to do this separately in its own task so we avoid recursing into
631 # dependencies we don't need to (e.g. buildtools-tarball) and bringing those
632 # into the SDK's sstate-cache
633 import oe.copy_buildsystem
634 sigfile = d.getVar('WORKDIR', True) + '/locked-sigs.inc'
635 oe.copy_buildsystem.generate_locked_sigs(sigfile, d)
636}
637addtask sdk_depends
638
639do_sdk_depends[dirs] = "${WORKDIR}"
640do_sdk_depends[depends] = "${@get_ext_sdk_depends(d)}"
641do_sdk_depends[recrdeptask] = "${@d.getVarFlag('do_populate_sdk', 'recrdeptask', False)}"
642do_sdk_depends[recrdeptask] += "do_populate_lic do_package_qa do_populate_sysroot do_deploy ${SDK_RECRDEP_TASKS}"
643do_sdk_depends[rdepends] = "${@get_sdk_ext_rdepends(d)}"
644
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500645def get_sdk_ext_rdepends(d):
646 localdata = d.createCopy()
647 localdata.appendVar('OVERRIDES', ':task-populate-sdk-ext')
648 bb.data.update_data(localdata)
649 return localdata.getVarFlag('do_populate_sdk', 'rdepends', True)
650
651do_populate_sdk_ext[dirs] = "${@d.getVarFlag('do_populate_sdk', 'dirs', False)}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500652
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500653do_populate_sdk_ext[depends] = "${@d.getVarFlag('do_populate_sdk', 'depends', False)} \
654 buildtools-tarball:do_populate_sdk uninative-tarball:do_populate_sdk \
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600655 ${@'meta-world-pkgdata:do_collect_packagedata' if d.getVar('SDK_INCLUDE_PKGDATA', True) == '1' else ''} \
656 ${@'meta-extsdk-toolchain:do_locked_sigs' if d.getVar('SDK_INCLUDE_TOOLCHAIN', True) == '1' else ''}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500657
658do_populate_sdk_ext[rdepends] += "${@' '.join([x + ':do_build' for x in d.getVar('SDK_TARGETS', True).split()])}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500659
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500660# Make sure code changes can result in rebuild
661do_populate_sdk_ext[vardeps] += "copy_buildsystem \
662 sdk_ext_postinst"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500663
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500664# Since any change in the metadata of any layer should cause a rebuild of the
665# sdk(since the layers are put in the sdk) set the task to nostamp so it
666# always runs.
667do_populate_sdk_ext[nostamp] = "1"
668
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600669SDKEXTDEPLOYDIR = "${WORKDIR}/deploy-${PN}-populate-sdk-ext"
670
671SSTATETASKS += "do_populate_sdk_ext"
672SSTATE_SKIP_CREATION_task-populate-sdk-ext = '1'
673do_populate_sdk_ext[cleandirs] = "${SDKDEPLOYDIR}"
674do_populate_sdk_ext[sstate-inputdirs] = "${SDKEXTDEPLOYDIR}"
675do_populate_sdk_ext[sstate-outputdirs] = "${SDK_DEPLOY}"
676do_populate_sdk_ext[stamp-extra-info] = "${MACHINE}"
677
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500678addtask populate_sdk_ext after do_sdk_depends