blob: 39f6142741de8364882ff69e0a561dc3d5000875 [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
Brad Bishop37a0e4d2017-12-04 01:01:44 -050091 cleanpaths = 'cache conf/sanity_info tmp'.split()
Patrick Williamsc0f7c042017-02-23 20:41:17 -060092 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
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500308 f.write('BB_SETSCENE_ENFORCE_WHITELIST = "%:* *:do_shared_workdir *:do_rm_work *:do_package"\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)
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500311 f.write('BUILDCFG_HEADER = ""\n\n')
312
313 # Map gcc-dependent uninative sstate cache for installer usage
314 f.write('SSTATE_MIRRORS = "file://universal/(.*) file://universal-4.9/\\1\\nfile://universal-4.9/(.*) file://universal-4.8/\\1"\n\n')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500315
316 # Allow additional config through sdk-extra.conf
317 fn = bb.cookerdata.findConfigFile('sdk-extra.conf', d)
318 if fn:
319 with open(fn, 'r') as xf:
320 for line in xf:
321 f.write(line)
322
323 # If you define a sdk_extraconf() function then it can contain additional config
324 # (Though this is awkward; sdk-extra.conf should probably be used instead)
325 extraconf = (d.getVar('sdk_extraconf', True) or '').strip()
326 if extraconf:
327 # Strip off any leading / trailing spaces
328 for line in extraconf.splitlines():
329 f.write(line.strip() + '\n')
330
331 f.write('require conf/locked-sigs.inc\n')
332 f.write('require conf/unlocked-sigs.inc\n')
333
334 if os.path.exists(builddir + '/conf/auto.conf'):
335 if derivative:
336 shutil.copyfile(builddir + '/conf/auto.conf', baseoutpath + '/conf/auto.conf')
337 else:
338 with open(builddir + '/conf/auto.conf', 'r') as f:
339 oldlines = f.readlines()
340 (updated, newlines) = bb.utils.edit_metadata(oldlines, varlist, handle_var)
341 with open(baseoutpath + '/conf/auto.conf', 'w') as f:
342 f.write('# WARNING: this configuration has been automatically generated and in\n')
343 f.write('# most cases should not be edited. If you need more flexibility than\n')
344 f.write('# this configuration provides, it is strongly suggested that you set\n')
345 f.write('# up a proper instance of the full build system and use that instead.\n\n')
346 for line in newlines:
347 if line.strip() and not line.startswith('#'):
348 f.write(line)
349
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500350 # Write a templateconf.cfg
351 with open(baseoutpath + '/conf/templateconf.cfg', 'w') as f:
352 f.write('meta/conf\n')
353
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500354 # Ensure any variables set from the external environment (by way of
355 # BB_ENV_EXTRAWHITE) are set in the SDK's configuration
356 extralines = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600357 for name, value in env_whitelist_values.items():
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500358 actualvalue = d.getVar(name, True) or ''
359 if value != actualvalue:
360 extralines.append('%s = "%s"\n' % (name, actualvalue))
361 if extralines:
362 with open(baseoutpath + '/conf/local.conf', 'a') as f:
363 f.write('\n')
364 f.write('# Extra settings from environment:\n')
365 for line in extralines:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500366 f.write(line)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500367 f.write('\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500368
369 # Filter the locked signatures file to just the sstate tasks we are interested in
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600370 excluded_targets = get_sdk_install_targets(d, images_only=True)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500371 sigfile = d.getVar('WORKDIR', True) + '/locked-sigs.inc'
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500372 lockedsigs_pruned = baseoutpath + '/conf/locked-sigs.inc'
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500373 oe.copy_buildsystem.prune_lockedsigs([],
374 excluded_targets.split(),
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500375 sigfile,
376 lockedsigs_pruned)
377
378 sstate_out = baseoutpath + '/sstate-cache'
379 bb.utils.remove(sstate_out, True)
Brad Bishop37a0e4d2017-12-04 01:01:44 -0500380
381 # uninative.bbclass sets NATIVELSBSTRING to 'universal%s' % oe.utils.host_gcc_version(d)
382 fixedlsbstring = "universal%s" % oe.utils.host_gcc_version(d)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500383
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600384 sdk_include_toolchain = (d.getVar('SDK_INCLUDE_TOOLCHAIN', True) == '1')
385 sdk_ext_type = d.getVar('SDK_EXT_TYPE', True)
386 if sdk_ext_type != 'minimal' or sdk_include_toolchain or derivative:
387 # Create the filtered task list used to generate the sstate cache shipped with the SDK
388 tasklistfn = d.getVar('WORKDIR', True) + '/tasklist.txt'
389 create_filtered_tasklist(d, baseoutpath, tasklistfn, conf_initpath)
390 else:
391 tasklistfn = None
392
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500393 # Add packagedata if enabled
394 if d.getVar('SDK_INCLUDE_PKGDATA', True) == '1':
395 lockedsigs_base = d.getVar('WORKDIR', True) + '/locked-sigs-base.inc'
396 lockedsigs_copy = d.getVar('WORKDIR', True) + '/locked-sigs-copy.inc'
397 shutil.move(lockedsigs_pruned, lockedsigs_base)
398 oe.copy_buildsystem.merge_lockedsigs(['do_packagedata'],
399 lockedsigs_base,
400 d.getVar('STAGING_DIR_HOST', True) + '/world-pkgdata/locked-sigs-pkgdata.inc',
401 lockedsigs_pruned,
402 lockedsigs_copy)
403
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600404 if sdk_include_toolchain:
405 lockedsigs_base = d.getVar('WORKDIR', True) + '/locked-sigs-base2.inc'
406 lockedsigs_toolchain = d.getVar('STAGING_DIR_HOST', True) + '/locked-sigs/locked-sigs-extsdk-toolchain.inc'
407 shutil.move(lockedsigs_pruned, lockedsigs_base)
408 oe.copy_buildsystem.merge_lockedsigs([],
409 lockedsigs_base,
410 lockedsigs_toolchain,
411 lockedsigs_pruned)
412 oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_toolchain,
413 d.getVar('SSTATE_DIR', True),
414 sstate_out, d,
415 fixedlsbstring,
416 filterfile=tasklistfn)
417
418 if sdk_ext_type == 'minimal':
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500419 if derivative:
420 # Assume the user is not going to set up an additional sstate
421 # mirror, thus we need to copy the additional artifacts (from
422 # workspace recipes) into the derivative SDK
423 lockedsigs_orig = d.getVar('TOPDIR', True) + '/conf/locked-sigs.inc'
424 if os.path.exists(lockedsigs_orig):
425 lockedsigs_extra = d.getVar('WORKDIR', True) + '/locked-sigs-extra.inc'
426 oe.copy_buildsystem.merge_lockedsigs(None,
427 lockedsigs_orig,
428 lockedsigs_pruned,
429 None,
430 lockedsigs_extra)
431 oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_extra,
432 d.getVar('SSTATE_DIR', True),
433 sstate_out, d,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600434 fixedlsbstring,
435 filterfile=tasklistfn)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500436 else:
437 oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_pruned,
438 d.getVar('SSTATE_DIR', True),
439 sstate_out, d,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600440 fixedlsbstring,
441 filterfile=tasklistfn)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500442
443 # We don't need sstate do_package files
444 for root, dirs, files in os.walk(sstate_out):
445 for name in files:
446 if name.endswith("_package.tgz"):
447 f = os.path.join(root, name)
448 os.remove(f)
449
450 # Write manifest file
451 # Note: at the moment we cannot include the env setup script here to keep
452 # it updated, since it gets modified during SDK installation (see
453 # sdk_ext_postinst() below) thus the checksum we take here would always
454 # be different.
455 manifest_file_list = ['conf/*']
456 manifest_file = os.path.join(baseoutpath, 'conf', 'sdk-conf-manifest')
457 with open(manifest_file, 'w') as f:
458 for item in manifest_file_list:
459 for fn in glob.glob(os.path.join(baseoutpath, item)):
460 if fn == manifest_file:
461 continue
462 chksum = bb.utils.sha256_file(fn)
463 f.write('%s\t%s\n' % (chksum, os.path.relpath(fn, baseoutpath)))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500464}
465
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600466def get_current_buildtools(d):
467 """Get the file name of the current buildtools installer"""
468 import glob
469 btfiles = glob.glob(os.path.join(d.getVar('SDK_DEPLOY', True), '*-buildtools-nativesdk-standalone-*.sh'))
470 btfiles.sort(key=os.path.getctime)
471 return os.path.basename(btfiles[-1])
472
473def get_sdk_required_utilities(buildtools_fn, d):
474 """Find required utilities that aren't provided by the buildtools"""
475 sanity_required_utilities = (d.getVar('SANITY_REQUIRED_UTILITIES', True) or '').split()
476 sanity_required_utilities.append(d.expand('${BUILD_PREFIX}gcc'))
477 sanity_required_utilities.append(d.expand('${BUILD_PREFIX}g++'))
478 buildtools_installer = os.path.join(d.getVar('SDK_DEPLOY', True), buildtools_fn)
479 filelist, _ = bb.process.run('%s -l' % buildtools_installer)
480 localdata = bb.data.createCopy(d)
481 localdata.setVar('SDKPATH', '.')
482 sdkpathnative = localdata.getVar('SDKPATHNATIVE', True)
483 sdkbindirs = [localdata.getVar('bindir_nativesdk', True),
484 localdata.getVar('sbindir_nativesdk', True),
485 localdata.getVar('base_bindir_nativesdk', True),
486 localdata.getVar('base_sbindir_nativesdk', True)]
487 for line in filelist.splitlines():
488 splitline = line.split()
489 if len(splitline) > 5:
490 fn = splitline[5]
491 if not fn.startswith('./'):
492 fn = './%s' % fn
493 if fn.startswith(sdkpathnative):
494 relpth = '/' + os.path.relpath(fn, sdkpathnative)
495 for bindir in sdkbindirs:
496 if relpth.startswith(bindir):
497 relpth = os.path.relpath(relpth, bindir)
498 if relpth in sanity_required_utilities:
499 sanity_required_utilities.remove(relpth)
500 break
501 return ' '.join(sanity_required_utilities)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500502
503install_tools() {
504 install -d ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600505 scripts="devtool recipetool oe-find-native-sysroot runqemu*"
506 for script in $scripts; do
507 for scriptfn in `find ${SDK_OUTPUT}/${SDKPATH}/${scriptrelpath} -maxdepth 1 -executable -name "$script"`; do
508 lnr ${scriptfn} ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}/`basename $scriptfn`
509 done
510 done
511 # We can't use the same method as above because files in the sysroot won't exist at this point
512 # (they get populated from sstate on installation)
513 if [ "${SDK_INCLUDE_TOOLCHAIN}" == "1" ] ; then
514 binrelpath=${@os.path.relpath(d.getVar('STAGING_BINDIR_NATIVE',True), d.getVar('TOPDIR', True))}
515 lnr ${SDK_OUTPUT}/${SDKPATH}/$binrelpath/unfsd ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}/unfsd
516 fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500517 touch ${SDK_OUTPUT}/${SDKPATH}/.devtoolbase
518
519 # find latest buildtools-tarball and install it
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600520 install ${SDK_DEPLOY}/${SDK_BUILDTOOLS_INSTALLER} ${SDK_OUTPUT}/${SDKPATH}
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500521
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500522 install -m 0644 ${COREBASE}/meta/files/ext-sdk-prepare.py ${SDK_OUTPUT}/${SDKPATH}
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500523}
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500524do_populate_sdk_ext[file-checksums] += "${COREBASE}/meta/files/ext-sdk-prepare.py:True"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500525
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500526sdk_ext_preinst() {
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600527 # Since bitbake won't run as root it doesn't make sense to try and install
528 # the extensible sdk as root.
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500529 if [ "`id -u`" = "0" ]; then
530 echo "ERROR: The extensible sdk cannot be installed as root."
531 exit 1
532 fi
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600533 if ! command -v locale > /dev/null; then
534 echo "ERROR: The installer requires the locale command, please install it first"
535 exit 1
536 fi
537 # Check setting of LC_ALL set above
538 canonicalised_locale=`echo $LC_ALL | sed 's/UTF-8/utf8/'`
539 if ! locale -a | grep -q $canonicalised_locale ; then
540 echo "ERROR: the installer requires the $LC_ALL locale to be installed (but not selected), please install it first"
541 exit 1
542 fi
543 # The relocation script used by buildtools installer requires python
544 if ! command -v python > /dev/null; then
545 echo "ERROR: The installer requires python, please install it first"
546 exit 1
547 fi
548 missing_utils=""
549 for util in ${SDK_REQUIRED_UTILITIES}; do
550 if ! command -v $util > /dev/null; then
551 missing_utils="$missing_utils $util"
552 fi
553 done
554 if [ -n "$missing_utils" ] ; then
555 echo "ERROR: the SDK requires the following missing utilities, please install them: $missing_utils"
556 exit 1
557 fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500558 SDK_EXTENSIBLE="1"
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500559 if [ "$publish" = "1" ] ; then
560 EXTRA_TAR_OPTIONS="$EXTRA_TAR_OPTIONS --exclude=ext-sdk-prepare.py"
561 if [ "${SDK_EXT_TYPE}" = "minimal" ] ; then
562 EXTRA_TAR_OPTIONS="$EXTRA_TAR_OPTIONS --exclude=sstate-cache"
563 fi
564 fi
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500565}
566SDK_PRE_INSTALL_COMMAND_task-populate-sdk-ext = "${sdk_ext_preinst}"
567
568# FIXME this preparation should be done as part of the SDK construction
569sdk_ext_postinst() {
570 printf "\nExtracting buildtools...\n"
571 cd $target_sdk_dir
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600572 env_setup_script="$target_sdk_dir/environment-setup-${REAL_MULTIMACH_TARGET_SYS}"
573 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 -0500574
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500575 # Delete the buildtools tar file since it won't be used again
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600576 rm -f ./${SDK_BUILDTOOLS_INSTALLER}
577 # We don't need the log either since it succeeded
578 rm -f buildtools.log
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500579
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500580 # Make sure when the user sets up the environment, they also get
581 # the buildtools-tarball tools in their path.
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500582 echo ". $target_sdk_dir/buildtools/environment-setup*" >> $env_setup_script
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500583
584 # Allow bitbake environment setup to be ran as part of this sdk.
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500585 echo "export OE_SKIP_SDK_CHECK=1" >> $env_setup_script
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500586
587 # A bit of another hack, but we need this in the path only for devtool
588 # so put it at the end of $PATH.
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500589 echo "export PATH=$target_sdk_dir/sysroots/${SDK_SYS}${bindir_nativesdk}:\$PATH" >> $env_setup_script
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500590
591 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
592
593 # Warn if trying to use external bitbake and the ext SDK together
594 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 -0500595
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500596 if [ "$prepare_buildsystem" != "no" ]; then
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500597 printf "Preparing build system...\n"
598 # dash which is /bin/sh on Ubuntu will not preserve the
599 # current working directory when first ran, nor will it set $1 when
600 # sourcing a script. That is why this has to look so ugly.
601 LOGFILE="$target_sdk_dir/preparing_build_system.log"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600602 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 -0500603 rm $target_sdk_dir/ext-sdk-prepare.py
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500604 fi
605 echo done
606}
607
608SDK_POST_INSTALL_COMMAND_task-populate-sdk-ext = "${sdk_ext_postinst}"
609
610SDK_POSTPROCESS_COMMAND_prepend_task-populate-sdk-ext = "copy_buildsystem; install_tools; "
611
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500612SDK_INSTALL_TARGETS = ""
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500613fakeroot python do_populate_sdk_ext() {
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500614 # FIXME hopefully we can remove this restriction at some point, but uninative
615 # currently forces this upon us
616 if d.getVar('SDK_ARCH', True) != d.getVar('BUILD_ARCH', True):
617 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)))
618
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500619 d.setVar('SDK_INSTALL_TARGETS', get_sdk_install_targets(d))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600620 buildtools_fn = get_current_buildtools(d)
621 d.setVar('SDK_REQUIRED_UTILITIES', get_sdk_required_utilities(buildtools_fn, d))
622 d.setVar('SDK_BUILDTOOLS_INSTALLER', buildtools_fn)
623 d.setVar('SDKDEPLOYDIR', '${SDKEXTDEPLOYDIR}')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500624
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600625 populate_sdk_common(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500626}
627
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500628def get_ext_sdk_depends(d):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600629 # Note: the deps varflag is a list not a string, so we need to specify expand=False
630 deps = d.getVarFlag('do_image_complete', 'deps', False)
631 pn = d.getVar('PN', True)
632 deplist = ['%s:%s' % (pn, dep) for dep in deps]
633 for task in ['do_image_complete', 'do_rootfs', 'do_build']:
634 deplist.extend((d.getVarFlag(task, 'depends', True) or '').split())
635 return ' '.join(deplist)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500636
637python do_sdk_depends() {
638 # We have to do this separately in its own task so we avoid recursing into
639 # dependencies we don't need to (e.g. buildtools-tarball) and bringing those
640 # into the SDK's sstate-cache
641 import oe.copy_buildsystem
642 sigfile = d.getVar('WORKDIR', True) + '/locked-sigs.inc'
643 oe.copy_buildsystem.generate_locked_sigs(sigfile, d)
644}
645addtask sdk_depends
646
647do_sdk_depends[dirs] = "${WORKDIR}"
648do_sdk_depends[depends] = "${@get_ext_sdk_depends(d)}"
649do_sdk_depends[recrdeptask] = "${@d.getVarFlag('do_populate_sdk', 'recrdeptask', False)}"
650do_sdk_depends[recrdeptask] += "do_populate_lic do_package_qa do_populate_sysroot do_deploy ${SDK_RECRDEP_TASKS}"
651do_sdk_depends[rdepends] = "${@get_sdk_ext_rdepends(d)}"
652
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500653def get_sdk_ext_rdepends(d):
654 localdata = d.createCopy()
655 localdata.appendVar('OVERRIDES', ':task-populate-sdk-ext')
656 bb.data.update_data(localdata)
657 return localdata.getVarFlag('do_populate_sdk', 'rdepends', True)
658
659do_populate_sdk_ext[dirs] = "${@d.getVarFlag('do_populate_sdk', 'dirs', False)}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500660
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500661do_populate_sdk_ext[depends] = "${@d.getVarFlag('do_populate_sdk', 'depends', False)} \
662 buildtools-tarball:do_populate_sdk uninative-tarball:do_populate_sdk \
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600663 ${@'meta-world-pkgdata:do_collect_packagedata' if d.getVar('SDK_INCLUDE_PKGDATA', True) == '1' else ''} \
664 ${@'meta-extsdk-toolchain:do_locked_sigs' if d.getVar('SDK_INCLUDE_TOOLCHAIN', True) == '1' else ''}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500665
666do_populate_sdk_ext[rdepends] += "${@' '.join([x + ':do_build' for x in d.getVar('SDK_TARGETS', True).split()])}"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500667
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500668# Make sure code changes can result in rebuild
669do_populate_sdk_ext[vardeps] += "copy_buildsystem \
670 sdk_ext_postinst"
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500671
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500672# Since any change in the metadata of any layer should cause a rebuild of the
673# sdk(since the layers are put in the sdk) set the task to nostamp so it
674# always runs.
675do_populate_sdk_ext[nostamp] = "1"
676
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600677SDKEXTDEPLOYDIR = "${WORKDIR}/deploy-${PN}-populate-sdk-ext"
678
679SSTATETASKS += "do_populate_sdk_ext"
680SSTATE_SKIP_CREATION_task-populate-sdk-ext = '1'
681do_populate_sdk_ext[cleandirs] = "${SDKDEPLOYDIR}"
682do_populate_sdk_ext[sstate-inputdirs] = "${SDKEXTDEPLOYDIR}"
683do_populate_sdk_ext[sstate-outputdirs] = "${SDK_DEPLOY}"
684do_populate_sdk_ext[stamp-extra-info] = "${MACHINE}"
685
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500686addtask populate_sdk_ext after do_sdk_depends