#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#

# Extensible SDK

inherit populate_sdk_base

# Used to override TOOLCHAIN_HOST_TASK in the eSDK case
TOOLCHAIN_HOST_TASK_ESDK = " \
    meta-environment-extsdk-${MACHINE} \
    "

SDK_RELOCATE_AFTER_INSTALL:task-populate-sdk-ext = "0"

SDK_EXT = ""
SDK_EXT:task-populate-sdk-ext = "-ext"

# Options are full or minimal
SDK_EXT_TYPE ?= "full"
SDK_INCLUDE_PKGDATA ?= "0"
SDK_INCLUDE_TOOLCHAIN ?= "${@'1' if d.getVar('SDK_EXT_TYPE') == 'full' else '0'}"
SDK_INCLUDE_NATIVESDK ?= "0"
SDK_INCLUDE_BUILDTOOLS ?= '1'

SDK_RECRDEP_TASKS ?= ""
SDK_CUSTOM_TEMPLATECONF ?= "0"

ESDK_LOCALCONF_ALLOW ?= ""
ESDK_LOCALCONF_REMOVE ?= "CONF_VERSION \
                             BB_NUMBER_THREADS \
                             BB_NUMBER_PARSE_THREADS \
                             PARALLEL_MAKE \
                             PRSERV_HOST \
                             SSTATE_MIRRORS \
                             DL_DIR \
                             SSTATE_DIR \
                             TMPDIR \
                             BB_SERVER_TIMEOUT \
                            "
ESDK_CLASS_INHERIT_DISABLE ?= "buildhistory icecc"
SDK_UPDATE_URL ?= ""

SDK_TARGETS ?= "${PN}"

def get_sdk_install_targets(d, images_only=False):
    sdk_install_targets = ''
    if images_only or d.getVar('SDK_EXT_TYPE') != 'minimal':
        sdk_install_targets = d.getVar('SDK_TARGETS')

        depd = d.getVar('BB_TASKDEPDATA', False)
        tasklist = bb.build.tasksbetween('do_image_complete', 'do_build', d)
        tasklist.remove('do_build')
        for v in depd.values():
            if v[1] in tasklist:
                if v[0] not in sdk_install_targets:
                    sdk_install_targets += ' {}'.format(v[0])

    if not images_only:
        if d.getVar('SDK_INCLUDE_PKGDATA') == '1':
            sdk_install_targets += ' meta-world-pkgdata:do_allpackagedata'
        if d.getVar('SDK_INCLUDE_TOOLCHAIN') == '1':
            sdk_install_targets += ' meta-extsdk-toolchain:do_populate_sysroot'

    return sdk_install_targets

get_sdk_install_targets[vardepsexclude] = "BB_TASKDEPDATA"

OE_INIT_ENV_SCRIPT ?= "oe-init-build-env"

# The files from COREBASE that you want preserved in the COREBASE copied
# into the sdk. This allows someone to have their own setup scripts in
# COREBASE be preserved as well as untracked files.
COREBASE_FILES ?= " \
    oe-init-build-env \
    scripts \
    LICENSE \
    .templateconf \
"

SDK_DIR:task-populate-sdk-ext = "${WORKDIR}/sdk-ext"
B:task-populate-sdk-ext = "${SDK_DIR}"
TOOLCHAINEXT_OUTPUTNAME ?= "${SDK_NAME}-toolchain-ext-${SDK_VERSION}"
TOOLCHAIN_OUTPUTNAME:task-populate-sdk-ext = "${TOOLCHAINEXT_OUTPUTNAME}"

SDK_EXT_TARGET_MANIFEST = "${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.target.manifest"
SDK_EXT_HOST_MANIFEST = "${SDK_DEPLOY}/${TOOLCHAINEXT_OUTPUTNAME}.host.manifest"

python write_target_sdk_ext_manifest () {
    from oe.sdk import get_extra_sdkinfo
    sstate_dir = d.expand('${SDK_OUTPUT}/${SDKPATH}/sstate-cache')
    extra_info = get_extra_sdkinfo(sstate_dir)

    target = d.getVar('TARGET_SYS')
    target_multimach = d.getVar('MULTIMACH_TARGET_SYS')
    real_target_multimach = d.getVar('REAL_MULTIMACH_TARGET_SYS')

    pkgs = {}
    os.makedirs(os.path.dirname(d.getVar('SDK_EXT_TARGET_MANIFEST')), exist_ok=True)
    with open(d.getVar('SDK_EXT_TARGET_MANIFEST'), 'w') as f:
        for fn in extra_info['filesizes']:
            info = fn.split(':')
            if info[2] in (target, target_multimach, real_target_multimach) \
                    or info[5] == 'allarch':
                if not info[1] in pkgs:
                    f.write("%s %s %s\n" % (info[1], info[2], info[3]))
                    pkgs[info[1]] = {}
}
python write_host_sdk_ext_manifest () {
    from oe.sdk import get_extra_sdkinfo
    sstate_dir = d.expand('${SDK_OUTPUT}/${SDKPATH}/sstate-cache')
    extra_info = get_extra_sdkinfo(sstate_dir)
    host = d.getVar('BUILD_SYS')
    with open(d.getVar('SDK_EXT_HOST_MANIFEST'), 'w') as f:
        for fn in extra_info['filesizes']:
            info = fn.split(':')
            if info[2] == host:
                f.write("%s %s %s\n" % (info[1], info[2], info[3]))
}

