subtree updates

meta-raspberrypi: b6a1645a97..c57b464b88:
  Lluis Campos (1):
        rpi-cmdline: do_compile: Use pure Python syntax to get `CMDLINE`

meta-openembedded: 2eb39477a7..a755af4fb5:
  Adrian Zaharia (1):
        lapack: add packageconfig for lapacke

  Akash Hadke (1):
        polkit: Add --shell /bin/nologin to polkitd user

  Alex Kiernan (3):
        ntpsec: Add UPSTREAM_CHECK_URI
        libgpiod: Detect ptest using PTEST_ENABLED
        ostree: Cleanup PACKAGECONFIGs

  Anuj Mittal (1):
        yasm: fix buildpaths warning

  Atanas Bunchev (1):
        python3-twitter: Upgrade 4.8.0 -> 4.10.1

  Bartosz Golaszewski (4):
        imagemagick: add PACKAGECONFIG for C++ bindings
        python3-matplotlib: don't use PYTHON_PN
        python3-matplotlib: add packaging to RDEPENDS
        python3-matplotlib: bump to 3.5.2

  Bruce Ashfield (3):
        vboxguestdrivers: fix build against 5.19 kernel / libc-headers
        zfs: update to v2.1.5
        vboxguestdrivers: make kernel shared directory dependency explicit

  Carsten Bäcker (1):
        spdlog: Fix CMake flag

  Changqing Li (3):
        fuse3: support ptest
        redis: fix do_patch fuzz warning
        dlt-daemon: fix dlt-system.service failed since buffer overflow

  Clément Péron (1):
        python: add Pydantic data validation package

  Devendra Tewari (1):
        android-tools: sleep more in android-gadget-start

  Ed Tanous (1):
        Add python-requests-unixsocket recipe

  Enguerrand de Ribaucourt (1):
        mdio-tools: add recipes

  Etienne Cordonnier (1):
        uutils-coreutils: add recipe

  Jagadeesh Krishnanjanappa (4):
        python3-asgiref: add recipe
        python3-django: make 3.2.x as default version
        python3-django: Add python3-asgiref runtime dependency
        python3-django: remove 2.2.x recipe

  Jan Luebbe (2):
        chrony: add support for config and source snippet includes
        gensio: upgrade 2.3.1 -> 2.5.2

  Jan Vermaete (1):
        makeself: added makeself as new recipe

  Jim Broadus (1):
        networkmanager: fix iptables and nft paths

  Jose Quaresma (2):
        wireguard-module: 1.0.20210219 -> 1.0.20220627
        wireguard-tools: Add a new package for wg-quick

  Julian Haller (2):
        pcsc-lite: upgrade 1.9.0 -> 1.9.8
        ccid: upgrade 1.4.33 -> 1.5.0

  Justin Bronder (1):
        lmdb: only set SONAME on the shared library

  Khem Raj (61):
        mariadb: Inherit pkgconfig
        mariadb: Add packageconfig for lz4 and enable it
        ibus: Swith to use main branch instead of master
        kronosnet: Upgrade to 1.24
        ostree: Upgrade to 2022.5 release
        sdbus-c++-libsystemd: Fix build with glibc 2.36
        xfstests: Upgrade to v2022.07.10
        autofs: Fix build with glibc 2.36
        audit: Upgrade to 3.0.8 and fix build with linux 5.17+
        pcp: Add to USERADD_PACKAGES instead of override
        mozjs: Use RUST_HOST_SYS and RUST_TARGET_SYS
        fluentbit: Fix build with clang
        audit: Fix build with musl
        fluentbit: Fix build with musl
        klibc: Upgrade to 2.0.10
        gnome-keyring,cunit,xfce4-panel: Do not inherit remove-libtool class here
        mpd: Update to 0.23.8
        openipmi: Enable largefile cflags
        proftpd: Always enable largefile support
        netperf: Always enable largefile support
        openipmi: Always enable largefile support
        unbound: Always enable largefile support
        sysbench: Always enable largefile support
        libmtp: Always enable largefile support
        toybox: Fix build with glibc 2.36+
        xfstests: Upgrade to 2022.07.31 release
        libmpd: Fix function returns and casts
        audit: Revert the tweak done in configure step in do_install
        mpd: Upgrade to 0.23.9
        fluentbit: Use CMAKE_C_STANDARD_LIBRARIES cmake var to pass libatomic
        fluentbit: Upgrade to 1.9.7 and fix build on x86
        klibc: Fix build with kernel 5.19 headers
        ntpsec: Add -D_GNU_SOURCE and fix building with devtool
        gd: Fix build with clang-15
        cpulimit: Define -D_GNU_SOURCE
        safec: Remove unused variable 'len'
        ncftp: Enable autoreconf
        ncftp: Fix TMPDIR path embedding into ncftpget
        libb64: Switch to github fork and upgrade to 2.0.0.1+git
        dhrystone: Disable warnings as errors with clang
        dibbler: Fix build with musl
        fio: Fix additional warnings seen with musl
        ssmtp: Fix null pointer assignments
        gst-editing-services: Add recipe
        rygel: Upgrade to 0.40.4
        libesmtp: Define _GNU_SOURCE
        python3-grpcio: Enable largefile support explicitly
        libteam: Include missing headers for strrchr and memcmp
        neon: Upgrade to 0.32.2
        satyr: Fix build on musl/clang
        libmusicbrainz: Avoid -Wnonnull warning
        aom: Upgrade to 3.4.0
        vorbis-tools: Fix build on musl
        dvb-apps: Use tarball for SRC_URI and fix build on musl
        python3-netifaces: Fix build with python3 and musl
        python3-pyephem: Fix build with python3 and musl
        samba: Fix warnings in configure tests for rpath checks
        lirc: Fix build on musl
        mongodb: Fix boost build with clang-15
        crda: Fix build with clang-15
        monkey: Fix build with musl

  Lei Maohui (2):
        dnf-plugin-tui: Fix somw issue in postinstall process.
        xrdp: Fix buildpaths warning.

  Leon Anavi (16):
        python3-nocasedict: Upgrade 1.0.3 -> 1.0.4
        python3-frozenlist: Upgrade 1.3.0 -> 1.3.1
        python3-networkx: Upgrade 2.8.4 -> 2.8.5
        python3-pyhamcrest: Upgrade 2.0.3 -> 2.0.4
        python3-aiohue: Upgrade 4.4.2 -> 4.5.0
        python3-pyperf: Upgrade 2.3.0 -> 2.4.1
        python3-eth-abi: Upgrade 3.0.0 -> 3.0.1
        python3-cytoolz: Upgrade 0.11.2 -> 0.12.0
        python3-yarl: Upgrade 1.7.2 -> 1.8.1
        python3-term: Upgrade 2.3 -> 2.4
        python3-coverage: Upgrade 6.4.1 -> 6.4.4
        python3-regex: Upgrade 2022.7.25 -> 2022.8.17
        python3-awesomeversion: Upgrade 22.6.0 -> 22.8.0
        python3-typed-ast: Upgrade 1.5.2 -> 1.5.4
        python3-prompt-toolkit: Upgrade 3.0.24 -> 3.0.30
        python3-prettytable: Upgrade 3.1.1 -> 3.3.0

  Markus Volk (6):
        libass: update to v1.16.0
        spdlog: update to v1.10.0
        waylandpp: add recipe
        wireplumber: update to v0.4.11
        pipewire: update to v0.3.56
        pipewire: improve runtime dependency settings

  Marta Rybczynska (1):
        polkit: update patches for musl compilation

  Matthias Klein (1):
        libftdi: update to 1.5

  Mike Crowe (1):
        yasm: Only depend on xmlto when docs are enabled

  Mike Petersen (1):
        sshpass: add recipe

  Mingli Yu (10):
        net-snmp: set ac_cv_path_PSPROG
        postgresql: Fix the buildpaths issue
        freeradius: Fix buildpaths issue
        openipmi: Fix buildpaths issue
        apache2: Fix the buildpaths issue
        frr: fix buildpaths issue
        nspr: fix buildpaths issue
        liblockfile: fix buildpaths issue
        freediameter: fix buildpaths issue
        postgresql: make sure pam conf installed when pam enabled

  Ovidiu Panait (1):
        net-snmp: upgrade 5.9.1 -> 5.9.3

  Paulo Neves (1):
        fluentbit Upgrade to 1.3.5 -> 1.9.6

  Philip Balister (2):
        python3-pybind11: Update to Version 2.10.0.
        Remove dead link and old information from the README.

  Potin Lai (7):
        libplist: add libplist_git.bb
        libimobiledevice-glue: SRCREV bump bc6c44b..d2ff796
        libimobiledevice: add libimobiledevice_git.bb
        libirecovery: SRCREV bump e190945..ab5b4d8
        libusbmuxd: add libusbmuxd_git.bb
        usbmuxd: add usbmuxd_git.bb
        idevicerestore: SRCREV bump 280575b..7d622d9

  Richard Purdie (1):
        lmdb: Don't inherit base

  Sam Van Den Berge (1):
        python3-jsonrpcserver: add patch to use importlib.resources instead of pkg_resources

  Saul Wold (10):
        libipc-signal-perl: Fix LICENSE string
        libdigest-hmac-perl: Fix LICENSE string
        libio-socket-ssl-perl: Fix LICENSE string
        libdigest-sha1-perl: Fix LICENSE string
        libmime-types-perl: Fix LICENSE string
        libauthen-sasl-perl: Fix LICENSE string
        libnet-ldap-perl: Fix LICENSE string
        libxml-libxml-perl: Fix LICENSE string
        libnet-telnet-perl: Fix LICENSE string
        libproc-waitstat-perl: Fix LICENSE string

  Sean Anderson (2):
        image_types_sparse: Pad source image to block size
        image_types_sparse: Generate "don't care" chunks

  Vyacheslav Yurkov (4):
        protobuf: correct ptest dependency
        protobuf: 3.19.4 -> 3.21.5 upgrade
        protobuf: change build system to cmake
        protobuf: disable protoc binary for target

  Wang Mingyu (60):
        cifs-utils: upgrade 6.15 -> 7.0
        geocode-glib: upgrade 3.26.3 -> 3.26.4
        gjs: upgrade 1.72.1 -> 1.72.2
        htpdate: upgrade 1.3.5 -> 1.3.6
        icewm: upgrade 2.9.8 -> 2.9.9
        ipc-run: upgrade 20200505.0 -> 20220807.0
        iwd: upgrade 1.28 -> 1.29
        ldns: upgrade 1.8.1 -> 1.8.2
        libadwaita: upgrade 1.1.3 -> 1.1.4
        libencode-perl: upgrade 3.18 -> 3.19
        libmime-charset-perl: upgrade 1.012.2 -> 1.013.1
        libtest-warn-perl: upgrade 0.36 -> 0.37
        nano: upgrade 6.3 -> 6.4
        nbdkit: upgrade 1.31.15 -> 1.32.1
        netdata: upgrade 1.35.1 -> 1.36.0
        fio: upgrade 3.30 -> 3.31
        nlohmann-json: upgrade 3.10.5 -> 3.11.2
        poco: upgrade 1.12.1 -> 1.12.2
        postgresql: upgrade 14.4 -> 14.5
        poppler: upgrade 22.07.0 -> 22.08.0
        smarty: upgrade 4.1.1 -> 4.2.0
        tracker: upgrade 3.3.2 -> 3.3.3
        uftp: upgrade 5.0 -> 5.0.1
        xdg-user-dirs: upgrade 0.17 -> 0.18
        python3-pycodestyle: upgrade 2.9.0 -> 2.9.1
        python3-pyzmq: upgrade 23.2.0 -> 23.2.1
        python3-setuptools-declarative-requirements: upgrade 1.2.0 -> 1.3.0
        python3-sqlalchemy: upgrade 1.4.39 -> 1.4.40
        python3-werkzeug: upgrade 2.2.1 -> 2.2.2
        python3-xmlschema: upgrade 2.0.1 -> 2.0.2
        python3-yappi: upgrade 1.3.5 -> 1.3.6
        ade: upgrade 0.1.1f -> 0.1.2
        babl: upgrade 0.1.92 -> 0.1.94
        ctags: upgrade 5.9.20220703.0 -> 5.9.20220821.0
        grilo-plugins: upgrade 0.3.14 -> 0.3.15
        ldns: upgrade 1.8.2 -> 1.8.3
        libcurses-perl: upgrade 1.38 -> 1.41
        mosquitto: upgrade 2.0.14 -> 2.0.15
        nbdkit: upgrade 1.32.1 -> 1.33.1
        netdata: upgrade 1.36.0 -> 1.36.1
        libsdl2-ttf: upgrade 2.20.0 -> 2.20.1
        xfstests: upgrade 2022.07.31 -> 2022.08.07
        php: upgrade 8.1.8 -> 8.1.9
        rdma-core: upgrade 41.0 -> 42.0
        spitools: upgrade 1.0.1 -> 1.0.2
        unbound: upgrade 1.16.1 -> 1.16.2
        zlog: upgrade 1.2.15 -> 1.2.16
        python3-hexbytes: upgrade 0.2.3 -> 0.3.0
        python3-pythonping: upgrade 1.1.2 -> 1.1.3
        python3-jsonrpcserver: Add dependence python3-typing-extensions
        feh: upgrade 3.9 -> 3.9.1
        gnome-bluetooth: upgrade 42.2 -> 42.3
        hunspell: upgrade 1.7.0 -> 1.7.1
        gtk4: upgrade 4.6.6 -> 4.6.7
        logwatch: upgrade 7.6 -> 7.7
        bdwgc: upgrade 8.2.0 -> 8.2.2
        tcpreplay: upgrade 4.4.1 -> 4.4.2
        tree: upgrade 2.0.2 -> 2.0.3
        xfsdump: upgrade 3.1.10 -> 3.1.11
        babl: upgrade 0.1.94 -> 0.1.96

  Wolfgang Meyer (1):
        libsdl2-ttf: upgrade 2.0.18 -> 2.20.0

  Xu Huan (18):
        python3-protobuf: upgrade 4.21.3 -> 4.21.4
        python3-pycodestyle: upgrade 2.8.0 -> 2.9.0
        python3-pyflakes: upgrade 2.4.0 -> 2.5.0
        python3-pythonping: upgrade 1.1.1 -> 1.1.2
        python3-regex: upgrade 2022.7.24 -> 2022.7.25
        python3-werkzeug: upgrade 2.2.0 -> 2.2.1
        python3-google-auth: upgrade 2.9.1 -> 2.10.0
        python3-humanize: upgrade 4.2.3 -> 4.3.0
        python3-hexbytes: upgrade 0.2.2 -> 0.2.3
        python3-imageio: upgrade 2.21.0 -> 2.21.1
        python3-nocaselist: upgrade 1.0.5 -> 1.0.6
        python3-protobuf: upgrade 4.21.4 -> 4.21.5
        python3-pycares: upgrade 4.2.1 -> 4.2.2
        python3-fastjsonschema: upgrade 2.16.1 -> 2.16.2
        python3-google-api-python-client: upgrade 2.56.0 -> 2.57.0
        python3-google-auth: upgrade 2.10.0 -> 2.11.0
        python3-grpcio-tools: upgrade 1.47.0 -> 1.48.0
        python3-grpcio: upgrade 1.47.0 -> 1.48.0

  Yi Zhao (5):
        strongswan: upgrade 5.9.6 -> 5.9.7
        libldb: upgrade 2.3.3 -> 2.3.4
        samba: upgrade 4.14.13 -> 4.14.14
        python3-jsonrpcserver: upgrade 5.0.7 -> 5.0.8
        samba: fix buildpaths issue

  wangmy (16):
        gedit: upgrade 42.1 -> 42.2
        libwacom: upgrade 2.3.0 -> 2.4.0
        htpdate: upgrade 1.3.4 -> 1.3.5
        nbdkit: upgrade 1.31.14 -> 1.31.15
        pure-ftpd: upgrade 1.0.50 -> 1.0.51
        avro-c: upgrade 1.11.0 -> 1.11.1
        debootstrap: upgrade 1.0.126 -> 1.0.127
        freerdp: upgrade 2.7.0 -> 2.8.0
        icewm: upgrade 2.9.7 -> 2.9.8
        libmxml: upgrade 3.3 -> 3.3.1
        poco: upgrade 1.12.0 -> 1.12.1
        xfontsel: upgrade 1.0.6 -> 1.1.0
        xmessage: upgrade 1.0.5 -> 1.0.6
        xrefresh: upgrade 1.0.6 -> 1.0.7
        zabbix: upgrade 6.0.5 -> 6.2.1
        xrdp: upgrade 0.9.18 -> 0.9.19

  zhengrq.fnst (4):
        python3-asttokens: upgrade 2.0.7 -> 2.0.8
        python3-charset-normalizer: upgrade 2.1.0 -> 2.1.1
        python3-eth-account: 0.6.1 -> 0.7.0
        python3-cantools: upgrade 37.1.0 -> 37.1.2

  zhengruoqin (12):
        python3-dominate: upgrade 2.6.0 -> 2.7.0
        python3-flask-login: upgrade 0.6.1 -> 0.6.2
        python3-google-api-python-client: upgrade 2.54.0 -> 2.55.0
        python3-haversine: upgrade 2.5.1 -> 2.6.0
        python3-imageio: upgrade 2.19.5 -> 2.21.0
        python3-autobahn: upgrade 22.6.1 -> 22.7.1
        python3-engineio: upgrade 4.3.3 -> 4.3.4
        python3-flask: upgrade 2.1.3 -> 2.2.2
        python3-gcovr: upgrade 5.1 -> 5.2
        python3-google-api-python-client: upgrade 2.55.0 -> 2.56.0
        python3-asttokens: upgrade 2.0.5 -> 2.0.7
        python3-zeroconf: upgrade 0.38.7 -> 0.39.0

