1*4882a593Smuzhiyun# Extensible SDK 2*4882a593Smuzhiyun 3*4882a593Smuzhiyuninherit populate_sdk_base 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun# Used to override TOOLCHAIN_HOST_TASK in the eSDK case 6*4882a593SmuzhiyunTOOLCHAIN_HOST_TASK_ESDK = " \ 7*4882a593Smuzhiyun meta-environment-extsdk-${MACHINE} \ 8*4882a593Smuzhiyun " 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunSDK_RELOCATE_AFTER_INSTALL:task-populate-sdk-ext = "0" 11*4882a593Smuzhiyun 12*4882a593SmuzhiyunSDK_EXT = "" 13*4882a593SmuzhiyunSDK_EXT:task-populate-sdk-ext = "-ext" 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun# Options are full or minimal 16*4882a593SmuzhiyunSDK_EXT_TYPE ?= "full" 17*4882a593SmuzhiyunSDK_INCLUDE_PKGDATA ?= "0" 18*4882a593SmuzhiyunSDK_INCLUDE_TOOLCHAIN ?= "${@'1' if d.getVar('SDK_EXT_TYPE') == 'full' else '0'}" 19*4882a593SmuzhiyunSDK_INCLUDE_NATIVESDK ?= "0" 20*4882a593SmuzhiyunSDK_INCLUDE_BUILDTOOLS ?= '1' 21*4882a593Smuzhiyun 22*4882a593SmuzhiyunSDK_RECRDEP_TASKS ?= "" 23*4882a593SmuzhiyunSDK_CUSTOM_TEMPLATECONF ?= "0" 24*4882a593Smuzhiyun 25*4882a593SmuzhiyunESDK_LOCALCONF_ALLOW ?= "" 26*4882a593SmuzhiyunESDK_LOCALCONF_REMOVE ?= "CONF_VERSION \ 27*4882a593Smuzhiyun BB_NUMBER_THREADS \ 28*4882a593Smuzhiyun BB_NUMBER_PARSE_THREADS \ 29*4882a593Smuzhiyun PARALLEL_MAKE \ 30*4882a593Smuzhiyun PRSERV_HOST \ 31*4882a593Smuzhiyun SSTATE_MIRRORS \ 32*4882a593Smuzhiyun DL_DIR \ 33*4882a593Smuzhiyun SSTATE_DIR \ 34*4882a593Smuzhiyun TMPDIR \ 35*4882a593Smuzhiyun BB_SERVER_TIMEOUT \ 36*4882a593Smuzhiyun " 37*4882a593SmuzhiyunESDK_CLASS_INHERIT_DISABLE ?= "buildhistory icecc" 38*4882a593SmuzhiyunSDK_UPDATE_URL ?= "" 39*4882a593Smuzhiyun 40*4882a593SmuzhiyunSDK_TARGETS ?= "${PN}" 41*4882a593Smuzhiyun 42*4882a593Smuzhiyundef get_sdk_install_targets(d, images_only=False): 43*4882a593Smuzhiyun sdk_install_targets = '' 44*4882a593Smuzhiyun if images_only or d.getVar('SDK_EXT_TYPE') != 'minimal': 45*4882a593Smuzhiyun sdk_install_targets = d.getVar('SDK_TARGETS') 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun depd = d.getVar('BB_TASKDEPDATA', False) 48*4882a593Smuzhiyun tasklist = bb.build.tasksbetween('do_image_complete', 'do_build', d) 49*4882a593Smuzhiyun tasklist.remove('do_build') 50*4882a593Smuzhiyun for v in depd.values(): 51*4882a593Smuzhiyun if v[1] in tasklist: 52*4882a593Smuzhiyun if v[0] not in sdk_install_targets: 53*4882a593Smuzhiyun sdk_install_targets += ' {}'.format(v[0]) 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun if not images_only: 56*4882a593Smuzhiyun if d.getVar('SDK_INCLUDE_PKGDATA') == '1': 57*4882a593Smuzhiyun sdk_install_targets += ' meta-world-pkgdata:do_allpackagedata' 58*4882a593Smuzhiyun if d.getVar('SDK_INCLUDE_TOOLCHAIN') == '1': 59*4882a593Smuzhiyun sdk_install_targets += ' meta-extsdk-toolchain:do_populate_sysroot' 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun return sdk_install_targets 62*4882a593Smuzhiyun 63*4882a593Smuzhiyunget_sdk_install_targets[vardepsexclude] = "BB_TASKDEPDATA" 64*4882a593Smuzhiyun 65*4882a593SmuzhiyunOE_INIT_ENV_SCRIPT ?= "oe-init-build-env" 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun# The files from COREBASE that you want preserved in the COREBASE copied 68*4882a593Smuzhiyun# into the sdk. This allows someone to have their own setup scripts in 69*4882a593Smuzhiyun# COREBASE be preserved as well as untracked files. 70*4882a593SmuzhiyunCOREBASE_FILES ?= " \ 71*4882a593Smuzhiyun oe-init-build-env \ 72*4882a593Smuzhiyun scripts \ 73*4882a593Smuzhiyun LICENSE \ 74*4882a593Smuzhiyun .templateconf \ 75*4882a593Smuzhiyun" 76*4882a593Smuzhiyun 77*4882a593SmuzhiyunSDK_DIR:task-populate-sdk-ext = "${WORKDIR}/sdk-ext" 78*4882a593SmuzhiyunB:task-populate-sdk-ext = "${SDK_DIR}" 79*4882a593SmuzhiyunTOOLCHAINEXT_OUTPUTNAME ?= "${SDK_NAME}-toolchain-ext-${SDK_VERSION}" 80*4882a593SmuzhiyunTOOLCHAIN_OUTPUTNAME:task-populate-sdk-ext = "${TOOLCHAINEXT_OUTPUTNAME}" 81*4882a593Smuzhiyun 82*4882a593SmuzhiyunSDK_EXT_TARGET_MANIFEST = "${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.target.manifest" 83*4882a593SmuzhiyunSDK_EXT_HOST_MANIFEST = "${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.host.manifest" 84*4882a593Smuzhiyun 85*4882a593Smuzhiyunpython write_target_sdk_ext_manifest () { 86*4882a593Smuzhiyun from oe.sdk import get_extra_sdkinfo 87*4882a593Smuzhiyun sstate_dir = d.expand('${SDK_OUTPUT}/${SDKPATH}/sstate-cache') 88*4882a593Smuzhiyun extra_info = get_extra_sdkinfo(sstate_dir) 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun target = d.getVar('TARGET_SYS') 91*4882a593Smuzhiyun target_multimach = d.getVar('MULTIMACH_TARGET_SYS') 92*4882a593Smuzhiyun real_target_multimach = d.getVar('REAL_MULTIMACH_TARGET_SYS') 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun pkgs = {} 95*4882a593Smuzhiyun os.makedirs(os.path.dirname(d.getVar('SDK_EXT_TARGET_MANIFEST')), exist_ok=True) 96*4882a593Smuzhiyun with open(d.getVar('SDK_EXT_TARGET_MANIFEST'), 'w') as f: 97*4882a593Smuzhiyun for fn in extra_info['filesizes']: 98*4882a593Smuzhiyun info = fn.split(':') 99*4882a593Smuzhiyun if info[2] in (target, target_multimach, real_target_multimach) \ 100*4882a593Smuzhiyun or info[5] == 'allarch': 101*4882a593Smuzhiyun if not info[1] in pkgs: 102*4882a593Smuzhiyun f.write("%s %s %s\n" % (info[1], info[2], info[3])) 103*4882a593Smuzhiyun pkgs[info[1]] = {} 104*4882a593Smuzhiyun} 105*4882a593Smuzhiyunpython write_host_sdk_ext_manifest () { 106*4882a593Smuzhiyun from oe.sdk import get_extra_sdkinfo 107*4882a593Smuzhiyun sstate_dir = d.expand('${SDK_OUTPUT}/${SDKPATH}/sstate-cache') 108*4882a593Smuzhiyun extra_info = get_extra_sdkinfo(sstate_dir) 109*4882a593Smuzhiyun host = d.getVar('BUILD_SYS') 110*4882a593Smuzhiyun with open(d.getVar('SDK_EXT_HOST_MANIFEST'), 'w') as f: 111*4882a593Smuzhiyun for fn in extra_info['filesizes']: 112*4882a593Smuzhiyun info = fn.split(':') 113*4882a593Smuzhiyun if info[2] == host: 114*4882a593Smuzhiyun f.write("%s %s %s\n" % (info[1], info[2], info[3])) 115*4882a593Smuzhiyun} 116*4882a593Smuzhiyun 117*4882a593SmuzhiyunSDK_POSTPROCESS_COMMAND:append:task-populate-sdk-ext = " write_target_sdk_ext_manifest; write_host_sdk_ext_manifest; " 118*4882a593Smuzhiyun 119*4882a593SmuzhiyunSDK_TITLE:task-populate-sdk-ext = "${@d.getVar('DISTRO_NAME') or d.getVar('DISTRO')} Extensible SDK" 120*4882a593Smuzhiyun 121*4882a593Smuzhiyundef clean_esdk_builddir(d, sdkbasepath): 122*4882a593Smuzhiyun """Clean up traces of the fake build for create_filtered_tasklist()""" 123*4882a593Smuzhiyun import shutil 124*4882a593Smuzhiyun cleanpaths = ['cache', 'tmp'] 125*4882a593Smuzhiyun for pth in cleanpaths: 126*4882a593Smuzhiyun fullpth = os.path.join(sdkbasepath, pth) 127*4882a593Smuzhiyun if os.path.isdir(fullpth): 128*4882a593Smuzhiyun shutil.rmtree(fullpth) 129*4882a593Smuzhiyun elif os.path.isfile(fullpth): 130*4882a593Smuzhiyun os.remove(fullpth) 131*4882a593Smuzhiyun 132*4882a593Smuzhiyundef create_filtered_tasklist(d, sdkbasepath, tasklistfile, conf_initpath): 133*4882a593Smuzhiyun """ 134*4882a593Smuzhiyun Create a filtered list of tasks. Also double-checks that the build system 135*4882a593Smuzhiyun within the SDK basically works and required sstate artifacts are available. 136*4882a593Smuzhiyun """ 137*4882a593Smuzhiyun import tempfile 138*4882a593Smuzhiyun import shutil 139*4882a593Smuzhiyun import oe.copy_buildsystem 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun # Create a temporary build directory that we can pass to the env setup script 142*4882a593Smuzhiyun shutil.copyfile(sdkbasepath + '/conf/local.conf', sdkbasepath + '/conf/local.conf.bak') 143*4882a593Smuzhiyun try: 144*4882a593Smuzhiyun with open(sdkbasepath + '/conf/local.conf', 'a') as f: 145*4882a593Smuzhiyun # Force the use of sstate from the build system 146*4882a593Smuzhiyun f.write('\nSSTATE_DIR:forcevariable = "%s"\n' % d.getVar('SSTATE_DIR')) 147*4882a593Smuzhiyun f.write('SSTATE_MIRRORS:forcevariable = "file://universal/(.*) file://universal-4.9/\\1 file://universal-4.9/(.*) file://universal-4.8/\\1"\n') 148*4882a593Smuzhiyun # Ensure TMPDIR is the default so that clean_esdk_builddir() can delete it 149*4882a593Smuzhiyun f.write('TMPDIR:forcevariable = "${TOPDIR}/tmp"\n') 150*4882a593Smuzhiyun f.write('TCLIBCAPPEND:forcevariable = ""\n') 151*4882a593Smuzhiyun # Drop uninative if the build isn't using it (or else NATIVELSBSTRING will 152*4882a593Smuzhiyun # be different and we won't be able to find our native sstate) 153*4882a593Smuzhiyun if not bb.data.inherits_class('uninative', d): 154*4882a593Smuzhiyun f.write('INHERIT:remove = "uninative"\n') 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun # Unfortunately the default SDKPATH (or even a custom value) may contain characters that bitbake 157*4882a593Smuzhiyun # will not allow in its COREBASE path, so we need to rename the directory temporarily 158*4882a593Smuzhiyun temp_sdkbasepath = d.getVar('SDK_OUTPUT') + '/tmp-renamed-sdk' 159*4882a593Smuzhiyun # Delete any existing temp dir 160*4882a593Smuzhiyun try: 161*4882a593Smuzhiyun shutil.rmtree(temp_sdkbasepath) 162*4882a593Smuzhiyun except FileNotFoundError: 163*4882a593Smuzhiyun pass 164*4882a593Smuzhiyun bb.utils.rename(sdkbasepath, temp_sdkbasepath) 165*4882a593Smuzhiyun cmdprefix = '. %s .; ' % conf_initpath 166*4882a593Smuzhiyun logfile = d.getVar('WORKDIR') + '/tasklist_bb_log.txt' 167*4882a593Smuzhiyun try: 168*4882a593Smuzhiyun oe.copy_buildsystem.check_sstate_task_list(d, get_sdk_install_targets(d), tasklistfile, cmdprefix=cmdprefix, cwd=temp_sdkbasepath, logfile=logfile) 169*4882a593Smuzhiyun except bb.process.ExecutionError as e: 170*4882a593Smuzhiyun msg = 'Failed to generate filtered task list for extensible SDK:\n%s' % e.stdout.rstrip() 171*4882a593Smuzhiyun if 'attempted to execute unexpectedly and should have been setscened' in e.stdout: 172*4882a593Smuzhiyun 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' 173*4882a593Smuzhiyun bb.fatal(msg) 174*4882a593Smuzhiyun bb.utils.rename(temp_sdkbasepath, sdkbasepath) 175*4882a593Smuzhiyun # Clean out residue of running bitbake, which check_sstate_task_list() 176*4882a593Smuzhiyun # will effectively do 177*4882a593Smuzhiyun clean_esdk_builddir(d, sdkbasepath) 178*4882a593Smuzhiyun finally: 179*4882a593Smuzhiyun localconf = sdkbasepath + '/conf/local.conf' 180*4882a593Smuzhiyun if os.path.exists(localconf + '.bak'): 181*4882a593Smuzhiyun os.replace(localconf + '.bak', localconf) 182*4882a593Smuzhiyun 183*4882a593Smuzhiyunpython copy_buildsystem () { 184*4882a593Smuzhiyun import re 185*4882a593Smuzhiyun import shutil 186*4882a593Smuzhiyun import glob 187*4882a593Smuzhiyun import oe.copy_buildsystem 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun oe_init_env_script = d.getVar('OE_INIT_ENV_SCRIPT') 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun conf_bbpath = '' 192*4882a593Smuzhiyun conf_initpath = '' 193*4882a593Smuzhiyun core_meta_subdir = '' 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun # Copy in all metadata layers + bitbake (as repositories) 196*4882a593Smuzhiyun buildsystem = oe.copy_buildsystem.BuildSystem('extensible SDK', d) 197*4882a593Smuzhiyun baseoutpath = d.getVar('SDK_OUTPUT') + '/' + d.getVar('SDKPATH') 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun #check if custome templateconf path is set 200*4882a593Smuzhiyun use_custom_templateconf = d.getVar('SDK_CUSTOM_TEMPLATECONF') 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun # Determine if we're building a derivative extensible SDK (from devtool build-sdk) 203*4882a593Smuzhiyun derivative = (d.getVar('SDK_DERIVATIVE') or '') == '1' 204*4882a593Smuzhiyun if derivative: 205*4882a593Smuzhiyun workspace_name = 'orig-workspace' 206*4882a593Smuzhiyun else: 207*4882a593Smuzhiyun workspace_name = None 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun corebase, sdkbblayers = buildsystem.copy_bitbake_and_layers(baseoutpath + '/layers', workspace_name) 210*4882a593Smuzhiyun conf_bbpath = os.path.join('layers', corebase, 'bitbake') 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun for path in os.listdir(baseoutpath + '/layers'): 213*4882a593Smuzhiyun relpath = os.path.join('layers', path, oe_init_env_script) 214*4882a593Smuzhiyun if os.path.exists(os.path.join(baseoutpath, relpath)): 215*4882a593Smuzhiyun conf_initpath = relpath 216*4882a593Smuzhiyun 217*4882a593Smuzhiyun relpath = os.path.join('layers', path, 'scripts', 'devtool') 218*4882a593Smuzhiyun if os.path.exists(os.path.join(baseoutpath, relpath)): 219*4882a593Smuzhiyun scriptrelpath = os.path.dirname(relpath) 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun relpath = os.path.join('layers', path, 'meta') 222*4882a593Smuzhiyun if os.path.exists(os.path.join(baseoutpath, relpath, 'lib', 'oe')): 223*4882a593Smuzhiyun core_meta_subdir = relpath 224*4882a593Smuzhiyun 225*4882a593Smuzhiyun d.setVar('oe_init_build_env_path', conf_initpath) 226*4882a593Smuzhiyun d.setVar('scriptrelpath', scriptrelpath) 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun # Write out config file for devtool 229*4882a593Smuzhiyun import configparser 230*4882a593Smuzhiyun config = configparser.SafeConfigParser() 231*4882a593Smuzhiyun config.add_section('General') 232*4882a593Smuzhiyun config.set('General', 'bitbake_subdir', conf_bbpath) 233*4882a593Smuzhiyun config.set('General', 'init_path', conf_initpath) 234*4882a593Smuzhiyun config.set('General', 'core_meta_subdir', core_meta_subdir) 235*4882a593Smuzhiyun config.add_section('SDK') 236*4882a593Smuzhiyun config.set('SDK', 'sdk_targets', d.getVar('SDK_TARGETS')) 237*4882a593Smuzhiyun updateurl = d.getVar('SDK_UPDATE_URL') 238*4882a593Smuzhiyun if updateurl: 239*4882a593Smuzhiyun config.set('SDK', 'updateserver', updateurl) 240*4882a593Smuzhiyun bb.utils.mkdirhier(os.path.join(baseoutpath, 'conf')) 241*4882a593Smuzhiyun with open(os.path.join(baseoutpath, 'conf', 'devtool.conf'), 'w') as f: 242*4882a593Smuzhiyun config.write(f) 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun unlockedsigs = os.path.join(baseoutpath, 'conf', 'unlocked-sigs.inc') 245*4882a593Smuzhiyun with open(unlockedsigs, 'w') as f: 246*4882a593Smuzhiyun pass 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun # Create a layer for new recipes / appends 249*4882a593Smuzhiyun bbpath = d.getVar('BBPATH') 250*4882a593Smuzhiyun env = os.environ.copy() 251*4882a593Smuzhiyun env['PYTHONDONTWRITEBYTECODE'] = '1' 252*4882a593Smuzhiyun bb.process.run(['devtool', '--bbpath', bbpath, '--basepath', baseoutpath, 'create-workspace', '--create-only', os.path.join(baseoutpath, 'workspace')], env=env) 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun # Create bblayers.conf 255*4882a593Smuzhiyun bb.utils.mkdirhier(baseoutpath + '/conf') 256*4882a593Smuzhiyun with open(baseoutpath + '/conf/bblayers.conf', 'w') as f: 257*4882a593Smuzhiyun f.write('# WARNING: this configuration has been automatically generated and in\n') 258*4882a593Smuzhiyun f.write('# most cases should not be edited. If you need more flexibility than\n') 259*4882a593Smuzhiyun f.write('# this configuration provides, it is strongly suggested that you set\n') 260*4882a593Smuzhiyun f.write('# up a proper instance of the full build system and use that instead.\n\n') 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun # LCONF_VERSION may not be set, for example when using meta-poky 263*4882a593Smuzhiyun # so don't error if it isn't found 264*4882a593Smuzhiyun lconf_version = d.getVar('LCONF_VERSION', False) 265*4882a593Smuzhiyun if lconf_version is not None: 266*4882a593Smuzhiyun f.write('LCONF_VERSION = "%s"\n\n' % lconf_version) 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun f.write('BBPATH = "$' + '{TOPDIR}"\n') 269*4882a593Smuzhiyun f.write('SDKBASEMETAPATH = "$' + '{TOPDIR}"\n') 270*4882a593Smuzhiyun f.write('BBLAYERS := " \\\n') 271*4882a593Smuzhiyun for layerrelpath in sdkbblayers: 272*4882a593Smuzhiyun f.write(' $' + '{SDKBASEMETAPATH}/layers/%s \\\n' % layerrelpath) 273*4882a593Smuzhiyun f.write(' $' + '{SDKBASEMETAPATH}/workspace \\\n') 274*4882a593Smuzhiyun f.write(' "\n') 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun # Copy uninative tarball 277*4882a593Smuzhiyun # For now this is where uninative.bbclass expects the tarball 278*4882a593Smuzhiyun if bb.data.inherits_class('uninative', d): 279*4882a593Smuzhiyun uninative_file = d.expand('${UNINATIVE_DLDIR}/' + d.getVarFlag("UNINATIVE_CHECKSUM", d.getVar("BUILD_ARCH")) + '/${UNINATIVE_TARBALL}') 280*4882a593Smuzhiyun uninative_checksum = bb.utils.sha256_file(uninative_file) 281*4882a593Smuzhiyun uninative_outdir = '%s/downloads/uninative/%s' % (baseoutpath, uninative_checksum) 282*4882a593Smuzhiyun bb.utils.mkdirhier(uninative_outdir) 283*4882a593Smuzhiyun shutil.copy(uninative_file, uninative_outdir) 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun env_passthrough = (d.getVar('BB_ENV_PASSTHROUGH_ADDITIONS') or '').split() 286*4882a593Smuzhiyun env_passthrough_values = {} 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun # Create local.conf 289*4882a593Smuzhiyun builddir = d.getVar('TOPDIR') 290*4882a593Smuzhiyun if derivative and os.path.exists(builddir + '/conf/site.conf'): 291*4882a593Smuzhiyun shutil.copyfile(builddir + '/conf/site.conf', baseoutpath + '/conf/site.conf') 292*4882a593Smuzhiyun if derivative and os.path.exists(builddir + '/conf/auto.conf'): 293*4882a593Smuzhiyun shutil.copyfile(builddir + '/conf/auto.conf', baseoutpath + '/conf/auto.conf') 294*4882a593Smuzhiyun if derivative: 295*4882a593Smuzhiyun shutil.copyfile(builddir + '/conf/local.conf', baseoutpath + '/conf/local.conf') 296*4882a593Smuzhiyun else: 297*4882a593Smuzhiyun local_conf_allowed = (d.getVar('ESDK_LOCALCONF_ALLOW') or '').split() 298*4882a593Smuzhiyun local_conf_remove = (d.getVar('ESDK_LOCALCONF_REMOVE') or '').split() 299*4882a593Smuzhiyun def handle_var(varname, origvalue, op, newlines): 300*4882a593Smuzhiyun if varname in local_conf_remove or (origvalue.strip().startswith('/') and not varname in local_conf_allowed): 301*4882a593Smuzhiyun newlines.append('# Removed original setting of %s\n' % varname) 302*4882a593Smuzhiyun return None, op, 0, True 303*4882a593Smuzhiyun else: 304*4882a593Smuzhiyun if varname in env_passthrough: 305*4882a593Smuzhiyun env_passthrough_values[varname] = origvalue 306*4882a593Smuzhiyun return origvalue, op, 0, True 307*4882a593Smuzhiyun varlist = ['[^#=+ ]*'] 308*4882a593Smuzhiyun oldlines = [] 309*4882a593Smuzhiyun if os.path.exists(builddir + '/conf/site.conf'): 310*4882a593Smuzhiyun with open(builddir + '/conf/site.conf', 'r') as f: 311*4882a593Smuzhiyun oldlines += f.readlines() 312*4882a593Smuzhiyun if os.path.exists(builddir + '/conf/auto.conf'): 313*4882a593Smuzhiyun with open(builddir + '/conf/auto.conf', 'r') as f: 314*4882a593Smuzhiyun oldlines += f.readlines() 315*4882a593Smuzhiyun if os.path.exists(builddir + '/conf/local.conf'): 316*4882a593Smuzhiyun with open(builddir + '/conf/local.conf', 'r') as f: 317*4882a593Smuzhiyun oldlines += f.readlines() 318*4882a593Smuzhiyun (updated, newlines) = bb.utils.edit_metadata(oldlines, varlist, handle_var) 319*4882a593Smuzhiyun 320*4882a593Smuzhiyun with open(baseoutpath + '/conf/local.conf', 'w') as f: 321*4882a593Smuzhiyun f.write('# WARNING: this configuration has been automatically generated and in\n') 322*4882a593Smuzhiyun f.write('# most cases should not be edited. If you need more flexibility than\n') 323*4882a593Smuzhiyun f.write('# this configuration provides, it is strongly suggested that you set\n') 324*4882a593Smuzhiyun f.write('# up a proper instance of the full build system and use that instead.\n\n') 325*4882a593Smuzhiyun for line in newlines: 326*4882a593Smuzhiyun if line.strip() and not line.startswith('#'): 327*4882a593Smuzhiyun f.write(line) 328*4882a593Smuzhiyun # Write a newline just in case there's none at the end of the original 329*4882a593Smuzhiyun f.write('\n') 330*4882a593Smuzhiyun 331*4882a593Smuzhiyun f.write('TMPDIR = "${TOPDIR}/tmp"\n') 332*4882a593Smuzhiyun f.write('TCLIBCAPPEND = ""\n') 333*4882a593Smuzhiyun f.write('DL_DIR = "${TOPDIR}/downloads"\n') 334*4882a593Smuzhiyun 335*4882a593Smuzhiyun if bb.data.inherits_class('uninative', d): 336*4882a593Smuzhiyun f.write('INHERIT += "%s"\n' % 'uninative') 337*4882a593Smuzhiyun f.write('UNINATIVE_CHECKSUM[%s] = "%s"\n\n' % (d.getVar('BUILD_ARCH'), uninative_checksum)) 338*4882a593Smuzhiyun f.write('CONF_VERSION = "%s"\n\n' % d.getVar('CONF_VERSION', False)) 339*4882a593Smuzhiyun 340*4882a593Smuzhiyun # Some classes are not suitable for SDK, remove them from INHERIT 341*4882a593Smuzhiyun f.write('INHERIT:remove = "%s"\n' % d.getVar('ESDK_CLASS_INHERIT_DISABLE', False)) 342*4882a593Smuzhiyun 343*4882a593Smuzhiyun # Bypass the default connectivity check if any 344*4882a593Smuzhiyun f.write('CONNECTIVITY_CHECK_URIS = ""\n\n') 345*4882a593Smuzhiyun 346*4882a593Smuzhiyun # This warning will come out if reverse dependencies for a task 347*4882a593Smuzhiyun # don't have sstate as well as the task itself. We already know 348*4882a593Smuzhiyun # this will be the case for the extensible sdk, so turn off the 349*4882a593Smuzhiyun # warning. 350*4882a593Smuzhiyun f.write('SIGGEN_LOCKEDSIGS_SSTATE_EXISTS_CHECK = "none"\n\n') 351*4882a593Smuzhiyun 352*4882a593Smuzhiyun # Warn if the sigs in the locked-signature file don't match 353*4882a593Smuzhiyun # the sig computed from the metadata. 354*4882a593Smuzhiyun f.write('SIGGEN_LOCKEDSIGS_TASKSIG_CHECK = "warn"\n\n') 355*4882a593Smuzhiyun 356*4882a593Smuzhiyun # We want to be able to set this without a full reparse 357*4882a593Smuzhiyun f.write('BB_HASHCONFIG_IGNORE_VARS:append = " SIGGEN_UNLOCKED_RECIPES"\n\n') 358*4882a593Smuzhiyun 359*4882a593Smuzhiyun # Set up which tasks are ignored for run on install 360*4882a593Smuzhiyun f.write('BB_SETSCENE_ENFORCE_IGNORE_TASKS = "%:* *:do_shared_workdir *:do_rm_work wic-tools:* *:do_addto_recipe_sysroot"\n\n') 361*4882a593Smuzhiyun 362*4882a593Smuzhiyun # Hide the config information from bitbake output (since it's fixed within the SDK) 363*4882a593Smuzhiyun f.write('BUILDCFG_HEADER = ""\n\n') 364*4882a593Smuzhiyun 365*4882a593Smuzhiyun # Write METADATA_REVISION 366*4882a593Smuzhiyun f.write('METADATA_REVISION = "%s"\n\n' % d.getVar('METADATA_REVISION')) 367*4882a593Smuzhiyun 368*4882a593Smuzhiyun f.write('# Provide a flag to indicate we are in the EXT_SDK Context\n') 369*4882a593Smuzhiyun f.write('WITHIN_EXT_SDK = "1"\n\n') 370*4882a593Smuzhiyun 371*4882a593Smuzhiyun # Map gcc-dependent uninative sstate cache for installer usage 372*4882a593Smuzhiyun f.write('SSTATE_MIRRORS += " file://universal/(.*) file://universal-4.9/\\1 file://universal-4.9/(.*) file://universal-4.8/\\1"\n\n') 373*4882a593Smuzhiyun 374*4882a593Smuzhiyun if d.getVar("PRSERV_HOST"): 375*4882a593Smuzhiyun # Override this, we now include PR data, so it should only point ot the local database 376*4882a593Smuzhiyun f.write('PRSERV_HOST = "localhost:0"\n\n') 377*4882a593Smuzhiyun 378*4882a593Smuzhiyun # Allow additional config through sdk-extra.conf 379*4882a593Smuzhiyun fn = bb.cookerdata.findConfigFile('sdk-extra.conf', d) 380*4882a593Smuzhiyun if fn: 381*4882a593Smuzhiyun with open(fn, 'r') as xf: 382*4882a593Smuzhiyun for line in xf: 383*4882a593Smuzhiyun f.write(line) 384*4882a593Smuzhiyun 385*4882a593Smuzhiyun # If you define a sdk_extraconf() function then it can contain additional config 386*4882a593Smuzhiyun # (Though this is awkward; sdk-extra.conf should probably be used instead) 387*4882a593Smuzhiyun extraconf = (d.getVar('sdk_extraconf') or '').strip() 388*4882a593Smuzhiyun if extraconf: 389*4882a593Smuzhiyun # Strip off any leading / trailing spaces 390*4882a593Smuzhiyun for line in extraconf.splitlines(): 391*4882a593Smuzhiyun f.write(line.strip() + '\n') 392*4882a593Smuzhiyun 393*4882a593Smuzhiyun f.write('require conf/locked-sigs.inc\n') 394*4882a593Smuzhiyun f.write('require conf/unlocked-sigs.inc\n') 395*4882a593Smuzhiyun 396*4882a593Smuzhiyun # Copy multiple configurations if they exist in the users config directory 397*4882a593Smuzhiyun if d.getVar('BBMULTICONFIG') is not None: 398*4882a593Smuzhiyun bb.utils.mkdirhier(os.path.join(baseoutpath, 'conf', 'multiconfig')) 399*4882a593Smuzhiyun for mc in d.getVar('BBMULTICONFIG').split(): 400*4882a593Smuzhiyun dest_stub = "/conf/multiconfig/%s.conf" % (mc,) 401*4882a593Smuzhiyun if os.path.exists(builddir + dest_stub): 402*4882a593Smuzhiyun shutil.copyfile(builddir + dest_stub, baseoutpath + dest_stub) 403*4882a593Smuzhiyun 404*4882a593Smuzhiyun if os.path.exists(builddir + '/cache/bb_unihashes.dat'): 405*4882a593Smuzhiyun bb.parse.siggen.save_unitaskhashes() 406*4882a593Smuzhiyun bb.utils.mkdirhier(os.path.join(baseoutpath, 'cache')) 407*4882a593Smuzhiyun shutil.copyfile(builddir + '/cache/bb_unihashes.dat', baseoutpath + '/cache/bb_unihashes.dat') 408*4882a593Smuzhiyun 409*4882a593Smuzhiyun # If PR Service is in use, we need to export this as well 410*4882a593Smuzhiyun bb.note('Do we have a pr database?') 411*4882a593Smuzhiyun if d.getVar("PRSERV_HOST"): 412*4882a593Smuzhiyun bb.note('Writing PR database...') 413*4882a593Smuzhiyun # Based on the code in classes/prexport.bbclass 414*4882a593Smuzhiyun import oe.prservice 415*4882a593Smuzhiyun #dump meta info of tables 416*4882a593Smuzhiyun localdata = d.createCopy() 417*4882a593Smuzhiyun localdata.setVar('PRSERV_DUMPOPT_COL', "1") 418*4882a593Smuzhiyun localdata.setVar('PRSERV_DUMPDIR', os.path.join(baseoutpath, 'conf')) 419*4882a593Smuzhiyun localdata.setVar('PRSERV_DUMPFILE', '${PRSERV_DUMPDIR}/prserv.inc') 420*4882a593Smuzhiyun 421*4882a593Smuzhiyun bb.note('PR Database write to %s' % (localdata.getVar('PRSERV_DUMPFILE'))) 422*4882a593Smuzhiyun 423*4882a593Smuzhiyun retval = oe.prservice.prserv_dump_db(localdata) 424*4882a593Smuzhiyun if not retval: 425*4882a593Smuzhiyun bb.error("prexport_handler: export failed!") 426*4882a593Smuzhiyun return 427*4882a593Smuzhiyun (metainfo, datainfo) = retval 428*4882a593Smuzhiyun oe.prservice.prserv_export_tofile(localdata, metainfo, datainfo, True) 429*4882a593Smuzhiyun 430*4882a593Smuzhiyun # Use templateconf.cfg file from builddir if exists 431*4882a593Smuzhiyun if os.path.exists(builddir + '/conf/templateconf.cfg') and use_custom_templateconf == '1': 432*4882a593Smuzhiyun shutil.copyfile(builddir + '/conf/templateconf.cfg', baseoutpath + '/conf/templateconf.cfg') 433*4882a593Smuzhiyun else: 434*4882a593Smuzhiyun # Write a templateconf.cfg 435*4882a593Smuzhiyun with open(baseoutpath + '/conf/templateconf.cfg', 'w') as f: 436*4882a593Smuzhiyun f.write('meta/conf\n') 437*4882a593Smuzhiyun 438*4882a593Smuzhiyun # Ensure any variables set from the external environment (by way of 439*4882a593Smuzhiyun # BB_ENV_PASSTHROUGH_ADDITIONS) are set in the SDK's configuration 440*4882a593Smuzhiyun extralines = [] 441*4882a593Smuzhiyun for name, value in env_passthrough_values.items(): 442*4882a593Smuzhiyun actualvalue = d.getVar(name) or '' 443*4882a593Smuzhiyun if value != actualvalue: 444*4882a593Smuzhiyun extralines.append('%s = "%s"\n' % (name, actualvalue)) 445*4882a593Smuzhiyun if extralines: 446*4882a593Smuzhiyun with open(baseoutpath + '/conf/local.conf', 'a') as f: 447*4882a593Smuzhiyun f.write('\n') 448*4882a593Smuzhiyun f.write('# Extra settings from environment:\n') 449*4882a593Smuzhiyun for line in extralines: 450*4882a593Smuzhiyun f.write(line) 451*4882a593Smuzhiyun f.write('\n') 452*4882a593Smuzhiyun 453*4882a593Smuzhiyun # Filter the locked signatures file to just the sstate tasks we are interested in 454*4882a593Smuzhiyun excluded_targets = get_sdk_install_targets(d, images_only=True) 455*4882a593Smuzhiyun sigfile = d.getVar('WORKDIR') + '/locked-sigs.inc' 456*4882a593Smuzhiyun lockedsigs_pruned = baseoutpath + '/conf/locked-sigs.inc' 457*4882a593Smuzhiyun #nativesdk-only sigfile to merge into locked-sigs.inc 458*4882a593Smuzhiyun sdk_include_nativesdk = (d.getVar("SDK_INCLUDE_NATIVESDK") == '1') 459*4882a593Smuzhiyun nativesigfile = d.getVar('WORKDIR') + '/locked-sigs_nativesdk.inc' 460*4882a593Smuzhiyun nativesigfile_pruned = d.getVar('WORKDIR') + '/locked-sigs_nativesdk_pruned.inc' 461*4882a593Smuzhiyun 462*4882a593Smuzhiyun if sdk_include_nativesdk: 463*4882a593Smuzhiyun oe.copy_buildsystem.prune_lockedsigs([], 464*4882a593Smuzhiyun excluded_targets.split(), 465*4882a593Smuzhiyun nativesigfile, 466*4882a593Smuzhiyun True, 467*4882a593Smuzhiyun nativesigfile_pruned) 468*4882a593Smuzhiyun 469*4882a593Smuzhiyun oe.copy_buildsystem.merge_lockedsigs([], 470*4882a593Smuzhiyun sigfile, 471*4882a593Smuzhiyun nativesigfile_pruned, 472*4882a593Smuzhiyun sigfile) 473*4882a593Smuzhiyun 474*4882a593Smuzhiyun oe.copy_buildsystem.prune_lockedsigs([], 475*4882a593Smuzhiyun excluded_targets.split(), 476*4882a593Smuzhiyun sigfile, 477*4882a593Smuzhiyun False, 478*4882a593Smuzhiyun lockedsigs_pruned) 479*4882a593Smuzhiyun 480*4882a593Smuzhiyun sstate_out = baseoutpath + '/sstate-cache' 481*4882a593Smuzhiyun bb.utils.remove(sstate_out, True) 482*4882a593Smuzhiyun 483*4882a593Smuzhiyun # uninative.bbclass sets NATIVELSBSTRING to 'universal%s' % oe.utils.host_gcc_version(d) 484*4882a593Smuzhiyun fixedlsbstring = "universal%s" % oe.utils.host_gcc_version(d) 485*4882a593Smuzhiyun 486*4882a593Smuzhiyun sdk_include_toolchain = (d.getVar('SDK_INCLUDE_TOOLCHAIN') == '1') 487*4882a593Smuzhiyun sdk_ext_type = d.getVar('SDK_EXT_TYPE') 488*4882a593Smuzhiyun if (sdk_ext_type != 'minimal' or sdk_include_toolchain or derivative) and not sdk_include_nativesdk: 489*4882a593Smuzhiyun # Create the filtered task list used to generate the sstate cache shipped with the SDK 490*4882a593Smuzhiyun tasklistfn = d.getVar('WORKDIR') + '/tasklist.txt' 491*4882a593Smuzhiyun create_filtered_tasklist(d, baseoutpath, tasklistfn, conf_initpath) 492*4882a593Smuzhiyun else: 493*4882a593Smuzhiyun tasklistfn = None 494*4882a593Smuzhiyun 495*4882a593Smuzhiyun if os.path.exists(builddir + '/cache/bb_unihashes.dat'): 496*4882a593Smuzhiyun bb.parse.siggen.save_unitaskhashes() 497*4882a593Smuzhiyun bb.utils.mkdirhier(os.path.join(baseoutpath, 'cache')) 498*4882a593Smuzhiyun shutil.copyfile(builddir + '/cache/bb_unihashes.dat', baseoutpath + '/cache/bb_unihashes.dat') 499*4882a593Smuzhiyun 500*4882a593Smuzhiyun # Add packagedata if enabled 501*4882a593Smuzhiyun if d.getVar('SDK_INCLUDE_PKGDATA') == '1': 502*4882a593Smuzhiyun lockedsigs_base = d.getVar('WORKDIR') + '/locked-sigs-base.inc' 503*4882a593Smuzhiyun lockedsigs_copy = d.getVar('WORKDIR') + '/locked-sigs-copy.inc' 504*4882a593Smuzhiyun shutil.move(lockedsigs_pruned, lockedsigs_base) 505*4882a593Smuzhiyun oe.copy_buildsystem.merge_lockedsigs(['do_packagedata'], 506*4882a593Smuzhiyun lockedsigs_base, 507*4882a593Smuzhiyun d.getVar('STAGING_DIR_HOST') + '/world-pkgdata/locked-sigs-pkgdata.inc', 508*4882a593Smuzhiyun lockedsigs_pruned, 509*4882a593Smuzhiyun lockedsigs_copy) 510*4882a593Smuzhiyun 511*4882a593Smuzhiyun if sdk_include_toolchain: 512*4882a593Smuzhiyun lockedsigs_base = d.getVar('WORKDIR') + '/locked-sigs-base2.inc' 513*4882a593Smuzhiyun lockedsigs_toolchain = d.expand("${STAGING_DIR}/${TUNE_PKGARCH}/meta-extsdk-toolchain/locked-sigs/locked-sigs-extsdk-toolchain.inc") 514*4882a593Smuzhiyun shutil.move(lockedsigs_pruned, lockedsigs_base) 515*4882a593Smuzhiyun oe.copy_buildsystem.merge_lockedsigs([], 516*4882a593Smuzhiyun lockedsigs_base, 517*4882a593Smuzhiyun lockedsigs_toolchain, 518*4882a593Smuzhiyun lockedsigs_pruned) 519*4882a593Smuzhiyun oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_toolchain, 520*4882a593Smuzhiyun d.getVar('SSTATE_DIR'), 521*4882a593Smuzhiyun sstate_out, d, 522*4882a593Smuzhiyun fixedlsbstring, 523*4882a593Smuzhiyun filterfile=tasklistfn) 524*4882a593Smuzhiyun 525*4882a593Smuzhiyun if sdk_ext_type == 'minimal': 526*4882a593Smuzhiyun if derivative: 527*4882a593Smuzhiyun # Assume the user is not going to set up an additional sstate 528*4882a593Smuzhiyun # mirror, thus we need to copy the additional artifacts (from 529*4882a593Smuzhiyun # workspace recipes) into the derivative SDK 530*4882a593Smuzhiyun lockedsigs_orig = d.getVar('TOPDIR') + '/conf/locked-sigs.inc' 531*4882a593Smuzhiyun if os.path.exists(lockedsigs_orig): 532*4882a593Smuzhiyun lockedsigs_extra = d.getVar('WORKDIR') + '/locked-sigs-extra.inc' 533*4882a593Smuzhiyun oe.copy_buildsystem.merge_lockedsigs(None, 534*4882a593Smuzhiyun lockedsigs_orig, 535*4882a593Smuzhiyun lockedsigs_pruned, 536*4882a593Smuzhiyun None, 537*4882a593Smuzhiyun lockedsigs_extra) 538*4882a593Smuzhiyun oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_extra, 539*4882a593Smuzhiyun d.getVar('SSTATE_DIR'), 540*4882a593Smuzhiyun sstate_out, d, 541*4882a593Smuzhiyun fixedlsbstring, 542*4882a593Smuzhiyun filterfile=tasklistfn) 543*4882a593Smuzhiyun else: 544*4882a593Smuzhiyun oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_pruned, 545*4882a593Smuzhiyun d.getVar('SSTATE_DIR'), 546*4882a593Smuzhiyun sstate_out, d, 547*4882a593Smuzhiyun fixedlsbstring, 548*4882a593Smuzhiyun filterfile=tasklistfn) 549*4882a593Smuzhiyun 550*4882a593Smuzhiyun # We don't need sstate do_package files 551*4882a593Smuzhiyun for root, dirs, files in os.walk(sstate_out): 552*4882a593Smuzhiyun for name in files: 553*4882a593Smuzhiyun if name.endswith("_package.tar.zst"): 554*4882a593Smuzhiyun f = os.path.join(root, name) 555*4882a593Smuzhiyun os.remove(f) 556*4882a593Smuzhiyun 557*4882a593Smuzhiyun # Write manifest file 558*4882a593Smuzhiyun # Note: at the moment we cannot include the env setup script here to keep 559*4882a593Smuzhiyun # it updated, since it gets modified during SDK installation (see 560*4882a593Smuzhiyun # sdk_ext_postinst() below) thus the checksum we take here would always 561*4882a593Smuzhiyun # be different. 562*4882a593Smuzhiyun manifest_file_list = ['conf/*'] 563*4882a593Smuzhiyun if d.getVar('BBMULTICONFIG') is not None: 564*4882a593Smuzhiyun manifest_file_list.append('conf/multiconfig/*') 565*4882a593Smuzhiyun 566*4882a593Smuzhiyun esdk_manifest_excludes = (d.getVar('ESDK_MANIFEST_EXCLUDES') or '').split() 567*4882a593Smuzhiyun esdk_manifest_excludes_list = [] 568*4882a593Smuzhiyun for exclude_item in esdk_manifest_excludes: 569*4882a593Smuzhiyun esdk_manifest_excludes_list += glob.glob(os.path.join(baseoutpath, exclude_item)) 570*4882a593Smuzhiyun manifest_file = os.path.join(baseoutpath, 'conf', 'sdk-conf-manifest') 571*4882a593Smuzhiyun with open(manifest_file, 'w') as f: 572*4882a593Smuzhiyun for item in manifest_file_list: 573*4882a593Smuzhiyun for fn in glob.glob(os.path.join(baseoutpath, item)): 574*4882a593Smuzhiyun if fn == manifest_file or os.path.isdir(fn): 575*4882a593Smuzhiyun continue 576*4882a593Smuzhiyun if fn in esdk_manifest_excludes_list: 577*4882a593Smuzhiyun continue 578*4882a593Smuzhiyun chksum = bb.utils.sha256_file(fn) 579*4882a593Smuzhiyun f.write('%s\t%s\n' % (chksum, os.path.relpath(fn, baseoutpath))) 580*4882a593Smuzhiyun} 581*4882a593Smuzhiyun 582*4882a593Smuzhiyundef get_current_buildtools(d): 583*4882a593Smuzhiyun """Get the file name of the current buildtools installer""" 584*4882a593Smuzhiyun import glob 585*4882a593Smuzhiyun btfiles = glob.glob(os.path.join(d.getVar('SDK_DEPLOY'), '*-buildtools-nativesdk-standalone-*.sh')) 586*4882a593Smuzhiyun btfiles.sort(key=os.path.getctime) 587*4882a593Smuzhiyun return os.path.basename(btfiles[-1]) 588*4882a593Smuzhiyun 589*4882a593Smuzhiyundef get_sdk_required_utilities(buildtools_fn, d): 590*4882a593Smuzhiyun """Find required utilities that aren't provided by the buildtools""" 591*4882a593Smuzhiyun sanity_required_utilities = (d.getVar('SANITY_REQUIRED_UTILITIES') or '').split() 592*4882a593Smuzhiyun sanity_required_utilities.append(d.expand('${BUILD_PREFIX}gcc')) 593*4882a593Smuzhiyun sanity_required_utilities.append(d.expand('${BUILD_PREFIX}g++')) 594*4882a593Smuzhiyun if buildtools_fn: 595*4882a593Smuzhiyun buildtools_installer = os.path.join(d.getVar('SDK_DEPLOY'), buildtools_fn) 596*4882a593Smuzhiyun filelist, _ = bb.process.run('%s -l' % buildtools_installer) 597*4882a593Smuzhiyun else: 598*4882a593Smuzhiyun buildtools_installer = None 599*4882a593Smuzhiyun filelist = "" 600*4882a593Smuzhiyun localdata = bb.data.createCopy(d) 601*4882a593Smuzhiyun localdata.setVar('SDKPATH', '.') 602*4882a593Smuzhiyun sdkpathnative = localdata.getVar('SDKPATHNATIVE') 603*4882a593Smuzhiyun sdkbindirs = [localdata.getVar('bindir_nativesdk'), 604*4882a593Smuzhiyun localdata.getVar('sbindir_nativesdk'), 605*4882a593Smuzhiyun localdata.getVar('base_bindir_nativesdk'), 606*4882a593Smuzhiyun localdata.getVar('base_sbindir_nativesdk')] 607*4882a593Smuzhiyun for line in filelist.splitlines(): 608*4882a593Smuzhiyun splitline = line.split() 609*4882a593Smuzhiyun if len(splitline) > 5: 610*4882a593Smuzhiyun fn = splitline[5] 611*4882a593Smuzhiyun if not fn.startswith('./'): 612*4882a593Smuzhiyun fn = './%s' % fn 613*4882a593Smuzhiyun if fn.startswith(sdkpathnative): 614*4882a593Smuzhiyun relpth = '/' + os.path.relpath(fn, sdkpathnative) 615*4882a593Smuzhiyun for bindir in sdkbindirs: 616*4882a593Smuzhiyun if relpth.startswith(bindir): 617*4882a593Smuzhiyun relpth = os.path.relpath(relpth, bindir) 618*4882a593Smuzhiyun if relpth in sanity_required_utilities: 619*4882a593Smuzhiyun sanity_required_utilities.remove(relpth) 620*4882a593Smuzhiyun break 621*4882a593Smuzhiyun return ' '.join(sanity_required_utilities) 622*4882a593Smuzhiyun 623*4882a593Smuzhiyuninstall_tools() { 624*4882a593Smuzhiyun install -d ${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk} 625*4882a593Smuzhiyun scripts="devtool recipetool oe-find-native-sysroot runqemu* wic" 626*4882a593Smuzhiyun for script in $scripts; do 627*4882a593Smuzhiyun for scriptfn in `find ${SDK_OUTPUT}/${SDKPATH}/${scriptrelpath} -maxdepth 1 -executable -name "$script"`; do 628*4882a593Smuzhiyun targetscriptfn="${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}/$(basename $scriptfn)" 629*4882a593Smuzhiyun test -e ${targetscriptfn} || ln -rs ${scriptfn} ${targetscriptfn} 630*4882a593Smuzhiyun done 631*4882a593Smuzhiyun done 632*4882a593Smuzhiyun # We can't use the same method as above because files in the sysroot won't exist at this point 633*4882a593Smuzhiyun # (they get populated from sstate on installation) 634*4882a593Smuzhiyun unfsd_path="${SDK_OUTPUT}/${SDKPATHNATIVE}${bindir_nativesdk}/unfsd" 635*4882a593Smuzhiyun if [ "${SDK_INCLUDE_TOOLCHAIN}" = "1" -a ! -e $unfsd_path ] ; then 636*4882a593Smuzhiyun binrelpath=${@os.path.relpath(d.getVar('STAGING_BINDIR_NATIVE'), d.getVar('TMPDIR'))} 637*4882a593Smuzhiyun ln -rs ${SDK_OUTPUT}/${SDKPATH}/tmp/$binrelpath/unfsd $unfsd_path 638*4882a593Smuzhiyun fi 639*4882a593Smuzhiyun touch ${SDK_OUTPUT}/${SDKPATH}/.devtoolbase 640*4882a593Smuzhiyun 641*4882a593Smuzhiyun # find latest buildtools-tarball and install it 642*4882a593Smuzhiyun if [ -n "${SDK_BUILDTOOLS_INSTALLER}" ]; then 643*4882a593Smuzhiyun install ${SDK_DEPLOY}/${SDK_BUILDTOOLS_INSTALLER} ${SDK_OUTPUT}/${SDKPATH} 644*4882a593Smuzhiyun fi 645*4882a593Smuzhiyun 646*4882a593Smuzhiyun install -m 0644 ${COREBASE}/meta/files/ext-sdk-prepare.py ${SDK_OUTPUT}/${SDKPATH} 647*4882a593Smuzhiyun} 648*4882a593Smuzhiyundo_populate_sdk_ext[file-checksums] += "${COREBASE}/meta/files/ext-sdk-prepare.py:True" 649*4882a593Smuzhiyun 650*4882a593Smuzhiyunsdk_ext_preinst() { 651*4882a593Smuzhiyun # Since bitbake won't run as root it doesn't make sense to try and install 652*4882a593Smuzhiyun # the extensible sdk as root. 653*4882a593Smuzhiyun if [ "`id -u`" = "0" ]; then 654*4882a593Smuzhiyun echo "ERROR: The extensible sdk cannot be installed as root." 655*4882a593Smuzhiyun exit 1 656*4882a593Smuzhiyun fi 657*4882a593Smuzhiyun if ! command -v locale > /dev/null; then 658*4882a593Smuzhiyun echo "ERROR: The installer requires the locale command, please install it first" 659*4882a593Smuzhiyun exit 1 660*4882a593Smuzhiyun fi 661*4882a593Smuzhiyun # Check setting of LC_ALL set above 662*4882a593Smuzhiyun canonicalised_locale=`echo $LC_ALL | sed 's/UTF-8/utf8/'` 663*4882a593Smuzhiyun if ! locale -a | grep -q $canonicalised_locale ; then 664*4882a593Smuzhiyun echo "ERROR: the installer requires the $LC_ALL locale to be installed (but not selected), please install it first" 665*4882a593Smuzhiyun exit 1 666*4882a593Smuzhiyun fi 667*4882a593Smuzhiyun # The relocation script used by buildtools installer requires python 668*4882a593Smuzhiyun if ! command -v python3 > /dev/null; then 669*4882a593Smuzhiyun echo "ERROR: The installer requires python3, please install it first" 670*4882a593Smuzhiyun exit 1 671*4882a593Smuzhiyun fi 672*4882a593Smuzhiyun missing_utils="" 673*4882a593Smuzhiyun for util in ${SDK_REQUIRED_UTILITIES}; do 674*4882a593Smuzhiyun if ! command -v $util > /dev/null; then 675*4882a593Smuzhiyun missing_utils="$missing_utils $util" 676*4882a593Smuzhiyun fi 677*4882a593Smuzhiyun done 678*4882a593Smuzhiyun if [ -n "$missing_utils" ] ; then 679*4882a593Smuzhiyun echo "ERROR: the SDK requires the following missing utilities, please install them: $missing_utils" 680*4882a593Smuzhiyun exit 1 681*4882a593Smuzhiyun fi 682*4882a593Smuzhiyun SDK_EXTENSIBLE="1" 683*4882a593Smuzhiyun if [ "$publish" = "1" ] && [ "${SDK_EXT_TYPE}" = "minimal" ] ; then 684*4882a593Smuzhiyun EXTRA_TAR_OPTIONS="$EXTRA_TAR_OPTIONS --exclude=sstate-cache" 685*4882a593Smuzhiyun fi 686*4882a593Smuzhiyun} 687*4882a593SmuzhiyunSDK_PRE_INSTALL_COMMAND:task-populate-sdk-ext = "${sdk_ext_preinst}" 688*4882a593Smuzhiyun 689*4882a593Smuzhiyun# FIXME this preparation should be done as part of the SDK construction 690*4882a593Smuzhiyunsdk_ext_postinst() { 691*4882a593Smuzhiyun printf "\nExtracting buildtools...\n" 692*4882a593Smuzhiyun cd $target_sdk_dir 693*4882a593Smuzhiyun env_setup_script="$target_sdk_dir/environment-setup-${REAL_MULTIMACH_TARGET_SYS}" 694*4882a593Smuzhiyun if [ -n "${SDK_BUILDTOOLS_INSTALLER}" ]; then 695*4882a593Smuzhiyun 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 ; } 696*4882a593Smuzhiyun 697*4882a593Smuzhiyun # Delete the buildtools tar file since it won't be used again 698*4882a593Smuzhiyun rm -f ./${SDK_BUILDTOOLS_INSTALLER} 699*4882a593Smuzhiyun # We don't need the log either since it succeeded 700*4882a593Smuzhiyun rm -f buildtools.log 701*4882a593Smuzhiyun 702*4882a593Smuzhiyun # Make sure when the user sets up the environment, they also get 703*4882a593Smuzhiyun # the buildtools-tarball tools in their path. 704*4882a593Smuzhiyun echo "# Save and reset OECORE_NATIVE_SYSROOT as buildtools may change it" >> $env_setup_script 705*4882a593Smuzhiyun echo "SAVED=\"\$OECORE_NATIVE_SYSROOT\"" >> $env_setup_script 706*4882a593Smuzhiyun echo ". $target_sdk_dir/buildtools/environment-setup*" >> $env_setup_script 707*4882a593Smuzhiyun echo "OECORE_NATIVE_SYSROOT=\"\$SAVED\"" >> $env_setup_script 708*4882a593Smuzhiyun fi 709*4882a593Smuzhiyun 710*4882a593Smuzhiyun # Allow bitbake environment setup to be ran as part of this sdk. 711*4882a593Smuzhiyun echo "export OE_SKIP_SDK_CHECK=1" >> $env_setup_script 712*4882a593Smuzhiyun # Work around runqemu not knowing how to get this information within the eSDK 713*4882a593Smuzhiyun echo "export DEPLOY_DIR_IMAGE=$target_sdk_dir/tmp/${@os.path.relpath(d.getVar('DEPLOY_DIR_IMAGE'), d.getVar('TMPDIR'))}" >> $env_setup_script 714*4882a593Smuzhiyun 715*4882a593Smuzhiyun # A bit of another hack, but we need this in the path only for devtool 716*4882a593Smuzhiyun # so put it at the end of $PATH. 717*4882a593Smuzhiyun echo "export PATH=\"$target_sdk_dir/sysroots/${SDK_SYS}${bindir_nativesdk}:\$PATH\"" >> $env_setup_script 718*4882a593Smuzhiyun 719*4882a593Smuzhiyun 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 720*4882a593Smuzhiyun 721*4882a593Smuzhiyun # Warn if trying to use external bitbake and the ext SDK together 722*4882a593Smuzhiyun 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 723*4882a593Smuzhiyun 724*4882a593Smuzhiyun if [ "$prepare_buildsystem" != "no" -a -n "${SDK_BUILDTOOLS_INSTALLER}" ]; then 725*4882a593Smuzhiyun printf "Preparing build system...\n" 726*4882a593Smuzhiyun # dash which is /bin/sh on Ubuntu will not preserve the 727*4882a593Smuzhiyun # current working directory when first ran, nor will it set $1 when 728*4882a593Smuzhiyun # sourcing a script. That is why this has to look so ugly. 729*4882a593Smuzhiyun LOGFILE="$target_sdk_dir/preparing_build_system.log" 730*4882a593Smuzhiyun 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 && python3 $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 ; } 731*4882a593Smuzhiyun fi 732*4882a593Smuzhiyun if [ -e $target_sdk_dir/ext-sdk-prepare.py ]; then 733*4882a593Smuzhiyun rm $target_sdk_dir/ext-sdk-prepare.py 734*4882a593Smuzhiyun fi 735*4882a593Smuzhiyun echo done 736*4882a593Smuzhiyun} 737*4882a593Smuzhiyun 738*4882a593SmuzhiyunSDK_POST_INSTALL_COMMAND:task-populate-sdk-ext = "${sdk_ext_postinst}" 739*4882a593Smuzhiyun 740*4882a593SmuzhiyunSDK_POSTPROCESS_COMMAND:prepend:task-populate-sdk-ext = "copy_buildsystem; install_tools; " 741*4882a593Smuzhiyun 742*4882a593SmuzhiyunSDK_INSTALL_TARGETS = "" 743*4882a593Smuzhiyunfakeroot python do_populate_sdk_ext() { 744*4882a593Smuzhiyun # FIXME hopefully we can remove this restriction at some point, but uninative 745*4882a593Smuzhiyun # currently forces this upon us 746*4882a593Smuzhiyun if d.getVar('SDK_ARCH') != d.getVar('BUILD_ARCH'): 747*4882a593Smuzhiyun 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'), d.getVar('BUILD_ARCH'))) 748*4882a593Smuzhiyun 749*4882a593Smuzhiyun # FIXME hopefully we can remove this restriction at some point, but the eSDK 750*4882a593Smuzhiyun # can only be built for the primary (default) multiconfig 751*4882a593Smuzhiyun if d.getVar('BB_CURRENT_MC') != 'default': 752*4882a593Smuzhiyun bb.fatal('The extensible SDK can currently only be built for the default multiconfig. Currently trying to build for %s.' % d.getVar('BB_CURRENT_MC')) 753*4882a593Smuzhiyun 754*4882a593Smuzhiyun # eSDK dependencies don't use the traditional variables and things don't work properly if they are set 755*4882a593Smuzhiyun d.setVar("TOOLCHAIN_HOST_TASK", "${TOOLCHAIN_HOST_TASK_ESDK}") 756*4882a593Smuzhiyun d.setVar("TOOLCHAIN_TARGET_TASK", "") 757*4882a593Smuzhiyun 758*4882a593Smuzhiyun d.setVar('SDK_INSTALL_TARGETS', get_sdk_install_targets(d)) 759*4882a593Smuzhiyun if d.getVar('SDK_INCLUDE_BUILDTOOLS') == '1': 760*4882a593Smuzhiyun buildtools_fn = get_current_buildtools(d) 761*4882a593Smuzhiyun else: 762*4882a593Smuzhiyun buildtools_fn = None 763*4882a593Smuzhiyun d.setVar('SDK_REQUIRED_UTILITIES', get_sdk_required_utilities(buildtools_fn, d)) 764*4882a593Smuzhiyun d.setVar('SDK_BUILDTOOLS_INSTALLER', buildtools_fn) 765*4882a593Smuzhiyun d.setVar('SDKDEPLOYDIR', '${SDKEXTDEPLOYDIR}') 766*4882a593Smuzhiyun # ESDKs have a libc from the buildtools so ensure we don't ship linguas twice 767*4882a593Smuzhiyun d.delVar('SDKIMAGE_LINGUAS') 768*4882a593Smuzhiyun if d.getVar("SDK_INCLUDE_NATIVESDK") == '1': 769*4882a593Smuzhiyun generate_nativesdk_lockedsigs(d) 770*4882a593Smuzhiyun populate_sdk_common(d) 771*4882a593Smuzhiyun} 772*4882a593Smuzhiyun 773*4882a593Smuzhiyundef generate_nativesdk_lockedsigs(d): 774*4882a593Smuzhiyun import oe.copy_buildsystem 775*4882a593Smuzhiyun sigfile = d.getVar('WORKDIR') + '/locked-sigs_nativesdk.inc' 776*4882a593Smuzhiyun oe.copy_buildsystem.generate_locked_sigs(sigfile, d) 777*4882a593Smuzhiyun 778*4882a593Smuzhiyundef get_ext_sdk_depends(d): 779*4882a593Smuzhiyun # Note: the deps varflag is a list not a string, so we need to specify expand=False 780*4882a593Smuzhiyun deps = d.getVarFlag('do_image_complete', 'deps', False) 781*4882a593Smuzhiyun pn = d.getVar('PN') 782*4882a593Smuzhiyun deplist = ['%s:%s' % (pn, dep) for dep in deps] 783*4882a593Smuzhiyun tasklist = bb.build.tasksbetween('do_image_complete', 'do_build', d) 784*4882a593Smuzhiyun tasklist.append('do_rootfs') 785*4882a593Smuzhiyun for task in tasklist: 786*4882a593Smuzhiyun deplist.extend((d.getVarFlag(task, 'depends') or '').split()) 787*4882a593Smuzhiyun return ' '.join(deplist) 788*4882a593Smuzhiyun 789*4882a593Smuzhiyunpython do_sdk_depends() { 790*4882a593Smuzhiyun # We have to do this separately in its own task so we avoid recursing into 791*4882a593Smuzhiyun # dependencies we don't need to (e.g. buildtools-tarball) and bringing those 792*4882a593Smuzhiyun # into the SDK's sstate-cache 793*4882a593Smuzhiyun import oe.copy_buildsystem 794*4882a593Smuzhiyun sigfile = d.getVar('WORKDIR') + '/locked-sigs.inc' 795*4882a593Smuzhiyun oe.copy_buildsystem.generate_locked_sigs(sigfile, d) 796*4882a593Smuzhiyun} 797*4882a593Smuzhiyunaddtask sdk_depends 798*4882a593Smuzhiyun 799*4882a593Smuzhiyundo_sdk_depends[dirs] = "${WORKDIR}" 800*4882a593Smuzhiyundo_sdk_depends[depends] = "${@get_ext_sdk_depends(d)} meta-extsdk-toolchain:do_populate_sysroot" 801*4882a593Smuzhiyundo_sdk_depends[recrdeptask] = "${@d.getVarFlag('do_populate_sdk', 'recrdeptask', False)}" 802*4882a593Smuzhiyundo_sdk_depends[recrdeptask] += "do_populate_lic do_package_qa do_populate_sysroot do_deploy ${SDK_RECRDEP_TASKS}" 803*4882a593Smuzhiyundo_sdk_depends[rdepends] = "${@' '.join([x + ':do_package_write_${IMAGE_PKGTYPE} ' + x + ':do_packagedata' for x in d.getVar('TOOLCHAIN_HOST_TASK_ESDK').split()])}" 804*4882a593Smuzhiyun 805*4882a593Smuzhiyundo_populate_sdk_ext[dirs] = "${@d.getVarFlag('do_populate_sdk', 'dirs', False)}" 806*4882a593Smuzhiyun 807*4882a593Smuzhiyundo_populate_sdk_ext[depends] = "${@d.getVarFlag('do_populate_sdk', 'depends', False)} \ 808*4882a593Smuzhiyun ${@'buildtools-tarball:do_populate_sdk' if d.getVar('SDK_INCLUDE_BUILDTOOLS') == '1' else ''} \ 809*4882a593Smuzhiyun ${@'meta-world-pkgdata:do_collect_packagedata' if d.getVar('SDK_INCLUDE_PKGDATA') == '1' else ''} \ 810*4882a593Smuzhiyun ${@'meta-extsdk-toolchain:do_locked_sigs' if d.getVar('SDK_INCLUDE_TOOLCHAIN') == '1' else ''}" 811*4882a593Smuzhiyun 812*4882a593Smuzhiyun# We must avoid depending on do_build here if rm_work.bbclass is active, 813*4882a593Smuzhiyun# because otherwise do_rm_work may run before do_populate_sdk_ext itself. 814*4882a593Smuzhiyun# We can't mark do_populate_sdk_ext and do_sdk_depends as having to 815*4882a593Smuzhiyun# run before do_rm_work, because then they would also run as part 816*4882a593Smuzhiyun# of normal builds. 817*4882a593Smuzhiyundo_populate_sdk_ext[rdepends] += "${@' '.join([x + ':' + (d.getVar('RM_WORK_BUILD_WITHOUT') or 'do_build') for x in d.getVar('SDK_TARGETS').split()])}" 818*4882a593Smuzhiyun 819*4882a593Smuzhiyun# Make sure code changes can result in rebuild 820*4882a593Smuzhiyundo_populate_sdk_ext[vardeps] += "copy_buildsystem \ 821*4882a593Smuzhiyun sdk_ext_postinst" 822*4882a593Smuzhiyun 823*4882a593Smuzhiyun# Since any change in the metadata of any layer should cause a rebuild of the 824*4882a593Smuzhiyun# sdk(since the layers are put in the sdk) set the task to nostamp so it 825*4882a593Smuzhiyun# always runs. 826*4882a593Smuzhiyundo_populate_sdk_ext[nostamp] = "1" 827*4882a593Smuzhiyun 828*4882a593SmuzhiyunSDKEXTDEPLOYDIR = "${WORKDIR}/deploy-${PN}-populate-sdk-ext" 829*4882a593Smuzhiyun 830*4882a593SmuzhiyunSSTATETASKS += "do_populate_sdk_ext" 831*4882a593SmuzhiyunSSTATE_SKIP_CREATION:task-populate-sdk-ext = '1' 832*4882a593Smuzhiyundo_populate_sdk_ext[cleandirs] = "${SDKEXTDEPLOYDIR}" 833*4882a593Smuzhiyundo_populate_sdk_ext[sstate-inputdirs] = "${SDKEXTDEPLOYDIR}" 834*4882a593Smuzhiyundo_populate_sdk_ext[sstate-outputdirs] = "${SDK_DEPLOY}" 835*4882a593Smuzhiyundo_populate_sdk_ext[stamp-extra-info] = "${MACHINE_ARCH}" 836*4882a593Smuzhiyun 837*4882a593Smuzhiyunaddtask populate_sdk_ext after do_sdk_depends 838