SDK_POSTPROCESS_COMMAND:append:task-populate-sdk-ext = " write_target_sdk_ext_manifest write_host_sdk_ext_manifest"    

SDK_TITLE:task-populate-sdk-ext = "${@d.getVar('DISTRO_NAME') or d.getVar('DISTRO')} Extensible SDK"

def clean_esdk_builddir(d, sdkbasepath):
    """Clean up traces of the fake build for create_filtered_tasklist()"""
    import shutil
    cleanpaths = ['cache', 'tmp']
    for pth in cleanpaths:
        fullpth = os.path.join(sdkbasepath, pth)
        if os.path.isdir(fullpth):
            shutil.rmtree(fullpth)
        elif os.path.isfile(fullpth):
            os.remove(fullpth)

def create_filtered_tasklist(d, sdkbasepath, tasklistfile, conf_initpath):
    """
    Create a filtered list of tasks. Also double-checks that the build system
    within the SDK basically works and required sstate artifacts are available.
    """
    import tempfile
    import shutil
    import oe.copy_buildsystem

    # Create a temporary build directory that we can pass to the env setup script
    shutil.copyfile(sdkbasepath + '/conf/local.conf', sdkbasepath + '/conf/local.conf.bak')
    try:
        with open(sdkbasepath + '/conf/local.conf', 'a') as f:
            # Force the use of sstate from the build system
            f.write('\nSSTATE_DIR:forcevariable = "%s"\n' % d.getVar('SSTATE_DIR'))
            f.write('SSTATE_MIRRORS:forcevariable = "file://universal/(.*) file://universal-4.9/\\1 file://universal-4.9/(.*) file://universal-4.8/\\1"\n')
            # Ensure TMPDIR is the default so that clean_esdk_builddir() can delete it
            f.write('TMPDIR:forcevariable = "${TOPDIR}/tmp"\n')
            f.write('TCLIBCAPPEND:forcevariable = ""\n')
            # Drop uninative if the build isn't using it (or else NATIVELSBSTRING will
            # be different and we won't be able to find our native sstate)
            if not bb.data.inherits_class('uninative', d):
                f.write('INHERIT:remove = "uninative"\n')

        # Unfortunately the default SDKPATH (or even a custom value) may contain characters that bitbake
        # will not allow in its COREBASE path, so we need to rename the directory temporarily
        temp_sdkbasepath = d.getVar('SDK_OUTPUT') + '/tmp-renamed-sdk'
        # Delete any existing temp dir
        try:
            shutil.rmtree(temp_sdkbasepath)
        except FileNotFoundError:
            pass
        bb.utils.rename(sdkbasepath, temp_sdkbasepath)
        cmdprefix = '. %s .; ' % conf_initpath
        logfile = d.getVar('WORKDIR') + '/tasklist_bb_log.txt'
        try:
            oe.copy_buildsystem.check_sstate_task_list(d, get_sdk_install_targets(d), tasklistfile, cmdprefix=cmdprefix, cwd=temp_sdkbasepath, logfile=logfile)
        except bb.process.ExecutionError as e:
            msg = 'Failed to generate filtered task list for extensible SDK:\n%s' %  e.stdout.rstrip()
            if 'attempted to execute unexpectedly and should have been setscened' in e.stdout:
                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'
            bb.fatal(msg)
        bb.utils.rename(temp_sdkbasepath, sdkbasepath)
        # Clean out residue of running bitbake, which check_sstate_task_list()
        # will effectively do
        clean_esdk_builddir(d, sdkbasepath)
    finally:
        localconf = sdkbasepath + '/conf/local.conf'
        if os.path.exists(localconf + '.bak'):
            os.replace(localconf + '.bak', localconf)

def copy_bitbake_and_layers(d, baseoutpath, derivative):
    oe_init_env_script = d.getVar('OE_INIT_ENV_SCRIPT')

    conf_bbpath = ''
    conf_initpath = ''
    core_meta_subdir = ''

    # Copy in all metadata layers + bitbake (as repositories)
    buildsystem = oe.copy_buildsystem.BuildSystem('extensible SDK', d)

    if derivative:
        workspace_name = 'orig-workspace'
    else:
        workspace_name = None

    corebase, sdkbblayers = buildsystem.copy_bitbake_and_layers(baseoutpath + '/layers', workspace_name)
    conf_bbpath = os.path.join('layers', corebase, 'bitbake')

    for path in os.listdir(baseoutpath + '/layers'):
        relpath = os.path.join('layers', path, oe_init_env_script)
        if os.path.exists(os.path.join(baseoutpath, relpath)):
            conf_initpath = relpath

        relpath = os.path.join('layers', path, 'scripts', 'esdk-tools', 'devtool')
        if os.path.exists(os.path.join(baseoutpath, relpath)):
            esdk_tools_path = os.path.dirname(relpath)

        relpath = os.path.join('layers', path, 'meta')
        if os.path.exists(os.path.join(baseoutpath, relpath, 'lib', 'oe')):
            core_meta_subdir = relpath

    d.setVar('oe_init_build_env_path', conf_initpath)
    d.setVar('esdk_tools_path', esdk_tools_path)

    return (conf_initpath, conf_bbpath, core_meta_subdir, sdkbblayers)