meta-security: 2a2d650ee0..10fdc2b13a:
  Anton Antonov (2):
        Use CARGO_TARGET_SUBDIR in do_install
        parsec-service: Update oeqa tests

  Armin Kuster (8):
        python3-privacyidea: update to 3.7.3
        lkrg-module: update to 0.9.5
        apparmor: update to 3.0.6
        packagegroup-core-security: add space for appends
        cryptmount: Add new pkg
        packagegroup-core-security: add pkg to grp
        cyptmount: Fix mount.h conflicts seen with glibc 2.36+
        kas: update testimage inherit

  John Edward Broadbent (1):
        meta-security: Add recipe for Glome

  Mingli Yu (1):
        samhain-standalone: fix buildpaths issue

poky: fc59c28724..9b1db65e7d:
  Alejandro Hernandez Samaniego (1):
        baremetal-image.bbclass: Emulate image.bbclass to handle new classes scope

  Alex Stewart (1):
        maintainers: update opkg maintainer

  Alexander Kanavin (113):
        kmscube: address linux 5.19 fails
        rpm: update 4.17.0 -> 4.17.1
        go: update 1.18.4 -> 1.19
        bluez5: update 5.64 -> 5.65
        python3-pip: update 22.2.1 -> 22.2.2
        ffmpeg: update 5.0.1 -> 5.1
        iproute2: upgrade 5.18.0 -> 5.19.0
        harfbuzz: upgrade 4.4.1 -> 5.1.0
        libwpe: upgrade 1.12.0 -> 1.12.2
        bind: upgrade 9.18.4 -> 9.18.5
        diffoscope: upgrade 218 -> 220
        ell: upgrade 0.51 -> 0.52
        gnutls: upgrade 3.7.6 -> 3.7.7
        iso-codes: upgrade 4.10.0 -> 4.11.0
        kea: upgrade 2.0.2 -> 2.2.0
        kexec-tools: upgrade 2.0.24 -> 2.0.25
        libcap: upgrade 2.64 -> 2.65
        libevdev: upgrade 1.12.1 -> 1.13.0
        libnotify: upgrade 0.8.0 -> 0.8.1
        libwebp: upgrade 1.2.2 -> 1.2.3
        libxcvt: upgrade 0.1.1 -> 0.1.2
        mesa: upgrade 22.1.3 -> 22.1.5
        mobile-broadband-provider-info: upgrade 20220511 -> 20220725
        nettle: upgrade 3.8 -> 3.8.1
        piglit: upgrade to latest revision
        puzzles: upgrade to latest revision
        python3: upgrade 3.10.5 -> 3.10.6
        python3-dtschema: upgrade 2022.7 -> 2022.8
        python3-hypothesis: upgrade 6.50.1 -> 6.54.1
        python3-jsonschema: upgrade 4.9.0 -> 4.9.1
        python3-markdown: upgrade 3.3.7 -> 3.4.1
        python3-setuptools: upgrade 63.3.0 -> 63.4.1
        python3-sphinx: upgrade 5.0.2 -> 5.1.1
        python3-urllib3: upgrade 1.26.10 -> 1.26.11
        sqlite3: upgrade 3.39.1 -> 3.39.2
        sysklogd: upgrade 2.4.0 -> 2.4.2
        webkitgtk: upgrade 2.36.4 -> 2.36.5
        kernel-dev: working with kernel using devtool does not require building and installing eSDK
        sdk-manual: describe how to use extensible SDK functionality directly in a Yocto build
        dropbear: merge .inc into .bb
        rust: update 1.62.0 -> 1.62.1
        cmake: update 3.23.2 -> 3.24.0
        weston: upgrade 10.0.1 -> 10.0.2
        patchelf: update 0.14.5 -> 0.15.0
        patchelf: replace a rejected patch with an equivalent uninative.bbclass tweak
        weston: exclude pre-releases from version check
        tzdata: upgrade 2022a -> 2022b
        libcgroup: update 2.0.2 -> 3.0.0
        python3-setuptools-rust: update 1.4.1 -> 1.5.1
        shadow: update 4.11.1 -> 4.12.1
        slang: update 2.3.2 -> 2.3.3
        xz: update 5.2.5 -> 5.2.6
        gdk-pixbuf: update 2.42.8 -> 2.42.9
        xorgproto: update 2022.1 -> 2022.2
        boost-build-native: update 4.4.1 -> 1.80.0
        boost: update 1.79.0 -> 1.80.0
        vulkan-samples: update to latest revision
        epiphany: upgrade 42.3 -> 42.4
        git: upgrade 2.37.1 -> 2.37.2
        glib-networking: upgrade 2.72.1 -> 2.72.2
        gnu-efi: upgrade 3.0.14 -> 3.0.15
        gpgme: upgrade 1.17.1 -> 1.18.0
        libjpeg-turbo: upgrade 2.1.3 -> 2.1.4
        libwebp: upgrade 1.2.3 -> 1.2.4
        lighttpd: upgrade 1.4.65 -> 1.4.66
        mesa: upgrade 22.1.5 -> 22.1.6
        meson: upgrade 0.63.0 -> 0.63.1
        mpg123: upgrade 1.30.1 -> 1.30.2
        pango: upgrade 1.50.8 -> 1.50.9
        piglit: upgrade to latest revision
        pkgconf: upgrade 1.8.0 -> 1.9.2
        python3-dtschema: upgrade 2022.8 -> 2022.8.1
        python3-more-itertools: upgrade 8.13.0 -> 8.14.0
        python3-numpy: upgrade 1.23.1 -> 1.23.2
        python3-pbr: upgrade 5.9.0 -> 5.10.0
        python3-pyelftools: upgrade 0.28 -> 0.29
        python3-pytz: upgrade 2022.1 -> 2022.2.1
        strace: upgrade 5.18 -> 5.19
        sysklogd: upgrade 2.4.2 -> 2.4.4
        wireless-regdb: upgrade 2022.06.06 -> 2022.08.12
        wpebackend-fdo: upgrade 1.12.0 -> 1.12.1
        python3-hatchling: update 1.6.0 -> 1.8.0
        python3-setuptools: update 63.4.1 -> 65.0.2
        devtool: do not leave behind source trees in workspace/sources
        systemtap: add a patch to address a python 3.11 failure
        bitbake: bitbake-layers: initialize tinfoil before registering command line arguments
        scripts/oe-setup-builddir: add a check that TEMPLATECONF is valid
        bitbake-layers: add a command to save the active build configuration as a template into a layer
        bitbake-layers: add ability to save current layer repository configuration into a file
        scripts/oe-setup-layers: add a script that restores the layer configuration from a json file
        selftest/bblayers: add a test for creating a layer setup and using it to restore the layers
        selftest/bblayers: adjust the revision for the layer setup test
        perl: run builds from a pristine source tree
        meta-poky/conf: move default templates to conf/templates/default/
        syslinux: mark all pending patches as Inactive-Upstream
        shadow: correct the pam patch status
        mtd-utils: remove patch that adds -I option
        gstreamer1.0-plugins-bad: remove an unneeded patch
        ghostscript: remove unneeded patch
        ovmf: drop the force no-stack-protector patch
        python: submit CC to cc_basename patch upstream
        mc: submit perl warnings patch upstream
        sysvinit: send install.patch upstream
        valgrind: (re)send ppc instructions patch upstream
        gdk-pixbuf: submit fatal-loader.patch upstream
        libsdl2: follow upstream version is even rule
        python3-pip: submit reproducible.patch upstream
        python3-pip: remove unneeded reproducible.patch
        llvm: remove 0006-llvm-TargetLibraryInfo-Undefine-libc-functions-if-th.patch
        scripts/oe-setup-builddir: migrate build/conf/templateconf.cfg to new template locations
        meta/files/layers.schema.json: drop the layers property
        scripts/oe-setup-builddir: write to conf/templateconf.cfg after the build is set up
        scripts/oe-setup-builddir: make environment variable the highest priority source for TEMPLATECONF

  Alexandre Belloni (1):
        ruby: drop capstone support

  Andrei Gherzan (7):
        shadow: Enable subid support
        rootfspostcommands.py: Restructure sort_passwd and related functions
        rootfspostcommands.py: Cleanup subid backup files generated by shadow-utils
        selftest: Add module for testing rootfs postcommands
        rootfs-postcommands.bbclass: Follow function rename in rootfspostcommands.py
        shadow: Avoid nss warning/error with musl
        linux-yocto: Fix COMPATIBLE_MACHINE regex match

  Andrey Konovalov (2):
        mesa: add pipe-loader's libraries to libopencl-mesa package
        mesa: build clover with native LLVM codegen support for freedreno

  Anuj Mittal (1):
        poky.conf: add ubuntu-22.04 to tested distros

  Armin Kuster (1):
        system-requirements.rst: remove EOL and Centos7 hosts

  Aryaman Gupta (1):
        bitbake: runqueue: add memory pressure regulation

  Awais Belal (1):
        kernel-fitimage.bbclass: only package unique DTBs

  Beniamin Sandu (1):
        libpam: use /run instead of /var/run in systemd tmpfiles

  Bertrand Marquis (1):
        sysvinit-inittab/start_getty: Fix respawn too fast

  Bruce Ashfield (22):
        linux-yocto/5.15: update to v5.15.58
        linux-yocto/5.10: update to v5.10.134
        linux-yocto-rt/5.15: update to -rt48 (and fix -stable merge)
        linux-libc-headers: update to v5.19
        kernel-devsrc: support arm v5.19+ on target build
        kernel-devsrc: support powerpc on v5.19+
        lttng-modules: fix build against mips and v5.19 kernel
        linux-yocto: introduce v5.19 reference kernel recipes
        meta/conf: update preferred linux-yocto version to v5.19
        linux-yocto: drop v5.10 reference kernel recipes
        linux-yocto/5.15: update to v5.15.59
        linux-yocto/5.15: fix reproducibility issues
        linux-yocto/5.19: cfg: update x32 configuration fragment
        linux-yocto/5.19: fix reproducibility issues
        poky: update preferred version to v5.19
        poky: change preferred kernel version to 5.15 in poky-alt
        yocto-bsp: drop v5.10 bbappend and create 5.19 placeholder
        lttng-modules: replace mips compaction fix with upstream change
        linux-yocto/5.15: update to v5.15.60
        linux-yocto/5.19: update to v5.19.1
        linux-yocto/5.19: update to v5.19.3
        linux-yocto/5.15: update to v5.15.62

  Changqing Li (1):
        apt: fix nativesdk-apt build failure during the second time build

  Chen Qi (2):
        python3-hypothesis: revert back to 6.46.11
        python3-requests: add python3-compression dependency

  Drew Moseley (1):
        rng-tools: Replace obsolete "wants systemd-udev-settle"

  Enrico Scholz (2):
        npm.bbclass: fix typo in 'fund' config option
        npm.bbclass: fix architecture mapping

  Ernst Sjöstrand (1):
        cve-check: Don't use f-strings

  Jacob Kroon (1):
        python3-cython: Remove debug lines

  Jan Luebbe (2):
        openssh: sync local ssh_config + sshd_config files with upstream 8.7p1
        openssh: add support for config snippet includes to ssh and sshd

  JeongBong Seo (1):
        wic: add 'none' fstype for custom image

  Johannes Schneider (1):
        classes: rootfs-postcommands: autologin root on serial-getty

  Jon Mason (2):
        oeqa/parselogs: add qemuarmv5 arm-charlcd masking
        ref-manual: add numa to machine features

  Jose Quaresma (4):
        bitbake: build: prefix the tasks with a timestamp in the log task_order
        archiver.bbclass: some recipes that uses the kernelsrc bbclass uses the shared source
        linux-yocto: prepend the the value with a space when append to KERNEL_EXTRA_ARGS
        shaderc: upgrade 2022.1 -> 2022.2

  Joshua Watt (4):
        bitbake: siggen: Fix insufficent entropy in sigtask file names
        bitbake: utils: Pass lock argument in fileslocked
        classes: cve-check: Get shared database lock
        meta/files: add layer setup JSON schema and example

  Kai Kang (1):
        packagegroup-self-hosted: update for strace

  Kevin Hao (1):
        uboot-config.bbclass: Don't bail out early in multi configs

  Khem Raj (83):
        qemu: Fix build with glibc 2.36
        mtd-utils: Fix build with glibc 2.36
        stress-ng: Upgrade to 0.14.03
        bootchart2: Fix build with glibc 2.36+
        ltp: Fix sys/mount.h conflicts needed for glibc 2.36+ compile
        efivar: Fix build with glibc 2.36
        cracklib: Drop using register keyword
        util-linux: Define pidfd_* function signatures
        util-linux: Upgrade to 2.38.1
        tcp-wrappers: Fix implicit-function-declaration warnings
        perl-cross: Correct function signatures in configure_func.sh
        perl: Pass additional flags to enable lfs and gnu source
        sysvinit: Fix mount.h conflicts seen with glibc 2.36+
        glibc: Bump to 2.36
        glibc: Update patch status
        zip: Enable largefile support based on distro feature
        zip: Make configure checks to be more robust
        unzip: Fix configure tests to use modern C
        unzip: Enable largefile support when enabled in distro
        iproute2: Fix netns check during configure
        glibc: Bump to latest 2.36 branch
        gstreamer1.0-plugins-base: Include required system headers for isspace() and sscanf()
        musl: Upgrade to latest tip of trunk
        zip: Always enable LARGE_FILE_SUPPORT
        libmicrohttpd: Enable largefile support unconditionally
        unzip: Always enable largefile support
        default-distrovars: Remove largefile from defualt DISTRO_FEATURES
        zlib: Resolve CVE-2022-37434
        json-c: Fix function prototypes
        rsync: Backport fix to address CVE-2022-29154
        rsync: Upgrade to 3.2.5
        libtirpc: Backport fix for CVE-2021-46828
        libxml2: Ignore CVE-2016-3709
        tiff: Backport a patch for CVE-2022-34526
        libtirpc: Upgrade to 1.3.3
        perf: Add packageconfig for libbfd support and use disabled as default
        connman: Backports for security fixes
        systemd: Upgrade to 251.4 and fix build with binutils 2.39
        time: Add missing include for memset
        screen: Add missing include files in configure checks
        setserial: Fix build with clang
        expect: Fix implicit-function-declaration warnings
        spirv-tools: Remove default copy constructor in header
        boost: Compile out stdlib unary/binary_functions for c++11 and newer
        vulkan-samples: Qualify move as std::move
        apt: Do not use std::binary_function
        ltp: Fix sys/mount.h and linux/mount.h conflict
        rpm: Remove -Wimplicit-function-declaration warnings
        binutils: Upgrade to 2.39 release
        binutils-cross: Disable gprofng for when building cross binutils
        binutils: Package up gprofng
        binutils: Disable gprofng when using clang
        binutils-cross-canadian: Package up new gprofng.rc file
        autoconf: Fix strict prototype errors in generated tests
        rsync: Add missing prototypes to function declarations
        nfs-utils: Upgrade to 2.6.2
        webkitgtk: Upgrade to 2.36.6 minor update
        musl: Update to tip
        binutils: Disable gprofng on musl systems
        binutils: Upgrade to latest on 2.39 release branch
        cargo_common.bbclass: Add missing space in shell conditional code
        rng-tools: Remove depndencies on hwrng
        ccache: Update the patch status
        ccache: Fix build with gcc12 on musl
        alsa-plugins: Include missing string.h
        xinetd: Pass missing -D_GNU_SOURCE
        watchdog: Include needed system header for function decls
        libcgroup: Use GNU strerror_r only when its available
        pinentry: enable _XOPEN_SOURCE on musl for wchar usage in curses
        apr: Use correct strerror_r implementation based on libc type
        gcr: Define _GNU_SOURCE
        ltp: Adjust types to match create_fifo_thread return
        gcc: Upgrade to 12.2.0
        glibc: Update to latest on 2.36
        ltp: Remove -mfpmath=sse on x86-64 too
        apr: Cache configure tests which use AC_TRY_RUN
        rust: Fix build failure on riscv32
        ncurses: Fix configure tests for exit and mbstate_t
        rust-llvm: Update to matching LLVM_VERSION from rust-source
        librepo: Fix build on musl
        rsync: Turn on -pedantic-errors at the end of 'configure'
        ccache: Upgrade to 4.6.2
        xmlto: Update to use upstream tip of trunk

  Konrad Weihmann (1):
        python3: disable user site-pkg for native target

  Lee Chee Yang (1):
        migration guides: add release notes for 4.0.3

  Luca Ceresoli (1):
        libmnl: remove unneeded SRC_URI 'name' option

  Markus Volk (2):
        connman: add PACKAGECONFIG to support iwd
        packagegroup-base.bb: add a configure option to set the wireless-daemon

  Martin Jansa (5):
        glibc: revert one upstream change to work around broken DEBUG_BUILD build
        syslinux: Fix build with glibc-2.36
        syslinux: refresh patches with devtool
        glibc: fix new upstream build issue with DEBUG_BUILD build
        glibc: apply proposed patch from upstream instead of revert

  Mateusz Marciniec (2):
        util-linux: Remove --enable-raw from EXTRA_OECONF
        util-linux: Improve check for magic in configure.ac

  Michael Halstead (1):
        uninative: Upgrade to 3.7 to work with glibc 2.36

  Michael Opdenacker (1):
        dev-manual: use proper note directive

  Mingli Yu (1):
        bitbake: fetch: use BPN instead

  Neil Horman (1):
        bitbake: Fix npm to use https rather than http

  Paul Eggleton (1):
        relocate_sdk.py: ensure interpreter size error causes relocation to fail

  Pavel Zhukov (6):
        package_rpm: Do not replace square brackets in %files
        selftest: Add regression test for rpm filesnames
        parselogs: Ignore xf86OpenConsole error
        bitbake: gitsm: Error out if submodule refers to parent repo
        bitbake: tests: Add Timeout class
        bitbake: tests: Add test for possible gitsm deadlock

  Peter Bergin (3):
        rust-cross-canadian: rename shell variables for easier appends
        packagegroup-rust-cross-canadian: add native compiler environment
        oeqa/sdk: extend rust test to also use a build script

  Peter Marko (1):
        create-spdx: handle links to inaccessible locations

  Quentin Schulz (3):
        docs: conf.py: update yocto_git base URL
        docs: README: add TeX font package required for building PDF
        docs: ref-manual: system-requirements: add missing packages

  Randy MacLeod (1):
        rust: update from 1.62.1 to 1.63.0

  Rasmus Villemoes (1):
        bitbake.conf: set BB_DEFAULT_UMASK using ??=

  Richard Purdie (85):
        oeqa/selftest/sstate: Ensure tests are deterministic
        nativesdk: Clear TUNE_FEATURES
        populate_sdk_base: Disable rust SDK for MIPS n32
        selftest/reproducible: Exclude rust/rust-dbg for now until we can fix
        conf/distro/no-static-libs: Allow static musl for rust
        rust-target-config: Add mips n32 target information
        rust-common: Add CXXFLAGS
        rust-common: Drop export directive from wrappers
        rust-common: Rework wrappers to handle musl
        rust: Work around reproducibility issues
        rust: Switch to use RUST_XXX_SYS consistently
        rust.inc: Rename variables to make code clearer
        rust.inc: Fix cross build llvm-config handling
        rust/mesa: Drop obsolete YOCTO_ALTERNATE_MULTILIB_NAME
        rust-target-config: Show clear error when target isn't defined
        rust: Generate per recipe target configuration files
        rust-common/rust: Improve bootstrap BUILD_SYS handling
        cargo_common: Handle build SYS as well as HOST/TARGET
        rust-llvm: Enable nativesdk variant
        rust.inc: Fix for cross compilation configuration
        rust-common: Update to match cross targets
        rust-target-config: Make target workaround generic
        rust-common: Simplify libc handling
        cargo: Drop cross-canadian variant and fix/use nativesdk
        rust-common: Set rustlibdir to match target expectation
        rust-cross-canadian: Simplify and fix
        rust: Drop cross/crosssdk
        rust: Enable nativesdk and target builds + replace rust-tools-cross-canadian
        rust: Fix musl builds
        rust: Ensure buildpaths are handled in debug symbols correctly
        rust: Update README
        selftest/wic: Tweak test case to not depend on kernel size
        bitbake: runqueue: Ensure deferred tasks are sorted by multiconfig
        bitbake: runqueue: Improve deadlock warning messages
        bitbake: runqueue: Drop deadlock breaking force fail
        rust-common: Remove conflict with utils create_wrapper
        kern-devsrc: Drop auto.conf creation
        cargo: Work around host system library conflicts
        rust-cross-canadian: Use shell from SDK, not the host
        buildhistory: Only use image-artifact-names as an image class
        rust: Remove unneeded RUST_TARGETGENS settings
        meta-skeleton/hello-mod: Switch to SPDX-License-Identifier
        perf: Fix reproducibility issues with 5.19 onwards
        selftest/runtime_test/incompatible_lic: Use IMAGE_CLASSES for testimage
        testexport: Fix to work as an image class
        testexport: Use IMAGE_CLASSES for testimage
        selftest/runtime_test: Use testexport in IMAGE_CLASSES, not globally
        bitbake: BBHandler: Allow earlier exit for classes not found
        bitbake: BBHandler: Make inherit calls more directly
        bitbake: bitbake: Add copyright headers where missing
        bitbake: BBHandler/cooker: Implement recipe and global classes
        classes: Add copyright statements to files without one
        scripts: Add copyright statements to files without one
        classes: Add SPDX license identifiers
        lib: Add copyright statements to files without one
        insane: Update to allow for class layout changes
        classes: Update classes to match new bitbake class scope functionality
        recipetool: Update for class changes
        package: Switch debug source handling to use prefix map
        libgcc/gcc-runtime: Improve source reference handling
        bitbake.conf: Handle S and B separately for debug mapping
        python3-cython: Update code to match debug path changes
        gcc-cross: Fix relative links
        gcc: Resolve relative prefix-map filenames
        gcc: Add a patch to avoid hardcoded paths in libgcc on powerpc
        gcc: Update patch status to submitted for two patches
        valgrind: Disable drd/tests/std_thread2 ptest
        valgrind: Update to match debug file layout changes
        skeleton/service: Ensure debug path handling works as intended
        distrooverrides: Move back to classes whilst it's usage is clarified
        vim: Upgrade 9.0.0115 -> 9.0.0242
        icu: Drop binconfig support (icu-config)
        libtirpc: Mark CVE-2021-46828 as resolved
        bitbake: runqueue: Change pressure file warning to a note
        rust-target-config: Drop has-elf-tls option
        llvm: Add llvm-config wrapper to improve flags handling
        mesa: Rework llvm handling
        rust-target-config: Fix qemuppc target cpu option
        rust: Fix crossbeam-utils for arches without atomics
        pseudo: Update to include recent upstream minor fixes
        bitbake: Revert "fetch: use BPN instead"
        vim: Upgrade 9.0.0242 -> 9.0.0341
        gcc-multilib-config: Fix i686 toolchain relocation issues
        kernel: Always set CC and LD for the kernel build
        kernel: Use consistent make flags for menuconfig

  Robert Joslyn (1):
        curl: Update to 7.85.0

  Ross Burton (9):
        oeqa/qemurunner: add run_serial() comment
        oeqa/commands: add support for running cross tools to runCmd
        oeqa/selftest: rewrite gdbserver test
        libxml2: wrap xmllint to use the correct XML catalogues
        oeqa/selftest: add test for debuginfod
        libgcrypt: remove obsolete pkgconfig install
        libgcrypt: remove obsolete patch
        libgcrypt: rewrite ptest
        cve-check: close cursors as soon as possible

  Sakib Sajal (2):
        qemu: fix CVE-2021-3507
        qemu: fix CVE-2022-0216

  Shubham Kulkarni (1):
        sanity: add a comment to ensure CONNECTIVITY_CHECK_URIS is correct

  Simone Weiss (1):
        json-c: Add ptest for json-c

  Sundeep KOKKONDA (1):
        glibc : stable 2.35 branch updates

  Thomas Roos (1):
        oeqa devtool: Add tests to cover devtool handling of various git URL styles

  Tom Hochstein (1):
        piglit: Add PACKAGECONFIG for glx and opencl

  Tom Rini (1):
        qemux86-64: Allow higher tunes

  Ulrich Ölmann (1):
        scripts/runqemu.README: fix typos and trailing whitespaces

  William A. Kennington III (1):
        image_types: Set SOURCE_DATE_EPOCH for squashfs

  Yang Xu (1):
        insane.bbclass: Skip patches not in oe-core by full path

  Yogesh Tyagi (1):
        gdbserver : add selftest

  Yongxin Liu (1):
        grub2: fix several CVEs

  wangmy (19):
        msmtp: upgrade 1.8.20 -> 1.8.22
        bind: upgrade 9.18.5 -> 9.18.6
        btrfs-tools: upgrade 5.18.1 -> 5.19
        libdnf: upgrade 0.67.0 -> 0.68.0
        librepo: upgrade 1.14.3 -> 1.14.4
        pkgconf: upgrade 1.9.2 -> 1.9.3
        python3-pygments: upgrade 2.12.0 -> 2.13.0
        ethtool: upgrade 5.18 -> 5.19
        librsvg: upgrade 2.54.4 -> 2.54.5
        libtasn1: upgrade 4.18.0 -> 4.19.0
        liburcu: upgrade 0.13.1 -> 0.13.2
        libwpe: upgrade 1.12.2 -> 1.12.3
        lttng-tools: upgrade 2.13.7 -> 2.13.8
        lttng-ust: upgrade 2.13.3 -> 2.13.4
        libatomic-ops: upgrade 7.6.12 -> 7.6.14
        lz4: upgrade 1.9.3 -> 1.9.4
        python3-hatchling: upgrade 1.8.0 -> 1.8.1
        python3-urllib3: upgrade 1.26.11 -> 1.26.12
        repo: upgrade 2.28 -> 2.29.1