def write_devtool_config(d, baseoutpath, conf_bbpath, conf_initpath, core_meta_subdir):
    # Write out config file for devtool
    import configparser
    config = configparser.ConfigParser()
    config.add_section('General')
    config.set('General', 'bitbake_subdir', conf_bbpath)
    config.set('General', 'init_path', conf_initpath)
    config.set('General', 'core_meta_subdir', core_meta_subdir)
    config.add_section('SDK')
    config.set('SDK', 'sdk_targets', d.getVar('SDK_TARGETS'))
    updateurl = d.getVar('SDK_UPDATE_URL')
    if updateurl:
        config.set('SDK', 'updateserver', updateurl)
    bb.utils.mkdirhier(os.path.join(baseoutpath, 'conf'))
    with open(os.path.join(baseoutpath, 'conf', 'devtool.conf'), 'w') as f:
        config.write(f)

def write_unlocked_sigs(d, baseoutpath):
    unlockedsigs =  os.path.join(baseoutpath, 'conf', 'unlocked-sigs.inc')
    with open(unlockedsigs, 'w') as f:
        pass

def write_bblayers_conf(d, baseoutpath, sdkbblayers):
    # Create a layer for new recipes / appends
    bbpath = d.getVar('BBPATH')
    env = os.environ.copy()
    env['PYTHONDONTWRITEBYTECODE'] = '1'
    bb.process.run(['devtool', '--bbpath', bbpath, '--basepath', baseoutpath, 'create-workspace', '--layerseries', d.getVar("LAYERSERIES_CORENAMES"), '--create-only', os.path.join(baseoutpath, 'workspace')], env=env)

    # Create bblayers.conf
    bb.utils.mkdirhier(baseoutpath + '/conf')
    with open(baseoutpath + '/conf/bblayers.conf', 'w') as f:
        f.write('# WARNING: this configuration has been automatically generated and in\n')
        f.write('# most cases should not be edited. If you need more flexibility than\n')
        f.write('# this configuration provides, it is strongly suggested that you set\n')
        f.write('# up a proper instance of the full build system and use that instead.\n\n')

        # LCONF_VERSION may not be set, for example when using meta-poky
        # so don't error if it isn't found
        lconf_version = d.getVar('LCONF_VERSION', False)
        if lconf_version is not None:
            f.write('LCONF_VERSION = "%s"\n\n' % lconf_version)

        f.write('BBPATH = "$' + '{TOPDIR}"\n')
        f.write('SDKBASEMETAPATH = "$' + '{TOPDIR}"\n')
        f.write('BBLAYERS := " \\\n')
        for layerrelpath in sdkbblayers:
            f.write('    $' + '{SDKBASEMETAPATH}/layers/%s \\\n' % layerrelpath)
        f.write('    $' + '{SDKBASEMETAPATH}/workspace \\\n')
        f.write('    "\n')

def copy_uninative(d, baseoutpath):
    import shutil

    # Copy uninative tarball
    # For now this is where uninative.bbclass expects the tarball
    if bb.data.inherits_class('uninative', d):
        uninative_file = d.expand('${UNINATIVE_DLDIR}/' + d.getVarFlag("UNINATIVE_CHECKSUM", d.getVar("BUILD_ARCH")) + '/${UNINATIVE_TARBALL}')
        uninative_checksum = bb.utils.sha256_file(uninative_file)
        uninative_outdir = '%s/downloads/uninative/%s' % (baseoutpath, uninative_checksum)
        bb.utils.mkdirhier(uninative_outdir)
        shutil.copy(uninative_file, uninative_outdir)

    return uninative_checksum

def write_local_conf(d, baseoutpath, derivative, core_meta_subdir, uninative_checksum):
    #check if custome templateconf path is set
    use_custom_templateconf = d.getVar('SDK_CUSTOM_TEMPLATECONF')

    env_passthrough = (d.getVar('BB_ENV_PASSTHROUGH_ADDITIONS') or '').split()
    env_passthrough_values = {}

    # Create local.conf
    builddir = d.getVar('TOPDIR')
    if derivative and os.path.exists(builddir + '/conf/site.conf'):
        shutil.copyfile(builddir + '/conf/site.conf', baseoutpath + '/conf/site.conf')
    if derivative and os.path.exists(builddir + '/conf/auto.conf'):
        shutil.copyfile(builddir + '/conf/auto.conf', baseoutpath + '/conf/auto.conf')
    if derivative:
        shutil.copyfile(builddir + '/conf/local.conf', baseoutpath + '/conf/local.conf')
    else:
        local_conf_allowed = (d.getVar('ESDK_LOCALCONF_ALLOW') or '').split()
        local_conf_remove = (d.getVar('ESDK_LOCALCONF_REMOVE') or '').split()
        def handle_var(varname, origvalue, op, newlines):
            if varname in local_conf_remove or (origvalue.strip().startswith('/') and not varname in local_conf_allowed):
                newlines.append('# Removed original setting of %s\n' % varname)
                return None, op, 0, True
            else:
                if varname in env_passthrough:
                    env_passthrough_values[varname] = origvalue
                return origvalue, op, 0, True
        varlist = ['[^#=+ ]*']
        oldlines = []
        if os.path.exists(builddir + '/conf/site.conf'):
            with open(builddir + '/conf/site.conf', 'r') as f:
                oldlines += f.readlines()
        if os.path.exists(builddir + '/conf/auto.conf'):
            with open(builddir + '/conf/auto.conf', 'r') as f:
                oldlines += f.readlines()
        if os.path.exists(builddir + '/conf/local.conf'):
            with open(builddir + '/conf/local.conf', 'r') as f:
                oldlines += f.readlines()
        (updated, newlines) = bb.utils.edit_metadata(oldlines, varlist, handle_var)

        with open(baseoutpath + '/conf/local.conf', 'w') as f:
            f.write('# WARNING: this configuration has been automatically generated and in\n')
            f.write('# most cases should not be edited. If you need more flexibility than\n')
            f.write('# this configuration provides, it is strongly suggested that you set\n')
            f.write('# up a proper instance of the full build system and use that instead.\n\n')
            for line in newlines:
                if line.strip() and not line.startswith('#'):
                    f.write(line)
            # Write a newline just in case there's none at the end of the original
            f.write('\n')

            f.write('TMPDIR = "${TOPDIR}/tmp"\n')
            f.write('TCLIBCAPPEND = ""\n')
            f.write('DL_DIR = "${TOPDIR}/downloads"\n')

            if bb.data.inherits_class('uninative', d):
               f.write('INHERIT += "%s"\n' % 'uninative')
               f.write('UNINATIVE_CHECKSUM[%s] = "%s"\n\n' % (d.getVar('BUILD_ARCH'), uninative_checksum))
            f.write('CONF_VERSION = "%s"\n\n' % d.getVar('CONF_VERSION', False))

            # Some classes are not suitable for SDK, remove them from INHERIT
            f.write('INHERIT:remove = "%s"\n' % d.getVar('ESDK_CLASS_INHERIT_DISABLE', False))

            # Bypass the default connectivity check if any
            f.write('CONNECTIVITY_CHECK_URIS = ""\n\n')

            # This warning will come out if reverse dependencies for a task
            # don't have sstate as well as the task itself. We already know
            # this will be the case for the extensible sdk, so turn off the
            # warning.
            f.write('SIGGEN_LOCKEDSIGS_SSTATE_EXISTS_CHECK = "none"\n\n')

            # Warn if the sigs in the locked-signature file don't match
            # the sig computed from the metadata.
            f.write('SIGGEN_LOCKEDSIGS_TASKSIG_CHECK = "warn"\n\n')

            # We want to be able to set this without a full reparse
            f.write('BB_HASHCONFIG_IGNORE_VARS:append = " SIGGEN_UNLOCKED_RECIPES"\n\n')

            # Set up which tasks are ignored for run on install
            f.write('BB_SETSCENE_ENFORCE_IGNORE_TASKS = "%:* *:do_shared_workdir *:do_rm_work wic-tools:* *:do_addto_recipe_sysroot"\n\n')

            # Hide the config information from bitbake output (since it's fixed within the SDK)
            f.write('BUILDCFG_HEADER = ""\n\n')

            # Write METADATA_REVISION
            # Needs distro override so it can override the value set in the bbclass code (later than local.conf)
            f.write('METADATA_REVISION:%s = "%s"\n\n' % (d.getVar('DISTRO'), d.getVar('METADATA_REVISION')))

            f.write('# Provide a flag to indicate we are in the EXT_SDK Context\n')
            f.write('WITHIN_EXT_SDK = "1"\n\n')

            # Map gcc-dependent uninative sstate cache for installer usage
            f.write('SSTATE_MIRRORS += " file://universal/(.*) file://universal-4.9/\\1 file://universal-4.9/(.*) file://universal-4.8/\\1"\n\n')

            if d.getVar("PRSERV_HOST"):
                # Override this, we now include PR data, so it should only point ot the local database
                f.write('PRSERV_HOST = "localhost:0"\n\n')

            # Allow additional config through sdk-extra.conf
            fn = bb.cookerdata.findConfigFile('sdk-extra.conf', d)
            if fn:
                with open(fn, 'r') as xf:
                    for line in xf:
                        f.write(line)

            # If you define a sdk_extraconf() function then it can contain additional config
            # (Though this is awkward; sdk-extra.conf should probably be used instead)
            extraconf = (d.getVar('sdk_extraconf') or '').strip()
            if extraconf:
                # Strip off any leading / trailing spaces
                for line in extraconf.splitlines():
                    f.write(line.strip() + '\n')

            f.write('require conf/locked-sigs.inc\n')
            f.write('require conf/unlocked-sigs.inc\n')

    # Copy multiple configurations if they exist in the users config directory
    if d.getVar('BBMULTICONFIG') is not None:
        bb.utils.mkdirhier(os.path.join(baseoutpath, 'conf', 'multiconfig'))
        for mc in d.getVar('BBMULTICONFIG').split():
            dest_stub = "/conf/multiconfig/%s.conf" % (mc,)
            if os.path.exists(builddir + dest_stub):
                shutil.copyfile(builddir + dest_stub, baseoutpath + dest_stub)

    cachedir = os.path.join(baseoutpath, 'cache')
    bb.utils.mkdirhier(cachedir)
    bb.parse.siggen.copy_unitaskhashes(cachedir)

    # If PR Service is in use, we need to export this as well
    bb.note('Do we have a pr database?')
    if d.getVar("PRSERV_HOST"):
        bb.note('Writing PR database...')
        # Based on the code in classes/prexport.bbclass
        import oe.prservice
        #dump meta info of tables
        localdata = d.createCopy()
        localdata.setVar('PRSERV_DUMPOPT_COL', "1")
        localdata.setVar('PRSERV_DUMPDIR', os.path.join(baseoutpath, 'conf'))
        localdata.setVar('PRSERV_DUMPFILE', '${PRSERV_DUMPDIR}/prserv.inc')

        bb.note('PR Database write to %s' % (localdata.getVar('PRSERV_DUMPFILE')))

        retval = oe.prservice.prserv_dump_db(localdata)
        if not retval:
            bb.error("prexport_handler: export failed!")
            return
        (metainfo, datainfo) = retval
        oe.prservice.prserv_export_tofile(localdata, metainfo, datainfo, True)

    # Use templateconf.cfg file from builddir if exists
    if os.path.exists(builddir + '/conf/templateconf.cfg') and use_custom_templateconf == '1':
        shutil.copyfile(builddir + '/conf/templateconf.cfg', baseoutpath + '/conf/templateconf.cfg')
    else:
        # Write a templateconf.cfg
        with open(baseoutpath + '/conf/templateconf.cfg', 'w') as f:
            f.write('meta/conf/templates/default\n')
        os.makedirs(os.path.join(baseoutpath, core_meta_subdir, 'conf/templates/default'), exist_ok=True)

    # Ensure any variables set from the external environment (by way of
    # BB_ENV_PASSTHROUGH_ADDITIONS) are set in the SDK's configuration
    extralines = []
    for name, value in env_passthrough_values.items():
        actualvalue = d.getVar(name) or ''
        if value != actualvalue:
            extralines.append('%s = "%s"\n' % (name, actualvalue))
    if extralines:
        with open(baseoutpath + '/conf/local.conf', 'a') as f:
            f.write('\n')
            f.write('# Extra settings from environment:\n')
            for line in extralines:
                f.write(line)
            f.write('\n')