meta-arm: 20a629180c..52f07a4b0b:
  Anton Antonov (11):
        arm/optee-os: backport RWX permission error patch
        work around for too few arguments to function init_disassemble_info() error
        arm/optee-os: backport linker warning patches
        arm/tf-a-tests: work around RWX permission error on segment
        Recipes for Trusted Services dependencies.
        Recipes for Trusted Services Secure Partitions
        ARM-FFA kernel drivers and kernel configs for Trusted Services
        Trusted Services test/demo NWd tools
        psa-api-tests for Trusted Services
        Include Trusted Services SPs into optee-os image
        Define qemuarm64-secureboot-ts CI pipeline and include it into meta-arm

  Gowtham Suresh Kumar (2):
        arm-bsp/secure-partitions: fix SMM gateway bug for EFI GetVariable()
        arm-bsp/u-boot: drop EFI GetVariable() workarounds patches

  Jon Mason (11):
        arm-bsp/fvp-base-arm32: Update kernel patch for v5.19
        arm/qemuarm64-secureboot: remove tfa memory patch
        arm/linux-yocto: remove optee num pages kernel config variable
        arm-bsp/juno: drop scmi patch
        arm/qemuarm-secureboot: remove vmalloc from QB_KERNEL_CMDLINE_APPEND
        arm/fvp: use image-artifact-names as an image class
        atp/atp: drop package inherits
        arm/optee: Update to 3.18
        arm-bsp/fvp-base: set preferred kernel to 5.15
        arm/arm-bsp: Add yocto-kernel-cache bluetooth support
        arm-bsp/corstone1000: use compressed kernel image

  Khem Raj (2):
        gator-daemon: Define _GNU_SOURCE feature test macro
        optee-os: Add section attribute parameters when clang is used

  Peter Hoyes (3):
        docs: Update FVP_CONSOLES in runfvp documentation
        docs: Introduce meta-arm OEQA documentation
        arm/oeqa: Make linuxboot test case timeout configurable

  Richard Purdie (1):
        gem5/gem5-m5ops: Drop uneeded package inherit

  Ross Burton (2):
        arm/trusted-firmware-a: remove redundant patches
        arm/trusted-firmware-a: work around RWX permission error on segment

  Rui Miguel Silva (2):
        arm-bsp:corstone500: rebase u-boot patches on v2022.07
        arm-bsp/corstone1000: rebase u-boot patches on top v2022.07

  Vishnu Banavath (3):
        arm-bsp/trusted-firmware-a: Bump TF-A version for N1SDP
        arm-bsp/optee: add optee-os support for N1SDP target
        arm/optee: update optee-client to v3.18

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I90aa0a94410dd208163af126566d22c77787abc2
diff --git a/poky/meta/classes-global/sstate.bbclass b/poky/meta/classes-global/sstate.bbclass
new file mode 100644
index 0000000..cd77c58
--- /dev/null
+++ b/poky/meta/classes-global/sstate.bbclass
@@ -0,0 +1,1364 @@
+#
+# Copyright OpenEmbedded Contributors
+#
+# SPDX-License-Identifier: MIT
+#
+
+SSTATE_VERSION = "10"
+
+SSTATE_ZSTD_CLEVEL ??= "8"
+
+SSTATE_MANIFESTS ?= "${TMPDIR}/sstate-control"
+SSTATE_MANFILEPREFIX = "${SSTATE_MANIFESTS}/manifest-${SSTATE_MANMACH}-${PN}"
+
+def generate_sstatefn(spec, hash, taskname, siginfo, d):
+    if taskname is None:
+       return ""
+    extension = ".tar.zst"
+    # 8 chars reserved for siginfo
+    limit = 254 - 8
+    if siginfo:
+        limit = 254
+        extension = ".tar.zst.siginfo"
+    if not hash:
+        hash = "INVALID"
+    fn = spec + hash + "_" + taskname + extension
+    # If the filename is too long, attempt to reduce it
+    if len(fn) > limit:
+        components = spec.split(":")
+        # Fields 0,5,6 are mandatory, 1 is most useful, 2,3,4 are just for information
+        # 7 is for the separators
+        avail = (limit - len(hash + "_" + taskname + extension) - len(components[0]) - len(components[1]) - len(components[5]) - len(components[6]) - 7) // 3
+        components[2] = components[2][:avail]
+        components[3] = components[3][:avail]
+        components[4] = components[4][:avail]
+        spec = ":".join(components)
+        fn = spec + hash + "_" + taskname + extension
+        if len(fn) > limit:
+            bb.fatal("Unable to reduce sstate name to less than 255 chararacters")
+    return hash[:2] + "/" + hash[2:4] + "/" + fn
+
+SSTATE_PKGARCH    = "${PACKAGE_ARCH}"
+SSTATE_PKGSPEC    = "sstate:${PN}:${PACKAGE_ARCH}${TARGET_VENDOR}-${TARGET_OS}:${PV}:${PR}:${SSTATE_PKGARCH}:${SSTATE_VERSION}:"
+SSTATE_SWSPEC     = "sstate:${PN}::${PV}:${PR}::${SSTATE_VERSION}:"
+SSTATE_PKGNAME    = "${SSTATE_EXTRAPATH}${@generate_sstatefn(d.getVar('SSTATE_PKGSPEC'), d.getVar('BB_UNIHASH'), d.getVar('SSTATE_CURRTASK'), False, d)}"
+SSTATE_PKG        = "${SSTATE_DIR}/${SSTATE_PKGNAME}"
+SSTATE_EXTRAPATH   = ""
+SSTATE_EXTRAPATHWILDCARD = ""
+SSTATE_PATHSPEC   = "${SSTATE_DIR}/${SSTATE_EXTRAPATHWILDCARD}*/*/${SSTATE_PKGSPEC}*_${SSTATE_PATH_CURRTASK}.tar.zst*"
+
+# explicitly make PV to depend on evaluated value of PV variable
+PV[vardepvalue] = "${PV}"
+
+# We don't want the sstate to depend on things like the distro string
+# of the system, we let the sstate paths take care of this.
+SSTATE_EXTRAPATH[vardepvalue] = ""
+SSTATE_EXTRAPATHWILDCARD[vardepvalue] = ""
+
+# For multilib rpm the allarch packagegroup files can overwrite (in theory they're identical)
+SSTATE_ALLOW_OVERLAP_FILES = "${DEPLOY_DIR}/licenses/"
+# Avoid docbook/sgml catalog warnings for now
+SSTATE_ALLOW_OVERLAP_FILES += "${STAGING_ETCDIR_NATIVE}/sgml ${STAGING_DATADIR_NATIVE}/sgml"
+# sdk-provides-dummy-nativesdk and nativesdk-buildtools-perl-dummy overlap for different SDKMACHINE
+SSTATE_ALLOW_OVERLAP_FILES += "${DEPLOY_DIR_RPM}/sdk_provides_dummy_nativesdk/ ${DEPLOY_DIR_IPK}/sdk-provides-dummy-nativesdk/"
+SSTATE_ALLOW_OVERLAP_FILES += "${DEPLOY_DIR_RPM}/buildtools_dummy_nativesdk/ ${DEPLOY_DIR_IPK}/buildtools-dummy-nativesdk/"
+# target-sdk-provides-dummy overlaps that allarch is disabled when multilib is used
+SSTATE_ALLOW_OVERLAP_FILES += "${COMPONENTS_DIR}/sdk-provides-dummy-target/ ${DEPLOY_DIR_RPM}/sdk_provides_dummy_target/ ${DEPLOY_DIR_IPK}/sdk-provides-dummy-target/"
+# Archive the sources for many architectures in one deploy folder
+SSTATE_ALLOW_OVERLAP_FILES += "${DEPLOY_DIR_SRC}"
+# ovmf/grub-efi/systemd-boot/intel-microcode multilib recipes can generate identical overlapping files
+SSTATE_ALLOW_OVERLAP_FILES += "${DEPLOY_DIR_IMAGE}/ovmf"
+SSTATE_ALLOW_OVERLAP_FILES += "${DEPLOY_DIR_IMAGE}/grub-efi"
+SSTATE_ALLOW_OVERLAP_FILES += "${DEPLOY_DIR_IMAGE}/systemd-boot"
+SSTATE_ALLOW_OVERLAP_FILES += "${DEPLOY_DIR_IMAGE}/microcode"
+
+SSTATE_SCAN_FILES ?= "*.la *-config *_config postinst-*"
+SSTATE_SCAN_CMD ??= 'find ${SSTATE_BUILDDIR} \( -name "${@"\" -o -name \"".join(d.getVar("SSTATE_SCAN_FILES").split())}" \) -type f'
+SSTATE_SCAN_CMD_NATIVE ??= 'grep -Irl -e ${RECIPE_SYSROOT} -e ${RECIPE_SYSROOT_NATIVE} -e ${HOSTTOOLS_DIR} ${SSTATE_BUILDDIR}'
+SSTATE_HASHEQUIV_FILEMAP ?= " \
+    populate_sysroot:*/postinst-useradd-*:${TMPDIR} \
+    populate_sysroot:*/postinst-useradd-*:${COREBASE} \
+    populate_sysroot:*/postinst-useradd-*:regex-\s(PATH|PSEUDO_IGNORE_PATHS|HOME|LOGNAME|OMP_NUM_THREADS|USER)=.*\s \
+    populate_sysroot:*/crossscripts/*:${TMPDIR} \
+    populate_sysroot:*/crossscripts/*:${COREBASE} \
+    "
+
+BB_HASHFILENAME = "False ${SSTATE_PKGSPEC} ${SSTATE_SWSPEC}"
+
+SSTATE_ARCHS = " \
+    ${BUILD_ARCH} \
+    ${BUILD_ARCH}_${ORIGNATIVELSBSTRING} \
+    ${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS} \
+    ${SDK_ARCH}_${SDK_OS} \
+    ${SDK_ARCH}_${PACKAGE_ARCH} \
+    allarch \
+    ${PACKAGE_ARCH} \
+    ${PACKAGE_EXTRA_ARCHS} \
+    ${MACHINE_ARCH}"
+SSTATE_ARCHS[vardepsexclude] = "ORIGNATIVELSBSTRING"
+
+SSTATE_MANMACH ?= "${SSTATE_PKGARCH}"
+
+SSTATECREATEFUNCS += "sstate_hardcode_path"
+SSTATECREATEFUNCS[vardeps] = "SSTATE_SCAN_FILES"
+SSTATEPOSTCREATEFUNCS = ""
+SSTATEPREINSTFUNCS = ""
+SSTATEPOSTUNPACKFUNCS = "sstate_hardcode_path_unpack"
+SSTATEPOSTINSTFUNCS = ""
+EXTRA_STAGING_FIXMES ?= "HOSTTOOLS_DIR"
+
+# Check whether sstate exists for tasks that support sstate and are in the
+# locked signatures file.
+SIGGEN_LOCKEDSIGS_SSTATE_EXISTS_CHECK ?= 'error'
+
+# Check whether the task's computed hash matches the task's hash in the
+# locked signatures file.
+SIGGEN_LOCKEDSIGS_TASKSIG_CHECK ?= "error"
+
+# The GnuPG key ID and passphrase to use to sign sstate archives (or unset to
+# not sign)
+SSTATE_SIG_KEY ?= ""
+SSTATE_SIG_PASSPHRASE ?= ""
+# Whether to verify the GnUPG signatures when extracting sstate archives
+SSTATE_VERIFY_SIG ?= "0"
+# List of signatures to consider valid.
+SSTATE_VALID_SIGS ??= ""
+SSTATE_VALID_SIGS[vardepvalue] = ""
+
+SSTATE_HASHEQUIV_METHOD ?= "oe.sstatesig.OEOuthashBasic"
+SSTATE_HASHEQUIV_METHOD[doc] = "The fully-qualified function used to calculate \
+    the output hash for a task, which in turn is used to determine equivalency. \
+    "
+
+SSTATE_HASHEQUIV_REPORT_TASKDATA ?= "0"
+SSTATE_HASHEQUIV_REPORT_TASKDATA[doc] = "Report additional useful data to the \
+    hash equivalency server, such as PN, PV, taskname, etc. This information \
+    is very useful for developers looking at task data, but may leak sensitive \
+    data if the equivalence server is public. \
+    "
+
+python () {
+    if bb.data.inherits_class('native', d):
+        d.setVar('SSTATE_PKGARCH', d.getVar('BUILD_ARCH', False))
+    elif bb.data.inherits_class('crosssdk', d):
+        d.setVar('SSTATE_PKGARCH', d.expand("${BUILD_ARCH}_${SDK_ARCH}_${SDK_OS}"))
+    elif bb.data.inherits_class('cross', d):
+        d.setVar('SSTATE_PKGARCH', d.expand("${BUILD_ARCH}"))
+    elif bb.data.inherits_class('nativesdk', d):
+        d.setVar('SSTATE_PKGARCH', d.expand("${SDK_ARCH}_${SDK_OS}"))
+    elif bb.data.inherits_class('cross-canadian', d):
+        d.setVar('SSTATE_PKGARCH', d.expand("${SDK_ARCH}_${PACKAGE_ARCH}"))
+    elif bb.data.inherits_class('allarch', d) and d.getVar("PACKAGE_ARCH") == "all":
+        d.setVar('SSTATE_PKGARCH', "allarch")
+    else:
+        d.setVar('SSTATE_MANMACH', d.expand("${PACKAGE_ARCH}"))
+
+    if bb.data.inherits_class('native', d) or bb.data.inherits_class('crosssdk', d) or bb.data.inherits_class('cross', d):
+        d.setVar('SSTATE_EXTRAPATH', "${NATIVELSBSTRING}/")
+        d.setVar('BB_HASHFILENAME', "True ${SSTATE_PKGSPEC} ${SSTATE_SWSPEC}")
+        d.setVar('SSTATE_EXTRAPATHWILDCARD', "${NATIVELSBSTRING}/")
+
+    unique_tasks = sorted(set((d.getVar('SSTATETASKS') or "").split()))
+    d.setVar('SSTATETASKS', " ".join(unique_tasks))
+    for task in unique_tasks:
+        d.prependVarFlag(task, 'prefuncs', "sstate_task_prefunc ")
+        d.appendVarFlag(task, 'postfuncs', " sstate_task_postfunc")
+        d.setVarFlag(task, 'network', '1')
+        d.setVarFlag(task + "_setscene", 'network', '1')
+}
+
+def sstate_init(task, d):
+    ss = {}
+    ss['task'] = task
+    ss['dirs'] = []
+    ss['plaindirs'] = []
+    ss['lockfiles'] = []
+    ss['lockfiles-shared'] = []
+    return ss
+
+def sstate_state_fromvars(d, task = None):
+    if task is None:
+        task = d.getVar('BB_CURRENTTASK')
+        if not task:
+            bb.fatal("sstate code running without task context?!")
+        task = task.replace("_setscene", "")
+
+    if task.startswith("do_"):
+        task = task[3:]
+    inputs = (d.getVarFlag("do_" + task, 'sstate-inputdirs') or "").split()
+    outputs = (d.getVarFlag("do_" + task, 'sstate-outputdirs') or "").split()
+    plaindirs = (d.getVarFlag("do_" + task, 'sstate-plaindirs') or "").split()
+    lockfiles = (d.getVarFlag("do_" + task, 'sstate-lockfile') or "").split()
+    lockfilesshared = (d.getVarFlag("do_" + task, 'sstate-lockfile-shared') or "").split()
+    interceptfuncs = (d.getVarFlag("do_" + task, 'sstate-interceptfuncs') or "").split()
+    fixmedir = d.getVarFlag("do_" + task, 'sstate-fixmedir') or ""
+    if not task or len(inputs) != len(outputs):
+        bb.fatal("sstate variables not setup correctly?!")
+
+    if task == "populate_lic":
+        d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
+        d.setVar("SSTATE_EXTRAPATH", "")
+        d.setVar('SSTATE_EXTRAPATHWILDCARD', "")
+
+    ss = sstate_init(task, d)
+    for i in range(len(inputs)):
+        sstate_add(ss, inputs[i], outputs[i], d)
+    ss['lockfiles'] = lockfiles
+    ss['lockfiles-shared'] = lockfilesshared
+    ss['plaindirs'] = plaindirs
+    ss['interceptfuncs'] = interceptfuncs
+    ss['fixmedir'] = fixmedir
+    return ss
+
+def sstate_add(ss, source, dest, d):
+    if not source.endswith("/"):
+         source = source + "/"
+    if not dest.endswith("/"):
+         dest = dest + "/"
+    source = os.path.normpath(source)
+    dest = os.path.normpath(dest)
+    srcbase = os.path.basename(source)
+    ss['dirs'].append([srcbase, source, dest])
+    return ss
+
+def sstate_install(ss, d):
+    import oe.path
+    import oe.sstatesig
+    import subprocess
+
+    sharedfiles = []
+    shareddirs = []
+    bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
+
+    sstateinst = d.expand("${WORKDIR}/sstate-install-%s/" % ss['task'])
+
+    manifest, d2 = oe.sstatesig.sstate_get_manifest_filename(ss['task'], d)
+
+    if os.access(manifest, os.R_OK):
+        bb.fatal("Package already staged (%s)?!" % manifest)
+
+    d.setVar("SSTATE_INST_POSTRM", manifest + ".postrm")
+
+    locks = []
+    for lock in ss['lockfiles-shared']:
+        locks.append(bb.utils.lockfile(lock, True))
+    for lock in ss['lockfiles']:
+        locks.append(bb.utils.lockfile(lock))
+
+    for state in ss['dirs']:
+        bb.debug(2, "Staging files from %s to %s" % (state[1], state[2]))
+        for walkroot, dirs, files in os.walk(state[1]):
+            for file in files:
+                srcpath = os.path.join(walkroot, file)
+                dstpath = srcpath.replace(state[1], state[2])
+                #bb.debug(2, "Staging %s to %s" % (srcpath, dstpath))
+                sharedfiles.append(dstpath)
+            for dir in dirs:
+                srcdir = os.path.join(walkroot, dir)
+                dstdir = srcdir.replace(state[1], state[2])
+                #bb.debug(2, "Staging %s to %s" % (srcdir, dstdir))
+                if os.path.islink(srcdir):
+                    sharedfiles.append(dstdir)
+                    continue
+                if not dstdir.endswith("/"):
+                    dstdir = dstdir + "/"
+                shareddirs.append(dstdir)
+
+    # Check the file list for conflicts against files which already exist
+    overlap_allowed = (d.getVar("SSTATE_ALLOW_OVERLAP_FILES") or "").split()
+    match = []
+    for f in sharedfiles:
+        if os.path.exists(f) and not os.path.islink(f):
+            f = os.path.normpath(f)
+            realmatch = True
+            for w in overlap_allowed:
+                w = os.path.normpath(w)
+                if f.startswith(w):
+                    realmatch = False
+                    break
+            if realmatch:
+                match.append(f)
+                sstate_search_cmd = "grep -rlF '%s' %s --exclude=master.list | sed -e 's:^.*/::'" % (f, d.expand("${SSTATE_MANIFESTS}"))
+                search_output = subprocess.Popen(sstate_search_cmd, shell=True, stdout=subprocess.PIPE).communicate()[0]
+                if search_output:
+                    match.append("  (matched in %s)" % search_output.decode('utf-8').rstrip())
+                else:
+                    match.append("  (not matched to any task)")
+    if match:
+        bb.error("The recipe %s is trying to install files into a shared " \
+          "area when those files already exist. Those files and their manifest " \
+          "location are:\n  %s\nPlease verify which recipe should provide the " \
+          "above files.\n\nThe build has stopped, as continuing in this scenario WILL " \
+          "break things - if not now, possibly in the future (we've seen builds fail " \
+          "several months later). If the system knew how to recover from this " \
+          "automatically it would, however there are several different scenarios " \
+          "which can result in this and we don't know which one this is. It may be " \
+          "you have switched providers of something like virtual/kernel (e.g. from " \
+          "linux-yocto to linux-yocto-dev), in that case you need to execute the " \
+          "clean task for both recipes and it will resolve this error. It may be " \
+          "you changed DISTRO_FEATURES from systemd to udev or vice versa. Cleaning " \
+          "those recipes should again resolve this error, however switching " \
+          "DISTRO_FEATURES on an existing build directory is not supported - you " \
+          "should really clean out tmp and rebuild (reusing sstate should be safe). " \
+          "It could be the overlapping files detected are harmless in which case " \
+          "adding them to SSTATE_ALLOW_OVERLAP_FILES may be the correct solution. It could " \
+          "also be your build is including two different conflicting versions of " \
+          "things (e.g. bluez 4 and bluez 5 and the correct solution for that would " \
+          "be to resolve the conflict. If in doubt, please ask on the mailing list, " \
+          "sharing the error and filelist above." % \
+          (d.getVar('PN'), "\n  ".join(match)))
+        bb.fatal("If the above message is too much, the simpler version is you're advised to wipe out tmp and rebuild (reusing sstate is fine). That will likely fix things in most (but not all) cases.")
+
+    if ss['fixmedir'] and os.path.exists(ss['fixmedir'] + "/fixmepath.cmd"):
+        sharedfiles.append(ss['fixmedir'] + "/fixmepath.cmd")
+        sharedfiles.append(ss['fixmedir'] + "/fixmepath")
+
+    # Write out the manifest
+    f = open(manifest, "w")
+    for file in sharedfiles:
+        f.write(file + "\n")
+
+    # We want to ensure that directories appear at the end of the manifest
+    # so that when we test to see if they should be deleted any contents
+    # added by the task will have been removed first.
+    dirs = sorted(shareddirs, key=len)
+    # Must remove children first, which will have a longer path than the parent
+    for di in reversed(dirs):
+        f.write(di + "\n")
+    f.close()
+
+    # Append to the list of manifests for this PACKAGE_ARCH
+
+    i = d2.expand("${SSTATE_MANIFESTS}/index-${SSTATE_MANMACH}")
+    l = bb.utils.lockfile(i + ".lock")
+    filedata = d.getVar("STAMP") + " " + d2.getVar("SSTATE_MANFILEPREFIX") + " " + d.getVar("WORKDIR") + "\n"
+    manifests = []
+    if os.path.exists(i):
+        with open(i, "r") as f:
+            manifests = f.readlines()
+    # We append new entries, we don't remove older entries which may have the same
+    # manifest name but different versions from stamp/workdir. See below.
+    if filedata not in manifests:
+        with open(i, "a+") as f:
+            f.write(filedata)
+    bb.utils.unlockfile(l)
+
+    # Run the actual file install
+    for state in ss['dirs']:
+        if os.path.exists(state[1]):
+            oe.path.copyhardlinktree(state[1], state[2])
+
+    for postinst in (d.getVar('SSTATEPOSTINSTFUNCS') or '').split():
+        # All hooks should run in the SSTATE_INSTDIR
+        bb.build.exec_func(postinst, d, (sstateinst,))
+
+    for lock in locks:
+        bb.utils.unlockfile(lock)
+
+sstate_install[vardepsexclude] += "SSTATE_ALLOW_OVERLAP_FILES STATE_MANMACH SSTATE_MANFILEPREFIX"
+sstate_install[vardeps] += "${SSTATEPOSTINSTFUNCS}"
+
+def sstate_installpkg(ss, d):
+    from oe.gpg_sign import get_signer
+
+    sstateinst = d.expand("${WORKDIR}/sstate-install-%s/" % ss['task'])
+    d.setVar("SSTATE_CURRTASK", ss['task'])
+    sstatefetch = d.getVar('SSTATE_PKGNAME')
+    sstatepkg = d.getVar('SSTATE_PKG')
+
+    if not os.path.exists(sstatepkg):
+        pstaging_fetch(sstatefetch, d)
+
+    if not os.path.isfile(sstatepkg):
+        bb.note("Sstate package %s does not exist" % sstatepkg)
+        return False
+
+    sstate_clean(ss, d)
+
+    d.setVar('SSTATE_INSTDIR', sstateinst)
+
+    if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
+        if not os.path.isfile(sstatepkg + '.sig'):
+            bb.warn("No signature file for sstate package %s, skipping acceleration..." % sstatepkg)
+            return False
+        signer = get_signer(d, 'local')
+        if not signer.verify(sstatepkg + '.sig', d.getVar("SSTATE_VALID_SIGS")):
+            bb.warn("Cannot verify signature on sstate package %s, skipping acceleration..." % sstatepkg)
+            return False
+
+    # Empty sstateinst directory, ensure its clean
+    if os.path.exists(sstateinst):
+        oe.path.remove(sstateinst)
+    bb.utils.mkdirhier(sstateinst)
+
+    sstateinst = d.getVar("SSTATE_INSTDIR")
+    d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
+
+    for f in (d.getVar('SSTATEPREINSTFUNCS') or '').split() + ['sstate_unpack_package']:
+        # All hooks should run in the SSTATE_INSTDIR
+        bb.build.exec_func(f, d, (sstateinst,))
+
+    return sstate_installpkgdir(ss, d)
+
+def sstate_installpkgdir(ss, d):
+    import oe.path
+    import subprocess
+
+    sstateinst = d.getVar("SSTATE_INSTDIR")
+    d.setVar('SSTATE_FIXMEDIR', ss['fixmedir'])
+
+    for f in (d.getVar('SSTATEPOSTUNPACKFUNCS') or '').split():
+        # All hooks should run in the SSTATE_INSTDIR
+        bb.build.exec_func(f, d, (sstateinst,))
+
+    def prepdir(dir):
+        # remove dir if it exists, ensure any parent directories do exist
+        if os.path.exists(dir):
+            oe.path.remove(dir)
+        bb.utils.mkdirhier(dir)
+        oe.path.remove(dir)
+
+    for state in ss['dirs']:
+        prepdir(state[1])
+        bb.utils.rename(sstateinst + state[0], state[1])
+    sstate_install(ss, d)
+
+    for plain in ss['plaindirs']:
+        workdir = d.getVar('WORKDIR')
+        sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
+        src = sstateinst + "/" + plain.replace(workdir, '')
+        if sharedworkdir in plain:
+            src = sstateinst + "/" + plain.replace(sharedworkdir, '')
+        dest = plain
+        bb.utils.mkdirhier(src)
+        prepdir(dest)
+        bb.utils.rename(src, dest)
+
+    return True
+
+python sstate_hardcode_path_unpack () {
+    # Fixup hardcoded paths
+    #
+    # Note: The logic below must match the reverse logic in
+    # sstate_hardcode_path(d)
+    import subprocess
+
+    sstateinst = d.getVar('SSTATE_INSTDIR')
+    sstatefixmedir = d.getVar('SSTATE_FIXMEDIR')
+    fixmefn = sstateinst + "fixmepath"
+    if os.path.isfile(fixmefn):
+        staging_target = d.getVar('RECIPE_SYSROOT')
+        staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
+
+        if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
+            sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRHOST:%s:g'" % (staging_host)
+        elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
+            sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g; s:FIXMESTAGINGDIRHOST:%s:g'" % (staging_target, staging_host)
+        else:
+            sstate_sed_cmd = "sed -i -e 's:FIXMESTAGINGDIRTARGET:%s:g'" % (staging_target)
+
+        extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
+        for fixmevar in extra_staging_fixmes.split():
+            fixme_path = d.getVar(fixmevar)
+            sstate_sed_cmd += " -e 's:FIXME_%s:%s:g'" % (fixmevar, fixme_path)
+
+        # Add sstateinst to each filename in fixmepath, use xargs to efficiently call sed
+        sstate_hardcode_cmd = "sed -e 's:^:%s:g' %s | xargs %s" % (sstateinst, fixmefn, sstate_sed_cmd)
+
+        # Defer do_populate_sysroot relocation command
+        if sstatefixmedir:
+            bb.utils.mkdirhier(sstatefixmedir)
+            with open(sstatefixmedir + "/fixmepath.cmd", "w") as f:
+                sstate_hardcode_cmd = sstate_hardcode_cmd.replace(fixmefn, sstatefixmedir + "/fixmepath")
+                sstate_hardcode_cmd = sstate_hardcode_cmd.replace(sstateinst, "FIXMEFINALSSTATEINST")
+                sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_host, "FIXMEFINALSSTATEHOST")
+                sstate_hardcode_cmd = sstate_hardcode_cmd.replace(staging_target, "FIXMEFINALSSTATETARGET")
+                f.write(sstate_hardcode_cmd)
+            bb.utils.copyfile(fixmefn, sstatefixmedir + "/fixmepath")
+            return
+
+        bb.note("Replacing fixme paths in sstate package: %s" % (sstate_hardcode_cmd))
+        subprocess.check_call(sstate_hardcode_cmd, shell=True)
+
+        # Need to remove this or we'd copy it into the target directory and may
+        # conflict with another writer
+        os.remove(fixmefn)
+}
+
+def sstate_clean_cachefile(ss, d):
+    import oe.path
+
+    if d.getVarFlag('do_%s' % ss['task'], 'task'):
+        d.setVar("SSTATE_PATH_CURRTASK", ss['task'])
+        sstatepkgfile = d.getVar('SSTATE_PATHSPEC')
+        bb.note("Removing %s" % sstatepkgfile)
+        oe.path.remove(sstatepkgfile)
+
+def sstate_clean_cachefiles(d):
+    for task in (d.getVar('SSTATETASKS') or "").split():
+        ld = d.createCopy()
+        ss = sstate_state_fromvars(ld, task)
+        sstate_clean_cachefile(ss, ld)
+
+def sstate_clean_manifest(manifest, d, canrace=False, prefix=None):
+    import oe.path
+
+    mfile = open(manifest)
+    entries = mfile.readlines()
+    mfile.close()
+
+    for entry in entries:
+        entry = entry.strip()
+        if prefix and not entry.startswith("/"):
+            entry = prefix + "/" + entry
+        bb.debug(2, "Removing manifest: %s" % entry)
+        # We can race against another package populating directories as we're removing them
+        # so we ignore errors here.
+        try:
+            if entry.endswith("/"):
+                if os.path.islink(entry[:-1]):
+                    os.remove(entry[:-1])
+                elif os.path.exists(entry) and len(os.listdir(entry)) == 0 and not canrace:
+                    # Removing directories whilst builds are in progress exposes a race. Only
+                    # do it in contexts where it is safe to do so.
+                    os.rmdir(entry[:-1])
+            else:
+                os.remove(entry)
+        except OSError:
+            pass
+
+    postrm = manifest + ".postrm"
+    if os.path.exists(manifest + ".postrm"):
+        import subprocess
+        os.chmod(postrm, 0o755)
+        subprocess.check_call(postrm, shell=True)
+        oe.path.remove(postrm)
+
+    oe.path.remove(manifest)
+
+def sstate_clean(ss, d):
+    import oe.path
+    import glob
+
+    d2 = d.createCopy()
+    stamp_clean = d.getVar("STAMPCLEAN")
+    extrainf = d.getVarFlag("do_" + ss['task'], 'stamp-extra-info')
+    if extrainf:
+        d2.setVar("SSTATE_MANMACH", extrainf)
+        wildcard_stfile = "%s.do_%s*.%s" % (stamp_clean, ss['task'], extrainf)
+    else:
+        wildcard_stfile = "%s.do_%s*" % (stamp_clean, ss['task'])
+
+    manifest = d2.expand("${SSTATE_MANFILEPREFIX}.%s" % ss['task'])
+
+    if os.path.exists(manifest):
+        locks = []
+        for lock in ss['lockfiles-shared']:
+            locks.append(bb.utils.lockfile(lock))
+        for lock in ss['lockfiles']:
+            locks.append(bb.utils.lockfile(lock))
+
+        sstate_clean_manifest(manifest, d, canrace=True)
+
+        for lock in locks:
+            bb.utils.unlockfile(lock)
+
+    # Remove the current and previous stamps, but keep the sigdata.
+    #
+    # The glob() matches do_task* which may match multiple tasks, for
+    # example: do_package and do_package_write_ipk, so we need to
+    # exactly match *.do_task.* and *.do_task_setscene.*
+    rm_stamp = '.do_%s.' % ss['task']
+    rm_setscene = '.do_%s_setscene.' % ss['task']
+    # For BB_SIGNATURE_HANDLER = "noop"
+    rm_nohash = ".do_%s" % ss['task']
+    for stfile in glob.glob(wildcard_stfile):
+        # Keep the sigdata
+        if ".sigdata." in stfile or ".sigbasedata." in stfile:
+            continue
+        # Preserve taint files in the stamps directory
+        if stfile.endswith('.taint'):
+            continue
+        if rm_stamp in stfile or rm_setscene in stfile or \
+                stfile.endswith(rm_nohash):
+            oe.path.remove(stfile)
+
+sstate_clean[vardepsexclude] = "SSTATE_MANFILEPREFIX"
+
+CLEANFUNCS += "sstate_cleanall"
+
+python sstate_cleanall() {
+    bb.note("Removing shared state for package %s" % d.getVar('PN'))
+
+    manifest_dir = d.getVar('SSTATE_MANIFESTS')
+    if not os.path.exists(manifest_dir):
+        return
+
+    tasks = d.getVar('SSTATETASKS').split()
+    for name in tasks:
+        ld = d.createCopy()
+        shared_state = sstate_state_fromvars(ld, name)
+        sstate_clean(shared_state, ld)
+}
+
+python sstate_hardcode_path () {
+    import subprocess, platform
+
+    # Need to remove hardcoded paths and fix these when we install the
+    # staging packages.
+    #
+    # Note: the logic in this function needs to match the reverse logic
+    # in sstate_installpkg(ss, d)
+
+    staging_target = d.getVar('RECIPE_SYSROOT')
+    staging_host = d.getVar('RECIPE_SYSROOT_NATIVE')
+    sstate_builddir = d.getVar('SSTATE_BUILDDIR')
+
+    sstate_sed_cmd = "sed -i -e 's:%s:FIXMESTAGINGDIRHOST:g'" % staging_host
+    if bb.data.inherits_class('native', d) or bb.data.inherits_class('cross-canadian', d):
+        sstate_grep_cmd = "grep -l -e '%s'" % (staging_host)
+    elif bb.data.inherits_class('cross', d) or bb.data.inherits_class('crosssdk', d):
+        sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
+        sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
+    else:
+        sstate_grep_cmd = "grep -l -e '%s' -e '%s'" % (staging_target, staging_host)
+        sstate_sed_cmd += " -e 's:%s:FIXMESTAGINGDIRTARGET:g'" % staging_target
+
+    extra_staging_fixmes = d.getVar('EXTRA_STAGING_FIXMES') or ''
+    for fixmevar in extra_staging_fixmes.split():
+        fixme_path = d.getVar(fixmevar)
+        sstate_sed_cmd += " -e 's:%s:FIXME_%s:g'" % (fixme_path, fixmevar)
+        sstate_grep_cmd += " -e '%s'" % (fixme_path)
+
+    fixmefn =  sstate_builddir + "fixmepath"
+
+    sstate_scan_cmd = d.getVar('SSTATE_SCAN_CMD')
+    sstate_filelist_cmd = "tee %s" % (fixmefn)
+
+    # fixmepath file needs relative paths, drop sstate_builddir prefix
+    sstate_filelist_relative_cmd = "sed -i -e 's:^%s::g' %s" % (sstate_builddir, fixmefn)
+
+    xargs_no_empty_run_cmd = '--no-run-if-empty'
+    if platform.system() == 'Darwin':
+        xargs_no_empty_run_cmd = ''
+
+    # Limit the fixpaths and sed operations based on the initial grep search
+    # This has the side effect of making sure the vfs cache is hot
+    sstate_hardcode_cmd = "%s | xargs %s | %s | xargs %s %s" % (sstate_scan_cmd, sstate_grep_cmd, sstate_filelist_cmd, xargs_no_empty_run_cmd, sstate_sed_cmd)
+
+    bb.note("Removing hardcoded paths from sstate package: '%s'" % (sstate_hardcode_cmd))
+    subprocess.check_output(sstate_hardcode_cmd, shell=True, cwd=sstate_builddir)
+
+        # If the fixmefn is empty, remove it..
+    if os.stat(fixmefn).st_size == 0:
+        os.remove(fixmefn)
+    else:
+        bb.note("Replacing absolute paths in fixmepath file: '%s'" % (sstate_filelist_relative_cmd))
+        subprocess.check_output(sstate_filelist_relative_cmd, shell=True)
+}
+
+def sstate_package(ss, d):
+    import oe.path
+    import time
+
+    tmpdir = d.getVar('TMPDIR')
+
+    fixtime = False
+    if ss['task'] == "package":
+        fixtime = True
+
+    def fixtimestamp(root, path):
+        f = os.path.join(root, path)
+        if os.lstat(f).st_mtime > sde:
+            os.utime(f, (sde, sde), follow_symlinks=False)
+
+    sstatebuild = d.expand("${WORKDIR}/sstate-build-%s/" % ss['task'])
+    sde = int(d.getVar("SOURCE_DATE_EPOCH") or time.time())
+    d.setVar("SSTATE_CURRTASK", ss['task'])
+    bb.utils.remove(sstatebuild, recurse=True)
+    bb.utils.mkdirhier(sstatebuild)
+    for state in ss['dirs']:
+        if not os.path.exists(state[1]):
+            continue
+        srcbase = state[0].rstrip("/").rsplit('/', 1)[0]
+        # Find and error for absolute symlinks. We could attempt to relocate but its not
+        # clear where the symlink is relative to in this context. We could add that markup
+        # to sstate tasks but there aren't many of these so better just avoid them entirely.
+        for walkroot, dirs, files in os.walk(state[1]):
+            for file in files + dirs:
+                if fixtime:
+                    fixtimestamp(walkroot, file)
+                srcpath = os.path.join(walkroot, file)
+                if not os.path.islink(srcpath):
+                    continue
+                link = os.readlink(srcpath)
+                if not os.path.isabs(link):
+                    continue
+                if not link.startswith(tmpdir):
+                    continue
+                bb.error("sstate found an absolute path symlink %s pointing at %s. Please replace this with a relative link." % (srcpath, link))
+        bb.debug(2, "Preparing tree %s for packaging at %s" % (state[1], sstatebuild + state[0]))
+        bb.utils.rename(state[1], sstatebuild + state[0])
+
+    workdir = d.getVar('WORKDIR')
+    sharedworkdir = os.path.join(d.getVar('TMPDIR'), "work-shared")
+    for plain in ss['plaindirs']:
+        pdir = plain.replace(workdir, sstatebuild)
+        if sharedworkdir in plain:
+            pdir = plain.replace(sharedworkdir, sstatebuild)
+        bb.utils.mkdirhier(plain)
+        bb.utils.mkdirhier(pdir)
+        bb.utils.rename(plain, pdir)
+        if fixtime:
+            fixtimestamp(pdir, "")
+            for walkroot, dirs, files in os.walk(pdir):
+                for file in files + dirs:
+                    fixtimestamp(walkroot, file)
+
+    d.setVar('SSTATE_BUILDDIR', sstatebuild)
+    d.setVar('SSTATE_INSTDIR', sstatebuild)
+
+    if d.getVar('SSTATE_SKIP_CREATION') == '1':
+        return
+
+    sstate_create_package = ['sstate_report_unihash', 'sstate_create_package']
+    if d.getVar('SSTATE_SIG_KEY'):
+        sstate_create_package.append('sstate_sign_package')
+
+    for f in (d.getVar('SSTATECREATEFUNCS') or '').split() + \
+             sstate_create_package + \
+             (d.getVar('SSTATEPOSTCREATEFUNCS') or '').split():
+        # All hooks should run in SSTATE_BUILDDIR.
+        bb.build.exec_func(f, d, (sstatebuild,))
+
+    # SSTATE_PKG may have been changed by sstate_report_unihash
+    siginfo = d.getVar('SSTATE_PKG') + ".siginfo"
+    if not os.path.exists(siginfo):
+        bb.siggen.dump_this_task(siginfo, d)
+    else:
+        try:
+            os.utime(siginfo, None)
+        except PermissionError:
+            pass
+        except OSError as e:
+            # Handle read-only file systems gracefully
+            import errno
+            if e.errno != errno.EROFS:
+                raise e
+
+    return
+
+sstate_package[vardepsexclude] += "SSTATE_SIG_KEY"
+
+def pstaging_fetch(sstatefetch, d):
+    import bb.fetch2
+
+    # Only try and fetch if the user has configured a mirror
+    mirrors = d.getVar('SSTATE_MIRRORS')
+    if not mirrors:
+        return
+
+    # Copy the data object and override DL_DIR and SRC_URI
+    localdata = bb.data.createCopy(d)
+
+    dldir = localdata.expand("${SSTATE_DIR}")
+    bb.utils.mkdirhier(dldir)
+
+    localdata.delVar('MIRRORS')
+    localdata.setVar('FILESPATH', dldir)
+    localdata.setVar('DL_DIR', dldir)
+    localdata.setVar('PREMIRRORS', mirrors)
+    localdata.setVar('SRCPV', d.getVar('SRCPV'))
+
+    # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
+    # we'll want to allow network access for the current set of fetches.
+    if bb.utils.to_boolean(localdata.getVar('BB_NO_NETWORK')) and \
+            bb.utils.to_boolean(localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK')):
+        localdata.delVar('BB_NO_NETWORK')
+
+    # Try a fetch from the sstate mirror, if it fails just return and
+    # we will build the package
+    uris = ['file://{0};downloadfilename={0}'.format(sstatefetch),
+            'file://{0}.siginfo;downloadfilename={0}.siginfo'.format(sstatefetch)]
+    if bb.utils.to_boolean(d.getVar("SSTATE_VERIFY_SIG"), False):
+        uris += ['file://{0}.sig;downloadfilename={0}.sig'.format(sstatefetch)]
+
+    for srcuri in uris:
+        localdata.setVar('SRC_URI', srcuri)
+        try:
+            fetcher = bb.fetch2.Fetch([srcuri], localdata, cache=False)
+            fetcher.checkstatus()
+            fetcher.download()
+
+        except bb.fetch2.BBFetchException:
+            pass
+
+pstaging_fetch[vardepsexclude] += "SRCPV"
+
+
+def sstate_setscene(d):
+    shared_state = sstate_state_fromvars(d)
+    accelerate = sstate_installpkg(shared_state, d)
+    if not accelerate:
+        msg = "No sstate archive obtainable, will run full task instead."
+        bb.warn(msg)
+        raise bb.BBHandledException(msg)
+
+python sstate_task_prefunc () {
+    shared_state = sstate_state_fromvars(d)
+    sstate_clean(shared_state, d)
+}
+sstate_task_prefunc[dirs] = "${WORKDIR}"
+
+python sstate_task_postfunc () {
+    shared_state = sstate_state_fromvars(d)
+
+    for intercept in shared_state['interceptfuncs']:
+        bb.build.exec_func(intercept, d, (d.getVar("WORKDIR"),))
+
+    omask = os.umask(0o002)
+    if omask != 0o002:
+       bb.note("Using umask 0o002 (not %0o) for sstate packaging" % omask)
+    sstate_package(shared_state, d)
+    os.umask(omask)
+
+    sstateinst = d.getVar("SSTATE_INSTDIR")
+    d.setVar('SSTATE_FIXMEDIR', shared_state['fixmedir'])
+
+    sstate_installpkgdir(shared_state, d)
+
+    bb.utils.remove(d.getVar("SSTATE_BUILDDIR"), recurse=True)
+}
+sstate_task_postfunc[dirs] = "${WORKDIR}"
+
+
+#
+# Shell function to generate a sstate package from a directory
+# set as SSTATE_BUILDDIR. Will be run from within SSTATE_BUILDDIR.
+#
+sstate_create_package () {
+	# Exit early if it already exists
+	if [ -e ${SSTATE_PKG} ]; then
+		touch ${SSTATE_PKG} 2>/dev/null || true
+		return
+	fi
+
+	mkdir --mode=0775 -p `dirname ${SSTATE_PKG}`
+	TFILE=`mktemp ${SSTATE_PKG}.XXXXXXXX`
+
+	OPT="-cS"
+	ZSTD="zstd -${SSTATE_ZSTD_CLEVEL} -T${ZSTD_THREADS}"
+	# Use pzstd if available
+	if [ -x "$(command -v pzstd)" ]; then
+		ZSTD="pzstd -${SSTATE_ZSTD_CLEVEL} -p ${ZSTD_THREADS}"
+	fi
+
+	# Need to handle empty directories
+	if [ "$(ls -A)" ]; then
+		set +e
+		tar -I "$ZSTD" $OPT -f $TFILE *
+		ret=$?
+		if [ $ret -ne 0 ] && [ $ret -ne 1 ]; then
+			exit 1
+		fi
+		set -e
+	else
+		tar -I "$ZSTD" $OPT --file=$TFILE --files-from=/dev/null
+	fi
+	chmod 0664 $TFILE
+	# Skip if it was already created by some other process
+	if [ -h ${SSTATE_PKG} ] && [ ! -e ${SSTATE_PKG} ]; then
+		# There is a symbolic link, but it links to nothing.
+		# Forcefully replace it with the new file.
+		ln -f $TFILE ${SSTATE_PKG} || true
+	elif [ ! -e ${SSTATE_PKG} ]; then
+		# Move into place using ln to attempt an atomic op.
+		# Abort if it already exists
+		ln $TFILE ${SSTATE_PKG} || true
+	else
+		touch ${SSTATE_PKG} 2>/dev/null || true
+	fi
+	rm $TFILE
+}
+
+python sstate_sign_package () {
+    from oe.gpg_sign import get_signer
+
+
+    signer = get_signer(d, 'local')
+    sstate_pkg = d.getVar('SSTATE_PKG')
+    if os.path.exists(sstate_pkg + '.sig'):
+        os.unlink(sstate_pkg + '.sig')
+    signer.detach_sign(sstate_pkg, d.getVar('SSTATE_SIG_KEY', False), None,
+                       d.getVar('SSTATE_SIG_PASSPHRASE'), armor=False)
+}
+
+python sstate_report_unihash() {
+    report_unihash = getattr(bb.parse.siggen, 'report_unihash', None)
+
+    if report_unihash:
+        ss = sstate_state_fromvars(d)
+        report_unihash(os.getcwd(), ss['task'], d)
+}
+
+#
+# Shell function to decompress and prepare a package for installation
+# Will be run from within SSTATE_INSTDIR.
+#
+sstate_unpack_package () {
+	ZSTD="zstd -T${ZSTD_THREADS}"
+	# Use pzstd if available
+	if [ -x "$(command -v pzstd)" ]; then
+		ZSTD="pzstd -p ${ZSTD_THREADS}"
+	fi
+
+	tar -I "$ZSTD" -xvpf ${SSTATE_PKG}
+	# update .siginfo atime on local/NFS mirror if it is a symbolic link
+	[ ! -h ${SSTATE_PKG}.siginfo ] || [ ! -e ${SSTATE_PKG}.siginfo ] || touch -a ${SSTATE_PKG}.siginfo 2>/dev/null || true
+	# update each symbolic link instead of any referenced file
+	touch --no-dereference ${SSTATE_PKG} 2>/dev/null || true
+	[ ! -e ${SSTATE_PKG}.sig ] || touch --no-dereference ${SSTATE_PKG}.sig 2>/dev/null || true
+	[ ! -e ${SSTATE_PKG}.siginfo ] || touch --no-dereference ${SSTATE_PKG}.siginfo 2>/dev/null || true
+}
+
+BB_HASHCHECK_FUNCTION = "sstate_checkhashes"
+
+def sstate_checkhashes(sq_data, d, siginfo=False, currentcount=0, summary=True, **kwargs):
+    found = set()
+    missed = set()
+
+    def gethash(task):
+        return sq_data['unihash'][task]
+
+    def getpathcomponents(task, d):
+        # Magic data from BB_HASHFILENAME
+        splithashfn = sq_data['hashfn'][task].split(" ")
+        spec = splithashfn[1]
+        if splithashfn[0] == "True":
+            extrapath = d.getVar("NATIVELSBSTRING") + "/"
+        else:
+            extrapath = ""
+        
+        tname = bb.runqueue.taskname_from_tid(task)[3:]
+
+        if tname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and splithashfn[2]:
+            spec = splithashfn[2]
+            extrapath = ""
+
+        return spec, extrapath, tname
+
+    def getsstatefile(tid, siginfo, d):
+        spec, extrapath, tname = getpathcomponents(tid, d)
+        return extrapath + generate_sstatefn(spec, gethash(tid), tname, siginfo, d)
+
+    for tid in sq_data['hash']:
+
+        sstatefile = d.expand("${SSTATE_DIR}/" + getsstatefile(tid, siginfo, d))
+
+        if os.path.exists(sstatefile):
+            found.add(tid)
+            bb.debug(2, "SState: Found valid sstate file %s" % sstatefile)
+        else:
+            missed.add(tid)
+            bb.debug(2, "SState: Looked for but didn't find file %s" % sstatefile)
+
+    foundLocal = len(found)
+    mirrors = d.getVar("SSTATE_MIRRORS")
+    if mirrors:
+        # Copy the data object and override DL_DIR and SRC_URI
+        localdata = bb.data.createCopy(d)
+
+        dldir = localdata.expand("${SSTATE_DIR}")
+        localdata.delVar('MIRRORS')
+        localdata.setVar('FILESPATH', dldir)
+        localdata.setVar('DL_DIR', dldir)
+        localdata.setVar('PREMIRRORS', mirrors)
+
+        bb.debug(2, "SState using premirror of: %s" % mirrors)
+
+        # if BB_NO_NETWORK is set but we also have SSTATE_MIRROR_ALLOW_NETWORK,
+        # we'll want to allow network access for the current set of fetches.
+        if bb.utils.to_boolean(localdata.getVar('BB_NO_NETWORK')) and \
+                bb.utils.to_boolean(localdata.getVar('SSTATE_MIRROR_ALLOW_NETWORK')):
+            localdata.delVar('BB_NO_NETWORK')
+
+        from bb.fetch2 import FetchConnectionCache
+        def checkstatus_init():
+            while not connection_cache_pool.full():
+                connection_cache_pool.put(FetchConnectionCache())
+
+        def checkstatus_end():
+            while not connection_cache_pool.empty():
+                connection_cache = connection_cache_pool.get()
+                connection_cache.close_connections()
+
+        def checkstatus(arg):
+            (tid, sstatefile) = arg
+
+            connection_cache = connection_cache_pool.get()
+            localdata2 = bb.data.createCopy(localdata)
+            srcuri = "file://" + sstatefile
+            localdata2.setVar('SRC_URI', srcuri)
+            bb.debug(2, "SState: Attempting to fetch %s" % srcuri)
+
+            import traceback
+
+            try:
+                fetcher = bb.fetch2.Fetch(srcuri.split(), localdata2,
+                            connection_cache=connection_cache)
+                fetcher.checkstatus()
+                bb.debug(2, "SState: Successful fetch test for %s" % srcuri)
+                found.add(tid)
+                missed.remove(tid)
+            except bb.fetch2.FetchError as e:
+                bb.debug(2, "SState: Unsuccessful fetch test for %s (%s)\n%s" % (srcuri, repr(e), traceback.format_exc()))
+            except Exception as e:
+                bb.error("SState: cannot test %s: %s\n%s" % (srcuri, repr(e), traceback.format_exc()))
+
+            connection_cache_pool.put(connection_cache)
+
+            if progress:
+                bb.event.fire(bb.event.ProcessProgress(msg, len(tasklist) - thread_worker.tasks.qsize()), d)
+
+        tasklist = []
+        for tid in missed:
+            sstatefile = d.expand(getsstatefile(tid, siginfo, d))
+            tasklist.append((tid, sstatefile))
+
+        if tasklist:
+            nproc = min(int(d.getVar("BB_NUMBER_THREADS")), len(tasklist))
+
+            progress = len(tasklist) >= 100
+            if progress:
+                msg = "Checking sstate mirror object availability"
+                bb.event.fire(bb.event.ProcessStarted(msg, len(tasklist)), d)
+
+            # Have to setup the fetcher environment here rather than in each thread as it would race
+            fetcherenv = bb.fetch2.get_fetcher_environment(d)
+            with bb.utils.environment(**fetcherenv):
+                bb.event.enable_threadlock()
+                import concurrent.futures
+                from queue import Queue
+                connection_cache_pool = Queue(nproc)
+                checkstatus_init()
+                with concurrent.futures.ThreadPoolExecutor(max_workers=nproc) as executor:
+                    executor.map(checkstatus, tasklist.copy())
+                checkstatus_end()
+                bb.event.disable_threadlock()
+
+            if progress:
+                bb.event.fire(bb.event.ProcessFinished(msg), d)
+
+    inheritlist = d.getVar("INHERIT")
+    if "toaster" in inheritlist:
+        evdata = {'missed': [], 'found': []};
+        for tid in missed:
+            sstatefile = d.expand(getsstatefile(tid, False, d))
+            evdata['missed'].append((bb.runqueue.fn_from_tid(tid), bb.runqueue.taskname_from_tid(tid), gethash(tid), sstatefile ) )
+        for tid in found:
+            sstatefile = d.expand(getsstatefile(tid, False, d))
+            evdata['found'].append((bb.runqueue.fn_from_tid(tid), bb.runqueue.taskname_from_tid(tid), gethash(tid), sstatefile ) )
+        bb.event.fire(bb.event.MetadataEvent("MissedSstate", evdata), d)
+
+    if summary:
+        # Print some summary statistics about the current task completion and how much sstate
+        # reuse there was. Avoid divide by zero errors.
+        total = len(sq_data['hash'])
+        complete = 0
+        if currentcount:
+            complete = (len(found) + currentcount) / (total + currentcount) * 100
+        match = 0
+        if total:
+            match = len(found) / total * 100
+        bb.plain("Sstate summary: Wanted %d Local %d Mirrors %d Missed %d Current %d (%d%% match, %d%% complete)" %
+            (total, foundLocal, len(found)-foundLocal, len(missed), currentcount, match, complete))
+
+    if hasattr(bb.parse.siggen, "checkhashes"):
+        bb.parse.siggen.checkhashes(sq_data, missed, found, d)
+
+    return found
+setscene_depvalid[vardepsexclude] = "SSTATE_EXCLUDEDEPS_SYSROOT"
+
+BB_SETSCENE_DEPVALID = "setscene_depvalid"
+
+def setscene_depvalid(task, taskdependees, notneeded, d, log=None):
+    # taskdependees is a dict of tasks which depend on task, each being a 3 item list of [PN, TASKNAME, FILENAME]
+    # task is included in taskdependees too
+    # Return - False - We need this dependency
+    #        - True - We can skip this dependency
+    import re
+
+    def logit(msg, log):
+        if log is not None:
+            log.append(msg)
+        else:
+            bb.debug(2, msg)
+
+    logit("Considering setscene task: %s" % (str(taskdependees[task])), log)
+
+    directtasks = ["do_populate_lic", "do_deploy_source_date_epoch", "do_shared_workdir", "do_stash_locale", "do_gcc_stash_builddir", "do_create_spdx"]
+
+    def isNativeCross(x):
+        return x.endswith("-native") or "-cross-" in x or "-crosssdk" in x or x.endswith("-cross")
+
+    # We only need to trigger deploy_source_date_epoch through direct dependencies
+    if taskdependees[task][1] in directtasks:
+        return True
+
+    # We only need to trigger packagedata through direct dependencies
+    # but need to preserve packagedata on packagedata links
+    if taskdependees[task][1] == "do_packagedata":
+        for dep in taskdependees:
+            if taskdependees[dep][1] == "do_packagedata":
+                return False
+        return True
+
+    for dep in taskdependees:
+        logit("  considering dependency: %s" % (str(taskdependees[dep])), log)
+        if task == dep:
+            continue
+        if dep in notneeded:
+            continue
+        # do_package_write_* and do_package doesn't need do_package
+        if taskdependees[task][1] == "do_package" and taskdependees[dep][1] in ['do_package', 'do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm', 'do_packagedata', 'do_package_qa']:
+            continue
+        # do_package_write_* need do_populate_sysroot as they're mainly postinstall dependencies
+        if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm']:
+            return False
+        # do_package/packagedata/package_qa/deploy don't need do_populate_sysroot
+        if taskdependees[task][1] == "do_populate_sysroot" and taskdependees[dep][1] in ['do_package', 'do_packagedata', 'do_package_qa', 'do_deploy']:
+            continue
+        # Native/Cross packages don't exist and are noexec anyway
+        if isNativeCross(taskdependees[dep][0]) and taskdependees[dep][1] in ['do_package_write_deb', 'do_package_write_ipk', 'do_package_write_rpm', 'do_packagedata', 'do_package', 'do_package_qa']:
+            continue
+
+        # This is due to the [depends] in useradd.bbclass complicating matters
+        # The logic *is* reversed here due to the way hard setscene dependencies are injected
+        if (taskdependees[task][1] == 'do_package' or taskdependees[task][1] == 'do_populate_sysroot') and taskdependees[dep][0].endswith(('shadow-native', 'shadow-sysroot', 'base-passwd', 'pseudo-native')) and taskdependees[dep][1] == 'do_populate_sysroot':
+            continue
+
+        # Consider sysroot depending on sysroot tasks
+        if taskdependees[task][1] == 'do_populate_sysroot' and taskdependees[dep][1] == 'do_populate_sysroot':
+            # Allow excluding certain recursive dependencies. If a recipe needs it should add a
+            # specific dependency itself, rather than relying on one of its dependees to pull
+            # them in.
+            # See also http://lists.openembedded.org/pipermail/openembedded-core/2018-January/146324.html
+            not_needed = False
+            excludedeps = d.getVar('_SSTATE_EXCLUDEDEPS_SYSROOT')
+            if excludedeps is None:
+                # Cache the regular expressions for speed
+                excludedeps = []
+                for excl in (d.getVar('SSTATE_EXCLUDEDEPS_SYSROOT') or "").split():
+                    excludedeps.append((re.compile(excl.split('->', 1)[0]), re.compile(excl.split('->', 1)[1])))
+                d.setVar('_SSTATE_EXCLUDEDEPS_SYSROOT', excludedeps)
+            for excl in excludedeps:
+                if excl[0].match(taskdependees[dep][0]):
+                    if excl[1].match(taskdependees[task][0]):
+                        not_needed = True
+                        break
+            if not_needed:
+                continue
+            # For meta-extsdk-toolchain we want all sysroot dependencies
+            if taskdependees[dep][0] == 'meta-extsdk-toolchain':
+                return False
+            # Native/Cross populate_sysroot need their dependencies
+            if isNativeCross(taskdependees[task][0]) and isNativeCross(taskdependees[dep][0]):
+                return False
+            # Target populate_sysroot depended on by cross tools need to be installed
+            if isNativeCross(taskdependees[dep][0]):
+                return False
+            # Native/cross tools depended upon by target sysroot are not needed
+            # Add an exception for shadow-native as required by useradd.bbclass
+            if isNativeCross(taskdependees[task][0]) and taskdependees[task][0] != 'shadow-native':
+                continue
+            # Target populate_sysroot need their dependencies
+            return False
+
+        if taskdependees[dep][1] in directtasks:
+            continue
+
+        # Safe fallthrough default
+        logit(" Default setscene dependency fall through due to dependency: %s" % (str(taskdependees[dep])), log)
+        return False
+    return True
+
+addhandler sstate_eventhandler
+sstate_eventhandler[eventmask] = "bb.build.TaskSucceeded"
+python sstate_eventhandler() {
+    d = e.data
+    writtensstate = d.getVar('SSTATE_CURRTASK')
+    if not writtensstate:
+        taskname = d.getVar("BB_RUNTASK")[3:]
+        spec = d.getVar('SSTATE_PKGSPEC')
+        swspec = d.getVar('SSTATE_SWSPEC')
+        if taskname in ["fetch", "unpack", "patch", "populate_lic", "preconfigure"] and swspec:
+            d.setVar("SSTATE_PKGSPEC", "${SSTATE_SWSPEC}")
+            d.setVar("SSTATE_EXTRAPATH", "")
+        d.setVar("SSTATE_CURRTASK", taskname)
+        siginfo = d.getVar('SSTATE_PKG') + ".siginfo"
+        if not os.path.exists(siginfo):
+            bb.siggen.dump_this_task(siginfo, d)
+        else:
+            try:
+                os.utime(siginfo, None)
+            except PermissionError:
+                pass
+            except OSError as e:
+                # Handle read-only file systems gracefully
+                import errno
+                if e.errno != errno.EROFS:
+                    raise e
+
+}
+
+SSTATE_PRUNE_OBSOLETEWORKDIR ?= "1"
+
+#
+# Event handler which removes manifests and stamps file for recipes which are no
+# longer 'reachable' in a build where they once were. 'Reachable' refers to
+# whether a recipe is parsed so recipes in a layer which was removed would no
+# longer be reachable. Switching between systemd and sysvinit where recipes
+# became skipped would be another example.
+#
+# Also optionally removes the workdir of those tasks/recipes
+#
+addhandler sstate_eventhandler_reachablestamps
+sstate_eventhandler_reachablestamps[eventmask] = "bb.event.ReachableStamps"
+python sstate_eventhandler_reachablestamps() {
+    import glob
+    d = e.data
+    stamps = e.stamps.values()
+    removeworkdir = (d.getVar("SSTATE_PRUNE_OBSOLETEWORKDIR", False) == "1")
+    preservestampfile = d.expand('${SSTATE_MANIFESTS}/preserve-stamps')
+    preservestamps = []
+    if os.path.exists(preservestampfile):
+        with open(preservestampfile, 'r') as f:
+            preservestamps = f.readlines()
+    seen = []
+
+    # The machine index contains all the stamps this machine has ever seen in this build directory.
+    # We should only remove things which this machine once accessed but no longer does.
+    machineindex = set()
+    bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
+    mi = d.expand("${SSTATE_MANIFESTS}/index-machine-${MACHINE}")
+    if os.path.exists(mi):
+        with open(mi, "r") as f:
+            machineindex = set(line.strip() for line in f.readlines())
+
+    for a in sorted(list(set(d.getVar("SSTATE_ARCHS").split()))):
+        toremove = []
+        i = d.expand("${SSTATE_MANIFESTS}/index-" + a)
+        if not os.path.exists(i):
+            continue
+        manseen = set()
+        ignore = []
+        with open(i, "r") as f:
+            lines = f.readlines()
+            for l in reversed(lines):
+                try:
+                    (stamp, manifest, workdir) = l.split()
+                    # The index may have multiple entries for the same manifest as the code above only appends
+                    # new entries and there may be an entry with matching manifest but differing version in stamp/workdir.
+                    # The last entry in the list is the valid one, any earlier entries with matching manifests
+                    # should be ignored.
+                    if manifest in manseen:
+                        ignore.append(l)
+                        continue
+                    manseen.add(manifest)
+                    if stamp not in stamps and stamp not in preservestamps and stamp in machineindex:
+                        toremove.append(l)
+                        if stamp not in seen:
+                            bb.debug(2, "Stamp %s is not reachable, removing related manifests" % stamp)
+                            seen.append(stamp)
+                except ValueError:
+                    bb.fatal("Invalid line '%s' in sstate manifest '%s'" % (l, i))
+
+        if toremove:
+            msg = "Removing %d recipes from the %s sysroot" % (len(toremove), a)
+            bb.event.fire(bb.event.ProcessStarted(msg, len(toremove)), d)
+
+            removed = 0
+            for r in toremove:
+                (stamp, manifest, workdir) = r.split()
+                for m in glob.glob(manifest + ".*"):
+                    if m.endswith(".postrm"):
+                        continue
+                    sstate_clean_manifest(m, d)
+                bb.utils.remove(stamp + "*")
+                if removeworkdir:
+                    bb.utils.remove(workdir, recurse = True)
+                lines.remove(r)
+                removed = removed + 1
+                bb.event.fire(bb.event.ProcessProgress(msg, removed), d)
+
+            bb.event.fire(bb.event.ProcessFinished(msg), d)
+
+        with open(i, "w") as f:
+            for l in lines:
+                if l in ignore:
+                    continue
+                f.write(l)
+    machineindex |= set(stamps)
+    with open(mi, "w") as f:
+        for l in machineindex:
+            f.write(l + "\n")
+
+    if preservestamps:
+        os.remove(preservestampfile)
+}
+
+
+#
+# Bitbake can generate an event showing which setscene tasks are 'stale',
+# i.e. which ones will be rerun. These are ones where a stamp file is present but
+# it is stable (e.g. taskhash doesn't match). With that list we can go through
+# the manifests for matching tasks and "uninstall" those manifests now. We do
+# this now rather than mid build since the distribution of files between sstate
+# objects may have changed, new tasks may run first and if those new tasks overlap
+# with the stale tasks, we'd see overlapping files messages and failures. Thankfully
+# removing these files is fast.
+#
+addhandler sstate_eventhandler_stalesstate
+sstate_eventhandler_stalesstate[eventmask] = "bb.event.StaleSetSceneTasks"
+python sstate_eventhandler_stalesstate() {
+    d = e.data
+    tasks = e.tasks
+
+    bb.utils.mkdirhier(d.expand("${SSTATE_MANIFESTS}"))
+
+    for a in list(set(d.getVar("SSTATE_ARCHS").split())):
+        toremove = []
+        i = d.expand("${SSTATE_MANIFESTS}/index-" + a)
+        if not os.path.exists(i):
+            continue
+        with open(i, "r") as f:
+            lines = f.readlines()
+            for l in lines:
+                try:
+                    (stamp, manifest, workdir) = l.split()
+                    for tid in tasks:
+                        for s in tasks[tid]:
+                            if s.startswith(stamp):
+                                taskname = bb.runqueue.taskname_from_tid(tid)[3:]
+                                manname = manifest + "." + taskname
+                                if os.path.exists(manname):
+                                    bb.debug(2, "Sstate for %s is stale, removing related manifest %s" % (tid, manname))
+                                    toremove.append((manname, tid, tasks[tid]))
+                                    break
+                except ValueError:
+                    bb.fatal("Invalid line '%s' in sstate manifest '%s'" % (l, i))
+
+        if toremove:
+            msg = "Removing %d stale sstate objects for arch %s" % (len(toremove), a)
+            bb.event.fire(bb.event.ProcessStarted(msg, len(toremove)), d)
+
+            removed = 0
+            for (manname, tid, stamps) in toremove:
+                sstate_clean_manifest(manname, d)
+                for stamp in stamps:
+                    bb.utils.remove(stamp)
+                removed = removed + 1
+                bb.event.fire(bb.event.ProcessProgress(msg, removed), d)
+
+            bb.event.fire(bb.event.ProcessFinished(msg), d)
+}