def prepare_locked_cache(d, baseoutpath, derivative, conf_initpath):
    import shutil

    # Filter the locked signatures file to just the sstate tasks we are interested in
    excluded_targets = get_sdk_install_targets(d, images_only=True)
    sigfile = d.getVar('WORKDIR') + '/locked-sigs.inc'
    lockedsigs_pruned = baseoutpath + '/conf/locked-sigs.inc'
    #nativesdk-only sigfile to merge into locked-sigs.inc
    sdk_include_nativesdk = (d.getVar("SDK_INCLUDE_NATIVESDK") == '1')
    nativesigfile = d.getVar('WORKDIR') + '/locked-sigs_nativesdk.inc'
    nativesigfile_pruned = d.getVar('WORKDIR') + '/locked-sigs_nativesdk_pruned.inc'

    if sdk_include_nativesdk:
        oe.copy_buildsystem.prune_lockedsigs([],
                                             excluded_targets.split(),
                                             nativesigfile,
                                             True,
                                             nativesigfile_pruned)

        oe.copy_buildsystem.merge_lockedsigs([],
                                             sigfile,
                                             nativesigfile_pruned,
                                             sigfile)

    oe.copy_buildsystem.prune_lockedsigs([],
                                         excluded_targets.split(),
                                         sigfile,
                                         False,
                                         lockedsigs_pruned)

    sstate_out = baseoutpath + '/sstate-cache'
    bb.utils.remove(sstate_out, True)

    # uninative.bbclass sets NATIVELSBSTRING to 'universal%s' % oe.utils.host_gcc_version(d)
    fixedlsbstring = "universal%s" % oe.utils.host_gcc_version(d)

    sdk_include_toolchain = (d.getVar('SDK_INCLUDE_TOOLCHAIN') == '1')
    sdk_ext_type = d.getVar('SDK_EXT_TYPE')
    if (sdk_ext_type != 'minimal' or sdk_include_toolchain or derivative) and not sdk_include_nativesdk:
        # Create the filtered task list used to generate the sstate cache shipped with the SDK
        tasklistfn = d.getVar('WORKDIR') + '/tasklist.txt'
        create_filtered_tasklist(d, baseoutpath, tasklistfn, conf_initpath)
    else:
        tasklistfn = None

    cachedir = os.path.join(baseoutpath, 'cache')
    bb.utils.mkdirhier(cachedir)
    bb.parse.siggen.copy_unitaskhashes(cachedir)

    # Add packagedata if enabled
    if d.getVar('SDK_INCLUDE_PKGDATA') == '1':
        lockedsigs_base = d.getVar('WORKDIR') + '/locked-sigs-base.inc'
        lockedsigs_copy = d.getVar('WORKDIR') + '/locked-sigs-copy.inc'
        shutil.move(lockedsigs_pruned, lockedsigs_base)
        oe.copy_buildsystem.merge_lockedsigs(['do_packagedata'],
                                             lockedsigs_base,
                                             d.getVar('STAGING_DIR_HOST') + '/world-pkgdata/locked-sigs-pkgdata.inc',
                                             lockedsigs_pruned,
                                             lockedsigs_copy)

    if sdk_include_toolchain:
        lockedsigs_base = d.getVar('WORKDIR') + '/locked-sigs-base2.inc'
        lockedsigs_toolchain = d.expand("${STAGING_DIR}/${TUNE_PKGARCH}/meta-extsdk-toolchain/locked-sigs/locked-sigs-extsdk-toolchain.inc")
        shutil.move(lockedsigs_pruned, lockedsigs_base)
        oe.copy_buildsystem.merge_lockedsigs([],
                                             lockedsigs_base,
                                             lockedsigs_toolchain,
                                             lockedsigs_pruned)
        oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_toolchain,
                                                       d.getVar('SSTATE_DIR'),
                                                       sstate_out, d,
                                                       fixedlsbstring,
                                                       filterfile=tasklistfn)

    if sdk_ext_type == 'minimal':
        if derivative:
            # Assume the user is not going to set up an additional sstate
            # mirror, thus we need to copy the additional artifacts (from
            # workspace recipes) into the derivative SDK
            lockedsigs_orig = d.getVar('TOPDIR') + '/conf/locked-sigs.inc'
            if os.path.exists(lockedsigs_orig):
                lockedsigs_extra = d.getVar('WORKDIR') + '/locked-sigs-extra.inc'
                oe.copy_buildsystem.merge_lockedsigs(None,
                                                     lockedsigs_orig,
                                                     lockedsigs_pruned,
                                                     None,
                                                     lockedsigs_extra)
                oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_extra,
                                                               d.getVar('SSTATE_DIR'),
                                                               sstate_out, d,
                                                               fixedlsbstring,
                                                               filterfile=tasklistfn)
    else:
        oe.copy_buildsystem.create_locked_sstate_cache(lockedsigs_pruned,
                                                       d.getVar('SSTATE_DIR'),
                                                       sstate_out, d,
                                                       fixedlsbstring,
                                                       filterfile=tasklistfn)

    # We don't need sstate do_package files
    for root, dirs, files in os.walk(sstate_out):
        for name in files:
            if name.endswith("_package.tar.zst"):
                f = os.path.join(root, name)
                os.remove(f)

def write_manifest(d, baseoutpath):
    import glob

    # Write manifest file
    # Note: at the moment we cannot include the env setup script here to keep
    # it updated, since it gets modified during SDK installation (see
    # sdk_ext_postinst() below) thus the checksum we take here would always
    # be different.
    manifest_file_list = ['conf/*']
    if d.getVar('BBMULTICONFIG') is not None:
        manifest_file_list.append('conf/multiconfig/*')

    esdk_manifest_excludes = (d.getVar('ESDK_MANIFEST_EXCLUDES') or '').split()
    esdk_manifest_excludes_list = []
    for exclude_item in esdk_manifest_excludes:
        esdk_manifest_excludes_list += glob.glob(os.path.join(baseoutpath, exclude_item))
    manifest_file = os.path.join(baseoutpath, 'conf', 'sdk-conf-manifest')
    with open(manifest_file, 'w') as f:
        for item in manifest_file_list:
            for fn in glob.glob(os.path.join(baseoutpath, item)):
                if fn == manifest_file or os.path.isdir(fn):
                    continue
                if fn in esdk_manifest_excludes_list:
                    continue
                chksum = bb.utils.sha256_file(fn)
                f.write('%s\t%s\n' % (chksum, os.path.relpath(fn, baseoutpath)))


python copy_buildsystem () {
    import oe.copy_buildsystem

    baseoutpath = d.getVar('SDK_OUTPUT') + '/' + d.getVar('SDKPATH')

    # Determine if we're building a derivative extensible SDK (from devtool build-sdk)
    derivative = (d.getVar('SDK_DERIVATIVE') or '') == '1'

    conf_initpath, conf_bbpath, core_meta_subdir, sdkbblayers = copy_bitbake_and_layers(d, baseoutpath, derivative)

    write_devtool_config(d, baseoutpath, conf_bbpath, conf_initpath, core_meta_subdir)

    write_unlocked_sigs(d, baseoutpath)

    write_bblayers_conf(d, baseoutpath, sdkbblayers)

    uninative_checksum = copy_uninative(d, baseoutpath)

    write_local_conf(d, baseoutpath, derivative, core_meta_subdir, uninative_checksum)

    prepare_locked_cache(d, baseoutpath, derivative, conf_initpath)

    write_manifest(d, baseoutpath)

}

def get_current_buildtools(d):
    """Get the file name of the current buildtools installer"""
    import glob
    btfiles = glob.glob(os.path.join(d.getVar('SDK_DEPLOY'), '*-buildtools-nativesdk-standalone-*.sh'))
    btfiles.sort(key=os.path.getctime)
    return os.path.basename(btfiles[-1])

def get_sdk_required_utilities(buildtools_fn, d):
    """Find required utilities that aren't provided by the buildtools"""
    sanity_required_utilities = (d.getVar('SANITY_REQUIRED_UTILITIES') or '').split()
    sanity_required_utilities.append(d.expand('${BUILD_PREFIX}gcc'))
    sanity_required_utilities.append(d.expand('${BUILD_PREFIX}g++'))
    if buildtools_fn:
        buildtools_installer = os.path.join(d.getVar('SDK_DEPLOY'), buildtools_fn)
        filelist, _ = bb.process.run('%s -l' % buildtools_installer)
    else:
        buildtools_installer = None
        filelist = ""
    localdata = bb.data.createCopy(d)
    localdata.setVar('SDKPATH', '.')
    sdkpathnative = localdata.getVar('SDKPATHNATIVE')
    sdkbindirs = [localdata.getVar('bindir_nativesdk'),
                  localdata.getVar('sbindir_nativesdk'),
                  localdata.getVar('base_bindir_nativesdk'),
                  localdata.getVar('base_sbindir_nativesdk')]
    for line in filelist.splitlines():
        splitline = line.split()
        if len(splitline) > 5:
            fn = splitline[5]
            if not fn.startswith('./'):
                fn = './%s' % fn
            if fn.startswith(sdkpathnative):
                relpth = '/' + os.path.relpath(fn, sdkpathnative)
                for bindir in sdkbindirs:
                    if relpth.startswith(bindir):
                        relpth = os.path.relpath(relpth, bindir)
                        if relpth in sanity_required_utilities:
                            sanity_required_utilities.remove(relpth)
                        break
    return ' '.join(sanity_required_utilities)

install_tools() {
	touch ${SDK_OUTPUT}/${SDKPATH}/.devtoolbase

	# find latest buildtools-tarball and install it
	if [ -n "${SDK_BUILDTOOLS_INSTALLER}" ]; then
		install ${SDK_DEPLOY}/${SDK_BUILDTOOLS_INSTALLER} ${SDK_OUTPUT}/${SDKPATH}
	fi

	install -m 0644 ${COREBASE}/meta/files/ext-sdk-prepare.py ${SDK_OUTPUT}/${SDKPATH}
}
do_populate_sdk_ext[file-checksums] += "${COREBASE}/meta/files/ext-sdk-prepare.py:True"

sdk_ext_preinst() {
	# Since bitbake won't run as root it doesn't make sense to try and install
	# the extensible sdk as root.
	if [ "`id -u`" = "0" ]; then
		echo "ERROR: The extensible sdk cannot be installed as root."
		exit 1
	fi
	if ! command -v locale > /dev/null; then
		echo "ERROR: The installer requires the locale command, please install it first"
		exit 1
	fi
        # Check setting of LC_ALL set above
	canonicalised_locale=`echo $LC_ALL | sed 's/UTF-8/utf8/'`
	if ! locale -a | grep -q $canonicalised_locale ; then
		echo "ERROR: the installer requires the $LC_ALL locale to be installed (but not selected), please install it first"
		exit 1
	fi
	# The relocation script used by buildtools installer requires python
	if ! command -v python3 > /dev/null; then
		echo "ERROR: The installer requires python3, please install it first"
		exit 1
	fi
	missing_utils=""
	for util in ${SDK_REQUIRED_UTILITIES}; do
		if ! command -v $util > /dev/null; then
			missing_utils="$missing_utils $util"
		fi
	done
	if [ -n "$missing_utils" ] ; then
		echo "ERROR: the SDK requires the following missing utilities, please install them: $missing_utils"
		exit 1
	fi
	SDK_EXTENSIBLE="1"
	if [ "$publish" = "1" ] && [ "${SDK_EXT_TYPE}" = "minimal" ] ; then
		EXTRA_TAR_OPTIONS="$EXTRA_TAR_OPTIONS --exclude=sstate-cache"
	fi
}
SDK_PRE_INSTALL_COMMAND:task-populate-sdk-ext = "${sdk_ext_preinst}"

# FIXME this preparation should be done as part of the SDK construction
sdk_ext_postinst() {
	printf "\nExtracting buildtools...\n"
	cd $target_sdk_dir
	env_setup_script="$target_sdk_dir/environment-setup-${REAL_MULTIMACH_TARGET_SYS}"
        if [ -n "${SDK_BUILDTOOLS_INSTALLER}" ]; then
		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 ; }

		# Delete the buildtools tar file since it won't be used again
		rm -f ./${SDK_BUILDTOOLS_INSTALLER}
		# We don't need the log either since it succeeded
		rm -f buildtools.log

		# Make sure when the user sets up the environment, they also get
		# the buildtools-tarball tools in their path.
		echo "# Save and reset OECORE_NATIVE_SYSROOT as buildtools may change it" >> $env_setup_script
		echo "SAVED=\"\$OECORE_NATIVE_SYSROOT\"" >> $env_setup_script
		echo ". $target_sdk_dir/buildtools/environment-setup*" >> $env_setup_script
		echo "OECORE_NATIVE_SYSROOT=\"\$SAVED\"" >> $env_setup_script
	fi

	# Allow bitbake environment setup to be ran as part of this sdk.
	echo "export OE_SKIP_SDK_CHECK=1" >> $env_setup_script
	# Work around runqemu not knowing how to get this information within the eSDK
	echo "export DEPLOY_DIR_IMAGE=$target_sdk_dir/tmp/${@os.path.relpath(d.getVar('DEPLOY_DIR_IMAGE'), d.getVar('TMPDIR'))}" >> $env_setup_script

	# A bit of another hack, but we need this in the path only for devtool
	# so put it at the end of $PATH.
	echo "export PATH=\"$target_sdk_dir/${esdk_tools_path}:\$PATH\"" >> $env_setup_script

	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

	# Warn if trying to use external bitbake and the ext SDK together
	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

	if [ "$prepare_buildsystem" != "no" -a -n "${SDK_BUILDTOOLS_INSTALLER}" ]; then
		printf "Preparing build system...\n"
		# dash which is /bin/sh on Ubuntu will not preserve the
		# current working directory when first ran, nor will it set $1 when
		# sourcing a script. That is why this has to look so ugly.
		LOGFILE="$target_sdk_dir/preparing_build_system.log"
		sh -c ". buildtools/environment-setup* > $LOGFILE 2>&1 && 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 2>&1 && 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 ; }
	fi
	if [ -e $target_sdk_dir/ext-sdk-prepare.py ]; then
		rm $target_sdk_dir/ext-sdk-prepare.py
	fi
	echo done
}

SDK_POST_INSTALL_COMMAND:task-populate-sdk-ext = "${sdk_ext_postinst}"

SDK_POSTPROCESS_COMMAND:prepend:task-populate-sdk-ext = "copy_buildsystem install_tools "

SDK_INSTALL_TARGETS = ""
fakeroot python do_populate_sdk_ext() {
    # FIXME hopefully we can remove this restriction at some point, but uninative
    # currently forces this upon us
    if d.getVar('SDK_ARCH') != d.getVar('BUILD_ARCH'):
        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')))

    # FIXME hopefully we can remove this restriction at some point, but the eSDK
    # can only be built for the primary (default) multiconfig
    if d.getVar('BB_CURRENT_MC') != 'default':
        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'))

    # eSDK dependencies don't use the traditional variables and things don't work properly if they are set
    d.setVar("TOOLCHAIN_HOST_TASK", "${TOOLCHAIN_HOST_TASK_ESDK}")
    d.setVar("TOOLCHAIN_TARGET_TASK", "")

    d.setVar('SDK_INSTALL_TARGETS', get_sdk_install_targets(d))
    if d.getVar('SDK_INCLUDE_BUILDTOOLS') == '1':
        buildtools_fn = get_current_buildtools(d)
    else:
        buildtools_fn = None
    d.setVar('SDK_REQUIRED_UTILITIES', get_sdk_required_utilities(buildtools_fn, d))
    d.setVar('SDK_BUILDTOOLS_INSTALLER', buildtools_fn)
    d.setVar('SDKDEPLOYDIR', '${SDKEXTDEPLOYDIR}')
    # ESDKs have a libc from the buildtools so ensure we don't ship linguas twice
    d.delVar('SDKIMAGE_LINGUAS')
    if d.getVar("SDK_INCLUDE_NATIVESDK") == '1':
        generate_nativesdk_lockedsigs(d)
    populate_sdk_common(d)
}

def generate_nativesdk_lockedsigs(d):
    import oe.copy_buildsystem
    sigfile = d.getVar('WORKDIR') + '/locked-sigs_nativesdk.inc'
    oe.copy_buildsystem.generate_locked_sigs(sigfile, d)

def get_ext_sdk_depends(d):
    # Note: the deps varflag is a list not a string, so we need to specify expand=False
    deps = d.getVarFlag('do_image_complete', 'deps', False)
    pn = d.getVar('PN')
    deplist = ['%s:%s' % (pn, dep) for dep in deps]
    tasklist = bb.build.tasksbetween('do_image_complete', 'do_build', d)
    tasklist.append('do_rootfs')
    for task in tasklist:
        deplist.extend((d.getVarFlag(task, 'depends') or '').split())
    return ' '.join(deplist)

python do_sdk_depends() {
    # We have to do this separately in its own task so we avoid recursing into
    # dependencies we don't need to (e.g. buildtools-tarball) and bringing those
    # into the SDK's sstate-cache
    import oe.copy_buildsystem
    sigfile = d.getVar('WORKDIR') + '/locked-sigs.inc'
    oe.copy_buildsystem.generate_locked_sigs(sigfile, d)
}
addtask sdk_depends

do_sdk_depends[dirs] = "${WORKDIR}"
do_sdk_depends[depends] = "${@get_ext_sdk_depends(d)} meta-extsdk-toolchain:do_populate_sysroot"
do_sdk_depends[recrdeptask] = "${@d.getVarFlag('do_populate_sdk', 'recrdeptask', False)}"
do_sdk_depends[recrdeptask] += "do_populate_lic do_package_qa do_populate_sysroot do_deploy ${SDK_RECRDEP_TASKS}"
do_sdk_depends[rdepends] = "${@' '.join([x + ':do_package_write_${IMAGE_PKGTYPE} ' + x + ':do_packagedata' for x in d.getVar('TOOLCHAIN_HOST_TASK_ESDK').split()])}"

do_populate_sdk_ext[dirs] = "${@d.getVarFlag('do_populate_sdk', 'dirs', False)}"

do_populate_sdk_ext[depends] = "${@d.getVarFlag('do_populate_sdk', 'depends', False)} \
                                ${@'buildtools-tarball:do_populate_sdk' if d.getVar('SDK_INCLUDE_BUILDTOOLS') == '1' else ''} \
                                ${@'meta-world-pkgdata:do_collect_packagedata' if d.getVar('SDK_INCLUDE_PKGDATA') == '1' else ''} \
                                ${@'meta-extsdk-toolchain:do_locked_sigs' if d.getVar('SDK_INCLUDE_TOOLCHAIN') == '1' else ''}"

# We must avoid depending on do_build here if rm_work.bbclass is active,
# because otherwise do_rm_work may run before do_populate_sdk_ext itself.
# We can't mark do_populate_sdk_ext and do_sdk_depends as having to
# run before do_rm_work, because then they would also run as part
# of normal builds.
do_populate_sdk_ext[rdepends] += "${@' '.join([x + ':' + (d.getVar('RM_WORK_BUILD_WITHOUT') or 'do_build') for x in d.getVar('SDK_TARGETS').split()])}"

# Make sure code changes can result in rebuild
do_populate_sdk_ext[vardeps] += "copy_buildsystem \
                                 sdk_ext_postinst"

# Since any change in the metadata of any layer should cause a rebuild of the
# sdk(since the layers are put in the sdk) set the task to nostamp so it
# always runs.
do_populate_sdk_ext[nostamp] = "1"

SDKEXTDEPLOYDIR = "${WORKDIR}/deploy-${PN}-populate-sdk-ext"

SSTATETASKS += "do_populate_sdk_ext"
SSTATE_SKIP_CREATION:task-populate-sdk-ext = '1'
do_populate_sdk_ext[cleandirs] = "${SDKEXTDEPLOYDIR}"
do_populate_sdk_ext[sstate-inputdirs] = "${SDKEXTDEPLOYDIR}"
do_populate_sdk_ext[sstate-outputdirs] = "${SDK_DEPLOY}"
do_populate_sdk_ext[stamp-extra-info] = "${MACHINE_ARCH}"

addtask populate_sdk_ext after do_sdk_depends
