openembedded-core.lists.openembedded.org archive mirror
 help / color / mirror / Atom feed
* [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions
@ 2026-07-14 18:31 Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 01/22] scripts/pull-spdx-licenses.py: Add exceptions Joshua Watt
                   ` (21 more replies)
  0 siblings, 22 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Reworks the way that the LICENSE variable is used so that it uses valid
SPDX License Expressions instead of the custom expressions that were
used previously (which are based on Python syntax). This includes
support for the SPDX "WITH" operator which allows a license exception to
be attached to a license identifier.

The old licenses expressions are still allowed, and will still be
correctly parsed, however a warning will be issued that indicates the
new license string that should be used.

Most layers should be able to use the newly-revised
scripts/contrib/convert-spdx-licenses.py script to do the majority of
the conversion work, although some manual work may still be required if
conditional or complex LICENSE expressions are encountered.

SPDX License Expressions require that all licenses listed are either a
known identifier (e.g. "GPL-2.0-or-later") or start with the prefix
"LicenseRef-" which indicates a custom license. When converting from old
expressions to new one this will need to be followed (the suggested new
license in the warning and the conversion script will automatically add
this prefix for any unrecognized license identifiers). This will most
commonly be the case for NO_GENERIC_LICENSE files; for a good example of
what needs to be done here see the changes to the linux-firmware recipe.
When adding new LicenseRef- licenses to a recipe, the actual license
name should be prefixed with the name of the recipe (e.g.
"LicenseRef-myrecipe-mylicense") to prevent conflicts when merging
multiple license documents together (e.g. in an image).

SPDX also introduces the "WITH" operator to add an exception to a
license instead of using a bespoke identifier to combine the two, as was
done with the legacy license expressions. Because of this, the logic for
dealing with the INCOMPATIBLE_LICENSE family of variables has changed
slightly. The main difference is that INCOMPATIBLE_LICENSE will now
match the LHS of a "WITH" expression (where as previously this was
"ignored" since it was a bespoke license ID). In order to allow a
license that would normally be rejected, but can be allowed with an
exception, specifically allowed exceptions can be added to the
INCOMPATIBLE_LICENSE_EXCEPTIONS variable (keep in mind, EXCEPTIONS here
means "exceptions to INCOMPATIBLE_LICENSES", not specifically SPDX
License Exceptions). If an SPDX exception is present here, any license
that has that exception will be allowed, even if it would normally match
INCOMPATIBLE_LICENSE. For example, to disallow all GPLv3 except for
those with the GCC exception, use:

    INCOMPATIBLE_LICENSE = "GPL-3.0* LGPL-3.0*"
    INCOMPATIBLE_LICENSE_EXCEPTIONS = "GCC-exception-3.1" # This new line is required


Additionally, "PD" ("Public Domain") is not allowed as a generic license
identifier. Aside from "PD" not being a valid SPDX License Identifier,
most "Public Domain" licenses do have some sort of text associated with
them (see the HPND family of SPDX Licenses, or use the [1](SPDX License
Match Website) ). In addition, the meaning of "Public Domain" can vary
by jurisdiction, so the actual text with a LicenseRef- or a SPDX License
Identifier needs to be used instead.

Finally, "CLOSED" is also no longer allowed as a license expression
(since it is not a valid SPDX License Identifier). Instead use a
LicenseRef- to point to a file that contains the actual license text
(usually something like "Copyright <name>, all rights reserved")

[1]: https://tools.spdx.org/app/check_license/


Joshua Watt (22):
  scripts/pull-spdx-licenses.py: Add exceptions
  Add SPDX License Exceptions
  Add SPDX license library
  Parse LICENSE as SPDX Expression
  linux-firmware: Convert to SPDX license strings
  meta-selftest: Add NO_GENERIC_LICENSE
  convert-spdx-licenses: Convert to valid SPDX expressions
  gcc-common.inc: Remove LICENSE
  gcc: Update license
  xz: Replace deprecated SPDX identifier
  autoconf-archive: Replace deprecated SPDX identifier
  gnu-config: Replace deprecated SPDX identifier
  libglvnd: Replace deprecated SPDX identifier
  flac: Replace deprecated SPDX identifier
  libgit2: Replace deprecated SPDX identifier
  Fix up licenses
  lib: oe: license: Rework package licenses matching
  classes/go-mod-update-modules: Switch to SPDX license
  license: Remove tidy_licenses()
  meta-selftest: Change license on test recipes
  Convert licenses to SPDX expressions
  meta-selftest: libxpm: Fix license

 .../python/python3-guessing-game_git.bb       |    2 +-
 .../python3-guessing-game_git.bb.upgraded     |    2 +-
 .../sysdig/sysdig-selftest_0.28.0.bb          |    2 +-
 .../recipes-test/aspell/aspell_0.0.0.1.bb     |    2 +-
 .../devtool/devtool-patch-overrides.bb        |    3 +-
 .../devtool/devtool-test-ignored.bb           |    3 +-
 .../devtool/devtool-test-localonly.bb         |    3 +-
 .../devtool/devtool-test-long-filename.bb     |    3 +-
 .../devtool/devtool-test-reset-re++.bb        |    3 +-
 .../devtool/devtool-test-subdir.bb            |    3 +-
 .../license/incompatible-license-alias.bb     |    2 +-
 .../license/incompatible-licenses.bb          |    2 +-
 .../license/incompatible-nonspdx-license.bb   |    3 +-
 .../recipes-test/logging-test/logging-test.bb |    3 +-
 .../sysroot-test/sysroot-la-test_1.0.bb       |    3 +-
 .../sysroot-test/sysroot-pc-test_1.0.bb       |    3 +-
 .../sysroot-test/sysroot-shebang-test_1.0.bb  |    3 +-
 .../sysroot-test/sysroot-test-arch1_1.0.bb    |    3 +-
 .../sysroot-test/sysroot-test-arch2_1.0.bb    |    3 +-
 .../sysroot-test/sysroot-test_1.0.bb          |    3 +-
 .../recipes-skeleton/libxpm/libxpm_3.5.6.bb   |    2 +-
 meta/classes-global/insane.bbclass            |    8 +-
 meta/classes-global/license.bbclass           |  113 +-
 .../go-mod-update-modules.bbclass             |   21 +-
 meta/classes-recipe/license_image.bbclass     |   31 +-
 meta/classes/buildhistory.bbclass             |    3 +-
 meta/classes/copyleft_filter.bbclass          |    4 +-
 meta/conf/licenses.conf                       |    4 +
 meta/files/common-licenses/389-exception      |    7 +
 meta/files/common-licenses/Asterisk-exception |    5 +
 .../Asterisk-linking-protocols-exception      |   13 +
 .../common-licenses/Autoconf-exception-2.0    |    5 +
 .../common-licenses/Autoconf-exception-3.0    |   26 +
 .../Autoconf-exception-generic                |    4 +
 .../Autoconf-exception-generic-3.0            |    6 +
 .../common-licenses/Autoconf-exception-macro  |   12 +
 .../common-licenses/Bison-exception-1.24      |    4 +
 .../files/common-licenses/Bison-exception-2.2 |    5 +
 .../common-licenses/Bootloader-exception      |   10 +
 .../common-licenses/CGAL-linking-exception    |    4 +
 .../files/common-licenses/CLISP-exception-2.0 |   15 +
 .../common-licenses/Classpath-exception-2.0   |    3 +
 .../Classpath-exception-2.0-short             |   11 +
 .../common-licenses/DigiRule-FOSS-exception   |   54 +
 .../Digia-Qt-LGPL-exception-1.1               |    9 +
 meta/files/common-licenses/FLTK-exception     |   17 +
 .../common-licenses/Fawkes-Runtime-exception  |    1 +
 meta/files/common-licenses/Font-exception-2.0 |    1 +
 meta/files/common-licenses/GCC-exception-2.0  |    1 +
 .../common-licenses/GCC-exception-2.0-note    |   16 +
 meta/files/common-licenses/GCC-exception-3.1  |   33 +
 meta/files/common-licenses/GNAT-exception     |    6 +
 .../common-licenses/GNOME-examples-exception  |    1 +
 .../common-licenses/GNU-compiler-exception    |    6 +
 .../GPL-3.0-389-ds-base-exception             |   10 +
 .../GPL-3.0-interface-exception               |    7 +
 .../common-licenses/GPL-3.0-linking-exception |    3 +
 .../GPL-3.0-linking-source-exception          |    3 +
 meta/files/common-licenses/GPL-CC-1.0         |   46 +
 .../common-licenses/GStreamer-exception-2005  |    1 +
 .../common-licenses/GStreamer-exception-2008  |    1 +
 meta/files/common-licenses/Gmsh-exception     |   16 +
 .../Independent-modules-exception             |   18 +
 .../common-licenses/KiCad-libraries-exception |    1 +
 .../LGPL-3.0-linking-exception                |   16 +
 meta/files/common-licenses/LLGPL              |   56 +
 meta/files/common-licenses/LLVM-exception     |   15 +
 meta/files/common-licenses/LZMA-exception     |    3 +
 meta/files/common-licenses/Libtool-exception  |    1 +
 meta/files/common-licenses/Linux-syscall-note |   12 +
 meta/files/common-licenses/OCCT-exception-1.0 |    3 +
 .../OCaml-LGPL-linking-exception              |    1 +
 .../OpenJDK-assembly-exception-1.0            |   31 +
 meta/files/common-licenses/PCRE2-exception    |    8 +
 .../PS-or-PDF-font-exception-20170817         |    8 +
 .../QPL-1.0-INRIA-2004-exception              |    5 +
 .../common-licenses/Qt-GPL-exception-1.0      |   21 +
 .../common-licenses/Qt-LGPL-exception-1.1     |   22 +
 meta/files/common-licenses/Qwt-exception-1.0  |   12 +
 .../RRDtool-FLOSS-exception-2.0               |   66 +
 meta/files/common-licenses/SANE-exception     |   20 +
 meta/files/common-licenses/SHL-2.0            |   22 +
 meta/files/common-licenses/SHL-2.1            |   49 +
 meta/files/common-licenses/SWI-exception      |    7 +
 .../Simple-Library-Usage-exception            |   33 +
 meta/files/common-licenses/Swift-exception    |    6 +
 meta/files/common-licenses/Texinfo-exception  |    4 +
 meta/files/common-licenses/UBDL-exception     |   59 +
 .../Universal-FOSS-exception-1.0              |   11 +
 .../common-licenses/WxWindows-exception-3.1   |    9 +
 .../cryptsetup-OpenSSL-exception              |   12 +
 meta/files/common-licenses/eCos-exception-2.0 |    3 +
 .../erlang-otp-linking-exception              |   11 +
 meta/files/common-licenses/fmt-exception      |    6 +
 .../common-licenses/freertos-exception-2.0    |   19 +
 .../common-licenses/gnu-javamail-exception    |    1 +
 meta/files/common-licenses/harbour-exception  |   23 +
 .../common-licenses/i2p-gpl-java-exception    |    1 +
 .../common-licenses/kvirc-openssl-exception   |   30 +
 .../common-licenses/libpri-OpenH323-exception |    4 +
 meta/files/common-licenses/mif-exception      |    1 +
 meta/files/common-licenses/mxml-exception     |   16 +
 .../common-licenses/openvpn-openssl-exception |    3 +
 .../files/common-licenses/polyparse-exception |    7 +
 meta/files/common-licenses/romic-exception    |    6 +
 .../common-licenses/rsync-linking-exception   |    6 +
 .../sqlitestudio-OpenSSL-exception            |    9 +
 meta/files/common-licenses/stunnel-exception  |    5 +
 .../common-licenses/u-boot-exception-2.0      |    6 +
 .../common-licenses/vsftpd-openssl-exception  |    5 +
 .../common-licenses/x11vnc-openssl-exception  |    9 +
 meta/files/license-hashes.csv                 |    4 +-
 meta/files/spdx-exceptions.json               |  971 ++++++++++
 meta/lib/oe/license.py                        |  585 +++---
 meta/lib/oe/license_finder.py                 |   10 +-
 meta/lib/oe/spdx30_tasks.py                   |  173 +-
 meta/lib/oe/spdx_license.py                   |  760 ++++++++
 meta/lib/oeqa/selftest/cases/devtool.py       |    5 +-
 .../oeqa/selftest/cases/incompatible_lic.py   |   31 +-
 meta/lib/oeqa/selftest/cases/oelib/license.py |  296 ++-
 meta/lib/oeqa/selftest/cases/recipetool.py    |  106 +-
 meta/recipes-bsp/alsa-state/alsa-state.bb     |    2 +-
 meta/recipes-bsp/gnu-efi/gnu-efi_4.0.4.bb     |    2 +-
 meta/recipes-bsp/usbutils/usbutils_019.bb     |    4 +-
 meta/recipes-connectivity/avahi/avahi_0.9.bb  |    2 +-
 meta/recipes-connectivity/bluez5/bluez5.inc   |    2 +-
 .../connman/connman-gnome_0.7.bb              |    2 +-
 .../nfs-utils/nfs-utils_2.9.1.bb              |    2 +-
 .../openssh/openssh_10.4p1.bb                 |    2 +-
 meta/recipes-connectivity/ppp/ppp_2.5.3.bb    |    2 +-
 .../slirp/libslirp_4.9.3.bb                   |    2 +-
 .../socat/socat_1.8.1.3.bb                    |    3 +-
 meta/recipes-core/busybox/busybox.inc         |    2 +-
 meta/recipes-core/dbus/dbus-glib_0.114.bb     |    2 +-
 meta/recipes-core/dbus/dbus_1.16.2.bb         |    2 +-
 .../recipes-core/dropbear/dropbear_2026.92.bb |    2 +-
 meta/recipes-core/gettext/gettext_1.0.bb      |    4 +-
 meta/recipes-core/glib-2.0/glib.inc           |    2 +-
 meta/recipes-core/glibc/glibc-common.inc      |    2 +-
 .../initscripts/init-system-helpers_1.69.bb   |    2 +-
 meta/recipes-core/kbd/kbd_2.10.0.bb           |    4 +-
 meta/recipes-core/libxcrypt/libxcrypt.inc     |    2 +-
 meta/recipes-core/musl/bsd-headers.bb         |    2 +-
 meta/recipes-core/musl/musl-locales_git.bb    |    2 +-
 meta/recipes-core/musl/musl-utils.bb          |    2 +-
 meta/recipes-core/newlib/newlib.inc           |    2 +-
 meta/recipes-core/picolibc/picolibc.inc       |    2 +-
 .../sysfsutils/sysfsutils_2.1.1.bb            |    2 +-
 meta/recipes-core/systemd/systemd.inc         |    2 +-
 meta/recipes-core/udev/eudev_3.2.14.bb        |    2 +-
 .../util-linux/util-linux_2.42.2.bb           |   40 +-
 .../autoconf-archive_2024.10.16.bb            |    2 +-
 .../btrfs-tools/btrfs-tools_7.0.bb            |    2 +-
 meta/recipes-devtools/ccache/ccache_4.13.6.bb |    2 +-
 .../cdrtools/cdrtools-native_3.01.bb          |    2 +-
 meta/recipes-devtools/clang/common.inc        |    2 +-
 meta/recipes-devtools/clang/llvm_git.bb       |    2 +-
 .../clang/nativesdk-clang-glue.bb             |    2 +-
 .../cmake/cmake-native_4.4.0.bb               |    2 +-
 meta/recipes-devtools/cmake/cmake_4.4.0.bb    |    2 +-
 .../debugedit/debugedit_5.3.bb                |    2 +-
 .../docbook-xml/docbook-xml-dtd4_4.5.bb       |    2 +-
 meta/recipes-devtools/e2fsprogs/e2fsprogs.inc |    2 +-
 .../elfutils/elfutils_0.195.bb                |   10 +-
 .../erofs-utils/erofs-utils_1.9.2.bb          |    2 +-
 meta/recipes-devtools/expect/expect_5.45.4.bb |    2 +-
 .../fastfloat/fastfloat_8.2.10.bb             |    2 +-
 meta/recipes-devtools/flex/flex_2.6.4.bb      |    2 +-
 meta/recipes-devtools/fmt/fmt_12.2.0.bb       |    2 +-
 meta/recipes-devtools/gcc/gcc-16.1.inc        |    2 +-
 meta/recipes-devtools/gcc/gcc-common.inc      |    1 -
 meta/recipes-devtools/gcc/gcc-runtime.inc     |    4 +-
 meta/recipes-devtools/gcc/gcc-sanitizers.inc  |    2 +-
 meta/recipes-devtools/gcc/libgcc-initial.inc  |    2 +-
 meta/recipes-devtools/gcc/libgcc.inc          |    8 +-
 meta/recipes-devtools/gcc/libgfortran.inc     |    6 +-
 meta/recipes-devtools/gdb/gdb.inc             |    2 +-
 meta/recipes-devtools/git/git_2.55.0.bb       |    2 +-
 .../gnu-config/gnu-config_git.bb              |    2 +-
 .../i2c-tools/i2c-tools_4.4.bb                |    2 +-
 .../libtool/libtool-2.5.4.inc                 |    2 +-
 .../log4cplus/log4cplus_2.2.0.1.bb            |    2 +-
 meta/recipes-devtools/orc/orc_0.4.42.bb       |    2 +-
 .../perl-cross/perlcross_1.6.4.bb             |    2 +-
 .../perl/libmodule-build-perl_0.4234.bb       |    2 +-
 .../perl/libtest-fatal-perl_0.018.bb          |    2 +-
 .../perl/libtest-needs-perl_0.002010.bb       |    2 +-
 .../perl/libtest-warnings-perl_0.038.bb       |    2 +-
 .../recipes-devtools/perl/libxml-perl_0.08.bb |    2 +-
 .../perl/libxml-simple-perl_2.25.bb           |    2 +-
 meta/recipes-devtools/perl/perl_5.42.2.bb     |    2 +-
 .../python/python-pycryptodome.inc            |    2 +-
 .../python/python3-cryptography-vectors.bb    |    2 +-
 .../python/python3-cryptography.bb            |    2 +-
 .../python/python3-docutils_0.23.bb           |    4 +-
 .../python/python3-dtc_1.8.1.bb               |    2 +-
 .../python/python3-idna_3.18.bb               |    2 +-
 .../python/python3-lxml_6.1.1.bb              |    2 +-
 .../python/python3-maturin_1.14.1.bb          |    2 +-
 .../python/python3-numpy_2.5.0.bb             |    2 +-
 .../python/python3-packaging_26.2.bb          |    2 +-
 .../python/python3-pip_26.1.2.bb              |    2 +-
 .../python/python3-poetry-core_2.4.1.bb       |    2 +-
 .../python/python3-pycairo_1.29.0.bb          |    2 +-
 .../python/python3-roman-numerals_4.1.0.bb    |    2 +-
 .../python/python3-sphinx-rtd-theme_3.1.0.bb  |    2 +-
 .../python/python3-sphinx_9.1.0.bb            |    2 +-
 .../python/python3-subunit_1.4.4.bb           |    2 +-
 .../python/python3-uv-build_0.11.28.bb        |    2 +-
 .../qemu/python3-qemu-qmp_0.0.6.bb            |    2 +-
 meta/recipes-devtools/qemu/qemu.inc           |    2 +-
 .../rpm-sequoia/rpm-sequoia_1.10.2.bb         |    2 +-
 meta/recipes-devtools/ruby/ruby_4.0.5.bb      |    2 +-
 meta/recipes-devtools/rust/cargo_1.96.1.bb    |    2 +-
 .../recipes-devtools/rust/libstd-rs_1.96.1.bb |    2 +-
 meta/recipes-devtools/rust/rust_1.96.1.bb     |    2 +-
 meta/recipes-devtools/strace/strace_7.1.bb    |    2 +-
 .../subversion/subversion_1.14.5.bb           |    2 +-
 meta/recipes-devtools/swig/swig_4.4.1.bb      |    2 +-
 .../systemd-bootchart_235.bb                  |    2 +-
 .../tcf-agent/tcf-agent_1.11.0.bb             |    2 +-
 meta/recipes-devtools/tcltk/tcl_9.0.4.bb      |    2 +-
 meta/recipes-devtools/tcltk8/tcl8_8.6.18.bb   |    2 +-
 .../valgrind/valgrind_3.27.1.bb               |    2 +-
 .../acpica/acpica_20260408.bb                 |    2 +-
 meta/recipes-extended/bzip2/bzip2_1.0.8.bb    |    4 +-
 meta/recipes-extended/cronie/cronie_1.7.2.bb  |    2 +-
 meta/recipes-extended/gawk/gawk_5.4.1.bb      |    2 +-
 meta/recipes-extended/hdparm/hdparm_9.65.bb   |    6 +-
 .../iputils/iputils_20250605.bb               |    2 +-
 .../jansson/jansson_2.15.1.bb                 |    2 +-
 meta/recipes-extended/less/less_704.bb        |    2 +-
 meta/recipes-extended/libidn/libidn2_2.3.8.bb |    4 +-
 meta/recipes-extended/ltp/ltp_20260529.bb     |    2 +-
 meta/recipes-extended/man-db/man-db_2.13.1.bb |    2 +-
 .../man-pages/man-pages_6.18.bb               |    2 +-
 meta/recipes-extended/mdadm/mdadm_4.6.bb      |    2 +-
 meta/recipes-extended/pam/libpam_1.7.2.bb     |    2 +-
 .../perl/libconvert-asn1-perl_0.34.bb         |    2 +-
 .../perl/libtimedate-perl_2.30.bb             |    2 +-
 .../perl/libxml-namespacesupport-perl_1.12.bb |    2 +-
 .../perl/libxml-sax-base-perl_1.09.bb         |    2 +-
 .../perl/libxml-sax-perl_1.02.bb              |    2 +-
 meta/recipes-extended/pigz/pigz_2.8.bb        |    2 +-
 meta/recipes-extended/procps/procps_4.0.6.bb  |    2 +-
 meta/recipes-extended/quota/quota_4.11.bb     |    2 +-
 .../shadow/shadow-sysroot_4.6.bb              |    2 +-
 meta/recipes-extended/sudo/sudo.inc           |    2 +-
 meta/recipes-extended/timezone/timezone.inc   |    2 +-
 meta/recipes-extended/xz/xz_5.8.3.bb          |    8 +-
 meta/recipes-extended/zstd/zstd_1.5.7.bb      |    2 +-
 .../gi-docgen/gi-docgen_2026.1.bb             |    2 +-
 .../gnome/adwaita-icon-theme_50.0.bb          |    2 +-
 .../gobject-introspection_1.86.0.bb           |    2 +-
 meta/recipes-gnome/gtk+/gtk+3_3.24.52.bb      |    2 +-
 meta/recipes-gnome/gtk+/gtk4_4.22.4.bb        |    2 +-
 meta/recipes-graphics/cairo/cairo_1.18.4.bb   |   16 +-
 .../cantarell-fonts_0.303.1.bb                |    2 +-
 .../fontconfig/fontconfig_2.18.2.bb           |    2 +-
 .../freetype/freetype_2.14.3.bb               |    2 +-
 .../glslang/glslang_1.4.350.1.bb              |    2 +-
 .../jpeg/libjpeg-turbo_3.2.0.bb               |    2 +-
 .../libglvnd/libglvnd_1.7.0.bb                |    2 +-
 .../libmatchbox/libmatchbox_1.14.bb           |    2 +-
 .../libsdl2/libsdl2_2.32.10.bb                |    4 +-
 .../recipes-graphics/mesa/mesa-demos_9.0.0.bb |    2 +-
 meta/recipes-graphics/piglit/piglit_git.bb    |    2 +-
 .../spir/spirv-headers_1.4.350.1.bb           |    2 +-
 .../vulkan/vulkan-headers_1.4.350.1.bb        |    2 +-
 .../vulkan-validation-layers_1.4.350.1.bb     |    2 +-
 .../xorg-font/encodings_1.1.0.bb              |    2 +-
 .../xorg-font/font-util_1.4.2.bb              |    2 +-
 .../xorg-font/xorg-minimal-fonts.bb           |    2 +-
 .../xorg-lib/libx11-compose-data_1.8.12.bb    |    2 +-
 .../xorg-lib/libx11_1.8.13.bb                 |    2 +-
 .../xorg-lib/libxfont2_2.0.8.bb               |    2 +-
 .../xorg-lib/libxfont_1.5.4.bb                |    2 +-
 meta/recipes-graphics/xorg-lib/libxi_1.8.3.bb |    2 +-
 .../xorg-lib/libxkbcommon_1.13.2.bb           |    2 +-
 .../recipes-graphics/xorg-lib/libxmu_1.3.1.bb |    2 +-
 meta/recipes-graphics/xorg-lib/libxt_1.3.1.bb |    2 +-
 .../xorg-lib/pixman_0.46.4.bb                 |    2 +-
 .../xorg-lib/xkeyboard-config_2.48.bb         |    2 +-
 .../xorg-xserver/xserver-xorg.inc             |    2 +-
 .../xwayland/xwayland_24.1.13.bb              |    2 +-
 meta/recipes-kernel/dtc/dtc_1.8.1.bb          |    2 +-
 .../kern-tools/kern-tools-native_git.bb       |    2 +-
 meta/recipes-kernel/kmod/kmod_34.2.bb         |    2 +-
 .../libtraceevent/libtraceevent_1.9.0.bb      |    2 +-
 .../linux-firmware/linux-firmware_20260622.bb | 1666 ++++++++---------
 .../linux/linux-yocto-fitimage.bb             |    2 +-
 meta/recipes-kernel/linux/linux-yocto.inc     |    2 +-
 .../recipes-kernel/lttng/babeltrace2_2.1.2.bb |    2 +-
 .../lttng/lttng-modules_2.15.2.bb             |    2 +-
 .../lttng/lttng-tools_2.15.1.bb               |    2 +-
 meta/recipes-kernel/lttng/lttng-ust_2.15.1.bb |    2 +-
 .../alsa/alsa-lib_1.2.16.1.bb                 |    2 +-
 .../alsa/alsa-plugins_1.2.12.bb               |    2 +-
 .../alsa/alsa-tools_1.2.15.bb                 |    2 +-
 .../recipes-multimedia/ffmpeg/ffmpeg_8.1.2.bb |    2 +-
 meta/recipes-multimedia/flac/flac_1.5.0.bb    |    2 +-
 .../gstreamer1.0-plugins-bad_1.28.4.bb        |    2 +-
 .../gstreamer1.0-plugins-ugly_1.28.4.bb       |    2 +-
 meta/recipes-multimedia/libtiff/tiff_4.7.2.bb |    2 +-
 .../pulseaudio/pulseaudio.inc                 |    2 +-
 meta/recipes-multimedia/sbc/sbc_2.2.bb        |    2 +-
 meta/recipes-rt/rt-tests/rt-tests_git.bb      |    2 +-
 .../matchbox-desktop/matchbox-desktop_2.3.bb  |    2 +-
 meta/recipes-sato/pcmanfm/pcmanfm_1.3.2.bb    |    2 +-
 .../sato-screenshot/sato-screenshot_0.3.bb    |    2 +-
 meta/recipes-sato/webkit/webkitgtk_2.52.5.bb  |    2 +-
 .../recipes-support/aspell/aspell_0.60.8.2.bb |    2 +-
 meta/recipes-support/attr/acl_2.4.0.bb        |    2 +-
 meta/recipes-support/attr/attr_2.6.0.bb       |    2 +-
 meta/recipes-support/boost/boost-1.91.0.inc   |    2 +-
 .../ca-certificates_20260601.bb               |    2 +-
 .../debianutils/debianutils_5.23.2.bb         |    2 +-
 meta/recipes-support/gmp/gmp_6.3.0.bb         |    2 +-
 meta/recipes-support/gnupg/gnupg_2.5.20.bb    |    2 +-
 meta/recipes-support/gnutls/gnutls_3.8.13.bb  |    2 +-
 .../recipes-support/gnutls/libtasn1_4.21.0.bb |    2 +-
 meta/recipes-support/gpgme/gpgme_2.1.2.bb     |    4 +-
 meta/recipes-support/hwdata/hwdata_0.409.bb   |    2 +-
 meta/recipes-support/icu/icu_78.3.bb          |    2 +-
 .../libassuan/libassuan_3.0.2.bb              |    2 +-
 .../libatomic-ops/libatomic-ops_7.10.0.bb     |    2 +-
 meta/recipes-support/libbsd/libbsd_0.12.2.bb  |    2 +-
 meta/recipes-support/libcap-ng/libcap-ng.inc  |    2 +-
 meta/recipes-support/libcap/libcap_2.78.bb    |    6 +-
 .../libevent/libevent_2.1.13.bb               |    2 +-
 meta/recipes-support/libfm/libfm_1.3.2.bb     |    2 +-
 .../libgcrypt/libgcrypt_1.12.2.bb             |    6 +-
 meta/recipes-support/libgit2/libgit2_1.9.4.bb |    2 +-
 .../libgpg-error/libgpg-error_1.61.bb         |    2 +-
 meta/recipes-support/libical/libical_4.0.3.bb |    2 +-
 .../libjitterentropy_3.6.3.bb                 |    2 +-
 meta/recipes-support/libksba/libksba_1.8.0.bb |    4 +-
 meta/recipes-support/libmd/libmd_1.2.0.bb     |    2 +-
 .../recipes-support/libpcre/libpcre2_10.47.bb |    2 +-
 .../libunistring/libunistring_1.4.2.bb        |    2 +-
 .../recipes-support/liburcu/liburcu_0.15.6.bb |    2 +-
 meta/recipes-support/lz4/lz4_1.10.0.bb        |    2 +-
 meta/recipes-support/nettle/nettle_4.0.bb     |    2 +-
 .../recipes-support/numactl/numactl_2.0.19.bb |    2 +-
 meta/recipes-support/re2c/re2c_4.5.1.bb       |    2 +-
 meta/recipes-support/taglib/taglib_2.3.bb     |    2 +-
 meta/recipes-support/utfcpp/utfcpp_4.1.1.bb   |    4 +-
 meta/recipes-support/vte/vte_0.84.0.bb        |    2 +-
 meta/recipes-support/xxhash/xxhash_0.8.3.bb   |    2 +-
 scripts/contrib/convert-spdx-licenses.py      |  254 ++-
 scripts/lib/recipetool/create.py              |  116 +-
 scripts/lib/recipetool/create_npm.py          |   13 +-
 scripts/pull-spdx-licenses.py                 |  124 +-
 353 files changed, 5087 insertions(+), 1895 deletions(-)
 create mode 100644 meta/files/common-licenses/389-exception
 create mode 100644 meta/files/common-licenses/Asterisk-exception
 create mode 100644 meta/files/common-licenses/Asterisk-linking-protocols-exception
 create mode 100644 meta/files/common-licenses/Autoconf-exception-2.0
 create mode 100644 meta/files/common-licenses/Autoconf-exception-3.0
 create mode 100644 meta/files/common-licenses/Autoconf-exception-generic
 create mode 100644 meta/files/common-licenses/Autoconf-exception-generic-3.0
 create mode 100644 meta/files/common-licenses/Autoconf-exception-macro
 create mode 100644 meta/files/common-licenses/Bison-exception-1.24
 create mode 100644 meta/files/common-licenses/Bison-exception-2.2
 create mode 100644 meta/files/common-licenses/Bootloader-exception
 create mode 100644 meta/files/common-licenses/CGAL-linking-exception
 create mode 100644 meta/files/common-licenses/CLISP-exception-2.0
 create mode 100644 meta/files/common-licenses/Classpath-exception-2.0
 create mode 100644 meta/files/common-licenses/Classpath-exception-2.0-short
 create mode 100644 meta/files/common-licenses/DigiRule-FOSS-exception
 create mode 100644 meta/files/common-licenses/Digia-Qt-LGPL-exception-1.1
 create mode 100644 meta/files/common-licenses/FLTK-exception
 create mode 100644 meta/files/common-licenses/Fawkes-Runtime-exception
 create mode 100644 meta/files/common-licenses/Font-exception-2.0
 create mode 100644 meta/files/common-licenses/GCC-exception-2.0
 create mode 100644 meta/files/common-licenses/GCC-exception-2.0-note
 create mode 100644 meta/files/common-licenses/GCC-exception-3.1
 create mode 100644 meta/files/common-licenses/GNAT-exception
 create mode 100644 meta/files/common-licenses/GNOME-examples-exception
 create mode 100644 meta/files/common-licenses/GNU-compiler-exception
 create mode 100644 meta/files/common-licenses/GPL-3.0-389-ds-base-exception
 create mode 100644 meta/files/common-licenses/GPL-3.0-interface-exception
 create mode 100644 meta/files/common-licenses/GPL-3.0-linking-exception
 create mode 100644 meta/files/common-licenses/GPL-3.0-linking-source-exception
 create mode 100644 meta/files/common-licenses/GPL-CC-1.0
 create mode 100644 meta/files/common-licenses/GStreamer-exception-2005
 create mode 100644 meta/files/common-licenses/GStreamer-exception-2008
 create mode 100644 meta/files/common-licenses/Gmsh-exception
 create mode 100644 meta/files/common-licenses/Independent-modules-exception
 create mode 100644 meta/files/common-licenses/KiCad-libraries-exception
 create mode 100644 meta/files/common-licenses/LGPL-3.0-linking-exception
 create mode 100644 meta/files/common-licenses/LLGPL
 create mode 100644 meta/files/common-licenses/LLVM-exception
 create mode 100644 meta/files/common-licenses/LZMA-exception
 create mode 100644 meta/files/common-licenses/Libtool-exception
 create mode 100644 meta/files/common-licenses/Linux-syscall-note
 create mode 100644 meta/files/common-licenses/OCCT-exception-1.0
 create mode 100644 meta/files/common-licenses/OCaml-LGPL-linking-exception
 create mode 100644 meta/files/common-licenses/OpenJDK-assembly-exception-1.0
 create mode 100644 meta/files/common-licenses/PCRE2-exception
 create mode 100644 meta/files/common-licenses/PS-or-PDF-font-exception-20170817
 create mode 100644 meta/files/common-licenses/QPL-1.0-INRIA-2004-exception
 create mode 100644 meta/files/common-licenses/Qt-GPL-exception-1.0
 create mode 100644 meta/files/common-licenses/Qt-LGPL-exception-1.1
 create mode 100644 meta/files/common-licenses/Qwt-exception-1.0
 create mode 100644 meta/files/common-licenses/RRDtool-FLOSS-exception-2.0
 create mode 100644 meta/files/common-licenses/SANE-exception
 create mode 100644 meta/files/common-licenses/SHL-2.0
 create mode 100644 meta/files/common-licenses/SHL-2.1
 create mode 100644 meta/files/common-licenses/SWI-exception
 create mode 100644 meta/files/common-licenses/Simple-Library-Usage-exception
 create mode 100644 meta/files/common-licenses/Swift-exception
 create mode 100644 meta/files/common-licenses/Texinfo-exception
 create mode 100644 meta/files/common-licenses/UBDL-exception
 create mode 100644 meta/files/common-licenses/Universal-FOSS-exception-1.0
 create mode 100644 meta/files/common-licenses/WxWindows-exception-3.1
 create mode 100644 meta/files/common-licenses/cryptsetup-OpenSSL-exception
 create mode 100644 meta/files/common-licenses/eCos-exception-2.0
 create mode 100644 meta/files/common-licenses/erlang-otp-linking-exception
 create mode 100644 meta/files/common-licenses/fmt-exception
 create mode 100644 meta/files/common-licenses/freertos-exception-2.0
 create mode 100644 meta/files/common-licenses/gnu-javamail-exception
 create mode 100644 meta/files/common-licenses/harbour-exception
 create mode 100644 meta/files/common-licenses/i2p-gpl-java-exception
 create mode 100644 meta/files/common-licenses/kvirc-openssl-exception
 create mode 100644 meta/files/common-licenses/libpri-OpenH323-exception
 create mode 100644 meta/files/common-licenses/mif-exception
 create mode 100644 meta/files/common-licenses/mxml-exception
 create mode 100644 meta/files/common-licenses/openvpn-openssl-exception
 create mode 100644 meta/files/common-licenses/polyparse-exception
 create mode 100644 meta/files/common-licenses/romic-exception
 create mode 100644 meta/files/common-licenses/rsync-linking-exception
 create mode 100644 meta/files/common-licenses/sqlitestudio-OpenSSL-exception
 create mode 100644 meta/files/common-licenses/stunnel-exception
 create mode 100644 meta/files/common-licenses/u-boot-exception-2.0
 create mode 100644 meta/files/common-licenses/vsftpd-openssl-exception
 create mode 100644 meta/files/common-licenses/x11vnc-openssl-exception
 create mode 100644 meta/files/spdx-exceptions.json
 create mode 100644 meta/lib/oe/spdx_license.py

-- 
2.54.0



^ permalink raw reply	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 01/22] scripts/pull-spdx-licenses.py: Add exceptions
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 02/22] Add SPDX License Exceptions Joshua Watt
                   ` (20 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Adds exceptions to the script that updates the SPDX license files

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 scripts/pull-spdx-licenses.py | 124 ++++++++++++++++++++++++----------
 1 file changed, 87 insertions(+), 37 deletions(-)

diff --git a/scripts/pull-spdx-licenses.py b/scripts/pull-spdx-licenses.py
index 597a62133f..7d1715ff24 100755
--- a/scripts/pull-spdx-licenses.py
+++ b/scripts/pull-spdx-licenses.py
@@ -13,6 +13,88 @@ from pathlib import Path
 TOP_DIR = Path(__file__).parent.parent
 
 
+def update_licenses(dest, version, overwrite, deprecated):
+    print(f"Pulling SPDX license list version {version}")
+    req = urllib.request.Request(
+        f"https://raw.githubusercontent.com/spdx/license-list-data/{version}/json/licenses.json"
+    )
+    with urllib.request.urlopen(req) as response:
+        spdx_licenses = json.load(response)
+
+    with (TOP_DIR / "meta" / "files" / "spdx-licenses.json").open("w") as f:
+        json.dump(spdx_licenses, f, sort_keys=True, indent=2)
+
+    total_count = len(spdx_licenses["licenses"])
+    updated = 0
+    for idx, lic in enumerate(spdx_licenses["licenses"]):
+        lic_id = lic["licenseId"]
+
+        print(f"[{idx + 1} of {total_count}] ", end="")
+
+        dest_license_file = dest / lic_id
+        if dest_license_file.is_file() and not overwrite:
+            print(f"Skipping {lic_id} since it already exists")
+            continue
+
+        print(f"Fetching {lic_id}... ", end="", flush=True)
+
+        req = urllib.request.Request(lic["detailsUrl"])
+        with urllib.request.urlopen(req) as response:
+            lic_data = json.load(response)
+
+        if lic_data["isDeprecatedLicenseId"] and not deprecated:
+            print("Skipping (deprecated)")
+            continue
+
+        with dest_license_file.open("w") as f:
+            f.write(lic_data["licenseText"])
+        updated += 1
+        print("done")
+
+    return updated
+
+
+def update_exceptions(dest, version, overwrite, deprecated):
+    print(f"Pulling SPDX license exceptions list version {version}")
+    req = urllib.request.Request(
+        f"https://raw.githubusercontent.com/spdx/license-list-data/{version}/json/exceptions.json"
+    )
+    with urllib.request.urlopen(req) as response:
+        spdx_exceptions = json.load(response)
+
+    with (TOP_DIR / "meta" / "files" / "spdx-exceptions.json").open("w") as f:
+        json.dump(spdx_exceptions, f, sort_keys=True, indent=2)
+
+    total_count = len(spdx_exceptions["exceptions"])
+    updated = 0
+    for idx, lic in enumerate(spdx_exceptions["exceptions"]):
+        lic_id = lic["licenseExceptionId"]
+
+        print(f"[{idx + 1} of {total_count}] ", end="")
+
+        dest_license_file = dest / lic_id
+        if dest_license_file.is_file() and not overwrite:
+            print(f"Skipping {lic_id} since it already exists")
+            continue
+
+        print(f"Fetching {lic_id}... ", end="", flush=True)
+
+        req = urllib.request.Request(lic["detailsUrl"])
+        with urllib.request.urlopen(req) as response:
+            lic_data = json.load(response)
+
+        if lic_data["isDeprecatedLicenseId"] and not deprecated:
+            print("Skipping (deprecated)")
+            continue
+
+        with dest_license_file.open("w") as f:
+            f.write(lic_data["licenseExceptionText"])
+        updated += 1
+        print("done")
+
+    return updated
+
+
 def main():
     parser = argparse.ArgumentParser(
         description="Update SPDX License files from upstream"
@@ -55,44 +137,12 @@ def main():
             data = json.load(response)
             version = data["tag_name"]
 
-    print(f"Pulling SPDX license list version {version}")
-    req = urllib.request.Request(
-        f"https://raw.githubusercontent.com/spdx/license-list-data/{version}/json/licenses.json"
+    license_count = update_licenses(args.dest, version, args.overwrite, args.deprecated)
+    exception_count = update_exceptions(
+        args.dest, version, args.overwrite, args.deprecated
     )
-    with urllib.request.urlopen(req) as response:
-        spdx_licenses = json.load(response)
-
-    with (TOP_DIR / "meta" / "files" / "spdx-licenses.json").open("w") as f:
-        json.dump(spdx_licenses, f, sort_keys=True, indent=2)
-
-    total_count = len(spdx_licenses["licenses"])
-    updated = 0
-    for idx, lic in enumerate(spdx_licenses["licenses"]):
-        lic_id = lic["licenseId"]
-
-        print(f"[{idx + 1} of {total_count}] ", end="")
-
-        dest_license_file = args.dest / lic_id
-        if dest_license_file.is_file() and not args.overwrite:
-            print(f"Skipping {lic_id} since it already exists")
-            continue
-
-        print(f"Fetching {lic_id}... ", end="", flush=True)
-
-        req = urllib.request.Request(lic["detailsUrl"])
-        with urllib.request.urlopen(req) as response:
-            lic_data = json.load(response)
-
-        if lic_data["isDeprecatedLicenseId"] and not args.deprecated:
-            print("Skipping (deprecated)")
-            continue
-
-        with dest_license_file.open("w") as f:
-            f.write(lic_data["licenseText"])
-        updated += 1
-        print("done")
-
-    print(f"Updated {updated} licenses")
+    print(f"Updated {license_count} licenses")
+    print(f"Updated {exception_count} exceptions")
 
     return 0
 
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 02/22] Add SPDX License Exceptions
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 01/22] scripts/pull-spdx-licenses.py: Add exceptions Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 03/22] Add SPDX license library Joshua Watt
                   ` (19 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Adds the JSON file that lists the SPDX license exceptions, as well as
the exception license files themselves.

This was done automatically using the pull-spdx-licenses.py script

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/files/common-licenses/389-exception      |   7 +
 meta/files/common-licenses/Asterisk-exception |   5 +
 .../Asterisk-linking-protocols-exception      |  13 +
 .../common-licenses/Autoconf-exception-2.0    |   5 +
 .../common-licenses/Autoconf-exception-3.0    |  26 +
 .../Autoconf-exception-generic                |   4 +
 .../Autoconf-exception-generic-3.0            |   6 +
 .../common-licenses/Autoconf-exception-macro  |  12 +
 .../common-licenses/Bison-exception-1.24      |   4 +
 .../files/common-licenses/Bison-exception-2.2 |   5 +
 .../common-licenses/Bootloader-exception      |  10 +
 .../common-licenses/CGAL-linking-exception    |   4 +
 .../files/common-licenses/CLISP-exception-2.0 |  15 +
 .../common-licenses/Classpath-exception-2.0   |   3 +
 .../Classpath-exception-2.0-short             |  11 +
 .../common-licenses/DigiRule-FOSS-exception   |  54 +
 .../Digia-Qt-LGPL-exception-1.1               |   9 +
 meta/files/common-licenses/FLTK-exception     |  17 +
 .../common-licenses/Fawkes-Runtime-exception  |   1 +
 meta/files/common-licenses/Font-exception-2.0 |   1 +
 meta/files/common-licenses/GCC-exception-2.0  |   1 +
 .../common-licenses/GCC-exception-2.0-note    |  16 +
 meta/files/common-licenses/GCC-exception-3.1  |  33 +
 meta/files/common-licenses/GNAT-exception     |   6 +
 .../common-licenses/GNOME-examples-exception  |   1 +
 .../common-licenses/GNU-compiler-exception    |   6 +
 .../GPL-3.0-389-ds-base-exception             |  10 +
 .../GPL-3.0-interface-exception               |   7 +
 .../common-licenses/GPL-3.0-linking-exception |   3 +
 .../GPL-3.0-linking-source-exception          |   3 +
 meta/files/common-licenses/GPL-CC-1.0         |  46 +
 .../common-licenses/GStreamer-exception-2005  |   1 +
 .../common-licenses/GStreamer-exception-2008  |   1 +
 meta/files/common-licenses/Gmsh-exception     |  16 +
 .../Independent-modules-exception             |  18 +
 .../common-licenses/KiCad-libraries-exception |   1 +
 .../LGPL-3.0-linking-exception                |  16 +
 meta/files/common-licenses/LLGPL              |  56 +
 meta/files/common-licenses/LLVM-exception     |  15 +
 meta/files/common-licenses/LZMA-exception     |   3 +
 meta/files/common-licenses/Libtool-exception  |   1 +
 meta/files/common-licenses/Linux-syscall-note |  12 +
 meta/files/common-licenses/OCCT-exception-1.0 |   3 +
 .../OCaml-LGPL-linking-exception              |   1 +
 .../OpenJDK-assembly-exception-1.0            |  31 +
 meta/files/common-licenses/PCRE2-exception    |   8 +
 .../PS-or-PDF-font-exception-20170817         |   8 +
 .../QPL-1.0-INRIA-2004-exception              |   5 +
 .../common-licenses/Qt-GPL-exception-1.0      |  21 +
 .../common-licenses/Qt-LGPL-exception-1.1     |  22 +
 meta/files/common-licenses/Qwt-exception-1.0  |  12 +
 .../RRDtool-FLOSS-exception-2.0               |  66 ++
 meta/files/common-licenses/SANE-exception     |  20 +
 meta/files/common-licenses/SHL-2.0            |  22 +
 meta/files/common-licenses/SHL-2.1            |  49 +
 meta/files/common-licenses/SWI-exception      |   7 +
 .../Simple-Library-Usage-exception            |  33 +
 meta/files/common-licenses/Swift-exception    |   6 +
 meta/files/common-licenses/Texinfo-exception  |   4 +
 meta/files/common-licenses/UBDL-exception     |  59 ++
 .../Universal-FOSS-exception-1.0              |  11 +
 .../common-licenses/WxWindows-exception-3.1   |   9 +
 .../cryptsetup-OpenSSL-exception              |  12 +
 meta/files/common-licenses/eCos-exception-2.0 |   3 +
 .../erlang-otp-linking-exception              |  11 +
 meta/files/common-licenses/fmt-exception      |   6 +
 .../common-licenses/freertos-exception-2.0    |  19 +
 .../common-licenses/gnu-javamail-exception    |   1 +
 meta/files/common-licenses/harbour-exception  |  23 +
 .../common-licenses/i2p-gpl-java-exception    |   1 +
 .../common-licenses/kvirc-openssl-exception   |  30 +
 .../common-licenses/libpri-OpenH323-exception |   4 +
 meta/files/common-licenses/mif-exception      |   1 +
 meta/files/common-licenses/mxml-exception     |  16 +
 .../common-licenses/openvpn-openssl-exception |   3 +
 .../files/common-licenses/polyparse-exception |   7 +
 meta/files/common-licenses/romic-exception    |   6 +
 .../common-licenses/rsync-linking-exception   |   6 +
 .../sqlitestudio-OpenSSL-exception            |   9 +
 meta/files/common-licenses/stunnel-exception  |   5 +
 .../common-licenses/u-boot-exception-2.0      |   6 +
 .../common-licenses/vsftpd-openssl-exception  |   5 +
 .../common-licenses/x11vnc-openssl-exception  |   9 +
 meta/files/spdx-exceptions.json               | 971 ++++++++++++++++++
 84 files changed, 2035 insertions(+)
 create mode 100644 meta/files/common-licenses/389-exception
 create mode 100644 meta/files/common-licenses/Asterisk-exception
 create mode 100644 meta/files/common-licenses/Asterisk-linking-protocols-exception
 create mode 100644 meta/files/common-licenses/Autoconf-exception-2.0
 create mode 100644 meta/files/common-licenses/Autoconf-exception-3.0
 create mode 100644 meta/files/common-licenses/Autoconf-exception-generic
 create mode 100644 meta/files/common-licenses/Autoconf-exception-generic-3.0
 create mode 100644 meta/files/common-licenses/Autoconf-exception-macro
 create mode 100644 meta/files/common-licenses/Bison-exception-1.24
 create mode 100644 meta/files/common-licenses/Bison-exception-2.2
 create mode 100644 meta/files/common-licenses/Bootloader-exception
 create mode 100644 meta/files/common-licenses/CGAL-linking-exception
 create mode 100644 meta/files/common-licenses/CLISP-exception-2.0
 create mode 100644 meta/files/common-licenses/Classpath-exception-2.0
 create mode 100644 meta/files/common-licenses/Classpath-exception-2.0-short
 create mode 100644 meta/files/common-licenses/DigiRule-FOSS-exception
 create mode 100644 meta/files/common-licenses/Digia-Qt-LGPL-exception-1.1
 create mode 100644 meta/files/common-licenses/FLTK-exception
 create mode 100644 meta/files/common-licenses/Fawkes-Runtime-exception
 create mode 100644 meta/files/common-licenses/Font-exception-2.0
 create mode 100644 meta/files/common-licenses/GCC-exception-2.0
 create mode 100644 meta/files/common-licenses/GCC-exception-2.0-note
 create mode 100644 meta/files/common-licenses/GCC-exception-3.1
 create mode 100644 meta/files/common-licenses/GNAT-exception
 create mode 100644 meta/files/common-licenses/GNOME-examples-exception
 create mode 100644 meta/files/common-licenses/GNU-compiler-exception
 create mode 100644 meta/files/common-licenses/GPL-3.0-389-ds-base-exception
 create mode 100644 meta/files/common-licenses/GPL-3.0-interface-exception
 create mode 100644 meta/files/common-licenses/GPL-3.0-linking-exception
 create mode 100644 meta/files/common-licenses/GPL-3.0-linking-source-exception
 create mode 100644 meta/files/common-licenses/GPL-CC-1.0
 create mode 100644 meta/files/common-licenses/GStreamer-exception-2005
 create mode 100644 meta/files/common-licenses/GStreamer-exception-2008
 create mode 100644 meta/files/common-licenses/Gmsh-exception
 create mode 100644 meta/files/common-licenses/Independent-modules-exception
 create mode 100644 meta/files/common-licenses/KiCad-libraries-exception
 create mode 100644 meta/files/common-licenses/LGPL-3.0-linking-exception
 create mode 100644 meta/files/common-licenses/LLGPL
 create mode 100644 meta/files/common-licenses/LLVM-exception
 create mode 100644 meta/files/common-licenses/LZMA-exception
 create mode 100644 meta/files/common-licenses/Libtool-exception
 create mode 100644 meta/files/common-licenses/Linux-syscall-note
 create mode 100644 meta/files/common-licenses/OCCT-exception-1.0
 create mode 100644 meta/files/common-licenses/OCaml-LGPL-linking-exception
 create mode 100644 meta/files/common-licenses/OpenJDK-assembly-exception-1.0
 create mode 100644 meta/files/common-licenses/PCRE2-exception
 create mode 100644 meta/files/common-licenses/PS-or-PDF-font-exception-20170817
 create mode 100644 meta/files/common-licenses/QPL-1.0-INRIA-2004-exception
 create mode 100644 meta/files/common-licenses/Qt-GPL-exception-1.0
 create mode 100644 meta/files/common-licenses/Qt-LGPL-exception-1.1
 create mode 100644 meta/files/common-licenses/Qwt-exception-1.0
 create mode 100644 meta/files/common-licenses/RRDtool-FLOSS-exception-2.0
 create mode 100644 meta/files/common-licenses/SANE-exception
 create mode 100644 meta/files/common-licenses/SHL-2.0
 create mode 100644 meta/files/common-licenses/SHL-2.1
 create mode 100644 meta/files/common-licenses/SWI-exception
 create mode 100644 meta/files/common-licenses/Simple-Library-Usage-exception
 create mode 100644 meta/files/common-licenses/Swift-exception
 create mode 100644 meta/files/common-licenses/Texinfo-exception
 create mode 100644 meta/files/common-licenses/UBDL-exception
 create mode 100644 meta/files/common-licenses/Universal-FOSS-exception-1.0
 create mode 100644 meta/files/common-licenses/WxWindows-exception-3.1
 create mode 100644 meta/files/common-licenses/cryptsetup-OpenSSL-exception
 create mode 100644 meta/files/common-licenses/eCos-exception-2.0
 create mode 100644 meta/files/common-licenses/erlang-otp-linking-exception
 create mode 100644 meta/files/common-licenses/fmt-exception
 create mode 100644 meta/files/common-licenses/freertos-exception-2.0
 create mode 100644 meta/files/common-licenses/gnu-javamail-exception
 create mode 100644 meta/files/common-licenses/harbour-exception
 create mode 100644 meta/files/common-licenses/i2p-gpl-java-exception
 create mode 100644 meta/files/common-licenses/kvirc-openssl-exception
 create mode 100644 meta/files/common-licenses/libpri-OpenH323-exception
 create mode 100644 meta/files/common-licenses/mif-exception
 create mode 100644 meta/files/common-licenses/mxml-exception
 create mode 100644 meta/files/common-licenses/openvpn-openssl-exception
 create mode 100644 meta/files/common-licenses/polyparse-exception
 create mode 100644 meta/files/common-licenses/romic-exception
 create mode 100644 meta/files/common-licenses/rsync-linking-exception
 create mode 100644 meta/files/common-licenses/sqlitestudio-OpenSSL-exception
 create mode 100644 meta/files/common-licenses/stunnel-exception
 create mode 100644 meta/files/common-licenses/u-boot-exception-2.0
 create mode 100644 meta/files/common-licenses/vsftpd-openssl-exception
 create mode 100644 meta/files/common-licenses/x11vnc-openssl-exception
 create mode 100644 meta/files/spdx-exceptions.json

diff --git a/meta/files/common-licenses/389-exception b/meta/files/common-licenses/389-exception
new file mode 100644
index 0000000000..fe5bff900a
--- /dev/null
+++ b/meta/files/common-licenses/389-exception
@@ -0,0 +1,7 @@
+This Program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
+
+This Program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this Program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+In addition, as a special exception, Red Hat, Inc. gives You the additional right to link the code of this Program with code not covered under the GNU General Public License ("Non-GPL Code") and to distribute linked combinations including the two, subject to the limitations in this paragraph. Non-GPL Code permitted under this exception must only link to the code of this Program through those well defined interfaces identified in the file named EXCEPTION found in the source code files (the "Approved Interfaces"). The files of Non-GPL Code may instantiate templates or use macros or inline functions from the Approved Interfaces without causing the resulting work to be covered by the GNU General Public License. Only Red Hat, Inc. may make changes or additions to the list of Approved Interfaces. You must obey the GNU General Public License in all respects for all of the Program code and other code used in conjunction with the Program except the Non-GPL Code covered by this exception. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to provide this exception without modification, you must delete this exception statement from your version and license this file solely under the GPL without exception.
diff --git a/meta/files/common-licenses/Asterisk-exception b/meta/files/common-licenses/Asterisk-exception
new file mode 100644
index 0000000000..88253f12d3
--- /dev/null
+++ b/meta/files/common-licenses/Asterisk-exception
@@ -0,0 +1,5 @@
+In addition, when this program is distributed with Asterisk in any 
+form that would qualify as a 'combined work' or as a 'derivative work' 
+(but not mere aggregation), you can redistribute and/or modify the 
+combination under the terms of the license provided with that copy 
+of Asterisk, instead of the license terms granted here.
diff --git a/meta/files/common-licenses/Asterisk-linking-protocols-exception b/meta/files/common-licenses/Asterisk-linking-protocols-exception
new file mode 100644
index 0000000000..6705829f47
--- /dev/null
+++ b/meta/files/common-licenses/Asterisk-linking-protocols-exception
@@ -0,0 +1,13 @@
+Specific permission is also granted to link Asterisk with OpenSSL, OpenH323
+UniMRCP, and/or the UW IMAP Toolkit and distribute the resulting binary files.
+
+In addition, Asterisk implements several management/control protocols.
+This includes the Asterisk Manager Interface (AMI), the Asterisk Gateway
+Interface (AGI), and the Asterisk REST Interface (ARI). It is our belief
+that applications using these protocols to manage or control an Asterisk
+instance do not have to be licensed under the GPL or a compatible license,
+as we believe these protocols do not create a 'derivative work' as referred
+to in the GPL. However, should any court or other judiciary body find that
+these protocols do fall under the terms of the GPL, then we hereby grant you a
+license to use these protocols in combination with Asterisk in external
+applications licensed under any license you wish.
diff --git a/meta/files/common-licenses/Autoconf-exception-2.0 b/meta/files/common-licenses/Autoconf-exception-2.0
new file mode 100644
index 0000000000..00cddeba4d
--- /dev/null
+++ b/meta/files/common-licenses/Autoconf-exception-2.0
@@ -0,0 +1,5 @@
+As a special exception, the Free Software Foundation gives unlimited permission to copy, distribute and modify the configure scripts that are the output of Autoconf. You need not follow the terms of the GNU General Public License when using or distributing such scripts, even though portions of the text of Autoconf appear in them. The GNU General Public License (GPL) does govern all other use of the material that constitutes the Autoconf program.
+
+Certain portions of the Autoconf source text are designed to be copied (in certain cases, depending on the input) into the output of Autoconf. We call these the "data" portions. The rest of the Autoconf source text consists of comments plus executable code that decides which of the data portions to output in any given case. We call these comments and executable code the "non-data" portions. Autoconf never copies any of the non-data portions into its output.
+
+This special exception to the GPL applies to versions of Autoconf released by the Free Software Foundation. When you make and distribute a modified version of Autoconf, you may extend this special exception to the GPL to apply to your modified version as well, *unless* your modified version has the potential to copy into its output some of the text that was the non-data portion of the version that you started with. (In other words, unless your change moves or copies text from the non-data portions to the data portions.) If your modification has such potential, you must delete any notice of this special exception to the GPL from your modified version.
diff --git a/meta/files/common-licenses/Autoconf-exception-3.0 b/meta/files/common-licenses/Autoconf-exception-3.0
new file mode 100644
index 0000000000..f212f9c7bc
--- /dev/null
+++ b/meta/files/common-licenses/Autoconf-exception-3.0
@@ -0,0 +1,26 @@
+AUTOCONF CONFIGURE SCRIPT EXCEPTION
+
+Version 3.0, 18 August 2009
+Copyright © 2009 Free Software Foundation, Inc. <http://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+This Exception is an additional permission under section 7 of the GNU General Public License, version 3 ("GPLv3"). It applies to a given file that bears a notice placed by the copyright holder of the file stating that the file is governed by GPLv3 along with this Exception.
+
+The purpose of this Exception is to allow distribution of Autoconf's typical output under terms of the recipient's choice (including proprietary).
+
+0. Definitions.
+
+"Covered Code" is the source or object code of a version of Autoconf that is a covered work under this License.
+
+"Normally Copied Code" for a version of Autoconf means all parts of its Covered Code which that version can copy from its code (i.e., not from its input file) into its minimally verbose, non-debugging and non-tracing output.
+
+"Ineligible Code" is Covered Code that is not Normally Copied Code.
+
+1. Grant of Additional Permission.
+
+You have permission to propagate output of Autoconf, even if such propagation would otherwise violate the terms of GPLv3. However, if by modifying Autoconf you cause any Ineligible Code of the version you received to become Normally Copied Code of your modified version, then you void this Exception for the resulting covered work. If you convey that resulting covered work, you must remove this Exception in accordance with the second paragraph of Section 7 of GPLv3.
+
+2. No Weakening of Autoconf Copyleft.
+
+The availability of this Exception does not imply any general presumption that third-party software is unaffected by the copyleft requirements of the license of Autoconf.
diff --git a/meta/files/common-licenses/Autoconf-exception-generic b/meta/files/common-licenses/Autoconf-exception-generic
new file mode 100644
index 0000000000..b39f827673
--- /dev/null
+++ b/meta/files/common-licenses/Autoconf-exception-generic
@@ -0,0 +1,4 @@
+As a special exception to the GNU General Public License, 
+if you distribute this file as part of a program that contains 
+a configuration script generated by Autoconf, you may include 
+it under the same distribution terms that you use for the rest of that program.
diff --git a/meta/files/common-licenses/Autoconf-exception-generic-3.0 b/meta/files/common-licenses/Autoconf-exception-generic-3.0
new file mode 100644
index 0000000000..2d3036772c
--- /dev/null
+++ b/meta/files/common-licenses/Autoconf-exception-generic-3.0
@@ -0,0 +1,6 @@
+As a special exception to the GNU General Public License, if you 
+distribute this file as part of a program that contains a  
+configuration script generated by Autoconf, you may include it under  
+the same distribution terms that you use for the rest of that 
+program.  This Exception is an additional permission under section 7  
+of the GNU General Public License, version 3 ("GPLv3").
diff --git a/meta/files/common-licenses/Autoconf-exception-macro b/meta/files/common-licenses/Autoconf-exception-macro
new file mode 100644
index 0000000000..8b5b4677f3
--- /dev/null
+++ b/meta/files/common-licenses/Autoconf-exception-macro
@@ -0,0 +1,12 @@
+As a special exception, the respective Autoconf Macro's copyright owner
+gives unlimited permission to copy, distribute and modify the configure
+scripts that are the output of Autoconf when processing the Macro. You
+need not follow the terms of the GNU General Public License when using
+or distributing such scripts, even though portions of the text of the
+Macro appear in them. The GNU General Public License (GPL) does govern
+all other use of the material that constitutes the Autoconf Macro.
+
+This special exception to the GPL applies to versions of the Autoconf
+Macro released by the Autoconf Archive. When you make and distribute a
+modified version of the Autoconf Macro, you may extend this special
+exception to the GPL to apply to your modified version as well.
diff --git a/meta/files/common-licenses/Bison-exception-1.24 b/meta/files/common-licenses/Bison-exception-1.24
new file mode 100644
index 0000000000..7f3c3009ee
--- /dev/null
+++ b/meta/files/common-licenses/Bison-exception-1.24
@@ -0,0 +1,4 @@
+As a special exception, when this file is copied by Bison into a
+Bison output file, you may use that output file without restriction.
+This special exception was added by the Free Software Foundation
+in version 1.24 of Bison.
diff --git a/meta/files/common-licenses/Bison-exception-2.2 b/meta/files/common-licenses/Bison-exception-2.2
new file mode 100644
index 0000000000..91140decee
--- /dev/null
+++ b/meta/files/common-licenses/Bison-exception-2.2
@@ -0,0 +1,5 @@
+Bison Exception
+
+As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception.
+
+This special exception was added by the Free Software Foundation in version 2.2 of Bison.
diff --git a/meta/files/common-licenses/Bootloader-exception b/meta/files/common-licenses/Bootloader-exception
new file mode 100644
index 0000000000..c557826705
--- /dev/null
+++ b/meta/files/common-licenses/Bootloader-exception
@@ -0,0 +1,10 @@
+Bootloader Exception
+--------------------
+
+In addition to the permissions in the GNU General Public License, the
+authors give you unlimited permission to link or embed compiled bootloader
+and related files into combinations with other programs, and to distribute
+those combinations without any restriction coming from the use of those
+files. (The General Public License restrictions do apply in other respects;
+for example, they cover modification of the files, and distribution when
+not linked into a combine executable.)
diff --git a/meta/files/common-licenses/CGAL-linking-exception b/meta/files/common-licenses/CGAL-linking-exception
new file mode 100644
index 0000000000..c6dbd55ca6
--- /dev/null
+++ b/meta/files/common-licenses/CGAL-linking-exception
@@ -0,0 +1,4 @@
+As a special exception, you have permission to link this library
+with the CGAL library (http://www.cgal.org) and distribute executables,
+as long as you follow the requirements of the GNU GPL in regard to
+all of the software in the executable aside from CGAL.
diff --git a/meta/files/common-licenses/CLISP-exception-2.0 b/meta/files/common-licenses/CLISP-exception-2.0
new file mode 100644
index 0000000000..9c981f9b97
--- /dev/null
+++ b/meta/files/common-licenses/CLISP-exception-2.0
@@ -0,0 +1,15 @@
+Summary:
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation; see file GNU-GPL.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+Note:
+
+This copyright does NOT cover user programs that run in CLISP and third-party packages not part of CLISP, if a) They only reference external symbols in CLISP's public packages that define API also provided by many other Common Lisp implementations (namely the packages COMMON-LISP, COMMON-LISP-USER, KEYWORD, CLOS, GRAY, EXT), i.e. if they don't rely on CLISP internals and would as well run in any other Common Lisp implementation. Or b) They only reference external symbols in CLISP's public packages that define API also provided by many other Common Lisp implementations (namely the packages COMMON-LISP, COMMON-LISP-USER, KEYWORD, CLOS, GRAY, EXT) and some external, not CLISP specific, symbols in third-party packages that are released with source code under a GPL compatible license and that run in a great number of Common Lisp implementations, i.e. if they rely on CLISP internals only to the extent needed for gaining some functionality also available in a great number of Common Lisp implementations. Such user programs are not covered by the term """"derived work"""" used in the GNU GPL. Neither is their compiled code, i.e. the result of compiling them by use of the function COMPILE-FILE. We refer to such user programs as """"independent work"""".
+
+You may copy and distribute memory image files generated by the function SAVEINITMEM, if it was generated only from CLISP and independent work, and provided that you accompany them, in the sense of section 3 of the GNU GPL, with the source code of CLISP - precisely the same CLISP version that was used to build the memory image -, the source or compiled code of the user programs needed to rebuild the memory image (source code for all the parts that are not independent work, see above), and a precise description how to rebuild the memory image from these.
+
+Foreign non-Lisp code that is linked with CLISP or loaded into CLISP through dynamic linking is not exempted from this copyright. I.e. such code, when distributed for use with CLISP, must be distributed under the GPL.
diff --git a/meta/files/common-licenses/Classpath-exception-2.0 b/meta/files/common-licenses/Classpath-exception-2.0
new file mode 100644
index 0000000000..1a0045415c
--- /dev/null
+++ b/meta/files/common-licenses/Classpath-exception-2.0
@@ -0,0 +1,3 @@
+Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination.
+
+As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
diff --git a/meta/files/common-licenses/Classpath-exception-2.0-short b/meta/files/common-licenses/Classpath-exception-2.0-short
new file mode 100644
index 0000000000..2e7df40484
--- /dev/null
+++ b/meta/files/common-licenses/Classpath-exception-2.0-short
@@ -0,0 +1,11 @@
+As a special exception, the copyright holders of this library give
+you permission to link this library with independent modules to
+produce an executable, regardless of the license terms of these
+independent modules, and to copy and distribute the resulting
+executable under terms of your choice, provided that you also
+meet, for each linked independent module, the terms and conditions
+of the license of that module. An independent module is a module
+which is not derived from or based on this library. If you modify
+this library, you may extend this exception to your version of
+the library, but you are not obligated to do so. If you do not
+wish to do so, delete this exception statement from your version.
diff --git a/meta/files/common-licenses/DigiRule-FOSS-exception b/meta/files/common-licenses/DigiRule-FOSS-exception
new file mode 100644
index 0000000000..2fa106b38e
--- /dev/null
+++ b/meta/files/common-licenses/DigiRule-FOSS-exception
@@ -0,0 +1,54 @@
+DigiRule Solutions’s FOSS License Exception Terms and Conditions
+
+1. Definitions.
+
+“Derivative Work” means a derivative work, as defined under applicable copyright law, formed entirely from the Program and one or more FOSS Applications.
+
+“FOSS Application” means a free and open source software application distributed subject to a license listed in the section below titled “FOSS License List.”
+
+“FOSS Notice” means a notice placed by DigiRule Solutions in a copy of the Client Libraries stating that such copy of the Client Libraries may be distributed under DigiRule Solutions's or FOSS License Exception.
+
+“Independent Work” means portions of the Derivative Work that are not derived from the Program and can reasonably be considered independent and separate works.
+
+“Program” means a copy of DigiRule Solutions’s Client Libraries that contain a FOSS Notice.
+
+2. A FOSS application developer (“you” or “your”) may distribute a Derivative Work provided that you and the Derivative Work meet all of the following conditions:
+
+     1. You obey the GPL in all respects for the Program and all portions (including modifications) of the Program included in the Derivative Work (provided that this condition does not apply to Independent Works);
+
+     2. The Derivative Work does not include any work licensed under the GPL other than the Program;
+
+     3. You distribute Independent Works subject to a license listed in the section below titled “FOSS License List”;
+
+     4. You distribute Independent Works in object code or executable form with the complete corresponding machine-readable source code on the same medium and under the same FOSS license applying to the object code or executable forms;
+
+     5. All works that are aggregated with the Program or the Derivative Work on a medium or volume of storage are not derivative works of the Program, Derivative Work or FOSS Application, and must reasonably be considered independent and separate works.
+
+3. DigiRule Solutions reserves all rights not expressly granted in these terms and conditions. If all of the above conditions are not met, then this FOSS License Exception does not apply to you or your Derivative Work.
+
+FOSS License List
+License Name Version(s)/Copyright Date
+Release Early Certified Software
+Academic Free License 2.0
+Apache Software License 1.0/1.1/2.0
+Apple Public Source License 2.0
+Artistic license From Perl 5.8.0
+BSD license “July 22 1999”
+Common Development and Distribution License (CDDL) 1.0
+Common Public License 1.0
+Eclipse Public License 1.0
+GNU Library or “Lesser” General Public License (LGPL) 2.0/2.1/3.0
+Jabber Open Source License 1.0
+MIT License (As listed in file MIT-License.txt) -
+Mozilla Public License (MPL) 1.0/1.1
+Open Software License 2.0
+OpenSSL license (with original SSLeay license) “2003” (“1998”)
+PHP License 3.0/3.01
+Python license (CNRI Python License) -
+Python Software Foundation License 2.1.1
+Sleepycat License “1999”
+University of Illinois/NCSA Open Source License -
+W3C License “2001”
+X11 License “2001”
+Zlib/libpng License -
+Zope Public License 2.0
diff --git a/meta/files/common-licenses/Digia-Qt-LGPL-exception-1.1 b/meta/files/common-licenses/Digia-Qt-LGPL-exception-1.1
new file mode 100644
index 0000000000..66cddd38aa
--- /dev/null
+++ b/meta/files/common-licenses/Digia-Qt-LGPL-exception-1.1
@@ -0,0 +1,9 @@
+Digia Qt LGPL Exception version 1.1
+
+As a special exception to the GNU Lesser General Public License version 2.1,
+the object code form of a "work that uses the Library" may incorporate material
+from a header file that is part of the Library. You may distribute such object
+code under terms of your choice, provided that the incorporated material (i)
+does not exceed more than 5% of the total size of the Library; and (ii) is
+limited to numerical parameters, data structure layouts, accessors, macros,
+inline functions and templates.
diff --git a/meta/files/common-licenses/FLTK-exception b/meta/files/common-licenses/FLTK-exception
new file mode 100644
index 0000000000..836c954b33
--- /dev/null
+++ b/meta/files/common-licenses/FLTK-exception
@@ -0,0 +1,17 @@
+The FLTK library and included programs are provided under the terms of the GNU Library General Public License (LGPL) with the following exceptions:
+
+Modifications to the FLTK configure script, config header file, and makefiles by themselves to support a specific platform do not constitute a modified or derivative work.
+
+The authors do request that such modifications be contributed to the FLTK project - send all contributions to "fltk-bugs@fltk.org".
+
+Widgets that are subclassed from FLTK widgets do not constitute a derivative work.
+
+Static linking of applications and widgets to the FLTK library does not constitute a derivative work and does not require the author to provide source code for the application or widget, use the shared FLTK libraries, or link their applications or widgets against a user-supplied version of FLTK.
+
+If you link the application or widget to a modified version of FLTK, then the changes to FLTK must be provided under the terms of the LGPL in sections 1, 2, and 4.
+
+You do not have to provide a copy of the FLTK license with programs that are linked to the FLTK library, nor do you have to identify the FLTK license in your program or documentation as required by section 6 of the LGPL.
+
+However, programs must still identify their use of FLTK. The following example statement can be included in user documentation to satisfy this requirement:
+
+[program/widget] is based in part on the work of the FLTK project (http://www.fltk.org).
diff --git a/meta/files/common-licenses/Fawkes-Runtime-exception b/meta/files/common-licenses/Fawkes-Runtime-exception
new file mode 100644
index 0000000000..0ec93c748b
--- /dev/null
+++ b/meta/files/common-licenses/Fawkes-Runtime-exception
@@ -0,0 +1 @@
+Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination. As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. Additionally if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License.
diff --git a/meta/files/common-licenses/Font-exception-2.0 b/meta/files/common-licenses/Font-exception-2.0
new file mode 100644
index 0000000000..a78eeae73c
--- /dev/null
+++ b/meta/files/common-licenses/Font-exception-2.0
@@ -0,0 +1 @@
+As a special exception, if you create a document which uses this font, and embed this font or unaltered portions of this font into the document, this font does not by itself cause the resulting document to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the document might be covered by the GNU General Public License. If you modify this font, you may extend this exception to your version of the font, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
diff --git a/meta/files/common-licenses/GCC-exception-2.0 b/meta/files/common-licenses/GCC-exception-2.0
new file mode 100644
index 0000000000..642ecdd736
--- /dev/null
+++ b/meta/files/common-licenses/GCC-exception-2.0
@@ -0,0 +1 @@
+In addition to the permissions in the GNU General Public License, the Free Software Foundation gives you unlimited permission to link the compiled version of this file into combinations with other programs, and to distribute those combinations without any restriction coming from the use of this file. (The General Public License restrictions do apply in other respects; for example, they cover modification of the file, and distribution when not linked into a combine executable.)
diff --git a/meta/files/common-licenses/GCC-exception-2.0-note b/meta/files/common-licenses/GCC-exception-2.0-note
new file mode 100644
index 0000000000..654099aac0
--- /dev/null
+++ b/meta/files/common-licenses/GCC-exception-2.0-note
@@ -0,0 +1,16 @@
+ In addition to the permissions in the GNU Lesser General Public
+   License, the Free Software Foundation gives you unlimited
+   permission to link the compiled version of this file with other
+   programs, and to distribute those programs without any restriction
+   coming from the use of this file. (The GNU Lesser General Public
+   License restrictions do apply in other respects; for example, they
+   cover modification of the file, and distribution when not linked
+   into another program.)
+
+   Note that people who make modified versions of this file are not
+   obligated to grant this special exception for their modified
+   versions; it is their choice whether to do so. The GNU Lesser
+   General Public License gives permission to release a modified
+   version without this exception; this exception also makes it
+   possible to release a modified version which carries forward this
+   exception.
diff --git a/meta/files/common-licenses/GCC-exception-3.1 b/meta/files/common-licenses/GCC-exception-3.1
new file mode 100644
index 0000000000..3d8345bec5
--- /dev/null
+++ b/meta/files/common-licenses/GCC-exception-3.1
@@ -0,0 +1,33 @@
+GCC RUNTIME LIBRARY EXCEPTION
+
+Version 3.1, 31 March 2009
+
+General information: http://www.gnu.org/licenses/gcc-exception.html
+Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+This GCC Runtime Library Exception ("Exception") is an additional permission under section 7 of the GNU General Public License, version 3 ("GPLv3"). It applies to a given file (the "Runtime Library") that bears a notice placed by the copyright holder of the file stating that the file is governed by GPLv3 along with this Exception.
+
+When you use GCC to compile a program, GCC may combine portions of certain GCC header files and runtime libraries with the compiled program. The purpose of this Exception is to allow compilation of non-GPL (including proprietary) programs to use, in this way, the header files and runtime libraries covered by this Exception.
+
+0. Definitions.
+
+A file is an "Independent Module" if it either requires the Runtime Library for execution after a Compilation Process, or makes use of an interface provided by the Runtime Library, but is not otherwise based on the Runtime Library.
+
+"GCC" means a version of the GNU Compiler Collection, with or without modifications, governed by version 3 (or a specified later version) of the GNU General Public License (GPL) with the option of using any subsequent versions published by the FSF.
+
+"GPL-compatible Software" is software whose conditions of propagation, modification and use would permit combination with GCC in accord with the license of GCC.
+
+"Target Code" refers to output from any compiler for a real or virtual target processor architecture, in executable form or suitable for input to an assembler, loader, linker and/or execution phase. Notwithstanding that, Target Code does not include data in any format that is used as a compiler intermediate representation, or used for producing a compiler intermediate representation.
+
+The "Compilation Process" transforms code entirely represented in non-intermediate languages designed for human-written code, and/or in Java Virtual Machine byte code, into Target Code. Thus, for example, use of source code generators and preprocessors need not be considered part of the Compilation Process, since the Compilation Process can be understood as starting with the output of the generators or preprocessors.
+
+A Compilation Process is "Eligible" if it is done using GCC, alone or with other GPL-compatible software, or if it is done without using any work based on GCC. For example, using non-GPL-compatible Software to optimize any GCC intermediate representations would not qualify as an Eligible Compilation Process.
+
+1. Grant of Additional Permission.
+
+You have permission to propagate a work of Target Code formed by combining the Runtime Library with Independent Modules, even if such propagation would otherwise violate the terms of GPLv3, provided that all Target Code was generated by Eligible Compilation Processes. You may then convey such a combination under terms of your choice, consistent with the licensing of the Independent Modules.
+
+2. No Weakening of GCC Copyleft.
+
+The availability of this Exception does not imply any general presumption that third-party software is unaffected by the copyleft requirements of the license of GCC.
diff --git a/meta/files/common-licenses/GNAT-exception b/meta/files/common-licenses/GNAT-exception
new file mode 100644
index 0000000000..2b5a96a62b
--- /dev/null
+++ b/meta/files/common-licenses/GNAT-exception
@@ -0,0 +1,6 @@
+As a special exception, if other files instantiate generics from this
+unit, or you link this unit with other files to produce an executable,
+this unit does not by itself cause the resulting executable to be
+covered by the GNU General Public License. This exception does not
+however invalidate any other reasons why the executable file might be
+covered by the GNU Public License.
diff --git a/meta/files/common-licenses/GNOME-examples-exception b/meta/files/common-licenses/GNOME-examples-exception
new file mode 100644
index 0000000000..0f0cd53b50
--- /dev/null
+++ b/meta/files/common-licenses/GNOME-examples-exception
@@ -0,0 +1 @@
+As a special exception, the copyright holders give you permission to copy, modify, and distribute the example code contained in this document under the terms of your choosing, without restriction.
diff --git a/meta/files/common-licenses/GNU-compiler-exception b/meta/files/common-licenses/GNU-compiler-exception
new file mode 100644
index 0000000000..684833ffb4
--- /dev/null
+++ b/meta/files/common-licenses/GNU-compiler-exception
@@ -0,0 +1,6 @@
+As a special exception, if you link this library with files
+compiled with a GNU compiler to produce an executable, this
+does not cause the resulting executable to be covered by
+the GNU General Public License. This exception does not
+however invalidate any other reasons why the executable
+file might be covered by the GNU General Public License.
diff --git a/meta/files/common-licenses/GPL-3.0-389-ds-base-exception b/meta/files/common-licenses/GPL-3.0-389-ds-base-exception
new file mode 100644
index 0000000000..52be470c10
--- /dev/null
+++ b/meta/files/common-licenses/GPL-3.0-389-ds-base-exception
@@ -0,0 +1,10 @@
+Additional permission under GPLv3 section 7:
+
+If you modify this Program, or any covered work, by
+linking or combining it with OpenSSL, or a modified
+version of OpenSSL licensed under the OpenSSL license
+(https://www.openssl.org/source/license.html), the licensors of this
+Program grant you additional permission to convey the resulting work.                                                                                                   
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts that are licensed
+under the OpenSSL license as well as that of the covered work.
diff --git a/meta/files/common-licenses/GPL-3.0-interface-exception b/meta/files/common-licenses/GPL-3.0-interface-exception
new file mode 100644
index 0000000000..a86a7fffd7
--- /dev/null
+++ b/meta/files/common-licenses/GPL-3.0-interface-exception
@@ -0,0 +1,7 @@
+Linking [name of library] statically or dynamically with other modules is making a combined work based on [name of library]. Thus, the terms and conditions of the GNU General Public License cover the whole combination.
+
+As a special exception, the copyright holders of [name of library] give you permission to combine [name of library] program with free software programs or libraries that are released under the GNU LGPL and with independent modules that communicate with [name of library] solely through the [name of library's interface] interface. You may copy and distribute such a system following the terms of the GNU GPL for [name of library] and the licenses of the other code concerned, provided that you include the source code of that other code when and as the GNU GPL requires distribution of source code and provided that you do not modify the [name of library's interface] interface.
+
+Note that people who make modified versions of [name of library] are not obligated to grant this special exception for their modified versions; it is their choice whether to do so. The GNU General Public License gives permission to release a modified version without this exception; this exception also makes it possible to release a modified version which carries forward this exception. If you modify the [name of library's interface] interface, this exception does not apply to your modified version of [name of library], and you must remove this exception when you distribute your modified version.
+
+This exception is an additional permission under section 7 of the GNU General Public License, version 3 ("GPLv3")
diff --git a/meta/files/common-licenses/GPL-3.0-linking-exception b/meta/files/common-licenses/GPL-3.0-linking-exception
new file mode 100644
index 0000000000..56096c0706
--- /dev/null
+++ b/meta/files/common-licenses/GPL-3.0-linking-exception
@@ -0,0 +1,3 @@
+Additional permission under GNU GPL version 3 section 7
+
+If you modify this Program, or any covered work, by linking or combining it with [name of library] (or a modified version of that library), containing parts covered by the terms of [name of library's license], the licensors of this Program grant you additional permission to convey the resulting work.
diff --git a/meta/files/common-licenses/GPL-3.0-linking-source-exception b/meta/files/common-licenses/GPL-3.0-linking-source-exception
new file mode 100644
index 0000000000..58a1d1b3a4
--- /dev/null
+++ b/meta/files/common-licenses/GPL-3.0-linking-source-exception
@@ -0,0 +1,3 @@
+Additional permission under GNU GPL version 3 section 7
+
+If you modify this Program, or any covered work, by linking or combining it with [name of library] (or a modified version of that library), containing parts covered by the terms of [name of library's license], the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of [name of library] used as well as that of the covered work.
diff --git a/meta/files/common-licenses/GPL-CC-1.0 b/meta/files/common-licenses/GPL-CC-1.0
new file mode 100644
index 0000000000..a687e0ddb6
--- /dev/null
+++ b/meta/files/common-licenses/GPL-CC-1.0
@@ -0,0 +1,46 @@
+GPL Cooperation Commitment
+Version 1.0
+
+Before filing or continuing to prosecute any legal proceeding or claim
+(other than a Defensive Action) arising from termination of a Covered
+License, we commit to extend to the person or entity ('you') accused
+of violating the Covered License the following provisions regarding
+cure and reinstatement, taken from GPL version 3. As used here, the
+term 'this License' refers to the specific Covered License being
+enforced.
+
+    However, if you cease all violation of this License, then your
+    license from a particular copyright holder is reinstated (a)
+    provisionally, unless and until the copyright holder explicitly
+    and finally terminates your license, and (b) permanently, if the
+    copyright holder fails to notify you of the violation by some
+    reasonable means prior to 60 days after the cessation.
+
+    Moreover, your license from a particular copyright holder is
+    reinstated permanently if the copyright holder notifies you of the
+    violation by some reasonable means, this is the first time you
+    have received notice of violation of this License (for any work)
+    from that copyright holder, and you cure the violation prior to 30
+    days after your receipt of the notice.
+
+We intend this Commitment to be irrevocable, and binding and
+enforceable against us and assignees of or successors to our
+copyrights.
+
+Definitions
+
+'Covered License' means the GNU General Public License, version 2
+(GPLv2), the GNU Lesser General Public License, version 2.1
+(LGPLv2.1), or the GNU Library General Public License, version 2
+(LGPLv2), all as published by the Free Software Foundation.
+
+'Defensive Action' means a legal proceeding or claim that We bring
+against you in response to a prior proceeding or claim initiated by
+you or your affiliate.
+
+'We' means each contributor to this repository as of the date of
+inclusion of this file, including subsidiaries of a corporate
+contributor.
+
+This work is available under a Creative Commons Attribution-ShareAlike
+4.0 International license (https://creativecommons.org/licenses/by-sa/4.0/).
diff --git a/meta/files/common-licenses/GStreamer-exception-2005 b/meta/files/common-licenses/GStreamer-exception-2005
new file mode 100644
index 0000000000..95ff750da3
--- /dev/null
+++ b/meta/files/common-licenses/GStreamer-exception-2005
@@ -0,0 +1 @@
+The Totem project hereby grant permission for non-gpl compatible GStreamer plugins to be used and distributed together with GStreamer and Totem. This permission are above and beyond the permissions granted by the GPL license Totem is covered by.
diff --git a/meta/files/common-licenses/GStreamer-exception-2008 b/meta/files/common-licenses/GStreamer-exception-2008
new file mode 100644
index 0000000000..28927e533e
--- /dev/null
+++ b/meta/files/common-licenses/GStreamer-exception-2008
@@ -0,0 +1 @@
+This project hereby grants permission for non-GPL compatible GStreamer plugins to be used and distributed together with GStreamer and this project. This permission is above and beyond the permissions granted by the GPL license by which this project is covered. If you modify this code, you may extend this exception to your version of the code, but you are not obligated to do so.  If you do not wish to do so, delete this exception statement from your version.
diff --git a/meta/files/common-licenses/Gmsh-exception b/meta/files/common-licenses/Gmsh-exception
new file mode 100644
index 0000000000..6d28f704e4
--- /dev/null
+++ b/meta/files/common-licenses/Gmsh-exception
@@ -0,0 +1,16 @@
+The copyright holders of Gmsh give you permission to combine Gmsh
+  with code included in the standard release of Netgen (from Joachim
+  Sch"oberl), METIS (from George Karypis at the University of
+  Minnesota), OpenCASCADE (from Open CASCADE S.A.S) and ParaView
+  (from Kitware, Inc.) under their respective licenses. You may copy
+  and distribute such a system following the terms of the GNU GPL for
+  Gmsh and the licenses of the other code concerned, provided that
+  you include the source code of that other code when and as the GNU
+  GPL requires distribution of source code.
+
+  Note that people who make modified versions of Gmsh are not
+  obligated to grant this special exception for their modified
+  versions; it is their choice whether to do so. The GNU General
+  Public License gives permission to release a modified version
+  without this exception; this exception also makes it possible to
+  release a modified version which carries forward this exception.
diff --git a/meta/files/common-licenses/Independent-modules-exception b/meta/files/common-licenses/Independent-modules-exception
new file mode 100644
index 0000000000..8f66dba6ab
--- /dev/null
+++ b/meta/files/common-licenses/Independent-modules-exception
@@ -0,0 +1,18 @@
+This is the file COPYING.FPC, it applies to the Free Pascal Run-Time Library 
+(RTL) and packages (packages) distributed by members of the Free Pascal 
+Development Team.
+
+The source code of the Free Pascal Runtime Libraries and packages are 
+distributed under the Library GNU General Public License 
+(see the file COPYING) with the following modification:
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent modules,
+and to copy and distribute the resulting executable under terms of your choice,
+provided that you also meet, for each linked independent module, the terms
+and conditions of the license of that module. An independent module is a module
+which is not derived from or based on this library. If you modify this
+library, you may extend this exception to your version of the library, but you are
+not obligated to do so. If you do not wish to do so, delete this exception
+statement from your version.
diff --git a/meta/files/common-licenses/KiCad-libraries-exception b/meta/files/common-licenses/KiCad-libraries-exception
new file mode 100644
index 0000000000..ae8854b119
--- /dev/null
+++ b/meta/files/common-licenses/KiCad-libraries-exception
@@ -0,0 +1 @@
+To the extent that the creation of electronic designs that use 'Licensed Material' can be considered to be 'Adapted Material', then the copyright holder waives article 3 of the license with respect to these designs and any generated files which use data provided as part of the 'Licensed Material'.
diff --git a/meta/files/common-licenses/LGPL-3.0-linking-exception b/meta/files/common-licenses/LGPL-3.0-linking-exception
new file mode 100644
index 0000000000..186456fb0e
--- /dev/null
+++ b/meta/files/common-licenses/LGPL-3.0-linking-exception
@@ -0,0 +1,16 @@
+As a special exception to the GNU Lesser General Public License version 3
+("LGPL3"), the copyright holders of this Library give you permission to
+convey to a third party a Combined Work that links statically or dynamically
+to this Library without providing any Minimal Corresponding Source or
+Minimal Application Code as set out in 4d or providing the installation
+information set out in section 4e, provided that you comply with the other
+provisions of LGPL3 and provided that you meet, for the Application the
+terms and conditions of the license(s) which apply to the Application.
+
+Except as stated in this special exception, the provisions of LGPL3 will
+continue to comply in full to this Library. If you modify this Library, you
+may apply this exception to your version of this Library, but you are not
+obliged to do so. If you do not wish to do so, delete this exception
+statement from your version. This exception does not (and cannot) modify any
+license terms which apply to the Application, with which you must still
+comply.
diff --git a/meta/files/common-licenses/LLGPL b/meta/files/common-licenses/LLGPL
new file mode 100644
index 0000000000..889d0b92e5
--- /dev/null
+++ b/meta/files/common-licenses/LLGPL
@@ -0,0 +1,56 @@
+Preamble to the Gnu Lesser General Public License
+
+Copyright (c) 2016 Franz Inc., Berkeley, CA 94704
+
+The concept of the GNU Lesser General Public License version 2.1 ("LGPL") 
+has been adopted to govern the use and distribution of above-mentioned 
+application. However, the LGPL uses terminology that is more appropriate 
+for a program written in C than one written in Lisp. Nevertheless, the
+LGPL can still be applied to a Lisp program if certain clarifications 
+are made. This document details those clarifications. Accordingly, the 
+license for the open-source Lisp applications consists of this document 
+plus the LGPL. Wherever there is a conflict between this document and 
+the LGPL, this document takes precedence over the LGPL.
+
+A "Library" in Lisp is a collection of Lisp functions, data and foreign 
+modules. The form of the Library can be Lisp source code (for processing 
+by an interpreter) or object code (usually the result of compilation of 
+source code or built with some other mechanisms). Foreign modules are 
+object code in a form that can be linked into a Lisp executable. When 
+we speak of functions we do so in the most general way to include, in 
+addition, methods and unnamed functions. Lisp "data" is also a general 
+term that includes the data structures resulting from defining Lisp 
+classes. A Lisp application may include the same set of Lisp objects 
+as does a Library, but this does not mean that the application is 
+necessarily a "work based on the Library" it contains.
+
+The Library consists of everything in the distribution file set before 
+any modifications are made to the files. If any of the functions or 
+classes in the Library are redefined in other files, then those 
+redefinitions ARE considered a work based on the Library. If additional 
+methods are added to generic functions in the Library, those additional 
+methods are NOT considered a work based on the Library. If Library classes 
+are subclassed, these subclasses are NOT considered a work based on the Library. 
+If the Library is modified to explicitly call other functions that are neither 
+part of Lisp itself nor an available add-on module to Lisp, then the functions 
+called by the modified Library ARE considered a work based on the Library. 
+The goal is to ensure that the Library will compile and run without getting 
+undefined function errors.
+
+It is permitted to add proprietary source code to the Library, but it must 
+be done in a way such that the Library will still run without that proprietary 
+code present. Section 5 of the LGPL distinguishes between the case of a 
+library being dynamically linked at runtime and one being statically linked 
+at build time. Section 5 of the LGPL states that the former results in an 
+executable that is a "work that uses the Library." Section 5 of the LGPL 
+states that the latter results in one that is a "derivative of the Library", 
+which is therefore covered by the LGPL. Since Lisp only offers one choice, 
+which is to link the Library into an executable at build time, we declare that, 
+for the purpose applying the LGPL to the Library, an executable that results 
+from linking a "work that uses the Library" with the Library is considered a 
+"work that uses the Library" and is therefore NOT covered by the LGPL.
+
+Because of this declaration, section 6 of LGPL is not applicable to the Library. 
+However, in connection with each distribution of this executable, you must also 
+deliver, in accordance with the terms and conditions of the LGPL, the source code 
+of Library (or your derivative thereof) that is incorporated into this executable.
diff --git a/meta/files/common-licenses/LLVM-exception b/meta/files/common-licenses/LLVM-exception
new file mode 100644
index 0000000000..fa4b725a0e
--- /dev/null
+++ b/meta/files/common-licenses/LLVM-exception
@@ -0,0 +1,15 @@
+---- LLVM Exceptions to the Apache 2.0 License ----
+
+   As an exception, if, as a result of your compiling your source code, portions
+   of this Software are embedded into an Object form of such source code, you
+   may redistribute such embedded portions in such Object form without complying
+   with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+   In addition, if you combine or link compiled forms of this Software with
+   software that is licensed under the GPLv2 ("Combined Software") and if a
+   court of competent jurisdiction determines that the patent provision (Section
+   3), the indemnity provision (Section 9) or other Section of the License
+   conflicts with the conditions of the GPLv2, you may retroactively and
+   prospectively choose to deem waived or otherwise exclude such Section(s) of
+   the License, but only in their entirety and only with respect to the Combined
+   Software.
diff --git a/meta/files/common-licenses/LZMA-exception b/meta/files/common-licenses/LZMA-exception
new file mode 100644
index 0000000000..6fc9c1352b
--- /dev/null
+++ b/meta/files/common-licenses/LZMA-exception
@@ -0,0 +1,3 @@
+I.6 Special exception for LZMA compression module
+
+Igor Pavlov and Amir Szekely, the authors of the LZMA compression module for NSIS, expressly permit you to statically or dynamically link your code (or bind by name) to the files from the LZMA compression module for NSIS without subjecting your linked code to the terms of the Common Public license version 1.0. Any modifications or additions to files from the LZMA compression module for NSIS, however, are subject to the terms of the Common Public License version 1.0.
diff --git a/meta/files/common-licenses/Libtool-exception b/meta/files/common-licenses/Libtool-exception
new file mode 100644
index 0000000000..729b1e9530
--- /dev/null
+++ b/meta/files/common-licenses/Libtool-exception
@@ -0,0 +1 @@
+As a special exception to the GNU General Public License, if you distribute this file as part of a program or library that is built using GNU Libtool, you may include this file under the same distribution terms that you use for the rest of that program.
diff --git a/meta/files/common-licenses/Linux-syscall-note b/meta/files/common-licenses/Linux-syscall-note
new file mode 100644
index 0000000000..fcd056364e
--- /dev/null
+++ b/meta/files/common-licenses/Linux-syscall-note
@@ -0,0 +1,12 @@
+   NOTE! This copyright does *not* cover user programs that use kernel
+ services by normal system calls - this is merely considered normal use
+ of the kernel, and does *not* fall under the heading of "derived work".
+ Also note that the GPL below is copyrighted by the Free Software
+ Foundation, but the instance of code that it refers to (the Linux
+ kernel) is copyrighted by me and others who actually wrote it.
+
+ Also note that the only valid version of the GPL as far as the kernel
+ is concerned is _this_ particular version of the license (ie v2, not
+ v2.2 or v3.x or whatever), unless explicitly otherwise stated.
+
+			Linus Torvalds
diff --git a/meta/files/common-licenses/OCCT-exception-1.0 b/meta/files/common-licenses/OCCT-exception-1.0
new file mode 100644
index 0000000000..d41c35bff5
--- /dev/null
+++ b/meta/files/common-licenses/OCCT-exception-1.0
@@ -0,0 +1,3 @@
+Open CASCADE Exception (version 1.0) to GNU LGPL version 2.1.
+
+The object code (i.e. not a source) form of a "work that uses the Library" can incorporate material from a header file that is part of the Library. As a special exception to the GNU Lesser General Public License version 2.1, you may distribute such object code incorporating material from header files provided with the Open CASCADE Technology libraries (including code of CDL generic classes) under terms of your choice, provided that you give prominent notice in supporting documentation to this code that it makes use of or is based on facilities provided by the Open CASCADE Technology software.
diff --git a/meta/files/common-licenses/OCaml-LGPL-linking-exception b/meta/files/common-licenses/OCaml-LGPL-linking-exception
new file mode 100644
index 0000000000..7fc88d7307
--- /dev/null
+++ b/meta/files/common-licenses/OCaml-LGPL-linking-exception
@@ -0,0 +1 @@
+As a special exception to the GNU Lesser General Public License, you may link, statically or dynamically, a "work that uses the OCaml Core System" with a publicly distributed version of the OCaml Core System to produce an executable file containing portions of the OCaml Core System, and distribute that executable file under terms of your choice, without any of the additional requirements listed in clause 6 of the GNU Lesser General Public License. By "a publicly distributed version of the OCaml Core System", we mean either the unmodified OCaml Core System as distributed by INRIA, or a modified version of the OCaml Core System that is distributed under the conditions defined in clause 2 of the GNU Lesser General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU Lesser General Public License.
diff --git a/meta/files/common-licenses/OpenJDK-assembly-exception-1.0 b/meta/files/common-licenses/OpenJDK-assembly-exception-1.0
new file mode 100644
index 0000000000..3a35f11ed2
--- /dev/null
+++ b/meta/files/common-licenses/OpenJDK-assembly-exception-1.0
@@ -0,0 +1,31 @@
+The OpenJDK source code made available by Oracle America, Inc.
+(Oracle) at openjdk.java.net ("OpenJDK Code") is distributed
+under the terms of the GNU General Public License
+<http://www.gnu.org/copyleft/gpl.html> version 2 only
+("GPL2"), with the following clarification and special
+exception.
+
+Linking this OpenJDK Code statically or dynamically with
+other code is making a combined work based on this
+library. Thus, the terms and conditions of GPL2 cover the
+whole combination.
+
+As a special exception, Oracle gives you permission to
+link this OpenJDK Code with certain code licensed by
+Oracle as indicated at
+http://openjdk.java.net/legal/exception-modules-2007-05-08.html
+("Designated Exception Modules") to produce an
+executable, regardless of the license terms of the
+Designated Exception Modules, and to copy and distribute
+the resulting executable under GPL2, provided that the
+Designated Exception Modules continue to be governed by
+the licenses under which they were offered by Oracle.
+
+As such, it allows licensees and sublicensees of Oracle's GPL2
+OpenJDK Code to build an executable that includes those
+portions of necessary code that Oracle could not provide under
+GPL2 (or that Oracle has provided under GPL2 with the Classpath
+exception). If you modify or add to the OpenJDK code, that new
+GPL2 code may still be combined with Designated Exception
+Modules if the new code is made subject to this exception by
+its copyright holder.
diff --git a/meta/files/common-licenses/PCRE2-exception b/meta/files/common-licenses/PCRE2-exception
new file mode 100644
index 0000000000..eb7fd11767
--- /dev/null
+++ b/meta/files/common-licenses/PCRE2-exception
@@ -0,0 +1,8 @@
+EXEMPTION FOR BINARY LIBRARY-LIKE PACKAGES
+------------------------------------------
+
+The second condition in the BSD licence (covering binary redistributions) does
+not apply all the way down a chain of software. If binary package A includes
+PCRE2, it must respect the condition, but if package B is software that
+includes package A, the condition is not imposed on package B unless it uses
+PCRE2 independently.
diff --git a/meta/files/common-licenses/PS-or-PDF-font-exception-20170817 b/meta/files/common-licenses/PS-or-PDF-font-exception-20170817
new file mode 100644
index 0000000000..cf22439fff
--- /dev/null
+++ b/meta/files/common-licenses/PS-or-PDF-font-exception-20170817
@@ -0,0 +1,8 @@
+The font and related files in this directory are distributed under the
+GNU AFFERO GENERAL PUBLIC LICENSE Version 3 (see the file COPYING), with
+the following exemption:
+
+As a special exception, permission is granted to include these font
+programs in a Postscript or PDF file that consists of a document that
+contains text to be displayed or printed using this font, regardless
+of the conditions or license applying to the document itself.
diff --git a/meta/files/common-licenses/QPL-1.0-INRIA-2004-exception b/meta/files/common-licenses/QPL-1.0-INRIA-2004-exception
new file mode 100644
index 0000000000..2418a26377
--- /dev/null
+++ b/meta/files/common-licenses/QPL-1.0-INRIA-2004-exception
@@ -0,0 +1,5 @@
+As a special exception to the Q Public Licence, you may develop
+application programs, reusable components and other software items
+that link with the original or modified versions of the Software
+and are not made available to the general public, without any of the
+additional requirements listed in clause 6c of the Q Public licence.
diff --git a/meta/files/common-licenses/Qt-GPL-exception-1.0 b/meta/files/common-licenses/Qt-GPL-exception-1.0
new file mode 100644
index 0000000000..761d0327a4
--- /dev/null
+++ b/meta/files/common-licenses/Qt-GPL-exception-1.0
@@ -0,0 +1,21 @@
+The Qt Company GPL Exception 1.0
+
+Exception 1:
+
+As a special exception you may create a larger work which contains the
+output of this application and distribute that work under terms of your
+choice, so long as the work is not otherwise derived from or based on
+this application and so long as the work does not in itself generate
+output that contains the output from this application in its original
+or modified form.
+
+Exception 2:
+
+As a special exception, you have permission to combine this application
+with Plugins licensed under the terms of your choice, to produce an
+executable, and to copy and distribute the resulting executable under
+the terms of your choice. However, the executable must be accompanied
+by a prominent notice offering all users of the executable the entire
+source code to this application, excluding the source code of the
+independent modules, but including any changes you have made to this
+application, under the terms of this license.
diff --git a/meta/files/common-licenses/Qt-LGPL-exception-1.1 b/meta/files/common-licenses/Qt-LGPL-exception-1.1
new file mode 100644
index 0000000000..bd94b5538f
--- /dev/null
+++ b/meta/files/common-licenses/Qt-LGPL-exception-1.1
@@ -0,0 +1,22 @@
+The Qt Company Qt LGPL Exception version 1.1
+
+As an additional permission to the GNU Lesser General Public License version
+2.1, the object code form of a "work that uses the Library" may incorporate
+material from a header file that is part of the Library.  You may distribute
+such object code under terms of your choice, provided that:
+    (i)   the header files of the Library have not been modified; and
+    (ii)  the incorporated material is limited to numerical parameters, data
+          structure layouts, accessors, macros, inline functions and
+          templates; and
+    (iii) you comply with the terms of Section 6 of the GNU Lesser General
+          Public License version 2.1.
+
+Moreover, you may apply this exception to a modified version of the Library,
+provided that such modification does not involve copying material from the
+Library into the modified Library's header files unless such material is
+limited to (i) numerical parameters; (ii) data structure layouts;
+(iii) accessors; and (iv) small macros, templates and inline functions of
+five lines or less in length.
+
+Furthermore, you are not required to apply this additional permission to a
+modified version of the Library.
diff --git a/meta/files/common-licenses/Qwt-exception-1.0 b/meta/files/common-licenses/Qwt-exception-1.0
new file mode 100644
index 0000000000..b45cdd0b54
--- /dev/null
+++ b/meta/files/common-licenses/Qwt-exception-1.0
@@ -0,0 +1,12 @@
+Qwt License Version 1.0,
+January 1, 2003
+
+The Qwt library and included programs are provided under the terms of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL) with the following exceptions:
+
+1. Widgets that are subclassed from Qwt widgets do not constitute a derivative work.
+
+2. Static linking of applications and widgets to the Qwt library does not constitute a derivative work and does not require the author to provide source code for the application or widget, use the shared Qwt libraries, or link their applications or widgets against a user-supplied version of Qwt. If you link the application or widget to a modified version of Qwt, then the changes to Qwt must be provided under the terms of the LGPL in sections 1, 2, and 4.
+
+3. You do not have to provide a copy of the Qwt license with programs that are linked to the Qwt library, nor do you have to identify the Qwt license in your program or documentation as required by section 6 of the LGPL.
+
+However, programs must still identify their use of Qwt. The following example statement can be included in user documentation to satisfy this requirement: [program/widget] is based in part on the work of the Qwt project (http://qwt.sf.net)."
diff --git a/meta/files/common-licenses/RRDtool-FLOSS-exception-2.0 b/meta/files/common-licenses/RRDtool-FLOSS-exception-2.0
new file mode 100644
index 0000000000..d88dae5868
--- /dev/null
+++ b/meta/files/common-licenses/RRDtool-FLOSS-exception-2.0
@@ -0,0 +1,66 @@
+FLOSS License Exception 
+=======================
+(Adapted from http://www.mysql.com/company/legal/licensing/foss-exception.html)
+
+I want specified Free/Libre and Open Source Software ("FLOSS")
+applications to be able to use specified GPL-licensed RRDtool
+libraries (the "Program") despite the fact that not all FLOSS licenses are
+compatible with version 2 of the GNU General Public License (the "GPL").
+
+As a special exception to the terms and conditions of version 2.0 of the GPL:
+
+You are free to distribute a Derivative Work that is formed entirely from
+the Program and one or more works (each, a "FLOSS Work") licensed under one
+or more of the licenses listed below, as long as:
+
+1. You obey the GPL in all respects for the Program and the Derivative
+Work, except for identifiable sections of the Derivative Work which are
+not derived from the Program, and which can reasonably be considered
+independent and separate works in themselves,
+
+2. all identifiable sections of the Derivative Work which are not derived
+from the Program, and which can reasonably be considered independent and
+separate works in themselves,
+
+1. are distributed subject to one of the FLOSS licenses listed
+below, and
+
+2. the object code or executable form of those sections are
+accompanied by the complete corresponding machine-readable source
+code for those sections on the same medium and under the same FLOSS
+license as the corresponding object code or executable forms of
+those sections, and
+
+3. any works which are aggregated with the Program or with a Derivative
+Work on a volume of a storage or distribution medium in accordance with
+the GPL, can reasonably be considered independent and separate works in
+themselves which are not derivatives of either the Program, a Derivative
+Work or a FLOSS Work.
+
+If the above conditions are not met, then the Program may only be copied,
+modified, distributed or used under the terms and conditions of the GPL.
+
+FLOSS License List
+==================
+License name	Version(s)/Copyright Date
+Academic Free License		2.0
+Apache Software License	1.0/1.1/2.0
+Apple Public Source License	2.0
+Artistic license		From Perl 5.8.0
+BSD license			"July 22 1999"
+Common Public License		1.0
+GNU Library or "Lesser" General Public License (LGPL)	2.0/2.1
+IBM Public License, Version    1.0
+Jabber Open Source License	1.0
+MIT License (As listed in file MIT-License.txt)	-
+Mozilla Public License (MPL)	1.0/1.1
+Open Software License		2.0
+OpenSSL license (with original SSLeay license)	"2003" ("1998")
+PHP License			3.01
+Python license (CNRI Python License)	-
+Python Software Foundation License	2.1.1
+Sleepycat License		"1999"
+W3C License			"2001"
+X11 License			"2001"
+Zlib/libpng License		-
+Zope Public License		2.0/2.1
diff --git a/meta/files/common-licenses/SANE-exception b/meta/files/common-licenses/SANE-exception
new file mode 100644
index 0000000000..198a8c67cc
--- /dev/null
+++ b/meta/files/common-licenses/SANE-exception
@@ -0,0 +1,20 @@
+As a special exception, the authors of sane-airscan give permission for
+additional uses of the libraries contained in this release of sane-airscan.
+
+The exception is that, if you link a sane-airscan library with other files
+to produce an executable, this does not by itself cause the
+resulting executable to be covered by the GNU General Public
+License. Your use of that executable is in no way restricted on
+account of linking the sane-airscan library code into it.
+
+This exception does not, however, invalidate any other reasons why
+the executable file might be covered by the GNU General Public
+License.
+
+If you submit changes to sane-airscan to the maintainers to be included in
+a subsequent release, you agree by submitting the changes that
+those changes may be distributed with this exception intact.
+
+If you write modifications of your own for sane-airscan, it is your choice
+whether to permit this exception to apply to your modifications.
+If you do not wish that, delete this exception notice.
diff --git a/meta/files/common-licenses/SHL-2.0 b/meta/files/common-licenses/SHL-2.0
new file mode 100644
index 0000000000..9218b47a72
--- /dev/null
+++ b/meta/files/common-licenses/SHL-2.0
@@ -0,0 +1,22 @@
+# Solderpad Hardware Licence Version 2.0
+
+This licence (the “Licence”) operates as a wraparound licence to the Apache License Version 2.0 (the “Apache License”) and grants to You the rights, and imposes the obligations, set out in the Apache License (which can be found here: http://apache.org/licenses/LICENSE-2.0), with the following extensions. It must be read in conjunction with the Apache License. Section 1 below modifies definitions in the Apache License, and section 2 below replaces sections 2 of the Apache License. You may, at your option, choose to treat any Work released under this License as released under the Apache License (thus ignoring all sections written below entirely). Words in italics indicate changes rom the Apache License, but are indicative and not to be taken into account in interpretation.
+
+1. The definitions set out in the Apache License are modified as follows:
+
+Copyright any reference to ‘copyright’ (whether capitalised or not) includes ‘Rights’ (as defined below).
+
+Contribution also includes any design, as well as any work of authorship.
+
+Derivative Works shall not include works that remain reversibly separable from, or merely link (or bind by name) or physically connect to or interoperate with the interfaces of the Work and Derivative Works thereof.
+
+Object form shall mean any form resulting from mechanical transformation or translation of a Source form or the application of a Source form to physical material, including but not limited to compiled object code, generated documentation, the instantiation of a hardware design or physical object and conversions to other media types, including intermediate forms such as bytecodes, FPGA bitstreams, moulds, artwork and semiconductor topographies (mask works).
+
+Rights means copyright and any similar right including design right (whether registered or unregistered), semiconductor topography (mask) rights and database rights (but excluding Patents and Trademarks).
+
+Source form shall mean the preferred form for making modifications, including but not limited to source code, net lists, board layouts, CAD files, documentation source, and configuration files.
+Work also includes a design or work of authorship, whether in Source form or other Object form.
+
+2. Grant of Licence
+
+2.1 Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable license under the Rights to reproduce, prepare Derivative Works of, make, adapt, repair, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form and do anything in relation to the Work as if the Rights did not exist.
diff --git a/meta/files/common-licenses/SHL-2.1 b/meta/files/common-licenses/SHL-2.1
new file mode 100644
index 0000000000..de45054588
--- /dev/null
+++ b/meta/files/common-licenses/SHL-2.1
@@ -0,0 +1,49 @@
+SOLDERPAD HARDWARE LICENSE VERSION 2.1
+
+This license operates as a wraparound license to the Apache License Version 2.0 (the "Apache License") and incorporates the terms and conditions of the Apache License (which can be found here: http://apache.org/licenses/LICENSE-2.0), with the following additions and modifications. It must be read in conjunction with the Apache License. Section 1 below modifies definitions and terminology in the Apache License and Section 2 below replaces Section 2 of the Apache License. The Appendix replaces the Appendix in the Apache License. You may, at your option, choose to treat any Work released under this license as released under the Apache License (thus ignoring all sections written below entirely).
+
+1.	Terminology in the Apache License is supplemented or modified as follows:
+
+"Authorship": any reference to 'authorship' shall be taken to read "authorship or design".
+
+"Copyright owner": any reference to 'copyright owner' shall be taken to read "Rights owner".
+
+"Copyright statement": the reference to 'copyright statement' shall be taken to read 'copyright or other statement pertaining to Rights'
+
+The following new definition shall be added to the Definitions section of the Apache License:
+
+"Rights" means copyright and any similar right including design right (whether registered or unregistered), rights in semiconductor topographies (mask works) and database rights (but excluding Patents and Trademarks).
+
+The following definitions shall replace the corresponding definitions in the Apache License:
+
+"License" shall mean this Solderpad Hardware License version 2.1, being the terms and conditions for use, manufacture, instantiation, adaptation, reproduction, and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the Rights owner or entity authorized by the Rights owner that is granting the License.
+ 
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship or design. For the purposes of this License, Derivative Works shall not include works that remain reversibly separable from, or merely link (or bind by name) or physically connect to or interoperate with the Work and Derivative Works thereof.
+
+"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form or the application of a Source form to physical material, including but not limited to compiled object code, generated documentation, the instantiation of a hardware design or physical object or material and conversions to other media types, including intermediate forms such as bytecodes, FPGA bitstreams, moulds, artwork and semiconductor topographies (mask works).
+
+"Source" form shall mean the preferred form for making modifications, including but not limited to source code, net lists, board layouts, CAD files, documentation source, and configuration files.
+
+"Work" shall mean the work of authorship or design, whether in Source or Object form, made available under the License, as indicated by a notice relating to Rights that is included in or attached to the work (an example is provided in the Appendix below).
+
+2.	Grant of License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable license under the Rights to reproduce, prepare Derivative Works of, make, adapt, repair, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form and do anything in relation to the Work as if the Rights did not exist.
+
+
+APPENDIX
+
+Copyright [yyyy] [name of copyright owner]
+SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
+
+Licensed under the Solderpad Hardware License v 2.1 (the "License"); you may not use this file except in compliance with the License, or, at your option, the Apache License version 2.0.
+You may obtain a copy of the License at
+
+https://solderpad.org/licenses/SHL-2.1/
+   
+Unless required by applicable law or agreed to in writing, any work distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and limitations under the License.
+
+
+
+
diff --git a/meta/files/common-licenses/SWI-exception b/meta/files/common-licenses/SWI-exception
new file mode 100644
index 0000000000..f2d1482789
--- /dev/null
+++ b/meta/files/common-licenses/SWI-exception
@@ -0,0 +1,7 @@
+As a special exception, if you link this library with other files,
+compiled with a Free Software compiler, to produce an executable, this
+library does not by itself cause the resulting executable to be covered
+by the GNU General Public License. This exception does not however
+invalidate any other reasons why the executable file might be covered by
+the GNU General Public License.
+
diff --git a/meta/files/common-licenses/Simple-Library-Usage-exception b/meta/files/common-licenses/Simple-Library-Usage-exception
new file mode 100644
index 0000000000..2db2bbe10f
--- /dev/null
+++ b/meta/files/common-licenses/Simple-Library-Usage-exception
@@ -0,0 +1,33 @@
+EXCEPTION NOTICE
+
+1. As a special exception, the copyright holders of this library give
+permission for additional uses of the text contained in this release
+of the library as licensed under the Simple Library Usage License,
+applying either version 1 of the License, or (at your option) any
+later version of the License as published by the copyright holders of
+version 1 of the License document.
+
+2. The exception is that you may combine or link a "work that uses the
+Library" (as defined by the LGPL) with the Library to produce a work
+containing portions of the Library in binary form, and distribute that
+work under terms of your choice, provided that:
+
+  a) You give prominent notice with each copy of the work that the
+  Library is used in it.
+
+  b) If the work during execution displays copyright notices, you must
+  include the copyright notice for the Library among them.
+
+3. If you copy code from files distributed under the terms of the GNU
+General Public License or the GNU Lesser General Public License into a
+copy of this library, as this license permits, the exception does not
+apply to the code that you add in this way.  To avoid misleading
+anyone as to the status of such modified files, you must delete this
+exception notice from such code and/or adjust the licensing conditions
+notice accordingly.
+
+4. If you write modifications of your own for this library, it is your
+choice whether to permit this exception to apply to your
+modifications.  If you do not wish that, you must delete the exception
+notice from such code and/or adjust the licensing conditions notice
+accordingly.
diff --git a/meta/files/common-licenses/Swift-exception b/meta/files/common-licenses/Swift-exception
new file mode 100644
index 0000000000..32b573cea5
--- /dev/null
+++ b/meta/files/common-licenses/Swift-exception
@@ -0,0 +1,6 @@
+### Runtime Library Exception to the Apache 2.0 License: ###
+
+As an exception, if you use this Software to compile your source code and
+portions of this Software are embedded into the binary product as a result,
+you may redistribute such product without providing attribution as would
+otherwise be required by Sections 4(a), 4(b) and 4(d) of the License.
diff --git a/meta/files/common-licenses/Texinfo-exception b/meta/files/common-licenses/Texinfo-exception
new file mode 100644
index 0000000000..931a4070b4
--- /dev/null
+++ b/meta/files/common-licenses/Texinfo-exception
@@ -0,0 +1,4 @@
+As a special exception, when this file is read by TeX when
+processing a Texinfo source document, you may use the result without
+restriction. This Exception is an additional permission under
+section 7 of the GNU General Public License, version 3 ("GPLv3").
diff --git a/meta/files/common-licenses/UBDL-exception b/meta/files/common-licenses/UBDL-exception
new file mode 100644
index 0000000000..780ddcd775
--- /dev/null
+++ b/meta/files/common-licenses/UBDL-exception
@@ -0,0 +1,59 @@
+UNMODIFIED BINARY DISTRIBUTION LICENCE
+
+
+PREAMBLE
+
+The GNU General Public License provides a legal guarantee that
+software covered by it remains free (in the sense of freedom, not
+price).  It achieves this guarantee by imposing obligations on anyone
+who chooses to distribute the software.
+
+Some of these obligations may be seen as unnecessarily burdensome.  In
+particular, when the source code for the software is already publicly
+and freely available, there is minimal value in imposing upon each
+distributor the obligation to provide the complete source code (or an
+equivalent written offer to provide the complete source code).
+
+This Licence allows for the distribution of unmodified binaries built
+from publicly available source code, without imposing the obligations
+of the GNU General Public License upon anyone who chooses to
+distribute only the unmodified binaries built from that source code.
+
+The extra permissions granted by this Licence apply only to unmodified
+binaries built from source code which has already been made available
+to the public in accordance with the terms of the GNU General Public
+Licence.  Nothing in this Licence allows for the creation of
+closed-source modified versions of the Program.  Any modified versions
+of the Program are subject to the usual terms and conditions of the
+GNU General Public License.
+
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+This Licence applies to any Program or other work which contains a
+notice placed by the copyright holder saying it may be distributed
+under the terms of this Unmodified Binary Distribution Licence.  All
+terms used in the text of this Licence are to be interpreted as they
+are used in version 2 of the GNU General Public License as published
+by the Free Software Foundation.
+
+If you have made this Program available to the public in both source
+code and executable form in accordance with the terms of the GNU
+General Public License as published by the Free Software Foundation;
+either version 2 of the License, or (at your option) any later
+version, then you are hereby granted an additional permission to use,
+copy, and distribute the unmodified executable form of this Program
+(the "Unmodified Binary") without restriction, including the right to
+permit persons to whom the Unmodified Binary is furnished to do
+likewise, subject to the following conditions:
+
+- when started running, the Program must display an announcement which
+  includes the details of your existing publication of the Program
+  made in accordance with the terms of the GNU General Public License.
+  For example, the Program could display the URL of the publicly
+  available source code from which the Unmodified Binary was built.
+
+- when exercising your right to grant permissions under this Licence,
+  you do not need to refer directly to the text of this Licence, but
+  you may not grant permissions beyond those granted to you by this
+  Licence.
diff --git a/meta/files/common-licenses/Universal-FOSS-exception-1.0 b/meta/files/common-licenses/Universal-FOSS-exception-1.0
new file mode 100644
index 0000000000..4a79cbdcf6
--- /dev/null
+++ b/meta/files/common-licenses/Universal-FOSS-exception-1.0
@@ -0,0 +1,11 @@
+The Universal FOSS Exception, Version 1.0
+ 
+In addition to the rights set forth in the other license(s) included in the distribution for this software, data, and/or documentation (collectively the "Software," and such licenses collectively with this additional permission the "Software License"), the copyright holders wish to facilitate interoperability with other software, data, and/or documentation distributed with complete corresponding source under a license that is OSI-approved and/or categorized by the FSF as free (collectively "Other FOSS").  We therefore hereby grant the following additional permission with respect to the use and distribution of the Software with Other FOSS, and the constants, function signatures, data structures and other invocation methods used to run or interact with each of them (as to each, such software's "Interfaces"):
+ 
+(i) The Software's Interfaces may, to the extent permitted by the license of the Other FOSS, be copied into, used and distributed in the Other FOSS in order to enable interoperability, without requiring a change to the license of the Other FOSS other than as to any Interfaces of the Software embedded therein.  The Software's Interfaces remain at all times under the Software License, including without limitation as used in the Other FOSS (which upon any such use also then contains a portion of the Software under the Software License).
+ 
+(ii) The Other FOSS's Interfaces may, to the extent permitted by the license of the Other FOSS, be copied into, used and distributed in the Software in order to enable interoperability, without requiring that such Interfaces be licensed under the terms of the Software License or otherwise altering their original terms, if this does not require any portion of the Software other than such Interfaces to be licensed under the terms other than the Software License.
+ 
+(iii) If only Interfaces and no other code is copied between the Software and the Other FOSS in either direction, the use and/or distribution of the Software with the Other FOSS shall not be deemed to require that the Other FOSS be licensed under the license of the Software, other than as to any Interfaces of the Software copied into the Other FOSS.  This includes, by way of example and without limitation, statically or dynamically linking the Software together with Other FOSS after enabling interoperability using the Interfaces of one or both, and distributing the resulting combination under different licenses for the respective portions thereof.
+ 
+For avoidance of doubt, a license which is OSI-approved or categorized by the FSF as free, includes, for the purpose of this permission, such licenses with additional permissions, and any license that has previously been so-approved or categorized as free, even if now deprecated or otherwise no longer recognized as approved or free.  Nothing in this additional permission grants any right to distribute any portion of the Software on terms other than those of the Software License or grants any additional permission of any kind for use or distribution of the Software in conjunction with software other than Other FOSS.
diff --git a/meta/files/common-licenses/WxWindows-exception-3.1 b/meta/files/common-licenses/WxWindows-exception-3.1
new file mode 100644
index 0000000000..9e71b0ae3f
--- /dev/null
+++ b/meta/files/common-licenses/WxWindows-exception-3.1
@@ -0,0 +1,9 @@
+EXCEPTION NOTICE
+
+1. As a special exception, the copyright holders of this library give permission for additional uses of the text contained in this release of the library as licenced under the wxWindows Library Licence, applying either version 3.1 of the Licence, or (at your option) any later version of the Licence as published by the copyright holders of version 3.1 of the Licence document.
+
+2. The exception is that you may use, copy, link, modify and distribute under your own terms, binary object code versions of works based on the Library.
+
+3. If you copy code from files distributed under the terms of the GNU General Public Licence or the GNU Library General Public Licence into a copy of this library, as this licence permits, the exception does not apply to the code that you add in this way. To avoid misleading anyone as to the status of such modified files, you must delete this exception notice from such code and/or adjust the licensing conditions notice accordingly.
+
+4. If you write modifications of your own for this library, it is your choice whether to permit this exception to apply to your modifications. If you do not wish that, you must delete the exception notice from such code and/or adjust the licensing conditions notice accordingly.
diff --git a/meta/files/common-licenses/cryptsetup-OpenSSL-exception b/meta/files/common-licenses/cryptsetup-OpenSSL-exception
new file mode 100644
index 0000000000..25c1c420d2
--- /dev/null
+++ b/meta/files/common-licenses/cryptsetup-OpenSSL-exception
@@ -0,0 +1,12 @@
+In addition, as a special exception, the copyright holders give
+permission to link the code of portions of this program with the OpenSSL
+library under certain conditions as described in each individual source
+file, and distribute linked combinations including the two.
+
+You must obey the GNU General Public License in all respects for all of
+the code used other than OpenSSL. If you modify file(s) with this
+exception, you may extend this exception to your version of the file(s),
+but you are not obligated to do so. If you do not wish to do so, delete
+this exception statement from your version. If you delete this exception
+statement from all source files in the program, then also delete it
+here.
diff --git a/meta/files/common-licenses/eCos-exception-2.0 b/meta/files/common-licenses/eCos-exception-2.0
new file mode 100644
index 0000000000..a0bf0077c5
--- /dev/null
+++ b/meta/files/common-licenses/eCos-exception-2.0
@@ -0,0 +1,3 @@
+As a special exception, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other works to produce a work based on this file, this file does not by itself cause the resulting work to be covered by the GNU General Public License. However the source code for this file must still be made available in accordance with section (3) of the GNU General Public License.
+
+This exception does not invalidate any other reasons why a work based on this file might be covered by the GNU General Public License.
diff --git a/meta/files/common-licenses/erlang-otp-linking-exception b/meta/files/common-licenses/erlang-otp-linking-exception
new file mode 100644
index 0000000000..ca8b775480
--- /dev/null
+++ b/meta/files/common-licenses/erlang-otp-linking-exception
@@ -0,0 +1,11 @@
+If you modify this Program, or any covered work, by linking or
+combining it with runtime libraries of Erlang/OTP as released by
+Ericsson on https://www.erlang.org (or a modified version of these
+libraries), containing parts covered by the terms of the Erlang Public
+License (https://www.erlang.org/EPLICENSE), the licensors of this
+Program grant you additional permission to convey the resulting work
+without the need to license the runtime libraries of Erlang/OTP under
+the GNU Affero General Public License. Corresponding Source for a
+non-source form of such a combination shall include the source code
+for the parts of the runtime libraries of Erlang/OTP used as well as
+that of the covered work.
diff --git a/meta/files/common-licenses/fmt-exception b/meta/files/common-licenses/fmt-exception
new file mode 100644
index 0000000000..6036f7d360
--- /dev/null
+++ b/meta/files/common-licenses/fmt-exception
@@ -0,0 +1,6 @@
+--- Optional exception to the license ---
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into a machine-executable object form of such
+source code, you may redistribute such embedded portions in such object form
+without including the above copyright and permission notices.
diff --git a/meta/files/common-licenses/freertos-exception-2.0 b/meta/files/common-licenses/freertos-exception-2.0
new file mode 100644
index 0000000000..0105e95971
--- /dev/null
+++ b/meta/files/common-licenses/freertos-exception-2.0
@@ -0,0 +1,19 @@
+Any FreeRTOS source code, whether modified or in its original release form, or whether in whole or in part, can only be distributed by you under the terms of the GNU General Public License plus this exception. An independent module is a module which is not derived from or based on FreeRTOS.
+
+EXCEPTION TEXT:
+
+Clause 1
+
+Linking FreeRTOS statically or dynamically with other modules is making a combined work based on FreeRTOS. Thus, the terms and conditions of the GNU General Public License cover the whole combination.
+
+As a special exception, the copyright holder of FreeRTOS gives you permission to link FreeRTOS with independent modules that communicate with FreeRTOS solely through the FreeRTOS API interface, regardless of the license terms of these independent modules, and to copy and distribute the resulting combined work under terms of your choice, provided that
+
+Every copy of the combined work is accompanied by a written statement that details to the recipient the version of FreeRTOS used and an offer by yourself to provide the FreeRTOS source code (including any modifications you may have made) should the recipient request it.
+
+The combined work is not itself an RTOS, scheduler, kernel or related product.
+
+The independent modules add significant and primary functionality to FreeRTOS and do not merely extend the existing functionality already present in FreeRTOS.
+
+Clause 2
+
+FreeRTOS may not be used for any competitive or comparative purpose, including the publication of any form of run time or compile time metric, without the express permission of Real Time Engineers Ltd. (this is the norm within the industry and is intended to ensure information accuracy).
diff --git a/meta/files/common-licenses/gnu-javamail-exception b/meta/files/common-licenses/gnu-javamail-exception
new file mode 100644
index 0000000000..8f3b9ab0d0
--- /dev/null
+++ b/meta/files/common-licenses/gnu-javamail-exception
@@ -0,0 +1 @@
+As a special exception, if you link this library with other files to produce an executable, this library does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License.
diff --git a/meta/files/common-licenses/harbour-exception b/meta/files/common-licenses/harbour-exception
new file mode 100644
index 0000000000..25d75e9fc7
--- /dev/null
+++ b/meta/files/common-licenses/harbour-exception
@@ -0,0 +1,23 @@
+As a special exception, the Harbour Project gives permission for
+additional uses of the text contained in its release of Harbour.
+
+The exception is that, if you link the Harbour libraries with other
+files to produce an executable, this does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+Your use of that executable is in no way restricted on account of
+linking the Harbour library code into it.
+
+This exception does not however invalidate any other reasons why
+the executable file might be covered by the GNU General Public License.
+
+This exception applies only to the code released by the Harbour
+Project under the name Harbour.  If you copy code from other
+Harbour Project or Free Software Foundation releases into a copy of
+Harbour, as the General Public License permits, the exception does
+not apply to the code that you add in this way.  To avoid misleading
+anyone as to the status of such modified files, you must delete
+this exception notice from them.
+
+If you write modifications of your own for Harbour, it is your choice
+whether to permit this exception to apply to your modifications.
+If you do not wish that, delete this exception notice.
diff --git a/meta/files/common-licenses/i2p-gpl-java-exception b/meta/files/common-licenses/i2p-gpl-java-exception
new file mode 100644
index 0000000000..2b7277d778
--- /dev/null
+++ b/meta/files/common-licenses/i2p-gpl-java-exception
@@ -0,0 +1 @@
+In addition, as a special exception, <<var;name=licensor;original=XXXX;match=.+>> gives permission to link the code of this program with the proprietary Java implementation provided by Sun (or other vendors as well), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than the proprietary Java implementation. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
diff --git a/meta/files/common-licenses/kvirc-openssl-exception b/meta/files/common-licenses/kvirc-openssl-exception
new file mode 100644
index 0000000000..beb605b8bd
--- /dev/null
+++ b/meta/files/common-licenses/kvirc-openssl-exception
@@ -0,0 +1,30 @@
+                       _OpenSSL Exception_
+
+0. Definitions
+
+"KVIrc" means KVIrc software licensed under version 2 or any later
+version of the GNU General Public License (collectively, "GPL"), or a
+work based on such software and licensed under the GPL.
+
+"OpenSSL" means OpenSSL toolkit software distributed by the OpenSSL
+Project and licensed under the OpenSSL Licenses, or a work based on such
+software and licensed under the OpenSSL Licenses.
+
+"OpenSSL Licenses" means the OpenSSL License and Original SSLeay License
+under which the OpenSSL Project distributes the OpenSSL toolkit software,
+as those licenses appear in the file LICENSE-OPENSSL.
+
+1. Exception
+
+You have permission to copy, modify, propagate, and distribute a work
+formed by combining OpenSSL with KVIrc, or a work derivative of such a
+combination, even if such copying, modification, propagation, or
+distribution would otherwise violate the terms of the GPL. You must
+comply with the GPL in all respects for all of the code used other than
+OpenSSL.
+
+You may include this OpenSSL Exception and its grant of permissions when
+you distribute KVIrc. Inclusion of this notice with such a
+distribution constitutes a grant of such permission. If you do not wish
+to grant these permissions, remove this section entitled "OpenSSL
+Exception" from your distribution.
diff --git a/meta/files/common-licenses/libpri-OpenH323-exception b/meta/files/common-licenses/libpri-OpenH323-exception
new file mode 100644
index 0000000000..490d9596d6
--- /dev/null
+++ b/meta/files/common-licenses/libpri-OpenH323-exception
@@ -0,0 +1,4 @@
+As a special exception, libpri may also be linked to the
+OpenH323 library, so long as the entirity of the derivative
+work (as defined within the GPL) is licensed either under
+the MPL of the OpenH323 license or the GPL of libpri.
diff --git a/meta/files/common-licenses/mif-exception b/meta/files/common-licenses/mif-exception
new file mode 100644
index 0000000000..ceb2626c6f
--- /dev/null
+++ b/meta/files/common-licenses/mif-exception
@@ -0,0 +1 @@
+As a special exception, you may use this file as part of a free software library without restriction. Specifically, if other files instantiate templates or use macros or inline functions from this file, or you compile this file and link it with other files to produce an executable, this file does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU General Public License.
diff --git a/meta/files/common-licenses/mxml-exception b/meta/files/common-licenses/mxml-exception
new file mode 100644
index 0000000000..32928e8dd6
--- /dev/null
+++ b/meta/files/common-licenses/mxml-exception
@@ -0,0 +1,16 @@
+Mini-XML
+
+Copyright © 2003-2024 by Michael R Sweet
+
+
+(Optional) Exceptions to the Apache 2.0 License:
+================================================
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 or LGPLv2 (“Combined Software”) and if
+a court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2 or LGPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of the
+License, but only in their entirety and only with respect to the Combined
+Software.
diff --git a/meta/files/common-licenses/openvpn-openssl-exception b/meta/files/common-licenses/openvpn-openssl-exception
new file mode 100644
index 0000000000..e9e0a367ea
--- /dev/null
+++ b/meta/files/common-licenses/openvpn-openssl-exception
@@ -0,0 +1,3 @@
+Special exception for linking OpenVPN with OpenSSL:
+
+In addition, as a special exception, OpenVPN Technologies, Inc. gives permission to link the code of this program with the OpenSSL Library (or with modified versions of OpenSSL that use the same license as OpenSSL), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than OpenSSL. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
diff --git a/meta/files/common-licenses/polyparse-exception b/meta/files/common-licenses/polyparse-exception
new file mode 100644
index 0000000000..55ed918bb9
--- /dev/null
+++ b/meta/files/common-licenses/polyparse-exception
@@ -0,0 +1,7 @@
+As a relaxation of clause 6 of the LGPL, the copyright holders of this
+library give permission to use, copy, link, modify, and distribute,
+binary-only object-code versions of an executable linked with the
+original unmodified Library, without requiring the supply of any
+mechanism to modify or replace the Library and relink (clauses 6a,
+6b, 6c, 6d, 6e), provided that all the other terms of clause 6 are
+complied with.
diff --git a/meta/files/common-licenses/romic-exception b/meta/files/common-licenses/romic-exception
new file mode 100644
index 0000000000..57def44818
--- /dev/null
+++ b/meta/files/common-licenses/romic-exception
@@ -0,0 +1,6 @@
+Additional permission under the GNU Affero GPL version 3 section 7:
+
+If you modify this Program, or any covered work, by linking or
+combining it with other code, such other code is not for that reason
+alone subject to any of the requirements of the GNU Affero GPL
+version 3.
diff --git a/meta/files/common-licenses/rsync-linking-exception b/meta/files/common-licenses/rsync-linking-exception
new file mode 100644
index 0000000000..ddad55cb28
--- /dev/null
+++ b/meta/files/common-licenses/rsync-linking-exception
@@ -0,0 +1,6 @@
+In addition, as a special exception, the copyright holders give
+permission to dynamically link rsync with the OpenSSL and xxhash
+libraries when those libraries are being distributed in compliance
+with their license terms, and to distribute a dynamically linked
+combination of rsync and these libraries.  This is also considered
+to be covered under the GPL's System Libraries exception.
diff --git a/meta/files/common-licenses/sqlitestudio-OpenSSL-exception b/meta/files/common-licenses/sqlitestudio-OpenSSL-exception
new file mode 100644
index 0000000000..07fdc13f98
--- /dev/null
+++ b/meta/files/common-licenses/sqlitestudio-OpenSSL-exception
@@ -0,0 +1,9 @@
+In addition, as a special exception, the copyright holders give
+permission to link the code of portions of this program with the OpenSSL
+library.
+You must obey the GNU General Public License in all respects for all of
+the code used other than OpenSSL. If you modify file(s) with this
+exception, you may extend this exception to your version of the file(s),
+but you are not obligated to do so. If you do not wish to do so, delete
+this exception statement from your version. If you delete this exception
+statement from all source files in the program, then also delete it here.  
diff --git a/meta/files/common-licenses/stunnel-exception b/meta/files/common-licenses/stunnel-exception
new file mode 100644
index 0000000000..5e38d00a0f
--- /dev/null
+++ b/meta/files/common-licenses/stunnel-exception
@@ -0,0 +1,5 @@
+Linking stunnel statically or dynamically with other modules is making a combined work based on stunnel. Thus, the terms and conditions of the GNU General Public License cover the whole combination.
+
+In addition, as a special exception, the copyright holder of stunnel gives you permission to combine stunnel with free software programs or libraries that are released under the GNU LGPL and with code included in the standard release of OpenSSL under the OpenSSL License (or modified versions of such code, with unchanged license). You may copy and distribute such a system following the terms of the GNU GPL for stunnel and the licenses of the other code concerned.
+
+Note that people who make modified versions of stunnel are not obligated to grant this special exception for their modified versions; it is their choice whether to do so. The GNU General Public License gives permission to release a modified version without this exception; this exception also makes it possible to release a modified version which carries forward this exception.
diff --git a/meta/files/common-licenses/u-boot-exception-2.0 b/meta/files/common-licenses/u-boot-exception-2.0
new file mode 100644
index 0000000000..3158dade32
--- /dev/null
+++ b/meta/files/common-licenses/u-boot-exception-2.0
@@ -0,0 +1,6 @@
+The U-Boot License Exception:
+
+Even though U-Boot in general is covered by the GPL-2.0/GPL-2.0+, this does *not* cover the so-called "standalone" applications that use U-Boot services by means of the jump table provided by U-Boot exactly for this purpose - this is merely considered normal use of U-Boot, and does *not* fall under the heading of "derived work".
+
+The header files "include/image.h" and "arch/*/include/asm/u-boot.h" define interfaces to U-Boot. Including these (unmodified) header files in another file is considered normal use of U-Boot, and does *not* fall under the heading of "derived work".
+-- Wolfgang Denk
diff --git a/meta/files/common-licenses/vsftpd-openssl-exception b/meta/files/common-licenses/vsftpd-openssl-exception
new file mode 100644
index 0000000000..a864761e48
--- /dev/null
+++ b/meta/files/common-licenses/vsftpd-openssl-exception
@@ -0,0 +1,5 @@
+vsftpd is licensed under version 2 of the GNU GPL.
+As copyright holder, I give permission for vsftpd to be linked to the OpenSSL
+libraries. This includes permission for vsftpd binaries to be distributed
+linked against the OpenSSL libraries. All other obligations under the GPL v2
+remain intact.
diff --git a/meta/files/common-licenses/x11vnc-openssl-exception b/meta/files/common-licenses/x11vnc-openssl-exception
new file mode 100644
index 0000000000..040e31c7a9
--- /dev/null
+++ b/meta/files/common-licenses/x11vnc-openssl-exception
@@ -0,0 +1,9 @@
+In addition, as a special exception, Karl J. Runge
+gives permission to link the code of its release of x11vnc with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables.  You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL".  If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so.  If you do not wish to do
+so, delete this exception statement from your version.
diff --git a/meta/files/spdx-exceptions.json b/meta/files/spdx-exceptions.json
new file mode 100644
index 0000000000..f9a5bc74b2
--- /dev/null
+++ b/meta/files/spdx-exceptions.json
@@ -0,0 +1,971 @@
+{
+  "exceptions": [
+    {
+      "detailsUrl": "https://spdx.org/licenses/389-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "389-exception",
+      "name": "389 Directory Server Exception",
+      "reference": "https://spdx.org/licenses/389-exception.html",
+      "referenceNumber": 49,
+      "seeAlso": [
+        "http://directory.fedoraproject.org/wiki/GPL_Exception_License_Text",
+        "https://web.archive.org/web/20080828121337/http://directory.fedoraproject.org/wiki/GPL_Exception_License_Text"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Asterisk-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Asterisk-exception",
+      "name": "Asterisk exception",
+      "reference": "https://spdx.org/licenses/Asterisk-exception.html",
+      "referenceNumber": 3,
+      "seeAlso": [
+        "https://github.com/asterisk/libpri/blob/7f91151e6bd10957c746c031c1f4a030e8146e9a/pri.c#L22",
+        "https://github.com/asterisk/libss7/blob/03e81bcd0d28ff25d4c77c78351ddadc82ff5c3f/ss7.c#L24"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Asterisk-linking-protocols-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Asterisk-linking-protocols-exception",
+      "name": "Asterisk linking protocols exception",
+      "reference": "https://spdx.org/licenses/Asterisk-linking-protocols-exception.html",
+      "referenceNumber": 4,
+      "seeAlso": [
+        "https://github.com/asterisk/asterisk/blob/115d7c01e32ccf4566a99e9d74e2b88830985a0b/LICENSE#L27"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Autoconf-exception-2.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Autoconf-exception-2.0",
+      "name": "Autoconf exception 2.0",
+      "reference": "https://spdx.org/licenses/Autoconf-exception-2.0.html",
+      "referenceNumber": 30,
+      "seeAlso": [
+        "http://ac-archive.sourceforge.net/doc/copyright.html",
+        "http://ftp.gnu.org/gnu/autoconf/autoconf-2.59.tar.gz"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Autoconf-exception-3.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Autoconf-exception-3.0",
+      "name": "Autoconf exception 3.0",
+      "reference": "https://spdx.org/licenses/Autoconf-exception-3.0.html",
+      "referenceNumber": 51,
+      "seeAlso": [
+        "http://www.gnu.org/licenses/autoconf-exception-3.0.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Autoconf-exception-generic.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Autoconf-exception-generic",
+      "name": "Autoconf generic exception",
+      "reference": "https://spdx.org/licenses/Autoconf-exception-generic.html",
+      "referenceNumber": 28,
+      "seeAlso": [
+        "https://launchpad.net/ubuntu/precise/+source/xmltooling/+copyright",
+        "https://tracker.debian.org/media/packages/s/sipwitch/copyright-1.9.15-3",
+        "https://opensource.apple.com/source/launchd/launchd-258.1/launchd/compile.auto.html",
+        "https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=gnulib-tool;h=029a8cf377ad8d8f2d9e54061bf2f20496ad2eef;hb=73c74ba0197e6566da6882c87b1adee63e24d75c#l407"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Autoconf-exception-generic-3.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Autoconf-exception-generic-3.0",
+      "name": "Autoconf generic exception for GPL-3.0",
+      "reference": "https://spdx.org/licenses/Autoconf-exception-generic-3.0.html",
+      "referenceNumber": 37,
+      "seeAlso": [
+        "https://src.fedoraproject.org/rpms/redhat-rpm-config/blob/rawhide/f/config.guess"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Autoconf-exception-macro.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Autoconf-exception-macro",
+      "name": "Autoconf macro exception",
+      "reference": "https://spdx.org/licenses/Autoconf-exception-macro.html",
+      "referenceNumber": 27,
+      "seeAlso": [
+        "https://github.com/freedesktop/xorg-macros/blob/39f07f7db58ebbf3dcb64a2bf9098ed5cf3d1223/xorg-macros.m4.in",
+        "https://www.gnu.org/software/autoconf-archive/ax_pthread.html",
+        "https://launchpad.net/ubuntu/precise/+source/xmltooling/+copyright"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Bison-exception-1.24.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Bison-exception-1.24",
+      "name": "Bison exception 1.24",
+      "reference": "https://spdx.org/licenses/Bison-exception-1.24.html",
+      "referenceNumber": 15,
+      "seeAlso": [
+        "https://github.com/arineng/rwhoisd/blob/master/rwhoisd/mkdb/y.tab.c#L180"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Bison-exception-2.2.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Bison-exception-2.2",
+      "name": "Bison exception 2.2",
+      "reference": "https://spdx.org/licenses/Bison-exception-2.2.html",
+      "referenceNumber": 74,
+      "seeAlso": [
+        "http://git.savannah.gnu.org/cgit/bison.git/tree/data/yacc.c?id=193d7c7054ba7197b0789e14965b739162319b5e#n141"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Bootloader-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Bootloader-exception",
+      "name": "Bootloader Distribution Exception",
+      "reference": "https://spdx.org/licenses/Bootloader-exception.html",
+      "referenceNumber": 29,
+      "seeAlso": [
+        "https://github.com/pyinstaller/pyinstaller/blob/develop/COPYING.txt"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/CGAL-linking-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "CGAL-linking-exception",
+      "name": "CGAL Linking Exception",
+      "reference": "https://spdx.org/licenses/CGAL-linking-exception.html",
+      "referenceNumber": 62,
+      "seeAlso": [
+        "https://github.com/openscad/openscad/blob/openscad-2021.01/COPYING#L3",
+        "https://github.com/floriankirsch/OpenCSG/blob/opencsg-1-4-2-release/license.txt#L3"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Classpath-exception-2.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Classpath-exception-2.0",
+      "name": "Classpath exception 2.0",
+      "reference": "https://spdx.org/licenses/Classpath-exception-2.0.html",
+      "referenceNumber": 2,
+      "seeAlso": [
+        "http://www.gnu.org/software/classpath/license.html",
+        "https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Classpath-exception-2.0-short.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Classpath-exception-2.0-short",
+      "name": "Classpath exception 2.0 - short",
+      "reference": "https://spdx.org/licenses/Classpath-exception-2.0-short.html",
+      "referenceNumber": 52,
+      "seeAlso": [
+        "https://sourceforge.net/projects/lazarus/files/Lazarus%20Zip%20_%20GZip/Lazarus%204.2/lazarus-4.2-0.tar.gz/download"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/CLISP-exception-2.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "CLISP-exception-2.0",
+      "name": "CLISP exception 2.0",
+      "reference": "https://spdx.org/licenses/CLISP-exception-2.0.html",
+      "referenceNumber": 21,
+      "seeAlso": [
+        "http://sourceforge.net/p/clisp/clisp/ci/default/tree/COPYRIGHT"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/cryptsetup-OpenSSL-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "cryptsetup-OpenSSL-exception",
+      "name": "cryptsetup OpenSSL exception",
+      "reference": "https://spdx.org/licenses/cryptsetup-OpenSSL-exception.html",
+      "referenceNumber": 1,
+      "seeAlso": [
+        "https://gitlab.com/cryptsetup/cryptsetup/-/blob/main/COPYING",
+        "https://gitlab.nic.cz/datovka/datovka/-/blob/develop/COPYING",
+        "https://github.com/nbs-system/naxsi/blob/951123ad456bdf5ac94e8d8819342fe3d49bc002/naxsi_src/naxsi_raw.c",
+        "http://web.mit.edu/jgross/arch/amd64_deb60/bin/mosh",
+        "https://sourceforge.net/p/linux-ima/ima-evm-utils/ci/master/tree/src/evmctl.c#l30",
+        "https://github.com/ocaml-omake/omake/blob/master/LICENSE.OMake#L20"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Digia-Qt-LGPL-exception-1.1.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Digia-Qt-LGPL-exception-1.1",
+      "name": "Digia Qt LGPL Exception version 1.1",
+      "reference": "https://spdx.org/licenses/Digia-Qt-LGPL-exception-1.1.html",
+      "referenceNumber": 5,
+      "seeAlso": [
+        "https://src.fedoraproject.org/rpms/qtlockedfile/blob/rawhide/f/LGPL_EXCEPTION"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/DigiRule-FOSS-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "DigiRule-FOSS-exception",
+      "name": "DigiRule FOSS License Exception",
+      "reference": "https://spdx.org/licenses/DigiRule-FOSS-exception.html",
+      "referenceNumber": 80,
+      "seeAlso": [
+        "http://www.digirulesolutions.com/drupal/foss"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/eCos-exception-2.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "eCos-exception-2.0",
+      "name": "eCos exception 2.0",
+      "reference": "https://spdx.org/licenses/eCos-exception-2.0.html",
+      "referenceNumber": 36,
+      "seeAlso": [
+        "http://ecos.sourceware.org/license-overview.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/erlang-otp-linking-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "erlang-otp-linking-exception",
+      "name": "Erlang/OTP Linking Exception",
+      "reference": "https://spdx.org/licenses/erlang-otp-linking-exception.html",
+      "referenceNumber": 26,
+      "seeAlso": [
+        "https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs",
+        "https://erlang.org/pipermail/erlang-questions/2012-May/066355.html",
+        "https://gitea.osmocom.org/erlang/osmo_ss7/src/commit/2286c1b8738d715950026650bf53f19a69d6ed0e/src/ss7_links.erl#L20"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Fawkes-Runtime-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Fawkes-Runtime-exception",
+      "name": "Fawkes Runtime Exception",
+      "reference": "https://spdx.org/licenses/Fawkes-Runtime-exception.html",
+      "referenceNumber": 25,
+      "seeAlso": [
+        "http://www.fawkesrobotics.org/about/license/"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/FLTK-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "FLTK-exception",
+      "name": "FLTK exception",
+      "reference": "https://spdx.org/licenses/FLTK-exception.html",
+      "referenceNumber": 32,
+      "seeAlso": [
+        "http://www.fltk.org/COPYING.php"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/fmt-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "fmt-exception",
+      "name": "fmt exception",
+      "reference": "https://spdx.org/licenses/fmt-exception.html",
+      "referenceNumber": 72,
+      "seeAlso": [
+        "https://github.com/fmtlib/fmt/blob/master/LICENSE",
+        "https://github.com/fmtlib/fmt/blob/2eb363297b24cd71a68ccfb20ff755430f17e60f/LICENSE#L22C1-L27C62"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Font-exception-2.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Font-exception-2.0",
+      "name": "Font exception 2.0",
+      "reference": "https://spdx.org/licenses/Font-exception-2.0.html",
+      "referenceNumber": 39,
+      "seeAlso": [
+        "http://www.gnu.org/licenses/gpl-faq.html#FontException"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/freertos-exception-2.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "freertos-exception-2.0",
+      "name": "FreeRTOS Exception 2.0",
+      "reference": "https://spdx.org/licenses/freertos-exception-2.0.html",
+      "referenceNumber": 38,
+      "seeAlso": [
+        "https://web.archive.org/web/20060809182744/http://www.freertos.org/a00114.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GCC-exception-2.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GCC-exception-2.0",
+      "name": "GCC Runtime Library exception 2.0",
+      "reference": "https://spdx.org/licenses/GCC-exception-2.0.html",
+      "referenceNumber": 78,
+      "seeAlso": [
+        "https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/libgcc1.c;h=762f5143fc6eed57b6797c82710f3538aa52b40b;hb=cb143a3ce4fb417c68f5fa2691a1b1b1053dfba9#l10",
+        "https://sourceware.org/git/?p=glibc.git;a=blob;f=csu/abi-note.c;h=c2ec208e94fbe91f63d3c375bd254b884695d190;hb=HEAD"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GCC-exception-2.0-note.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GCC-exception-2.0-note",
+      "name": "GCC    Runtime Library exception 2.0 - note variant",
+      "reference": "https://spdx.org/licenses/GCC-exception-2.0-note.html",
+      "referenceNumber": 53,
+      "seeAlso": [
+        "https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/start.S"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GCC-exception-3.1.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GCC-exception-3.1",
+      "name": "GCC Runtime Library exception 3.1",
+      "reference": "https://spdx.org/licenses/GCC-exception-3.1.html",
+      "referenceNumber": 48,
+      "seeAlso": [
+        "http://www.gnu.org/licenses/gcc-exception-3.1.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Gmsh-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Gmsh-exception",
+      "name": "Gmsh exception",
+      "reference": "https://spdx.org/licenses/Gmsh-exception.html",
+      "referenceNumber": 22,
+      "seeAlso": [
+        "https://gitlab.onelab.info/gmsh/gmsh/-/raw/master/LICENSE.txt"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GNAT-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GNAT-exception",
+      "name": "GNAT exception",
+      "reference": "https://spdx.org/licenses/GNAT-exception.html",
+      "referenceNumber": 20,
+      "seeAlso": [
+        "https://github.com/AdaCore/florist/blob/master/libsrc/posix-configurable_file_limits.adb"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GNOME-examples-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GNOME-examples-exception",
+      "name": "GNOME examples exception",
+      "reference": "https://spdx.org/licenses/GNOME-examples-exception.html",
+      "referenceNumber": 35,
+      "seeAlso": [
+        "https://gitlab.gnome.org/Archive/gnome-devel-docs/-/blob/master/platform-demos/C/legal.xml?ref_type=heads",
+        "http://meldmerge.org/help/"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GNU-compiler-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GNU-compiler-exception",
+      "name": "GNU Compiler Exception",
+      "reference": "https://spdx.org/licenses/GNU-compiler-exception.html",
+      "referenceNumber": 19,
+      "seeAlso": [
+        "https://sourceware.org/git?p=binutils-gdb.git;a=blob;f=libiberty/unlink-if-ordinary.c;h=e49f2f2f67bfdb10d6b2bd579b0e01cad0fd708e;hb=HEAD#l19",
+        "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/lib/crtsavres.S?h=v6.16-rc6#n34"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/gnu-javamail-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "gnu-javamail-exception",
+      "name": "GNU JavaMail exception",
+      "reference": "https://spdx.org/licenses/gnu-javamail-exception.html",
+      "referenceNumber": 71,
+      "seeAlso": [
+        "http://www.gnu.org/software/classpathx/javamail/javamail.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GPL-3.0-389-ds-base-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GPL-3.0-389-ds-base-exception",
+      "name": "GPL-3.0 389 DS Base Exception",
+      "reference": "https://spdx.org/licenses/GPL-3.0-389-ds-base-exception.html",
+      "referenceNumber": 13,
+      "seeAlso": []
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GPL-3.0-interface-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GPL-3.0-interface-exception",
+      "name": "GPL-3.0 Interface Exception",
+      "reference": "https://spdx.org/licenses/GPL-3.0-interface-exception.html",
+      "referenceNumber": 11,
+      "seeAlso": [
+        "https://www.gnu.org/licenses/gpl-faq.en.html#LinkingOverControlledInterface"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GPL-3.0-linking-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GPL-3.0-linking-exception",
+      "name": "GPL-3.0 Linking Exception",
+      "reference": "https://spdx.org/licenses/GPL-3.0-linking-exception.html",
+      "referenceNumber": 59,
+      "seeAlso": [
+        "https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GPL-3.0-linking-source-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GPL-3.0-linking-source-exception",
+      "name": "GPL-3.0 Linking Exception (with Corresponding Source)",
+      "reference": "https://spdx.org/licenses/GPL-3.0-linking-source-exception.html",
+      "referenceNumber": 69,
+      "seeAlso": [
+        "https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs",
+        "https://github.com/mirror/wget/blob/master/src/http.c#L20"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GPL-CC-1.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GPL-CC-1.0",
+      "name": "GPL Cooperation Commitment 1.0",
+      "reference": "https://spdx.org/licenses/GPL-CC-1.0.html",
+      "referenceNumber": 40,
+      "seeAlso": [
+        "https://github.com/gplcc/gplcc/blob/master/Project/COMMITMENT",
+        "https://gplcc.github.io/gplcc/Project/README-PROJECT.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GStreamer-exception-2005.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GStreamer-exception-2005",
+      "name": "GStreamer Exception (2005)",
+      "reference": "https://spdx.org/licenses/GStreamer-exception-2005.html",
+      "referenceNumber": 16,
+      "seeAlso": [
+        "https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/licensing.html?gi-language=c#licensing-of-applications-using-gstreamer"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/GStreamer-exception-2008.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "GStreamer-exception-2008",
+      "name": "GStreamer Exception (2008)",
+      "reference": "https://spdx.org/licenses/GStreamer-exception-2008.html",
+      "referenceNumber": 41,
+      "seeAlso": [
+        "https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/licensing.html?gi-language=c#licensing-of-applications-using-gstreamer"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/harbour-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "harbour-exception",
+      "name": "harbour exception",
+      "reference": "https://spdx.org/licenses/harbour-exception.html",
+      "referenceNumber": 60,
+      "seeAlso": [
+        "https://github.com/harbour/core/blob/master/LICENSE.txt#L44-L66"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/i2p-gpl-java-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "i2p-gpl-java-exception",
+      "name": "i2p GPL+Java Exception",
+      "reference": "https://spdx.org/licenses/i2p-gpl-java-exception.html",
+      "referenceNumber": 58,
+      "seeAlso": [
+        "http://geti2p.net/en/get-involved/develop/licenses#java_exception"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Independent-modules-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Independent-modules-exception",
+      "name": "Independent Module Linking exception",
+      "reference": "https://spdx.org/licenses/Independent-modules-exception.html",
+      "referenceNumber": 9,
+      "seeAlso": [
+        "https://gitlab.com/freepascal.org/fpc/source/-/blob/release_3_2_2/rtl/COPYING.FPC"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/KiCad-libraries-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "KiCad-libraries-exception",
+      "name": "KiCad Libraries Exception",
+      "reference": "https://spdx.org/licenses/KiCad-libraries-exception.html",
+      "referenceNumber": 46,
+      "seeAlso": [
+        "https://www.kicad.org/libraries/license/"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/kvirc-openssl-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "kvirc-openssl-exception",
+      "name": "kvirc OpenSSL Exception",
+      "reference": "https://spdx.org/licenses/kvirc-openssl-exception.html",
+      "referenceNumber": 34,
+      "seeAlso": [
+        "https://github.com/kvirc/KVIrc/blob/ba18690abb4f5ce77bb10164ee0835cc150f4a2a/doc/ABOUT-LICENSE#L34"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/LGPL-3.0-linking-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "LGPL-3.0-linking-exception",
+      "name": "LGPL-3.0 Linking Exception",
+      "reference": "https://spdx.org/licenses/LGPL-3.0-linking-exception.html",
+      "referenceNumber": 56,
+      "seeAlso": [
+        "https://raw.githubusercontent.com/go-xmlpath/xmlpath/v2/LICENSE",
+        "https://github.com/goamz/goamz/blob/master/LICENSE",
+        "https://github.com/juju/errors/blob/master/LICENSE"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/libpri-OpenH323-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "libpri-OpenH323-exception",
+      "name": "libpri OpenH323 exception",
+      "reference": "https://spdx.org/licenses/libpri-OpenH323-exception.html",
+      "referenceNumber": 81,
+      "seeAlso": [
+        "https://github.com/asterisk/libpri/blob/1.6.0/README#L19-L22"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Libtool-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Libtool-exception",
+      "name": "Libtool Exception",
+      "reference": "https://spdx.org/licenses/Libtool-exception.html",
+      "referenceNumber": 14,
+      "seeAlso": [
+        "http://git.savannah.gnu.org/cgit/libtool.git/tree/m4/libtool.m4",
+        "https://git.savannah.gnu.org/cgit/libtool.git/tree/libltdl/lt__alloc.c#n15"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Linux-syscall-note.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Linux-syscall-note",
+      "name": "Linux Syscall Note",
+      "reference": "https://spdx.org/licenses/Linux-syscall-note.html",
+      "referenceNumber": 44,
+      "seeAlso": [
+        "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/COPYING"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/LLGPL.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "LLGPL",
+      "name": "LLGPL Preamble",
+      "reference": "https://spdx.org/licenses/LLGPL.html",
+      "referenceNumber": 47,
+      "seeAlso": [
+        "http://opensource.franz.com/preamble.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/LLVM-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "LLVM-exception",
+      "name": "LLVM Exception",
+      "reference": "https://spdx.org/licenses/LLVM-exception.html",
+      "referenceNumber": 82,
+      "seeAlso": [
+        "http://llvm.org/foundation/relicensing/LICENSE.txt",
+        "https://web.archive.org/web/20240423023852/https://foundation.llvm.org/relicensing/LICENSE.txt"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/LZMA-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "LZMA-exception",
+      "name": "LZMA exception",
+      "reference": "https://spdx.org/licenses/LZMA-exception.html",
+      "referenceNumber": 83,
+      "seeAlso": [
+        "http://nsis.sourceforge.net/Docs/AppendixI.html#I.6"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/mif-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "mif-exception",
+      "name": "Macros and Inline Functions Exception",
+      "reference": "https://spdx.org/licenses/mif-exception.html",
+      "referenceNumber": 43,
+      "seeAlso": [
+        "http://www.scs.stanford.edu/histar/src/lib/cppsup/exception",
+        "http://dev.bertos.org/doxygen/",
+        "https://www.threadingbuildingblocks.org/licensing"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/mxml-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "mxml-exception",
+      "name": "mxml Exception",
+      "reference": "https://spdx.org/licenses/mxml-exception.html",
+      "referenceNumber": 61,
+      "seeAlso": [
+        "https://github.com/michaelrsweet/mxml/blob/master/NOTICE",
+        "https://github.com/michaelrsweet/mxml/blob/master/LICENSE"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Nokia-Qt-exception-1.1.json",
+      "isDeprecatedLicenseId": true,
+      "licenseExceptionId": "Nokia-Qt-exception-1.1",
+      "name": "Nokia Qt LGPL exception 1.1",
+      "reference": "https://spdx.org/licenses/Nokia-Qt-exception-1.1.html",
+      "referenceNumber": 7,
+      "seeAlso": [
+        "https://www.keepassx.org/dev/projects/keepassx/repository/revisions/b8dfb9cc4d5133e0f09cd7533d15a4f1c19a40f2/entry/LICENSE.NOKIA-LGPL-EXCEPTION"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/OCaml-LGPL-linking-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "OCaml-LGPL-linking-exception",
+      "name": "OCaml LGPL Linking Exception",
+      "reference": "https://spdx.org/licenses/OCaml-LGPL-linking-exception.html",
+      "referenceNumber": 54,
+      "seeAlso": [
+        "https://caml.inria.fr/ocaml/license.en.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/OCCT-exception-1.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "OCCT-exception-1.0",
+      "name": "Open CASCADE Exception 1.0",
+      "reference": "https://spdx.org/licenses/OCCT-exception-1.0.html",
+      "referenceNumber": 67,
+      "seeAlso": [
+        "http://www.opencascade.com/content/licensing"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/OpenJDK-assembly-exception-1.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "OpenJDK-assembly-exception-1.0",
+      "name": "OpenJDK Assembly exception 1.0",
+      "reference": "https://spdx.org/licenses/OpenJDK-assembly-exception-1.0.html",
+      "referenceNumber": 23,
+      "seeAlso": [
+        "http://openjdk.java.net/legal/assembly-exception.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/openvpn-openssl-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "openvpn-openssl-exception",
+      "name": "OpenVPN OpenSSL Exception",
+      "reference": "https://spdx.org/licenses/openvpn-openssl-exception.html",
+      "referenceNumber": 18,
+      "seeAlso": [
+        "http://openvpn.net/index.php/license.html",
+        "https://github.com/psycopg/psycopg2/blob/2_9_3/LICENSE#L14"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/PCRE2-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "PCRE2-exception",
+      "name": "PCRE2 exception",
+      "reference": "https://spdx.org/licenses/PCRE2-exception.html",
+      "referenceNumber": 55,
+      "seeAlso": [
+        "https://www.pcre.org/licence.txt"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/polyparse-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "polyparse-exception",
+      "name": "Polyparse Exception",
+      "reference": "https://spdx.org/licenses/polyparse-exception.html",
+      "referenceNumber": 6,
+      "seeAlso": [
+        "https://hackage.haskell.org/package/polyparse-1.13/src/COPYRIGHT"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/PS-or-PDF-font-exception-20170817.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "PS-or-PDF-font-exception-20170817",
+      "name": "PS/PDF font exception (2017-08-17)",
+      "reference": "https://spdx.org/licenses/PS-or-PDF-font-exception-20170817.html",
+      "referenceNumber": 66,
+      "seeAlso": [
+        "https://github.com/ArtifexSoftware/urw-base35-fonts/blob/65962e27febc3883a17e651cdb23e783668c996f/LICENSE"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/QPL-1.0-INRIA-2004-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "QPL-1.0-INRIA-2004-exception",
+      "name": "INRIA QPL 1.0 2004 variant exception",
+      "reference": "https://spdx.org/licenses/QPL-1.0-INRIA-2004-exception.html",
+      "referenceNumber": 10,
+      "seeAlso": [
+        "https://git.frama-c.com/pub/frama-c/-/blob/master/licenses/Q_MODIFIED_LICENSE",
+        "https://github.com/maranget/hevea/blob/master/LICENSE"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Qt-GPL-exception-1.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Qt-GPL-exception-1.0",
+      "name": "Qt GPL exception 1.0",
+      "reference": "https://spdx.org/licenses/Qt-GPL-exception-1.0.html",
+      "referenceNumber": 64,
+      "seeAlso": [
+        "http://code.qt.io/cgit/qt/qtbase.git/tree/LICENSE.GPL3-EXCEPT"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Qt-LGPL-exception-1.1.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Qt-LGPL-exception-1.1",
+      "name": "Qt LGPL exception 1.1",
+      "reference": "https://spdx.org/licenses/Qt-LGPL-exception-1.1.html",
+      "referenceNumber": 79,
+      "seeAlso": [
+        "http://code.qt.io/cgit/qt/qtbase.git/tree/LGPL_EXCEPTION.txt"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Qwt-exception-1.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Qwt-exception-1.0",
+      "name": "Qwt exception 1.0",
+      "reference": "https://spdx.org/licenses/Qwt-exception-1.0.html",
+      "referenceNumber": 75,
+      "seeAlso": [
+        "http://qwt.sourceforge.net/qwtlicense.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/romic-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "romic-exception",
+      "name": "Romic Exception",
+      "reference": "https://spdx.org/licenses/romic-exception.html",
+      "referenceNumber": 76,
+      "seeAlso": [
+        "https://web.archive.org/web/20210124015834/http://mo.morsi.org/blog/2009/08/13/lesser_affero_gplv3/",
+        "https://sourceforge.net/p/romic/code/ci/3ab2856180cf0d8b007609af53154cf092efc58f/tree/COPYING",
+        "https://github.com/moll/node-mitm/blob/bbf24b8bd7596dc6e091e625363161ce91984fc7/LICENSE#L8-L11",
+        "https://github.com/zenbones/SmallMind/blob/3c62b5995fe7f27c453f140ff9b60560a0893f2a/COPYRIGHT#L25-L30",
+        "https://github.com/CubeArtisan/cubeartisan/blob/2c6ab53455237b88a3ea07be02a838a135c4ab79/LICENSE.LESSER#L10-L15",
+        "https://github.com/savearray2/py.js/blob/b781273c08c8afa89f4954de4ecf42ec01429bae/README.md#license"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/RRDtool-FLOSS-exception-2.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "RRDtool-FLOSS-exception-2.0",
+      "name": "RRDtool FLOSS exception 2.0",
+      "reference": "https://spdx.org/licenses/RRDtool-FLOSS-exception-2.0.html",
+      "referenceNumber": 70,
+      "seeAlso": [
+        "https://github.com/oetiker/rrdtool-1.x/blob/master/COPYRIGHT#L25-L90",
+        "https://oss.oetiker.ch/rrdtool/license.en.html"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/rsync-linking-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "rsync-linking-exception",
+      "name": "rsync Linking Exception",
+      "reference": "https://spdx.org/licenses/rsync-linking-exception.html",
+      "referenceNumber": 33,
+      "seeAlso": [
+        "https://github.com/RsyncProject/rsync/blob/master/COPYING"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/SANE-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "SANE-exception",
+      "name": "SANE Exception",
+      "reference": "https://spdx.org/licenses/SANE-exception.html",
+      "referenceNumber": 63,
+      "seeAlso": [
+        "https://github.com/alexpevzner/sane-airscan/blob/master/LICENSE",
+        "https://gitlab.com/sane-project/backends/-/blob/master/sanei/sanei_pp.c?ref_type=heads",
+        "https://gitlab.com/sane-project/frontends/-/blob/master/sanei/sanei_codec_ascii.c?ref_type=heads"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/SHL-2.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "SHL-2.0",
+      "name": "Solderpad Hardware License v2.0",
+      "reference": "https://spdx.org/licenses/SHL-2.0.html",
+      "referenceNumber": 24,
+      "seeAlso": [
+        "https://solderpad.org/licenses/SHL-2.0/"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/SHL-2.1.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "SHL-2.1",
+      "name": "Solderpad Hardware License v2.1",
+      "reference": "https://spdx.org/licenses/SHL-2.1.html",
+      "referenceNumber": 45,
+      "seeAlso": [
+        "https://solderpad.org/licenses/SHL-2.1/"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Simple-Library-Usage-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Simple-Library-Usage-exception",
+      "name": "Simple Library Usage Exception",
+      "reference": "https://spdx.org/licenses/Simple-Library-Usage-exception.html",
+      "referenceNumber": 8,
+      "seeAlso": [
+        "https://sourceforge.net/p/teem/code/HEAD/tree/teem/trunk/LICENSE.txt"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/sqlitestudio-OpenSSL-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "sqlitestudio-OpenSSL-exception",
+      "name": "sqlitestudio OpenSSL exception",
+      "reference": "https://spdx.org/licenses/sqlitestudio-OpenSSL-exception.html",
+      "referenceNumber": 12,
+      "seeAlso": [
+        "https://github.com/pawelsalawa/sqlitestudio/blob/master/LICENSE"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/stunnel-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "stunnel-exception",
+      "name": "stunnel Exception",
+      "reference": "https://spdx.org/licenses/stunnel-exception.html",
+      "referenceNumber": 68,
+      "seeAlso": [
+        "https://github.com/mtrojnar/stunnel/blob/master/COPYING.md"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/SWI-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "SWI-exception",
+      "name": "SWI exception",
+      "reference": "https://spdx.org/licenses/SWI-exception.html",
+      "referenceNumber": 77,
+      "seeAlso": [
+        "https://github.com/SWI-Prolog/packages-clpqr/blob/bfa80b9270274f0800120d5b8e6fef42ac2dc6a5/clpqr/class.pl"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Swift-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Swift-exception",
+      "name": "Swift Exception",
+      "reference": "https://spdx.org/licenses/Swift-exception.html",
+      "referenceNumber": 57,
+      "seeAlso": [
+        "https://swift.org/LICENSE.txt",
+        "https://github.com/apple/swift-package-manager/blob/7ab2275f447a5eb37497ed63a9340f8a6d1e488b/LICENSE.txt#L205"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Texinfo-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Texinfo-exception",
+      "name": "Texinfo exception",
+      "reference": "https://spdx.org/licenses/Texinfo-exception.html",
+      "referenceNumber": 73,
+      "seeAlso": [
+        "https://git.savannah.gnu.org/cgit/automake.git/tree/lib/texinfo.tex?h=v1.16.5#n23"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/u-boot-exception-2.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "u-boot-exception-2.0",
+      "name": "U-Boot exception 2.0",
+      "reference": "https://spdx.org/licenses/u-boot-exception-2.0.html",
+      "referenceNumber": 84,
+      "seeAlso": [
+        "http://git.denx.de/?p=u-boot.git;a=blob;f=Licenses/Exceptions"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/UBDL-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "UBDL-exception",
+      "name": "Unmodified Binary Distribution exception",
+      "reference": "https://spdx.org/licenses/UBDL-exception.html",
+      "referenceNumber": 31,
+      "seeAlso": [
+        "https://github.com/ipxe/ipxe/blob/master/COPYING.UBDL"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/Universal-FOSS-exception-1.0.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "Universal-FOSS-exception-1.0",
+      "name": "Universal FOSS Exception, Version 1.0",
+      "reference": "https://spdx.org/licenses/Universal-FOSS-exception-1.0.html",
+      "referenceNumber": 50,
+      "seeAlso": [
+        "https://oss.oracle.com/licenses/universal-foss-exception/"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/vsftpd-openssl-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "vsftpd-openssl-exception",
+      "name": "vsftpd OpenSSL exception",
+      "reference": "https://spdx.org/licenses/vsftpd-openssl-exception.html",
+      "referenceNumber": 65,
+      "seeAlso": [
+        "https://git.stg.centos.org/source-git/vsftpd/blob/f727873674d9c9cd7afcae6677aa782eb54c8362/f/LICENSE",
+        "https://launchpad.net/debian/squeeze/+source/vsftpd/+copyright",
+        "https://github.com/richardcochran/vsftpd/blob/master/COPYING"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/WxWindows-exception-3.1.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "WxWindows-exception-3.1",
+      "name": "WxWindows Library Exception 3.1",
+      "reference": "https://spdx.org/licenses/WxWindows-exception-3.1.html",
+      "referenceNumber": 17,
+      "seeAlso": [
+        "http://www.opensource.org/licenses/WXwindows"
+      ]
+    },
+    {
+      "detailsUrl": "https://spdx.org/licenses/x11vnc-openssl-exception.json",
+      "isDeprecatedLicenseId": false,
+      "licenseExceptionId": "x11vnc-openssl-exception",
+      "name": "x11vnc OpenSSL Exception",
+      "reference": "https://spdx.org/licenses/x11vnc-openssl-exception.html",
+      "referenceNumber": 42,
+      "seeAlso": [
+        "https://github.com/LibVNC/x11vnc/blob/master/src/8to24.c#L22"
+      ]
+    }
+  ],
+  "licenseListVersion": "3.28.0",
+  "releaseDate": "2026-02-20T00:00:00Z"
+}
\ No newline at end of file
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 03/22] Add SPDX license library
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 01/22] scripts/pull-spdx-licenses.py: Add exceptions Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 02/22] Add SPDX License Exceptions Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 04/22] Parse LICENSE as SPDX Expression Joshua Watt
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Adds a library to parse SPDX license expressions into an abstract syntax
tree

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/lib/oe/spdx_license.py | 760 ++++++++++++++++++++++++++++++++++++
 1 file changed, 760 insertions(+)
 create mode 100644 meta/lib/oe/spdx_license.py

diff --git a/meta/lib/oe/spdx_license.py b/meta/lib/oe/spdx_license.py
new file mode 100644
index 0000000000..f14683f428
--- /dev/null
+++ b/meta/lib/oe/spdx_license.py
@@ -0,0 +1,760 @@
+#
+# Copyright OpenEmbedded Contributors
+#
+# SPDX-License-Identifier: MIT
+#
+
+import re
+import json
+from abc import abstractmethod, ABC
+from enum import Enum
+from pathlib import Path
+from dataclasses import dataclass
+
+THIS_DIR = Path(__file__).parent
+
+_LICENSES = {}
+_EXCEPTIONS = {}
+
+
+def _load_licenses():
+    p = THIS_DIR.parent.parent / "files" / "spdx-licenses.json"
+    with p.open("r") as f:
+        data = json.load(f)
+
+    for lic in data["licenses"]:
+        _LICENSES[lic["licenseId"].lower()] = lic
+
+
+_load_licenses()
+
+
+def _load_exceptions():
+    p = THIS_DIR.parent.parent / "files" / "spdx-exceptions.json"
+    with p.open("r") as f:
+        data = json.load(f)
+
+    for lic in data["exceptions"]:
+        _EXCEPTIONS[lic["licenseExceptionId"].lower()] = lic
+
+
+_load_exceptions()
+
+
+def get_license(ident):
+    return _LICENSES.get(ident.lower())
+
+
+def get_exception(ident):
+    return _EXCEPTIONS.get(ident.lower())
+
+
+class ParseError(Exception):
+    def __init__(self, n, s):
+        super().__init__(s)
+        self.n = n
+        self.expression = ""
+
+    def format(self, *, prefix="ERROR:"):
+        if not self.n:
+            return f"{prefix}0: {str(self)}\n{self.expression}"
+
+        start, end = self.n.get_range()
+
+        if start < 0:
+            start = 0
+
+        if end < 0:
+            end = len(self.expression)
+
+        ident = " " * start
+        for i in range(start, end):
+            ident += "^"
+
+        return "\n".join(
+            [
+                f"{prefix}{start}: " + str(self),
+                self.expression,
+                ident,
+            ]
+        )
+
+
+def check_stack_types(stack, types):
+    if len(stack) < len(types):
+        return False
+
+    for i, t in enumerate(types):
+        if isinstance(t, list):
+            t = tuple(t)
+        if not isinstance(stack[-(len(types) - i)], t):
+            return False
+
+    return True
+
+
+class Token(object):
+    def __init__(self):
+        self.value = ""
+        self.start = 0
+        self.end = 0
+
+    def copy(self):
+        t = self.__class__()
+        t.value = self.value
+        t.start = self.start
+        t.value = self.value
+        return t
+
+    def get_range(self):
+        return self.start, self.end
+
+
+class Node(ABC):
+    @dataclass
+    class Sort:
+        node: object
+        key: list
+
+    def __init__(self, children, *, token=None):
+        self.token = token
+        self.children = children
+
+    @abstractmethod
+    def copy(self):
+        raise NotImplementedError("Method not implemented")
+
+    @abstractmethod
+    def to_string(self):
+        raise NotImplementedError("Method not implemented")
+
+    def _copy_token(self):
+        if self.token:
+            return self.token.copy()
+        return None
+
+    def iter(self):
+        yield self
+
+        for c in self.children:
+            yield from c.iter()
+
+    def get_range(self):
+        if self.token:
+            start = self.token.start
+            end = self.token.end
+        else:
+            start = -1
+            end = -1
+
+        for c in self.children:
+            child_start, child_end = c.get_range()
+            if start < 0:
+                start = child_start
+            else:
+                start = min(start, child_start)
+            if end < 0:
+                end = child_end
+            else:
+                end = max(end, child_end)
+
+        return start, end
+
+    def _simplify(self):
+        self.children = [c._simplify() for c in self.children]
+        return self
+
+    def to_ast_string(self, indent=0):
+        s = " " * indent + self.__class__.__name__
+        if self.token:
+            s += f"({self.token.value})"
+        s += "\n"
+        for c in self.children:
+            s += c.to_ast_string(indent + 2)
+        return s
+
+    def sort(self):
+        """
+        Sort the tree into a consistent ordering and removing duplicate
+        licenses (e.g. "FOO AND FOO" or "FOO OR FOO")
+
+        Returns the root of a new tree which is a sorted copy of the original
+        """
+        return self.copy()._sort().node
+
+    def _sort(self):
+        raise NotImplementedError("Method not implemented")
+
+
+class ReservedToken(Node):
+    def __init__(self, **kwargs):
+        super().__init__([], **kwargs)
+
+    def copy(self):
+        return self.__class__(token=self._copy_token())
+
+    @property
+    def value(self):
+        return self.token.value
+
+    def to_string(self):
+        return self.token.value
+
+    @classmethod
+    def reduce(cls, stack, lookahead):
+        if not check_stack_types(stack, [Token]):
+            return False
+
+        token = stack[-1]
+        if not token.value in RESERVED:
+            return False
+
+        stack.pop()
+        stack.append(cls(token=token))
+
+    def _sort(self):
+        return Node.Sort(self, [self.__class__.__name__, self.token.value])
+
+
+class Identifier(Node):
+    def __init__(self, ident, **kwargs):
+        super().__init__([], **kwargs)
+        self.ident = ident
+
+    def copy(self):
+        return self.__class__(self.ident, token=self._copy_token())
+
+    def to_string(self):
+        return self.ident
+
+    def _sort(self):
+        return Node.Sort(self, [self.__class__.__name__, self.ident])
+
+
+class UnknownId(Identifier):
+    @classmethod
+    def reduce(cls, stack, lookahead):
+        if not check_stack_types(stack, [Token]):
+            return False
+
+        t = stack.pop()
+        stack.append(cls(t.value, token=t))
+        return True
+
+
+class LicenseId(Identifier):
+    @property
+    def deprecated(self):
+        return get_license(self.ident)["isDeprecatedLicenseId"]
+
+    @property
+    def name(self):
+        return self.ident
+
+    @classmethod
+    def reduce(cls, stack, lookahead):
+        if not check_stack_types(stack, [Token]):
+            return False
+
+        lic = get_license(stack[-1].value)
+        if lic is None:
+            return False
+
+        stack.append(cls(lic["licenseId"], token=stack.pop()))
+        return True
+
+
+class ExceptionId(Identifier):
+    @property
+    def deprecated(self):
+        return get_exception(self.ident)["isDeprecatedLicenseId"]
+
+    @property
+    def name(self):
+        return self.ident
+
+    @classmethod
+    def reduce(cls, stack, lookahead):
+        if not check_stack_types(stack, [Token]):
+            return False
+
+        lic = get_exception(stack[-1].value)
+        if lic is None:
+            return False
+
+        stack.append(cls(lic["licenseExceptionId"], token=stack.pop()))
+        return True
+
+
+class LicenseRef(Identifier):
+    REGEX = re.compile(
+        r"^(DocumentRef-[A-Za-z0-9\.\-]+:)?LicenseRef-(?P<name>[A-Za-z0-9\.\-]+)$"
+    )
+
+    def __init__(self, ident, name, **kwargs):
+        super().__init__(ident, **kwargs)
+        self.name = name
+
+    def copy(self):
+        return self.__class__(self.ident, self.name, token=self._copy_token())
+
+    @classmethod
+    def reduce(cls, stack, lookahead):
+        if not check_stack_types(stack, [Token]):
+            return False
+
+        m = cls.REGEX.match(stack[-1].value)
+        if m is None:
+            return False
+
+        t = stack.pop()
+        stack.append(cls(t.value, m.group("name"), token=t))
+        return True
+
+
+class CompoundExpression(Node):
+    def __init__(self, child, **kwargs):
+        super().__init__([child], **kwargs)
+
+    def copy(self):
+        return self.child.copy()
+
+    @property
+    def child(self):
+        return self.children[0]
+
+    def to_string(self):
+        return self.child.to_string()
+
+    def _simplify(self):
+        return self.child._simplify()
+
+    @classmethod
+    def reduce(cls, stack, lookahead):
+        if check_stack_types(stack, [ReservedToken]) and stack[-1].value == ")":
+            if not check_stack_types(
+                stack,
+                [
+                    COMPOUND_EXPRESSION,
+                    ReservedToken,
+                ],
+            ):
+                raise ParseError(stack[-2], "Invalid expression for parentheses")
+
+            if not check_stack_types(
+                stack,
+                [
+                    ReservedToken,
+                    COMPOUND_EXPRESSION,
+                    ReservedToken,
+                ],
+            ):
+                raise ParseError(stack[-1], "Missing matching '('")
+
+            rparen = stack[-1]
+            n = stack[-2]
+            lparen = stack[-3]
+
+            if lparen.value != "(":
+                raise ParseError(lparen, "'(' expected, but not found")
+
+            stack.pop()
+            stack.pop()
+            stack.pop()
+
+            stack.append(cls(n))
+            return True
+
+        if not check_stack_types(
+            stack,
+            [(AndOp, OrOp, WithOp)],
+        ):
+            return False
+
+        stack.append(cls(stack.pop()))
+        return True
+
+    def _sort(self):
+        return self.child._sort()
+
+
+SIMPLE_EXPRESSION = [LicenseId, LicenseRef, UnknownId]
+COMPOUND_EXPRESSION = SIMPLE_EXPRESSION + [CompoundExpression]
+
+
+class Operator(Node):
+    OPERATORS = {}
+
+
+class UnaryOp(Operator):
+    def __init__(self, child, **kwargs):
+        super().__init__([child], **kwargs)
+
+    def __init_subclass__(cls):
+        Operator.OPERATORS[cls.NAME] = cls
+
+    def copy(self):
+        return self.__class__(self.child.copy(), token=self._copy_token())
+
+    @property
+    def child(self):
+        return self.children[0]
+
+    def to_string(self):
+        if isinstance(self.child, Operator) and self.child.PRECEDENCE > self.PRECEDENCE:
+            return self.NAME + " (" + self.child.to_string() + ")"
+        return self.NAME + " " + self.child.to_string()
+
+    @classmethod
+    def reduce(cls, stack, lookahead):
+        if not check_stack_types(stack, cls.TYPES):
+            return False
+
+        child = stack[-1]
+        token = stack[-2]
+
+        if token.value != cls.NAME:
+            return False
+
+        if token.value not in cls.OPERATORS:
+            return False
+
+        if (
+            lookahead
+            and lookahead.value in cls.OPERATORS
+            and cls.PRECEDENCE < cls.OPERATORS[lookahead.value].PRECEDENCE
+        ):
+            return False
+
+        stack.pop()
+        stack.pop()
+
+        stack.append(cls(child, token=token))
+        return True
+
+
+class BinOp(Operator):
+    def __init__(self, left, right, **kwargs):
+        super().__init__([left, right], **kwargs)
+
+    def __init_subclass__(cls):
+        if name := getattr(cls, "NAME", None):
+            Operator.OPERATORS[name] = cls
+
+    def copy(self):
+        return self.__class__(
+            self.left.copy(), self.right.copy(), token=self._copy_token()
+        )
+
+    @property
+    def left(self):
+        return self.children[0]
+
+    @property
+    def right(self):
+        return self.children[1]
+
+    def to_string(self):
+        strs = []
+        for c in self.children:
+            s = c.to_string()
+            if isinstance(c, BinOp) and c.PRECEDENCE < self.PRECEDENCE:
+                s = "(" + s + ")"
+            if strs:
+                strs.append(self.NAME)
+            strs.append(s)
+
+        return " ".join(strs)
+
+    @classmethod
+    def reduce(cls, stack, lookahead):
+        if not check_stack_types(stack, cls.TYPES):
+            return False
+
+        right = stack[-1]
+        token = stack[-2]
+        left = stack[-3]
+
+        if token.value != cls.NAME:
+            return False
+
+        if token.value not in cls.OPERATORS:
+            return False
+
+        if (
+            lookahead
+            and lookahead.value in cls.OPERATORS
+            and cls.PRECEDENCE < cls.OPERATORS[lookahead.value].PRECEDENCE
+        ):
+            return False
+
+        stack.pop()
+        stack.pop()
+        stack.pop()
+
+        stack.append(cls(left, right, token=token))
+        return True
+
+
+class ConjunctionOp(BinOp):
+    def __init__(self, left, right, **kwargs):
+        super().__init__(left, right, **kwargs)
+
+    @classmethod
+    def join(cls, nodes):
+        if len(nodes) == 0:
+            return None
+
+        if len(nodes) == 1:
+            return nodes[0]
+
+        root = cls(nodes.pop(), nodes.pop())
+        while nodes:
+            root = cls(root, nodes.pop())
+        return root
+
+    def _sort(self):
+        # Sort children
+        children = sorted([c._sort() for c in self.children], key=lambda x: x.key)
+        self.children = [c.node for c in children]
+        s = Node.Sort(self, [self.__class__.__name__] + [c.key for c in children])
+
+        if children[0].key == children[1].key:
+            # Duplicate expressions
+            return children[0]
+
+        if isinstance(self.left, Identifier) and isinstance(self.right, Identifier):
+            if self.left.ident == self.right.ident:
+                return (self.left, [self.left.ident])
+            # Already sorted
+            return s
+
+        # Find the parent of the left most child of the right child
+        right_parent = None
+        if isinstance(self.right, self.__class__):
+            right_parent = self.right
+            while isinstance(right_parent.left, self.__class__):
+                right_parent = right_parent.left
+
+        # Find the parent of the right most child of the left child
+        left_parent = None
+        if isinstance(self.left, self.__class__):
+            left_parent = self.left
+            while isinstance(left_parent.right, self.__class__):
+                left_parent = left_parent.right
+
+        if left_parent and right_parent:
+            left_key = left_parent.right._sort().key
+            right_key = right_parent.left._sort().key
+            if left_key == right_key:
+                # Swap right children to allow the identical nodes to
+                # eventually merge together
+                tmp = self.children[1]
+                self.children[1] = self.left.children[1]
+                self.left.children[1] = tmp
+
+                # Sort again
+                return self._sort()
+
+            if left_key > right_key:
+                tmp = left_parent.children[1]
+                left_parent.children[1] = right_parent.children[0]
+                right_parent.children[0] = tmp
+
+                # Sort again
+                return self._sort()
+
+            # We don't want a "balanced" node (that is, one with both
+            # children being the same) to ensure that the resulting
+            # tree is consistent (and thus, comparable). Swap terminal
+            # nodes left to "bubble" up this node
+            tmp = left_parent.children[1]
+            left_parent.children[1] = self.children[1]
+            self.children = [tmp, left_parent]
+            return self._sort()
+
+        elif left_parent:
+            left_key = left_parent.right._sort().key
+            right_key = self.right._sort().key
+            if left_key == right_key:
+                return children[0]
+
+            if left_key > right_key:
+                tmp = self.children[1]
+                self.children[1] = left_parent.children[1]
+                left_parent.children[1] = tmp
+
+                # Sort again
+                return self._sort()
+
+        elif right_parent:
+            left_key = self.left._sort().key
+            right_key = right_parent.left._sort().key
+            if left_key == right_key:
+                return children[1][0], children[1][1]
+
+            if left_key > right_key:
+                tmp = self.children[0]
+                self.children[0] = right_parent.children[0]
+                right_parent.children[0] = tmp
+
+                # Sort again
+                return self._sort()
+
+        return s
+
+
+class OrOp(ConjunctionOp):
+    NAME = "OR"
+    PRECEDENCE = 1
+    TYPES = [COMPOUND_EXPRESSION, ReservedToken, COMPOUND_EXPRESSION]
+
+
+class AndOp(ConjunctionOp):
+    NAME = "AND"
+    PRECEDENCE = 2
+    TYPES = [COMPOUND_EXPRESSION, ReservedToken, COMPOUND_EXPRESSION]
+
+
+class NotOp(UnaryOp):
+    NAME = "NOT"
+    PRECEDENCE = 3
+    TYPES = [ReservedToken, COMPOUND_EXPRESSION]
+
+
+class WithOp(BinOp):
+    NAME = "WITH"
+    PRECEDENCE = 4
+    TYPES = [SIMPLE_EXPRESSION, ReservedToken, ExceptionId]
+
+    @property
+    def license(self):
+        return self.left
+
+    @property
+    def exception(self):
+        return self.right
+
+    def _sort(self):
+        return Node.Sort(
+            self,
+            [
+                self.__class__.__name__,
+                self.license._sort().key,
+                self.exception._sort().key,
+            ],
+        )
+
+
+RESERVED = set(Operator.OPERATORS.keys()) | {"(", ")", "+"}
+
+REDUCTIONS = (
+    ReservedToken.reduce,
+    LicenseId.reduce,
+    ExceptionId.reduce,
+    LicenseRef.reduce,
+    WithOp.reduce,
+    NotOp.reduce,
+    AndOp.reduce,
+    OrOp.reduce,
+    CompoundExpression.reduce,
+)
+
+
+def _reduce(stack, lookahead):
+    # print(stack)
+    for r in REDUCTIONS:
+        if r(stack, lookahead):
+            # print(f"Applied reduction {r}")
+            _reduce(stack, lookahead)
+
+
+def tokenize(s):
+    tokens = []
+    t = Token()
+
+    def end_token(end):
+        nonlocal t
+        nonlocal tokens
+        if t.value:
+            t.end = end + 1
+            tokens.append(t)
+        t = Token()
+
+    for idx, c in enumerate(s):
+        if c in RESERVED:
+            end_token(idx - 1)
+            t.start = idx
+            t.value = c
+            end_token(idx)
+        elif c in (" ", "\t", "\n", "\r"):
+            end_token(idx - 1)
+        else:
+            if not t.value:
+                t.start = idx
+            t.value += c
+
+    end_token(len(s) - 1)
+    return tokens
+
+
+def create_ast(tokens, *, allow_unknown=False):
+    stack = []
+    while tokens:
+        t = tokens.pop(0)
+
+        if tokens:
+            lookahead = tokens[0]
+        else:
+            lookahead = None
+
+        stack.append(t)
+        _reduce(stack, lookahead)
+        # If unknown IDs are allowed, attempt a reduction to an unknown ID
+        if allow_unknown and UnknownId.reduce(stack, lookahead):
+            _reduce(stack, lookahead)
+
+    if len(stack) == 0:
+        raise ParseError(None, "Empty expression")
+
+    # Error on any unknown tokens
+    for n in stack:
+        if isinstance(n, Token):
+            raise ParseError(n, f"Unknown Expression '{n.value}'")
+
+    # Error on any unconsumed reserved keywords
+    for n in stack:
+        if isinstance(n, ReservedToken):
+            raise ParseError(n, f"Unexpected '{n.value}'")
+
+    if len(stack) > 1:
+        raise ParseError(stack[1], "Unexpected Expression")
+
+    return stack.pop()._simplify()
+
+
+def parse(s, *, allow_unknown=False):
+    def check_node(n):
+        if isinstance(n, NotOp):
+            raise ParseError(n, "Expression not allowed in this context")
+
+        for child in n.children:
+            check_node(child)
+
+    try:
+        tokens = tokenize(s)
+        n = create_ast(tokens, allow_unknown=allow_unknown)
+        check_node(n)
+        return n
+    except ParseError as e:
+        e.expression = s
+        raise
+
+
+def parse_match(s):
+    try:
+        tokens = tokenizer(s)
+        return create_ast(tokens)
+    except ParseError as e:
+        e.expression = s
+        raise
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 04/22] Parse LICENSE as SPDX Expression
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (2 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 03/22] Add SPDX license library Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 05/22] linux-firmware: Convert to SPDX license strings Joshua Watt
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Reworks the LICENSE parsing code to parse the expressions as SPDX
license expressions. An initial conversion is done to convert legacy
LICENSE expressions to SPDX expressions in case recipes are still using
the older style, but this is idempotent so it is a no-op if the license
is already an SPDX expression.

If LICENSE is detected to be in the old format, a warning is issued to
the user to tell them to upgrade, with the new license string that
should be used.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/classes-global/insane.bbclass            |   8 +-
 meta/classes-global/license.bbclass           | 113 ++---
 meta/classes-recipe/license_image.bbclass     |   6 +-
 meta/classes/buildhistory.bbclass             |   3 +-
 meta/classes/copyleft_filter.bbclass          |   4 +-
 meta/conf/licenses.conf                       |   4 +
 meta/lib/oe/license.py                        | 468 ++++++++++--------
 meta/lib/oe/spdx30_tasks.py                   | 173 +++----
 .../oeqa/selftest/cases/incompatible_lic.py   |   7 +-
 meta/lib/oeqa/selftest/cases/oelib/license.py | 296 ++++++++---
 10 files changed, 623 insertions(+), 459 deletions(-)

diff --git a/meta/classes-global/insane.bbclass b/meta/classes-global/insane.bbclass
index c1d8b16586..c0868849fb 100644
--- a/meta/classes-global/insane.bbclass
+++ b/meta/classes-global/insane.bbclass
@@ -990,8 +990,8 @@ def package_qa_check_unlisted_pkg_lics(package, d):
     if not pkg_lics:
         return
 
-    recipe_lics_set = oe.license.list_licenses(d.getVar('LICENSE'))
-    package_lics = oe.license.list_licenses(pkg_lics)
+    recipe_lics_set = oe.license.list_licenses(d.getVar('LICENSE'), d)
+    package_lics = oe.license.list_licenses(pkg_lics, d)
     unlisted = package_lics - recipe_lics_set
     if unlisted:
         oe.qa.handle_error("unlisted-pkg-lics",
@@ -1113,7 +1113,7 @@ python do_package_qa () {
     import oe.packagedata
 
     # Check for obsolete license references in main LICENSE (packages are checked below for any changes)
-    main_licenses = oe.license.list_licenses(d.getVar('LICENSE'))
+    main_licenses = oe.license.list_licenses(d.getVar('LICENSE'), d)
     obsolete = set(oe.license.obsolete_license_list()) & main_licenses
     if obsolete:
         oe.qa.handle_error("obsolete-license", "Recipe LICENSE includes obsolete licenses %s" % ' '.join(obsolete), d)
@@ -1332,7 +1332,7 @@ python do_qa_patch() {
 
     # Detect cargo-based tests
     elif os.path.exists(os.path.join(srcdir, "Cargo.toml")) and (
-        match_line_in_files(srcdir, "**/*.rs", r'\s*#\s*\[\s*test\s*\]') or 
+        match_line_in_files(srcdir, "**/*.rs", r'\s*#\s*\[\s*test\s*\]') or
         match_line_in_files(srcdir, "**/*.rs", r'\s*#\s*\[\s*cfg\s*\(\s*test\s*\)\s*\]')
     ):
         oe.qa.handle_error("unimplemented-ptest", "%s: cargo-based tests detected" % d.getVar('PN'), d)
diff --git a/meta/classes-global/license.bbclass b/meta/classes-global/license.bbclass
index 2d4ad6df26..86c9ee5878 100644
--- a/meta/classes-global/license.bbclass
+++ b/meta/classes-global/license.bbclass
@@ -52,10 +52,12 @@ python perform_packagecopy:prepend () {
 perform_packagecopy[vardeps] += "LICENSE_CREATE_PACKAGE"
 
 def get_recipe_info(d):
+    import oe.license
+
     info = {}
     info["PV"] = d.getVar("PV")
     info["PR"] = d.getVar("PR")
-    info["LICENSE"] = d.getVar("LICENSE")
+    info["LICENSE"] = oe.license.convert_legacy_license_to_spdx(d, d.getVar("LICENSE"))
     return info
 
 def add_package_and_files(d):
@@ -116,6 +118,7 @@ def find_license_files(d):
     """
     import shutil
     import oe.license
+    import oe.spdx_license
     from collections import defaultdict, OrderedDict
 
     # All the license files for the package
@@ -128,86 +131,18 @@ def find_license_files(d):
     # List of basename, path tuples
     lic_files_paths = []
     # hash for keep track generic lics mappings
-    non_generic_lics = {}
+    non_generic_lics = set()
     # Entries from LIC_FILES_CHKSUM
     lic_chksums = {}
-    license_source_dirs = []
-    license_source_dirs.append(generic_directory)
-    try:
-        additional_lic_dirs = d.getVar('LICENSE_PATH').split()
-        for lic_dir in additional_lic_dirs:
-            license_source_dirs.append(lic_dir)
-    except:
-        pass
-
-    class FindVisitor(oe.license.LicenseVisitor):
-        def visit_Str(self, node):
-            #
-            # Until I figure out what to do with
-            # the two modifiers I support (or greater = +
-            # and "with exceptions" being *
-            # we'll just strip out the modifier and put
-            # the base license.
-            find_licenses(node.s.replace("+", "").replace("*", ""))
-            self.generic_visit(node)
-
-        def visit_Constant(self, node):
-            find_licenses(node.value.replace("+", "").replace("*", ""))
-            self.generic_visit(node)
-
-    def find_licenses(license_type):
-        try:
-            bb.utils.mkdirhier(gen_lic_dest)
-        except:
-            pass
-        spdx_generic = None
-        license_source = None
-        # If the generic does not exist we need to check to see if there is an SPDX mapping to it,
-        # unless NO_GENERIC_LICENSE is set.
-        for lic_dir in license_source_dirs:
-            if not os.path.isfile(os.path.join(lic_dir, license_type)):
-                if d.getVarFlag('SPDXLICENSEMAP', license_type) != None:
-                    # Great, there is an SPDXLICENSEMAP. We can copy!
-                    bb.debug(1, "We need to use a SPDXLICENSEMAP for %s" % (license_type))
-                    spdx_generic = d.getVarFlag('SPDXLICENSEMAP', license_type)
-                    license_source = lic_dir
-                    break
-            elif os.path.isfile(os.path.join(lic_dir, license_type)):
-                spdx_generic = license_type
-                license_source = lic_dir
-                break
-
-        non_generic_lic = d.getVarFlag('NO_GENERIC_LICENSE', license_type)
-        if spdx_generic and license_source:
-            # we really should copy to generic_ + spdx_generic, however, that ends up messing the manifest
-            # audit up. This should be fixed in emit_pkgdata (or, we actually got and fix all the recipes)
-
-            lic_files_paths.append(("generic_" + license_type, os.path.join(license_source, spdx_generic),
-                                    None, None))
-
-            # The user may attempt to use NO_GENERIC_LICENSE for a generic license which doesn't make sense
-            # and should not be allowed, warn the user in this case.
-            if d.getVarFlag('NO_GENERIC_LICENSE', license_type):
-                oe.qa.handle_error("license-no-generic",
-                    "%s: %s is a generic license, please don't use NO_GENERIC_LICENSE for it." % (pn, license_type), d)
-
-        elif non_generic_lic and non_generic_lic in lic_chksums:
-            # if NO_GENERIC_LICENSE is set, we copy the license files from the fetched source
-            # of the package rather than the license_source_dirs.
-            lic_files_paths.append(("generic_" + license_type,
-                                    os.path.join(srcdir, non_generic_lic), None, None))
-            non_generic_lics[non_generic_lic] = license_type
-        else:
-            # Explicitly avoid the CLOSED license because this isn't generic
-            if license_type != 'CLOSED':
-                # And here is where we warn people that their licenses are lousy
-                oe.qa.handle_error("license-exists",
-                    "%s: No generic license file exists for: %s in any provider" % (pn, license_type), d)
-            pass
 
     if not generic_directory:
         bb.fatal("COMMON_LICENSE_DIR is unset. Please set this in your distro config")
 
+    try:
+        bb.utils.mkdirhier(gen_lic_dest)
+    except:
+        pass
+
     for url in lic_files.split():
         try:
             (method, host, path, user, pswd, parm) = bb.fetch.decodeurl(url)
@@ -221,14 +156,28 @@ def find_license_files(d):
         endline = parm.get('endline')
         lic_chksums[path] = (chksum, beginline, endline)
 
-    v = FindVisitor()
+    def walk_license(node):
+        if isinstance(node, oe.spdx_license.Identifier):
+            p, non_generic_fn = oe.license.get_license_path(d, node)
+            if p is not None and (not non_generic_fn or non_generic_fn in lic_chksums):
+                lic_files_paths.append(("generic_" + node.ident, p, None, None))
+                if non_generic_fn:
+                    non_generic_lics.add(non_generic_fn)
+            else:
+                oe.qa.handle_error("license-exists",
+                    "%s: No generic license file exists for: %s in any provider" % (pn, node.ident), d)
+
+        for child in node.children:
+            walk_license(child)
+
     try:
-        v.visit_string(d.getVar('LICENSE'))
-    except oe.license.InvalidLicense as exc:
-        bb.fatal('%s: %s' % (d.getVar('PF'), exc))
-    except SyntaxError:
-        oe.qa.handle_error("license-syntax",
-            "%s: Failed to parse LICENSE: %s" % (d.getVar('PF'), d.getVar('LICENSE')), d)
+        licensestr = d.getVar("LICENSE")
+        if licensestr and licensestr != "CLOSED":
+            node = oe.license.parse_legacy_license(d, licensestr)
+            walk_license(node)
+    except oe.spdx_license.ParseError as e:
+        oe.qa.handle_error("license-syntax", e.format(prefix=f"{d.getVar('PF')}: "), d)
+
     # Add files from LIC_FILES_CHKSUM to list of license files
     lic_chksum_paths = defaultdict(OrderedDict)
     for path, data in sorted(lic_chksums.items()):
diff --git a/meta/classes-recipe/license_image.bbclass b/meta/classes-recipe/license_image.bbclass
index 1ecd8f88bc..258082c82a 100644
--- a/meta/classes-recipe/license_image.bbclass
+++ b/meta/classes-recipe/license_image.bbclass
@@ -131,10 +131,10 @@ def write_license_files(d, license_manifest, pkg_dic, rootfs):
                     oe.qa.handle_error('license-exception', "Including %s with incompatible license(s) %s into the image, because it has been allowed by exception list." %(pkg, ' '.join(incompatible_licenses)), d)
             try:
                 (pkg_dic[pkg]["LICENSE"], pkg_dic[pkg]["LICENSES"]) = \
-                    oe.license.manifest_licenses(pkg_dic[pkg]["LICENSE"],
-                    remaining_bad_licenses, oe.license.canonical_license, d)
+                    oe.license.manifest_licenses(d, pkg_dic[pkg]["LICENSE"],
+                    remaining_bad_licenses)
             except oe.license.LicenseError as exc:
-                bb.fatal('%s: %s' % (d.getVar('P'), exc))
+                bb.fatal(exc.format(prefix=d.getVar("P") + ": "))
 
             if not "IMAGE_MANIFEST" in pkg_dic[pkg]:
                 # Rootfs manifest
diff --git a/meta/classes/buildhistory.bbclass b/meta/classes/buildhistory.bbclass
index 8f605a720e..ce6ef8971a 100644
--- a/meta/classes/buildhistory.bbclass
+++ b/meta/classes/buildhistory.bbclass
@@ -82,6 +82,7 @@ python buildhistory_emit_pkghistory() {
     import shlex
     import errno
     import shutil
+    import oe.license
 
     if not "package" in (d.getVar('BUILDHISTORY_FEATURES') or "").split():
         return 0
@@ -199,7 +200,7 @@ python buildhistory_emit_pkghistory() {
     pv = d.getVar('PV')
     pr = d.getVar('PR')
     layer = bb.utils.get_file_layer(d.getVar('FILE'), d)
-    license = d.getVar('LICENSE')
+    license = oe.license.convert_legacy_license_to_spdx(d, d.getVar('LICENSE'))
 
     pkgdata_dir = d.getVar('PKGDATA_DIR')
     packages = ""
diff --git a/meta/classes/copyleft_filter.bbclass b/meta/classes/copyleft_filter.bbclass
index 83cd90060d..89bb779ebc 100644
--- a/meta/classes/copyleft_filter.bbclass
+++ b/meta/classes/copyleft_filter.bbclass
@@ -61,9 +61,9 @@ def copyleft_should_include(d):
         exclude = oe.data.typed_value('COPYLEFT_LICENSE_EXCLUDE', d)
 
         try:
-            is_included, reason = oe.license.is_included(d.getVar('LICENSE'), include, exclude)
+            is_included, reason = oe.license.is_included(d, d.getVar('LICENSE'), include, exclude)
         except oe.license.LicenseError as exc:
-            bb.fatal('%s: %s' % (d.getVar('PF'), exc))
+            bb.fatal(exc.format(prefix=d.getVar("PF") + ": "))
         else:
             if is_included:
                 if reason:
diff --git a/meta/conf/licenses.conf b/meta/conf/licenses.conf
index dcb499c3f3..c639477b72 100644
--- a/meta/conf/licenses.conf
+++ b/meta/conf/licenses.conf
@@ -114,6 +114,10 @@ SPDXLICENSEMAP[vim] = "Vim"
 # Silicon Graphics variations
 SPDXLICENSEMAP[SGIv1] = "SGI-OpenGL"
 
+SPDXLICENSEMAP[Apache-2.0-with-LLVM-exception] = "Apache-2.0 WITH LLVM-exception"
+SPDXLICENSEMAP[GPL-3-with-bison-exception] = "GPL-3.0-or-later WITH Bison-exception-2.2"
+SPDXLICENSEMAP[GPL-2.0-with-Linux-syscall-note] = "GPL-2.0-only WITH Linux-syscall-note"
+
 # Additional license directories. Add your custom licenses directories this path.
 # LICENSE_PATH += "${COREBASE}/custom-licenses"
 
diff --git a/meta/lib/oe/license.py b/meta/lib/oe/license.py
index bd28a247c9..9e59d82f8d 100644
--- a/meta/lib/oe/license.py
+++ b/meta/lib/oe/license.py
@@ -9,6 +9,7 @@ import ast
 import re
 import oe.qa
 from fnmatch import fnmatchcase as fnmatch
+import oe.spdx_license
 
 def license_ok(license, dont_want_licenses):
     """ Return False if License exist in dont_want_licenses else True """
@@ -27,89 +28,34 @@ def obsolete_license_list():
             "Artistic-1", "AFL-2", "AFL-1", "AFLv2", "AFLv1", "CDDLv1", "CDDL-1", "EPLv1.0", "FreeType", "Nauman",
             "tcl", "vim", "SGIv1"]
 
-class LicenseError(Exception):
-    pass
-
-class LicenseSyntaxError(LicenseError):
-    def __init__(self, licensestr, exc):
-        self.licensestr = licensestr
-        self.exc = exc
-        LicenseError.__init__(self)
-
-    def __str__(self):
-        return "error in '%s': %s" % (self.licensestr, self.exc)
-
-class InvalidLicense(LicenseError):
-    def __init__(self, license):
-        self.license = license
-        LicenseError.__init__(self)
-
-    def __str__(self):
-        return "invalid characters in license '%s'" % self.license
-
-license_operator_chars = '&|() '
-license_operator = re.compile(r'([' + license_operator_chars + '])')
-license_pattern = re.compile(r'[a-zA-Z0-9.+_\-]+$')
-
-class LicenseVisitor(ast.NodeVisitor):
-    """Get elements based on OpenEmbedded license strings"""
-    def get_elements(self, licensestr):
-        new_elements = []
-        elements = list([x for x in license_operator.split(licensestr) if x.strip()])
-        for pos, element in enumerate(elements):
-            if license_pattern.match(element):
-                if pos > 0 and license_pattern.match(elements[pos-1]):
-                    new_elements.append('&')
-                element = '"' + element + '"'
-            elif not license_operator.match(element):
-                raise InvalidLicense(element)
-            new_elements.append(element)
-
-        return new_elements
-
-    """Syntax tree visitor which can accept elements previously generated with
-    OpenEmbedded license string"""
-    def visit_elements(self, elements):
-        self.visit(ast.parse(' '.join(elements)))
-
-    """Syntax tree visitor which can accept OpenEmbedded license strings"""
-    def visit_string(self, licensestr):
-        self.visit_elements(self.get_elements(licensestr))
-
-class FlattenVisitor(LicenseVisitor):
-    """Flatten a license tree (parsed from a string) by selecting one of each
-    set of OR options, in the way the user specifies"""
-    def __init__(self, choose_licenses):
-        self.choose_licenses = choose_licenses
-        self.licenses = []
-        LicenseVisitor.__init__(self)
-
-    def visit_Constant(self, node):
-        self.licenses.append(node.value)
-
-    def visit_BinOp(self, node):
-        if isinstance(node.op, ast.BitOr):
-            left = FlattenVisitor(self.choose_licenses)
-            left.visit(node.left)
-
-            right = FlattenVisitor(self.choose_licenses)
-            right.visit(node.right)
-
-            selected = self.choose_licenses(left.licenses, right.licenses)
-            self.licenses.extend(selected)
-        else:
-            self.generic_visit(node)
 
-def flattened_licenses(licensestr, choose_licenses):
+LicenseError = oe.spdx_license.ParseError
+
+def flattened_licenses(d, licensestr, choose_licenses):
     """Given a license string and choose_licenses function, return a flat list of licenses"""
-    flatten = FlattenVisitor(choose_licenses)
-    try:
-        flatten.visit_string(licensestr)
-    except SyntaxError as exc:
-        raise LicenseSyntaxError(licensestr, exc)
-    return flatten.licenses
+    def walk_license(node):
+        if isinstance(node, oe.spdx_license.Identifier):
+            return [node.ident]
+
+        if isinstance(node, oe.spdx_license.OrOp):
+            left = walk_license(node.left)
+            right = walk_license(node.right)
+
+            return choose_licenses(left, right)
+
+        ret = []
+        for child in node.children:
+            ret.extend(walk_license(child))
+
+        return ret
+
+    n = parse_legacy_license(d, licensestr)
+    if n is None:
+        return []
+
+    return walk_license(n)
 
-def is_included(licensestr, include_licenses=None, exclude_licenses=None):
+def is_included(d, licensestr, include_licenses=None, exclude_licenses=None):
     """Given a license string, a list of licenses to include and a list of
     licenses to exclude, determine if the license string matches the include
     list and does not match the exclude list.
@@ -147,7 +93,7 @@ def is_included(licensestr, include_licenses=None, exclude_licenses=None):
     if not exclude_licenses:
         exclude_licenses = []
 
-    licenses = flattened_licenses(licensestr, choose_licenses)
+    licenses = flattened_licenses(d, licensestr, choose_licenses)
     excluded = [lic for lic in licenses if exclude_license(lic)]
     included = [lic for lic in licenses if include_license(lic)]
     if excluded:
@@ -155,100 +101,76 @@ def is_included(licensestr, include_licenses=None, exclude_licenses=None):
     else:
         return True, included
 
-class ManifestVisitor(LicenseVisitor):
-    """Walk license tree (parsed from a string) removing the incompatible
-    licenses specified"""
-    def __init__(self, dont_want_licenses, canonical_license, d):
-        self._dont_want_licenses = dont_want_licenses
-        self._canonical_license = canonical_license
-        self._d = d
-        self._operators = []
-
-        self.licenses = []
-        self.licensestr = ''
-
-        LicenseVisitor.__init__(self)
-
-    def visit(self, node):
-        if isinstance(node, ast.Constant):
-            lic = node.value
-
-            if license_ok(self._canonical_license(self._d, lic),
-                    self._dont_want_licenses) == True:
-                if self._operators:
-                    ops = []
-                    for op in self._operators:
-                        if op == '[':
-                            ops.append(op)
-                        elif op == ']':
-                            ops.append(op)
-                        else:
-                            if not ops:
-                                ops.append(op)
-                            elif ops[-1] in ['[', ']']:
-                                ops.append(op)
-                            else:
-                                ops[-1] = op 
-
-                    for op in ops:
-                        if op == '[' or op == ']':
-                            self.licensestr += op
-                        elif self.licenses:
-                            self.licensestr += ' ' + op + ' '
-
-                    self._operators = []
-
-                self.licensestr += lic
-                self.licenses.append(lic)
-        elif isinstance(node, ast.BitAnd):
-            self._operators.append("&")
-        elif isinstance(node, ast.BitOr):
-            self._operators.append("|")
-        elif isinstance(node, ast.List):
-            self._operators.append("[")
-        elif isinstance(node, ast.Load):
-            self.licensestr += "]"
-
-        self.generic_visit(node)
-
-def manifest_licenses(licensestr, dont_want_licenses, canonical_license, d):
+def manifest_licenses(d, licensestr, dont_want_licenses):
     """Given a license string and dont_want_licenses list,
        return license string filtered and a list of licenses"""
-    manifest = ManifestVisitor(dont_want_licenses, canonical_license, d)
 
-    try:
-        elements = manifest.get_elements(licensestr)
+    node = parse_legacy_license(d, licensestr)
+    licenses = []
+
+    def walk_license(node):
+        nonlocal licenses
+        if isinstance(node, oe.spdx_license.Identifier):
+            if license_ok(node.ident, dont_want_licenses):
+                licenses.append(node.ident)
+                return node
+
+            return None
+
+        old_children = node.children
+        node.children = []
 
-        # Replace '()' to '[]' for handle in ast as List and Load types.
-        elements = ['[' if e == '(' else e for e in elements]
-        elements = [']' if e == ')' else e for e in elements]
+        for child in old_children:
+            node.children.append(walk_license(child))
 
-        manifest.visit_elements(elements)
-    except SyntaxError as exc:
-        raise LicenseSyntaxError(licensestr, exc)
+        # If all children are removed, remove this node also
+        if not any(node.children):
+            return None
 
-    # Replace '[]' to '()' for output correct license.
-    manifest.licensestr = manifest.licensestr.replace('[', '(').replace(']', ')')
+        # Elide a binary operation if it now only has one child
+        if isinstance(node, (oe.spdx_license.AndOp, oe.spdx_license.OrOp)):
+            if node.left is None:
+                return node.right
+            if node.right is None:
+                return node.left
 
-    return (manifest.licensestr, manifest.licenses)
+        # The left side (the license side) of a WITH can be removed, but not
+        # the right (the exception)
+        if isinstance(node, oe.spdx_license.WithOp):
+            if node.license is None:
+                return None
 
-class ListVisitor(LicenseVisitor):
-    """Record all different licenses found in the license string"""
-    def __init__(self):
-        self.licenses = set()
+        # If one of the above cases doesn't catch everything, raise an error
+        if not all(node.children):
+            node.children = old_children
+            pn = d.getVar("PN")
+            bb.fatal(f"{pn}: Removing licenses from {node.to_string} results in an invalid license expression")
 
-    def visit_Constant(self, node):
-        self.licenses.add(node.value)
+        return node
 
-def list_licenses(licensestr):
-    """Simply get a list of all licenses mentioned in a license string.
+    if node:
+        node = walk_license(node)
+
+    if not node:
+        return ("", licenses)
+
+    return (node.to_string(), licenses)
+
+def list_licenses(licensestr, d):
+    """Simply get a set of all licenses mentioned in a license string.
        Binary operators are not applied or taken into account in any way"""
-    visitor = ListVisitor()
-    try:
-        visitor.visit_string(licensestr)
-    except SyntaxError as exc:
-        raise LicenseSyntaxError(licensestr, exc)
-    return visitor.licenses
+    licenses = []
+
+    def walk_license(node):
+        nonlocal licenses
+        if isinstance(node, oe.spdx_license.Identifier):
+            licenses.append(node.ident)
+
+        for child in node.children:
+            walk_license(child)
+
+    walk_license(parse_legacy_license(d, licensestr))
+    return set(licenses)
 
 def apply_pkg_license_exception(pkg, bad_licenses, exceptions):
     """Return remaining bad licenses after removing any package exceptions"""
@@ -293,31 +215,38 @@ def expand_wildcard_licenses(d, wildcard_licenses):
 
     return list(licenses)
 
-def incompatible_license_contains(license, truevalue, falsevalue, d):
+def incompatible_license_contains(d, license, truevalue, falsevalue):
     license = canonical_license(d, license)
     bad_licenses = (d.getVar('INCOMPATIBLE_LICENSE') or "").split()
     bad_licenses = expand_wildcard_licenses(d, bad_licenses)
     return truevalue if license in bad_licenses else falsevalue
 
 def incompatible_pkg_license(d, dont_want_licenses, license):
-    # Handles an "or" or two license sets provided by
-    # flattened_licenses(), pick one that works if possible.
-    def choose_lic_set(a, b):
-        return a if all(license_ok(canonical_license(d, lic),
-                            dont_want_licenses) for lic in a) else b
+    def walk_license(node):
+        if isinstance(node, oe.spdx_license.Identifier):
+            if license_ok(node.ident, dont_want_licenses):
+                return []
+            return [node.ident]
+
+        incompatible_lic = []
+        for child in node.children:
+            c = walk_license(child)
+            if not c and isinstance(node, oe.spdx_license.OrOp):
+                return []
+            incompatible_lic.extend(c)
+
+        return incompatible_lic
 
     try:
-        licenses = flattened_licenses(license, choose_lic_set)
-    except LicenseError as exc:
-        bb.fatal('%s: %s' % (d.getVar('P'), exc))
+        node = parse_legacy_license(d, license)
+    except oe.spdx_license.ParseError as e:
+        bb.fatal(e.format(prefix=d.getVar('P') + ":"))
+        return []
 
-    incompatible_lic = []
-    for l in licenses:
-        license = canonical_license(d, l)
-        if not license_ok(license, dont_want_licenses):
-            incompatible_lic.append(license)
+    if not node:
+        return []
 
-    return sorted(incompatible_lic)
+    return sorted(walk_license(node))
 
 def incompatible_license(d, dont_want_licenses, package=None):
     """
@@ -394,6 +323,92 @@ def check_license_flags(d):
             return unmatched_flags
     return None
 
+
+def _substitute_legacy_license(licensestr):
+    if not licensestr or licensestr == "CLOSED":
+        return None
+
+    licensestr = licensestr.replace("&", " AND ").replace("|", " OR ")
+
+    return licensestr
+
+def _parse_legacy_license(d, licensestr):
+    node = oe.spdx_license.parse(licensestr, allow_unknown=True)
+
+    unknown_found = False
+
+    def convert_unknown(node):
+        nonlocal unknown_found
+
+        if isinstance(node, oe.spdx_license.UnknownId):
+            if d is not None:
+                v = d.getVarFlag("SPDXLICENSEMAP", node.ident)
+                if v:
+                    return oe.spdx_license.parse(v)
+
+            if node.ident == "Unknown":
+                return node
+
+            ident = re.sub(r'[^a-zA-Z0-9\.\-]', '-', node.ident)
+            unknown_found = True
+            return oe.spdx_license.LicenseRef("LicenseRef-" + ident, node.ident, token=node.token)
+
+        node.children = [convert_unknown(child) for child in node.children]
+        return node
+
+    return convert_unknown(node), unknown_found
+
+def parse_legacy_license(d, licensestr):
+    """
+    Converts a legacy license string to a SPDX license string and parses it,
+    returning a SPDX license abstract syntax tree
+
+    This can be removed and replaced with oe.spdx_license.parse(licensestr)
+    once legacy licenses are not longer allowed.
+
+    Unknown license IDs in the string are automatically converted to
+    LicenseRefs, assuming that they are provided as either a common license
+    file or a NO_GENERIC_LICENSE
+    """
+    licensestr = _substitute_legacy_license(licensestr)
+    if licensestr is None:
+        return None
+
+    node, _ = _parse_legacy_license(d, licensestr)
+    return node
+
+def convert_legacy_license_to_spdx(d, licensestr):
+    """
+    Converts a legacy license string to an SPDX-compatible license string
+    """
+    s = parse_legacy_license(d, licensestr)
+    if not s:
+        return licensestr
+
+    return s.to_string()
+
+def get_license_path(d, node):
+    """
+    Given an node from an SPDX AST, return the path to the license file
+    """
+    if isinstance(node, oe.spdx_license.LicenseRef):
+        filename = d.getVarFlag("NO_GENERIC_LICENSE", node.name)
+        if filename:
+            return d.expand("${S}/" + filename), filename
+
+    for lic_dir in [d.getVar("COMMON_LICENSE_DIR")] + (d.getVar("LICENSE_PATH") or "").split():
+        p = os.path.join(lic_dir, node.name)
+        if os.path.isfile(p):
+            return p, None
+
+        # Some license expressions already contain the "LicenseRef-" prefix, so
+        # look for a matching license name
+        p = os.path.join(lic_dir, node.ident)
+        if os.path.isfile(p):
+            return p, None
+
+    return None, None
+
 def check_license_format(d):
     """
     This function checks if LICENSE is well defined,
@@ -401,22 +416,75 @@ def check_license_format(d):
         No spaces are allowed between LICENSES.
     """
     pn = d.getVar('PN')
-    licenses = d.getVar('LICENSE')
-
-    elements = list(filter(lambda x: x.strip(), license_operator.split(licenses)))
-    for pos, element in enumerate(elements):
-        if license_pattern.match(element):
-            if pos > 0 and license_pattern.match(elements[pos - 1]):
-                oe.qa.handle_error('license-format',
-                        '%s: LICENSE value "%s" has an invalid format - license names ' \
-                        'must be separated by the following characters to indicate ' \
-                        'the license selection: %s' %
-                        (pn, licenses, license_operator_chars), d)
-        elif not license_operator.match(element):
-            oe.qa.handle_error('license-format',
-                    '%s: LICENSE value "%s" has an invalid separator "%s" that is not ' \
-                    'in the valid list of separators (%s)' %
-                    (pn, licenses, element, license_operator_chars), d)
+    packages = d.getVar("PACKAGES").split()
+
+    for v in ["LICENSE"] + [f"LICENSE:{p}" for p in packages]:
+        licenses = d.getVar(v)
+
+        if licenses == "INVALID":
+            continue
+
+        if licenses == "CLOSED":
+            bb.warn(f'{pn}: {v} is using "CLOSED", which is deprecated. Convert to using a license ref pointing to an actual license file, e.g.\n{v} = "LicenseRef-{pn}-CLOSED"')
+            continue
+
+        if not licenses:
+            continue
+
+        try:
+            spdx_license = _substitute_legacy_license(licenses)
+
+            s, unknown_found = _parse_legacy_license(d, spdx_license)
+            if not s:
+                continue
+
+            if spdx_license != licenses or unknown_found:
+                bb.warn(f'{pn}: {v} is using an old syntax and should be upgraded to: "{s.sort().to_string()}"')
+
+            if s:
+                # Check license refs
+                missing_generic_refs = set()
+                missing_refs = set()
+                deprecated = set()
+                def walk_license(node):
+                    nonlocal missing_generic_refs
+                    nonlocal missing_refs
+
+                    if isinstance(node, oe.spdx_license.LicenseRef):
+                        p, non_generic_fn = get_license_path(d, node)
+                        if not p:
+                            if non_generic_fn:
+                                missing_refs.add(node.ident)
+                            else:
+                                missing_generic_refs.add(node.ident)
+
+                    if isinstance(node, (oe.spdx_license.LicenseId, oe.spdx_license.ExceptionId)):
+                        if node.deprecated:
+                            deprecated.add(node.ident)
+
+                    for child in node.children:
+                        walk_license(child)
+
+                walk_license(s)
+                if missing_refs:
+                    missing_refs = ', '.join(sorted(missing_refs))
+                    oe.qa.handle_error("license-format",
+                                        f'{pn}: LICENSE contains a reference to license(s) {missing_refs} which are not defined in NO_GENERIC_LICENSE',
+                                        d)
+
+                if missing_generic_refs:
+                    missing_generic_refs = ', '.join(sorted(missing_generic_refs))
+                    oe.qa.handle_error("license-format",
+                                        f'{pn}: LICENSE contains a reference to license(s) {missing_generic_refs} for which no generic license was found',
+                                        d)
+
+                if deprecated:
+                    deprecated = ", ".join(sorted(deprecated))
+                    bb.warn(f'{pn}: {v} contains deprecated licenses {deprecated}')
+
+        except oe.spdx_license.ParseError as e:
+            oe.qa.handle_error("license-format",
+                            f'{pn}: {v} value has an invalid format:\n{e.format()}\n', d)
 
 def skip_incompatible_package_licenses(d, pkgs):
     if not pkgs:
@@ -461,13 +529,11 @@ def tidy_licenses(value):
     """
     Flat, split and sort licenses.
     """
-    from oe.license import flattened_licenses
-
     def _choose(a, b):
-        str_a, str_b  = sorted((" & ".join(a), " & ".join(b)), key=str.casefold)
-        return ["(%s | %s)" % (str_a, str_b)]
+        str_a, str_b  = sorted((" AND ".join(a), " AND ".join(b)), key=str.casefold)
+        return ["(%s OR %s)" % (str_a, str_b)]
 
     if not isinstance(value, str):
-        value = " & ".join(value)
+        value = " AND ".join(value)
 
-    return sorted(list(set(flattened_licenses(value, _choose))), key=str.casefold)
+    return sorted(list(set(flattened_licenses(None, value, _choose))), key=str.casefold)
diff --git a/meta/lib/oe/spdx30_tasks.py b/meta/lib/oe/spdx30_tasks.py
index 79e18db11d..987f8692f6 100644
--- a/meta/lib/oe/spdx30_tasks.py
+++ b/meta/lib/oe/spdx30_tasks.py
@@ -6,12 +6,14 @@
 
 import json
 import oe.cve_check
+import oe.license
 import oe.packagedata
 import oe.patch
 import oe.sbom30
+import oe.sdk
 import oe.spdx30
 import oe.spdx_common
-import oe.sdk
+import oe.spdx_license
 import os
 import re
 import urllib.parse
@@ -37,101 +39,52 @@ def set_timestamp_now(d, o, prop):
 def add_license_expression(
     d, objset, license_expression, license_data, search_objsets=[]
 ):
-    simple_license_text = {}
     license_text_map = {}
+    pn = d.getVar("PN")
 
-    def add_license_text(name):
-        nonlocal objset
-        nonlocal simple_license_text
-
-        if name in simple_license_text:
-            return simple_license_text[name]
-
-        for o in [objset] + search_objsets:
-            lic = o.find_filter(
-                oe.spdx30.simplelicensing_SimpleLicensingText,
-                name=name,
-            )
-
-            if lic is not None:
-                simple_license_text[name] = lic
-                return lic
-
-        lic = objset.add(
-            oe.spdx30.simplelicensing_SimpleLicensingText(
-                _id=objset.new_spdxid("license-text", name),
-                creationInfo=objset.doc.creationInfo,
-                name=name,
-            )
-        )
-        objset.set_element_alias(lic)
-        simple_license_text[name] = lic
-
-        if name == "PD":
-            lic.simplelicensing_licenseText = "Software released to the public domain"
-            return lic
-
-        # Seach for the license in COMMON_LICENSE_DIR and LICENSE_PATH
-        for directory in [d.getVar("COMMON_LICENSE_DIR")] + (
-            d.getVar("LICENSE_PATH") or ""
-        ).split():
-            try:
-                with (Path(directory) / name).open(errors="replace") as f:
-                    lic.simplelicensing_licenseText = f.read()
-                    return lic
-
-            except FileNotFoundError:
-                pass
-
-        # If it's not SPDX or PD, then NO_GENERIC_LICENSE must be set
-        filename = d.getVarFlag("NO_GENERIC_LICENSE", name)
-        if filename:
-            filename = d.expand("${S}/" + filename)
-            with open(filename, errors="replace") as f:
-                lic.simplelicensing_licenseText = f.read()
-                return lic
-        else:
-            bb.fatal("Cannot find any text for license %s" % name)
-
-    def convert(l):
+    def walk_license(node):
         nonlocal license_text_map
 
-        if l == "(" or l == ")":
-            return l
-
-        if l == "&":
-            return "AND"
-
-        if l == "|":
-            return "OR"
-
-        if l == "CLOSED":
-            return "NONE"
+        if isinstance(node, oe.spdx_license.LicenseRef):
+            if node.ident not in license_text_map:
+                lic = None
+                for o in [objset] + search_objsets:
+                    lic = o.find_filter(
+                        oe.spdx30.simplelicensing_SimpleLicensingText,
+                        name=node.name,
+                    )
+                    if lic:
+                        break
 
-        spdx_license = d.getVarFlag("SPDXLICENSEMAP", l) or l
-        if spdx_license in license_data["licenses"]:
-            return spdx_license
+                if lic is None:
+                    p, _ = oe.license.get_license_path(d, node)
+                    if p is None:
+                        bb.fatal(f"{pn}: No generic license file exists for: {node.ident} in any provider")
+                        return
+
+                    with open(p, errors="replace") as f:
+                        lic_text = f.read()
+
+                    lic = objset.add(
+                        oe.spdx30.simplelicensing_SimpleLicensingText(
+                            _id=objset.new_spdxid("license-text", node.name),
+                            creationInfo=objset.doc.creationInfo,
+                            name=node.name,
+                            simplelicensing_licenseText=lic_text,
+                        )
+                    )
+                    objset.set_element_alias(lic)
 
-        spdx_license = "LicenseRef-" + l
-        if spdx_license not in license_text_map:
-            license_text_map[spdx_license] = oe.sbom30.get_element_link_id(
-                add_license_text(l)
-            )
+                license_text_map[node.ident] = lic
 
-        return spdx_license
+        for child in node.children:
+            walk_license(child)
 
-    lic_split = (
-        license_expression.replace("(", " ( ")
-        .replace(")", " ) ")
-        .replace("|", " | ")
-        .replace("&", " & ")
-        .split()
-    )
-    spdx_license_expression = " ".join(convert(l) for l in lic_split)
+    s = oe.license.parse_legacy_license(d, license_expression)
+    if s is None:
+        return None
 
-    o = objset.new_license_expression(
-        spdx_license_expression, license_data, license_text_map
-    )
+    o = objset.new_license_expression(s.to_string(), license_data, license_text_map)
     objset.set_element_alias(o)
     return o
 
@@ -862,11 +815,18 @@ def create_spdx(d):
     recipe_spdx_license = add_license_expression(
         d, build_objset, d.getVar("LICENSE"), license_data, [recipe_objset]
     )
-    build_objset.new_relationship(
-        source_files,
-        oe.spdx30.RelationshipType.hasDeclaredLicense,
-        [oe.sbom30.get_element_link_id(recipe_spdx_license)],
-    )
+    if recipe_spdx_license:
+        build_objset.new_relationship(
+            source_files,
+            oe.spdx30.RelationshipType.hasDeclaredLicense,
+            [oe.sbom30.get_element_link_id(recipe_spdx_license)],
+        )
+    else:
+        build_objset.new_relationship(
+            source_files,
+            oe.spdx30.RelationshipType.hasDeclaredLicense,
+            None,
+        )
 
     dep_sources = {}
     if oe.spdx_common.process_sources(d) and include_sources:
@@ -1022,11 +982,18 @@ def create_spdx(d):
             else:
                 package_spdx_license = recipe_spdx_license
 
-            pkg_objset.new_relationship(
-                [spdx_package],
-                oe.spdx30.RelationshipType.hasDeclaredLicense,
-                [oe.sbom30.get_element_link_id(package_spdx_license)],
-            )
+            if package_spdx_license:
+                pkg_objset.new_relationship(
+                    [spdx_package],
+                    oe.spdx30.RelationshipType.hasDeclaredLicense,
+                    [oe.sbom30.get_element_link_id(package_spdx_license)],
+                )
+            else:
+                pkg_objset.new_relationship(
+                    [spdx_package],
+                    oe.spdx30.RelationshipType.hasDeclaredLicense,
+                    None,
+                )
 
             # Add concluded license relationship if manually set
             # Only add when license analysis has been explicitly performed
@@ -1037,12 +1004,12 @@ def create_spdx(d):
                 concluded_spdx_license = add_license_expression(
                     d, build_objset, concluded_license_str, license_data
                 )
-
-                pkg_objset.new_relationship(
-                    [spdx_package],
-                    oe.spdx30.RelationshipType.hasConcludedLicense,
-                    [oe.sbom30.get_element_link_id(concluded_spdx_license)],
-                )
+                if concluded_spdx_license:
+                    pkg_objset.new_relationship(
+                        [spdx_package],
+                        oe.spdx30.RelationshipType.hasConcludedLicense,
+                        [oe.sbom30.get_element_link_id(concluded_spdx_license)],
+                    )
 
             bb.debug(1, "Adding package files to SPDX for package %s" % pkg_name)
             package_files, excluded_files = add_package_files(
diff --git a/meta/lib/oeqa/selftest/cases/incompatible_lic.py b/meta/lib/oeqa/selftest/cases/incompatible_lic.py
index 12f4d14f16..5467640cdd 100644
--- a/meta/lib/oeqa/selftest/cases/incompatible_lic.py
+++ b/meta/lib/oeqa/selftest/cases/incompatible_lic.py
@@ -96,7 +96,7 @@ class IncompatibleLicenseTests(OESelftestTestCase):
     # Verify that a package with a non-SPDX license cannot be built when
     # INCOMPATIBLE_LICENSE contains this license
     def test_incompatible_nonspdx_license(self):
-        self.lic_test('incompatible-nonspdx-license', 'FooLicense', 'FooLicense')
+        self.lic_test('incompatible-nonspdx-license', 'LicenseRef-FooLicense', 'LicenseRef-FooLicense')
 
 class IncompatibleLicensePerImageTests(OESelftestTestCase):
     def default_config(self):
@@ -104,6 +104,7 @@ class IncompatibleLicensePerImageTests(OESelftestTestCase):
 IMAGE_INSTALL:append = " bash"
 INCOMPATIBLE_LICENSE:pn-core-image-minimal = "GPL-3.0* LGPL-3.0*"
 MACHINE_ESSENTIAL_EXTRA_RDEPENDS:remove = "tar"
+NO_GENERIC_LICENSE[SomeLicense] = "COPYING"
 """
 
     def test_bash_default(self):
@@ -116,7 +117,7 @@ MACHINE_ESSENTIAL_EXTRA_RDEPENDS:remove = "tar"
 
     def test_bash_and_license(self):
         self.disable_class("create-spdx")
-        self.write_config(self.default_config() + '\nLICENSE:append:pn-bash = " & SomeLicense"\nERROR_QA:remove:pn-bash = "license-exists"')
+        self.write_config(self.default_config() + '\nLICENSE:append:pn-bash = " AND LicenseRef-SomeLicense"\nERROR_QA:remove:pn-bash = "license-exists"')
         error_msg = "ERROR: core-image-minimal-1.0-r0 do_rootfs: Some packages cannot be installed into the image because they have incompatible licenses:\n\tbash (GPL-3.0-or-later)"
 
         result = bitbake('core-image-minimal', ignore_status=True)
@@ -125,7 +126,7 @@ MACHINE_ESSENTIAL_EXTRA_RDEPENDS:remove = "tar"
 
     def test_bash_or_license(self):
         self.disable_class("create-spdx")
-        self.write_config(self.default_config() + '\nLICENSE:append:pn-bash = " | SomeLicense"\nERROR_QA:remove:pn-bash = "license-exists"\nERROR_QA:remove:pn-core-image-minimal = "license-file-missing"')
+        self.write_config(self.default_config() + '\nLICENSE:append:pn-bash = " OR LicenseRef-SomeLicense"\nERROR_QA:remove:pn-bash = "license-exists"\nERROR_QA:remove:pn-core-image-minimal = "license-file-missing"')
 
         bitbake('core-image-minimal')
 
diff --git a/meta/lib/oeqa/selftest/cases/oelib/license.py b/meta/lib/oeqa/selftest/cases/oelib/license.py
index 49b28951f7..33a08ada67 100644
--- a/meta/lib/oeqa/selftest/cases/oelib/license.py
+++ b/meta/lib/oeqa/selftest/cases/oelib/license.py
@@ -6,14 +6,8 @@
 
 from unittest.case import TestCase
 import oe.license
+import oe.spdx_license
 
-class SeenVisitor(oe.license.LicenseVisitor):
-    def __init__(self):
-        self.seen = []
-        oe.license.LicenseVisitor.__init__(self)
-
-    def visit_Constant(self, node):
-        self.seen.append(node.value)
 
 class TestSingleLicense(TestCase):
     licenses = [
@@ -22,84 +16,266 @@ class TestSingleLicense(TestCase):
         "Artistic-1.0",
         "MIT",
         "GPL-3.0-or-later",
-        "FOO_BAR",
+        "LicenseRef-FOO-BAR",
     ]
     invalid_licenses = ["GPL/BSD"]
 
     @staticmethod
     def parse(licensestr):
-        visitor = SeenVisitor()
-        visitor.visit_string(licensestr)
-        return visitor.seen
+        return oe.spdx_license.parse(licensestr)
 
     def test_single_licenses(self):
         for license in self.licenses:
-            licenses = self.parse(license)
-            self.assertListEqual(licenses, [license])
+            n = oe.spdx_license.parse(license)
+            self.assertListEqual([n.ident], [license])
 
     def test_invalid_licenses(self):
         for license in self.invalid_licenses:
-            with self.assertRaises(oe.license.InvalidLicense) as cm:
-                self.parse(license)
-            self.assertEqual(cm.exception.license, license)
+            with self.assertRaises(oe.spdx_license.ParseError) as cm:
+                oe.spdx_license.parse(license)
+            self.assertEqual(cm.exception.expression, license)
+
 
 class TestSimpleCombinations(TestCase):
-    tests = {
-        "FOO&BAR": ["FOO", "BAR"],
-        "BAZ & MOO": ["BAZ", "MOO"],
-        "ALPHA|BETA": ["ALPHA"],
-        "BAZ&MOO|FOO": ["FOO"],
-        "FOO&BAR|BAZ": ["FOO", "BAR"],
-    }
-    preferred = ["ALPHA", "FOO", "BAR"]
+    tests = [
+        (
+            "LicenseRef-FOO AND LicenseRef-BAR",
+            ["LicenseRef-FOO", "LicenseRef-BAR"],
+        ),
+        (
+            "LicenseRef-BAZ AND LicenseRef-MOO",
+            ["LicenseRef-BAZ", "LicenseRef-MOO"],
+        ),
+        (
+            "LicenseRef-ALPHA OR LicenseRef-BETA",
+            ["LicenseRef-ALPHA"],
+        ),
+        (
+            "LicenseRef-BAZ AND LicenseRef-MOO OR LicenseRef-FOO",
+            ["LicenseRef-FOO"],
+        ),
+        (
+            "LicenseRef-FOO AND LicenseRef-BAR OR LicenseRef-BAZ",
+            ["LicenseRef-FOO", "LicenseRef-BAR"],
+        ),
+    ]
+    preferred = ["LicenseRef-ALPHA", "LicenseRef-FOO", "LicenseRef-BAR"]
 
     def test_tests(self):
         def choose(a, b):
+            print(a, b)
             if all(lic in self.preferred for lic in b):
                 return b
             else:
                 return a
 
-        for license, expected in self.tests.items():
-            licenses = oe.license.flattened_licenses(license, choose)
+        for license, expected in self.tests:
+            licenses = oe.license.flattened_licenses(None, license, choose)
             self.assertListEqual(licenses, expected)
 
+
 class TestComplexCombinations(TestSimpleCombinations):
-    tests = {
-        "FOO & (BAR | BAZ)&MOO": ["FOO", "BAR", "MOO"],
-        "(ALPHA|(BETA&THETA)|OMEGA)&DELTA": ["OMEGA", "DELTA"],
-        "((ALPHA|BETA)&FOO)|BAZ": ["BETA", "FOO"],
-        "(GPL-2.0-only|Proprietary)&BSD-4-clause&MIT": ["GPL-2.0-only", "BSD-4-clause", "MIT"],
-    }
-    preferred = ["BAR", "OMEGA", "BETA", "GPL-2.0-only"]
+    tests = [
+        (
+            "LicenseRef-FOO AND (LicenseRef-BAR OR LicenseRef-BAZ) AND LicenseRef-MOO",
+            ["LicenseRef-FOO", "LicenseRef-BAR", "LicenseRef-MOO"],
+        ),
+        (
+            "(LicenseRef-ALPHA OR (LicenseRef-BETA AND LicenseRef-THETA) OR LicenseRef-OMEGA) AND LicenseRef-DELTA",
+            ["LicenseRef-OMEGA", "LicenseRef-DELTA"],
+        ),
+        (
+            "((LicenseRef-ALPHA OR LicenseRef-BETA) AND LicenseRef-FOO) OR LicenseRef-BAZ",
+            ["LicenseRef-BETA", "LicenseRef-FOO"],
+        ),
+        (
+            "(GPL-2.0-only OR LicenseRef-Proprietary) AND BSD-4-clause AND MIT",
+            ["GPL-2.0-only", "BSD-4-Clause", "MIT"],
+        ),
+    ]
+    preferred = [
+        "LicenseRef-BAR",
+        "LicenseRef-OMEGA",
+        "LicenseRef-BETA",
+        "GPL-2.0-only",
+    ]
+
 
 class TestIsIncluded(TestCase):
-    tests = {
-        ("FOO | BAR", None, None):
-            [True, ["FOO"]],
-        ("FOO | BAR", None, "FOO"):
-            [True, ["BAR"]],
-        ("FOO | BAR", "BAR", None):
-            [True, ["BAR"]],
-        ("FOO | BAR & FOOBAR", "*BAR", None):
-            [True, ["BAR", "FOOBAR"]],
-        ("FOO | BAR & FOOBAR", None, "FOO*"):
-            [False, ["FOOBAR"]],
-        ("(FOO | BAR) & FOOBAR | BARFOO", None, "FOO"):
-            [True, ["BAR", "FOOBAR"]],
-        ("(FOO | BAR) & FOOBAR | BAZ & MOO & BARFOO", None, "FOO"):
-            [True, ["BAZ", "MOO", "BARFOO"]],
-        ("GPL-3.0-or-later & GPL-2.0-only & LGPL-2.1-only | Proprietary", None, None):
-            [True, ["GPL-3.0-or-later", "GPL-2.0-only", "LGPL-2.1-only"]],
-        ("GPL-3.0-or-later & GPL-2.0-only & LGPL-2.1-only | Proprietary", None, "GPL-3.0-or-later"):
-            [True, ["Proprietary"]],
-        ("GPL-3.0-or-later & GPL-2.0-only & LGPL-2.1-only | Proprietary", None, "GPL-3.0-or-later Proprietary"):
-            [False, ["GPL-3.0-or-later"]]
-    }
+    tests = [
+        (
+            "LicenseRef-FOO OR LicenseRef-BAR",
+            None,
+            None,
+            True,
+            ["LicenseRef-FOO"],
+        ),
+        (
+            "LicenseRef-FOO OR LicenseRef-BAR",
+            None,
+            "LicenseRef-FOO",
+            True,
+            ["LicenseRef-BAR"],
+        ),
+        (
+            "LicenseRef-FOO OR LicenseRef-BAR",
+            "LicenseRef-BAR",
+            None,
+            True,
+            ["LicenseRef-BAR"],
+        ),
+        (
+            "LicenseRef-FOO OR LicenseRef-BAR AND LicenseRef-FOOBAR",
+            "*BAR",
+            None,
+            True,
+            ["LicenseRef-BAR", "LicenseRef-FOOBAR"],
+        ),
+        (
+            "LicenseRef-FOO OR LicenseRef-BAR AND LicenseRef-FOOBAR",
+            None,
+            "LicenseRef-FOO*",
+            False,
+            ["LicenseRef-FOOBAR"],
+        ),
+        (
+            "(LicenseRef-FOO OR LicenseRef-BAR) AND LicenseRef-FOOBAR OR LicenseRef-BARFOO",
+            None,
+            "LicenseRef-FOO",
+            True,
+            ["LicenseRef-BAR", "LicenseRef-FOOBAR"],
+        ),
+        (
+            "(FOO OR BAR) AND FOOBAR OR BAZ AND MOO AND BARFOO",
+            None,
+            "FOO",
+            True,
+            ["LicenseRef-BAZ", "LicenseRef-MOO", "LicenseRef-BARFOO"],
+        ),
+        (
+            "GPL-3.0-or-later AND GPL-2.0-only AND LGPL-2.1-only OR Proprietary",
+            None,
+            None,
+            True,
+            ["GPL-3.0-or-later", "GPL-2.0-only", "LGPL-2.1-only"],
+        ),
+        (
+            "GPL-3.0-or-later AND GPL-2.0-only AND LGPL-2.1-only OR Proprietary",
+            None,
+            "GPL-3.0-or-later",
+            True,
+            ["LicenseRef-Proprietary"],
+        ),
+        (
+            "GPL-3.0-or-later AND GPL-2.0-only AND LGPL-2.1-only OR Proprietary",
+            None,
+            "GPL-3.0-or-later LicenseRef-Proprietary",
+            False,
+            ["GPL-3.0-or-later"],
+        ),
+    ]
 
     def test_tests(self):
-        for args, expected in self.tests.items():
-            is_included, licenses = oe.license.is_included(
-                args[0], (args[1] or '').split(), (args[2] or '').split())
-            self.assertEqual(is_included, expected[0])
-            self.assertListEqual(licenses, expected[1])
+        for (
+            expression,
+            include,
+            exclude,
+            expect_included,
+            expect_licenses,
+        ) in self.tests:
+            actual_included, actual_licenses = oe.license.is_included(
+                None,
+                expression,
+                (include or "").split(),
+                (exclude or "").split(),
+            )
+            self.assertEqual(actual_included, expect_included)
+            self.assertListEqual(actual_licenses, expect_licenses)
+
+
+class TestSort(TestCase):
+    tests = [
+        (
+            "MIT AND MIT",
+            "MIT",
+        ),
+        (
+            "MIT OR MIT",
+            "MIT",
+        ),
+        (
+            "MIT AND 0BSD",
+            "0BSD AND MIT",
+        ),
+        (
+            "MIT OR 0BSD",
+            "0BSD OR MIT",
+        ),
+        (
+            "(MIT AND 0BSD) AND (MIT AND 0BSD)",
+            "0BSD AND MIT",
+        ),
+        (
+            "(MIT AND 0BSD) OR (MIT AND GPL-3.0-or-later)",
+            "0BSD AND MIT OR GPL-3.0-or-later AND MIT",
+        ),
+        (
+            "(MIT OR 0BSD) AND (MIT OR GPL-3.0-or-later)",
+            "(0BSD OR MIT) AND (GPL-3.0-or-later OR MIT)",
+        ),
+        (
+            "(MIT AND 0BSD) AND (MIT AND GPL-3.0-or-later)",
+            "0BSD AND GPL-3.0-or-later AND MIT",
+        ),
+        (
+            "(MIT OR 0BSD) OR (MIT OR GPL-3.0-or-later)",
+            "0BSD OR GPL-3.0-or-later OR MIT",
+        ),
+        (
+            "((MIT OR 0BSD) OR MIT) OR GPL-3.0-or-later",
+            "0BSD OR GPL-3.0-or-later OR MIT",
+        ),
+        (
+            "MIT OR (0BSD OR (MIT OR GPL-3.0-or-later))",
+            "0BSD OR GPL-3.0-or-later OR MIT",
+        ),
+        (
+            "MIT OR (0BSD OR MIT) OR GPL-3.0-or-later",
+            "0BSD OR GPL-3.0-or-later OR MIT",
+        ),
+        (
+            "(MIT AND (0BSD OR MIT)) AND (0BSD AND GPL-3.0-or-later)",
+            "0BSD AND GPL-3.0-or-later AND MIT AND (0BSD OR MIT)",
+        ),
+        (
+            "(MIT OR (0BSD AND MIT)) OR (0BSD OR GPL-3.0-or-later)",
+            "0BSD AND MIT OR 0BSD OR GPL-3.0-or-later OR MIT",
+        ),
+        (
+            "(MIT AND ((0BSD OR MIT) AND LGPL-3.0-or-later)) AND (0BSD AND GPL-3.0-or-later)",
+            "0BSD AND GPL-3.0-or-later AND LGPL-3.0-or-later AND MIT AND (0BSD OR MIT)",
+        ),
+        (
+            "(MIT AND ((0BSD OR MIT) AND LGPL-3.0-or-later)) AND ((0BSD AND (0BSD OR MIT)) AND GPL-3.0-or-later)",
+            "0BSD AND GPL-3.0-or-later AND LGPL-3.0-or-later AND MIT AND (0BSD OR MIT)",
+        ),
+        (
+            # GPL-3.0-later is split across an otherwise sorted list; make sure
+            # it can be detected and merged
+            "(0BSD AND GPL-3.0-or-later) AND (GPL-3.0-or-later AND MIT)",
+            "0BSD AND GPL-3.0-or-later AND MIT",
+        ),
+        (
+            "GPL-3.0-or-later WITH GCC-exception-3.1 AND GPL-3.0-or-later WITH GCC-exception-3.1",
+            "GPL-3.0-or-later WITH GCC-exception-3.1",
+        ),
+        (
+            "GPL-3.0-or-later WITH GCC-exception-3.1 AND GPL-3.0-or-later",
+            "GPL-3.0-or-later AND GPL-3.0-or-later WITH GCC-exception-3.1",
+        ),
+    ]
+
+    def test_sort(self):
+        for expression, expected in self.tests:
+            actual = oe.spdx_license.parse(expression).sort()
+            self.assertEqual(actual.to_string(), expected)
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 05/22] linux-firmware: Convert to SPDX license strings
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (3 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 04/22] Parse LICENSE as SPDX Expression Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 06/22] meta-selftest: Add NO_GENERIC_LICENSE Joshua Watt
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Converts all LICENSE strings to SPDX licenses expressions

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 .../linux-firmware/linux-firmware_20260622.bb | 1666 ++++++++---------
 1 file changed, 833 insertions(+), 833 deletions(-)

diff --git a/meta/recipes-kernel/linux-firmware/linux-firmware_20260622.bb b/meta/recipes-kernel/linux-firmware/linux-firmware_20260622.bb
index 016905ef6d..33b28c45f4 100644
--- a/meta/recipes-kernel/linux-firmware/linux-firmware_20260622.bb
+++ b/meta/recipes-kernel/linux-firmware/linux-firmware_20260622.bb
@@ -21,135 +21,135 @@ REMOVE_UNLICENSED += "yamaha/yss225_registers.bin"
 
 
 LICENSE = "\
-    Firmware-Abilis \
-    & Firmware-adsp_sst \
-    & Firmware-advansys \
-    & Firmware-aeonsemi \
-    & Firmware-agere \
-    & Firmware-airoha \
-    & Firmware-alacritech \
-    & Firmware-amdgpu \
-    & Firmware-amdisp \
-    & Firmware-amdnpu \
-    & Firmware-amd_pmf \
-    & Firmware-amd-sev \
-    & Firmware-amd-ucode \
-    & Firmware-amlogic \
-    & Firmware-amlogic_vdec \
-    & Firmware-amphion_vpu \
-    & Firmware-atheros_firmware \
-    & Firmware-atmel \
-    & Firmware-bfa \
-    & Firmware-bmi260 \
-    & Firmware-bnx2 \
-    & Firmware-bnx2x \
-    & Firmware-broadcom_bcm43xx \
-    & Firmware-ca0132 \
-    & Firmware-cadence \
-    & Firmware-cavium \
-    & Firmware-chelsio_firmware \
-    & Firmware-cirrus \
-    & Firmware-cnm \
-    & Firmware-conexant \
-    & Firmware-cw1200 \
-    & Firmware-cw1200-sdd \
-    & Firmware-cxgb3 \
-    & Firmware-cypress \
-    & Firmware-dabusb \
-    & Firmware-dell \
-    & Firmware-dib0700 \
-    & Firmware-drxk \
-    & Firmware-e100 \
-    & Firmware-emi26 \
-    & Firmware-ene_firmware \
-    & Firmware-fw_sst_0f28 \
-    & Firmware-go7007 \
-    & Firmware-hfi1_firmware \
-    & Firmware-HP \
-    & Firmware-i915 \
-    & Firmware-ib_qib \
-    & Firmware-ibt_firmware \
-    & Firmware-ice \
-    & Firmware-ice_enhanced \
-    & Firmware-inside-secure \
-    & Firmware-intel \
-    & Firmware-intel_vpu \
-    & Firmware-ipu3_firmware \
-    & Firmware-it913x \
-    & Firmware-ivsc \
-    & Firmware-iwlwifi_firmware \
-    & Firmware-ixp4xx \
-    & Firmware-IntcSST2 \
-    & Firmware-kaweth \
-    & Firmware-keyspan \
-    & Firmware-lenovo \
-    & Firmware-linaro \
-    & Firmware-Lontium \
-    & Firmware-mali_csffw \
-    & Firmware-Marvell \
-    & Firmware-mediatek \
-    & Firmware-mellanox \
-    & Firmware-mga \
-    & Firmware-microchip \
-    & Firmware-montage \
-    & Firmware-moxa \
-    & Firmware-myri10ge_firmware \
-    & Firmware-netronome \
-    & Firmware-nvidia \
-    & Firmware-nxp \
-    & Firmware-nxp_mc_firmware \
-    & Firmware-OLPC \
-    & Firmware-ath9k-htc \
-    & Firmware-phanfw \
-    & Firmware-powervr \
-    & Firmware-qat \
-    & Firmware-qcom \
-    & Firmware-qcom-2 \
-    & Firmware-qcom-yamato \
-    & Firmware-qed \
-    & Firmware-qla1280 \
-    & Firmware-qla2xxx \
-    & Firmware-qualcommAthos_ar3k \
-    & Firmware-qualcommAthos_ath10k \
-    & Firmware-r8169 \
-    & Firmware-r8a779x_usb3 \
-    & Firmware-radeon \
-    & Firmware-ralink_a_mediatek_company_firmware \
-    & Firmware-ralink-firmware \
-    & Firmware-r8a779g_pcie_phy \
-    & Firmware-rockchip \
-    & Firmware-rp2 \
-    & Firmware-rsi \
-    & Firmware-rt1320 \
-    & Firmware-rtlwifi_firmware \
-    & Firmware-imx-sdma_firmware \
-    & Firmware-s5p-mfc \
-    & Firmware-sensoray \
-    & Firmware-siano \
-    & Firmware-tehuti \
-    & Firmware-ti-connectivity \
-    & Firmware-ti-keystone \
-    & Firmware-ti-tspa \
-    & Firmware-tigon \
-    & Firmware-tlg2300 \
-    & Firmware-typhoon \
-    & Firmware-ueagle-atm4-firmware \
-    & Firmware-via_vt6656 \
-    & Firmware-vxge \
-    & Firmware-wfx \
-    & Firmware-wl1251 \
-    & Firmware-xc4000 \
-    & Firmware-xc5000 \
-    & Firmware-xc5000c \
-    & Firmware-xe \
-    & WHENCE \
-    & GPL-1.0-only \
-    & GPL-2.0-or-later \
-    & GPL-2.0-only \
-    & GPL-3.0-only \
-    & MPL-1.1 \
-    & Apache-2.0 \
-    & MIT \
+    LicenseRef-Firmware-Abilis \
+    AND LicenseRef-Firmware-adsp-sst \
+    AND LicenseRef-Firmware-advansys \
+    AND LicenseRef-Firmware-aeonsemi \
+    AND LicenseRef-Firmware-agere \
+    AND LicenseRef-Firmware-airoha \
+    AND LicenseRef-Firmware-alacritech \
+    AND LicenseRef-Firmware-amdgpu \
+    AND LicenseRef-Firmware-amdisp \
+    AND LicenseRef-Firmware-amdnpu \
+    AND LicenseRef-Firmware-amd-pmf \
+    AND LicenseRef-Firmware-amd-sev \
+    AND LicenseRef-Firmware-amd-ucode \
+    AND LicenseRef-Firmware-amlogic \
+    AND LicenseRef-Firmware-amlogic-vdec \
+    AND LicenseRef-Firmware-amphion-vpu \
+    AND LicenseRef-Firmware-atheros-firmware \
+    AND LicenseRef-Firmware-atmel \
+    AND LicenseRef-Firmware-bfa \
+    AND LicenseRef-Firmware-bmi260 \
+    AND LicenseRef-Firmware-bnx2 \
+    AND LicenseRef-Firmware-bnx2x \
+    AND LicenseRef-Firmware-broadcom-bcm43xx \
+    AND LicenseRef-Firmware-ca0132 \
+    AND LicenseRef-Firmware-cadence \
+    AND LicenseRef-Firmware-cavium \
+    AND LicenseRef-Firmware-chelsio-firmware \
+    AND LicenseRef-Firmware-cirrus \
+    AND LicenseRef-Firmware-cnm \
+    AND LicenseRef-Firmware-conexant \
+    AND LicenseRef-Firmware-cw1200 \
+    AND LicenseRef-Firmware-cw1200-sdd \
+    AND LicenseRef-Firmware-cxgb3 \
+    AND LicenseRef-Firmware-cypress \
+    AND LicenseRef-Firmware-dabusb \
+    AND LicenseRef-Firmware-dell \
+    AND LicenseRef-Firmware-dib0700 \
+    AND LicenseRef-Firmware-drxk \
+    AND LicenseRef-Firmware-e100 \
+    AND LicenseRef-Firmware-emi26 \
+    AND LicenseRef-Firmware-ene-firmware \
+    AND LicenseRef-Firmware-fw-sst-0f28 \
+    AND LicenseRef-Firmware-go7007 \
+    AND LicenseRef-Firmware-hfi1-firmware \
+    AND LicenseRef-Firmware-HP \
+    AND LicenseRef-Firmware-i915 \
+    AND LicenseRef-Firmware-ib-qib \
+    AND LicenseRef-Firmware-ibt-firmware \
+    AND LicenseRef-Firmware-ice \
+    AND LicenseRef-Firmware-ice-enhanced \
+    AND LicenseRef-Firmware-inside-secure \
+    AND LicenseRef-Firmware-intel \
+    AND LicenseRef-Firwmare-intel-vpu \
+    AND LicenseRef-Firmware-ipu3-firmware \
+    AND LicenseRef-Firmware-it913x \
+    AND LicenseRef-Firmware-ivsc \
+    AND LicenseRef-Firmware-iwlwifi-firmware \
+    AND LicenseRef-Firmware-ixp4xx \
+    AND LicenseRef-Firmware-IntcSST2 \
+    AND LicenseRef-Firmware-kaweth \
+    AND LicenseRef-Firmware-keyspan \
+    AND LicenseRef-Firmware-lenovo \
+    AND LicenseRef-Firmware-linaro \
+    AND LicenseRef-Firmware-Lontium \
+    AND LicenseRef-Firmware-mali-csffw \
+    AND LicenseRef-Firmware-Marvell \
+    AND LicenseRef-Firmware-mediatek \
+    AND LicenseRef-Firmware-mellanox \
+    AND LicenseRef-Firmware-mga \
+    AND LicenseRef-Firmware-microchip \
+    AND LicenseRef-Firmware-montage \
+    AND LicenseRef-Firmware-moxa \
+    AND LicenseRef-Firmware-myri10ge-firmware \
+    AND LicenseRef-Firmware-netronome \
+    AND LicenseRef-Firmware-nvidia \
+    AND LicenseRef-Firmware-nxp \
+    AND LicenseRef-Firmware-nxp-mc-firmware \
+    AND LicenseRef-Firmware-OLPC \
+    AND LicenseRef-Firmware-ath9k-htc \
+    AND LicenseRef-Firmware-phanfw \
+    AND LicenseRef-Firmware-powervr \
+    AND LicenseRef-Firmware-qat \
+    AND LicenseRef-Firmware-qcom \
+    AND LicenseRef-Firmware-qcom-2 \
+    AND LicenseRef-Firmware-qcom-yamato \
+    AND LicenseRef-Firmware-qed \
+    AND LicenseRef-Firmware-qla1280 \
+    AND LicenseRef-Firmware-qla2xxx \
+    AND LicenseRef-Firmware-qualcommAthos-ar3k \
+    AND LicenseRef-Firmware-qualcommAthos-ath10k \
+    AND LicenseRef-Firmware-r8169 \
+    AND LicenseRef-Firmware-r8a779x-usb3 \
+    AND LicenseRef-Firmware-radeon \
+    AND LicenseRef-Firmware-ralink-a-mediatek-company-firmware \
+    AND LicenseRef-Firmware-ralink-firmware \
+    AND LicenseRef-Firmware-r8a779g-pcie-phy \
+    AND LicenseRef-Firmware-rockchip \
+    AND LicenseRef-Firmware-rp2 \
+    AND LicenseRef-Firmware-rsi \
+    AND LicenseRef-Firmware-rt1320 \
+    AND LicenseRef-Firmware-rtlwifi-firmware \
+    AND LicenseRef-Firmware-imx-sdma-firmware \
+    AND LicenseRef-Firmware-s5p-mfc \
+    AND LicenseRef-Firmware-sensoray \
+    AND LicenseRef-Firmware-siano \
+    AND LicenseRef-Firmware-tehuti \
+    AND LicenseRef-Firmware-ti-connectivity \
+    AND LicenseRef-Firmware-ti-keystone \
+    AND LicenseRef-Firmware-ti-tspa \
+    AND LicenseRef-Firmware-tigon \
+    AND LicenseRef-Firmware-tlg2300 \
+    AND LicenseRef-Firmware-typhoon \
+    AND LicenseRef-Firmware-ueagle-atm4-firmware \
+    AND LicenseRef-Firmware-via-vt6656 \
+    AND LicenseRef-Firmware-vxge \
+    AND LicenseRef-Firmware-wfx \
+    AND LicenseRef-Firmware-wl1251 \
+    AND LicenseRef-Firmware-xc4000 \
+    AND LicenseRef-Firmware-xc5000 \
+    AND LicenseRef-Firmware-xc5000c \
+    AND LicenseRef-Firmware-xe \
+    AND LicenseRef-Firmware-WHENCE \
+    AND GPL-1.0-only \
+    AND GPL-2.0-or-later \
+    AND GPL-2.0-only \
+    AND GPL-3.0-only \
+    AND MPL-1.1 \
+    AND Apache-2.0 \
+    AND MIT \
 "
 
 LIC_FILES_CHKSUM = "file://LICENSES/LICENCE.Abilis;md5=b5ee3f410780e56711ad48eadc22b8bc \
@@ -283,7 +283,7 @@ WHENCE_CHKSUM  = "991f6e7ad5cc20508ae8923edc342c8e"
 # These are not common licenses, set NO_GENERIC_LICENSE for them
 # so that the license files will be copied from fetched source
 NO_GENERIC_LICENSE[Firmware-Abilis] = "LICENSES/LICENCE.Abilis"
-NO_GENERIC_LICENSE[Firmware-adsp_sst] = "LICENSES/LICENCE.adsp_sst"
+NO_GENERIC_LICENSE[Firmware-adsp-sst] = "LICENSES/LICENCE.adsp_sst"
 NO_GENERIC_LICENSE[Firmware-advansys] = "LICENSES/LICENCE.advansys"
 NO_GENERIC_LICENSE[Firmware-aeonsemi] = "LICENSES/LICENSE.aeonsemi"
 NO_GENERIC_LICENSE[Firmware-agere] = "LICENSES/LICENCE.agere"
@@ -292,23 +292,23 @@ NO_GENERIC_LICENSE[Firmware-alacritech] = "LICENSES/LICENCE.alacritech"
 NO_GENERIC_LICENSE[Firmware-amdgpu] = "LICENSES/LICENSE.amdgpu"
 NO_GENERIC_LICENSE[Firmware-amdisp] = "LICENSES/LICENSE.amdisp"
 NO_GENERIC_LICENSE[Firmware-amdnpu] = "LICENSES/LICENSE.amdnpu"
-NO_GENERIC_LICENSE[Firmware-amd_pmf] = "LICENSES/LICENSE.amd_pmf"
+NO_GENERIC_LICENSE[Firmware-amd-pmf] = "LICENSES/LICENSE.amd_pmf"
 NO_GENERIC_LICENSE[Firmware-amd-sev] = "LICENSES/LICENSE.amd-sev"
 NO_GENERIC_LICENSE[Firmware-amd-ucode] = "LICENSES/LICENSE.amd-ucode"
 NO_GENERIC_LICENSE[Firmware-amlogic] = "LICENSES/LICENSE.amlogic"
-NO_GENERIC_LICENSE[Firmware-amlogic_vdec] = "LICENSES/LICENSE.amlogic_vdec"
-NO_GENERIC_LICENSE[Firmware-amphion_vpu] = "LICENSES/LICENSE.amphion_vpu"
-NO_GENERIC_LICENSE[Firmware-atheros_firmware] = "LICENSES/LICENCE.atheros_firmware"
+NO_GENERIC_LICENSE[Firmware-amlogic-vdec] = "LICENSES/LICENSE.amlogic_vdec"
+NO_GENERIC_LICENSE[Firmware-amphion-vpu] = "LICENSES/LICENSE.amphion_vpu"
+NO_GENERIC_LICENSE[Firmware-atheros-firmware] = "LICENSES/LICENCE.atheros_firmware"
 NO_GENERIC_LICENSE[Firmware-atmel] = "LICENSES/LICENSE.atmel"
 NO_GENERIC_LICENSE[Firmware-bfa] = "LICENSES/LICENSE.bfa"
 NO_GENERIC_LICENSE[Firmware-bmi260] = "LICENSES/LICENSE.bmi260"
 NO_GENERIC_LICENSE[Firmware-bnx2] = "LICENSES/LICENCE.bnx2"
 NO_GENERIC_LICENSE[Firmware-bnx2x] = "LICENSES/LICENCE.bnx2x"
-NO_GENERIC_LICENSE[Firmware-broadcom_bcm43xx] = "LICENSES/LICENCE.broadcom_bcm43xx"
+NO_GENERIC_LICENSE[Firmware-broadcom-bcm43xx] = "LICENSES/LICENCE.broadcom_bcm43xx"
 NO_GENERIC_LICENSE[Firmware-ca0132] = "LICENSES/LICENCE.ca0132"
 NO_GENERIC_LICENSE[Firmware-cadence] = "LICENSES/LICENCE.cadence"
 NO_GENERIC_LICENSE[Firmware-cavium] = "LICENSES/LICENCE.cavium"
-NO_GENERIC_LICENSE[Firmware-chelsio_firmware] = "LICENSES/LICENCE.chelsio_firmware"
+NO_GENERIC_LICENSE[Firmware-chelsio-firmware] = "LICENSES/LICENCE.chelsio_firmware"
 NO_GENERIC_LICENSE[Firmware-cirrus] = "LICENSES/LICENSE.cirrus"
 NO_GENERIC_LICENSE[Firmware-cnm] = "LICENSES/LICENCE.cnm"
 NO_GENERIC_LICENSE[Firmware-conexant] = "LICENSES/LICENSE.conexant"
@@ -322,31 +322,31 @@ NO_GENERIC_LICENSE[Firmware-dib0700] = "LICENSES/LICENSE.dib0700"
 NO_GENERIC_LICENSE[Firmware-drxk] = "LICENSES/LICENSE.drxk"
 NO_GENERIC_LICENSE[Firmware-e100] = "LICENSES/LICENCE.e100"
 NO_GENERIC_LICENSE[Firmware-emi26] = "LICENSES/LICENCE.emi26"
-NO_GENERIC_LICENSE[Firmware-ene_firmware] = "LICENSES/LICENCE.ene_firmware"
-NO_GENERIC_LICENSE[Firmware-fw_sst_0f28] = "LICENSES/LICENCE.fw_sst_0f28"
+NO_GENERIC_LICENSE[Firmware-ene-firmware] = "LICENSES/LICENCE.ene_firmware"
+NO_GENERIC_LICENSE[Firmware-fw-sst-0f28] = "LICENSES/LICENCE.fw_sst_0f28"
 NO_GENERIC_LICENSE[Firmware-go7007] = "LICENSES/LICENCE.go7007"
-NO_GENERIC_LICENSE[Firmware-hfi1_firmware] = "LICENSES/LICENSE.hfi1_firmware"
+NO_GENERIC_LICENSE[Firmware-hfi1-firmware] = "LICENSES/LICENSE.hfi1_firmware"
 NO_GENERIC_LICENSE[Firmware-HP] = "LICENSES/LICENCE.HP"
 NO_GENERIC_LICENSE[Firmware-i915] = "LICENSES/LICENSE.i915"
-NO_GENERIC_LICENSE[Firmware-ib_qib] = "LICENSES/LICENSE.ib_qib"
-NO_GENERIC_LICENSE[Firmware-ibt_firmware] = "LICENSES/LICENCE.ibt_firmware"
+NO_GENERIC_LICENSE[Firmware-ib-qib] = "LICENSES/LICENSE.ib_qib"
+NO_GENERIC_LICENSE[Firmware-ibt-firmware] = "LICENSES/LICENCE.ibt_firmware"
 NO_GENERIC_LICENSE[Firmware-ice] = "LICENSES/LICENSE.ice"
-NO_GENERIC_LICENSE[Firmware-ice_enhanced] = "LICENSES/LICENSE.ice_enhanced"
+NO_GENERIC_LICENSE[Firmware-ice-enhanced] = "LICENSES/LICENSE.ice_enhanced"
 NO_GENERIC_LICENSE[Firmware-inside-secure] = "LICENSES/LICENCE.inside-secure"
 NO_GENERIC_LICENSE[Firmware-IntcSST2] = "LICENSES/LICENCE.IntcSST2"
 NO_GENERIC_LICENSE[Firmware-intel] = "LICENSES/LICENSE.intel"
-NO_GENERIC_LICENSE[Firmware-intel_vpu] = "LICENSES/LICENSE.intel_vpu"
-NO_GENERIC_LICENSE[Firmware-ipu3_firmware] = "LICENSES/LICENSE.ipu3_firmware"
+NO_GENERIC_LICENSE[Firwmare-intel-vpu] = "LICENSES/LICENSE.intel_vpu"
+NO_GENERIC_LICENSE[Firmware-ipu3-firmware] = "LICENSES/LICENSE.ipu3_firmware"
 NO_GENERIC_LICENSE[Firmware-it913x] = "LICENSES/LICENCE.it913x"
 NO_GENERIC_LICENSE[Firmware-ivsc] = "LICENSES/LICENSE.ivsc"
-NO_GENERIC_LICENSE[Firmware-iwlwifi_firmware] = "LICENSES/LICENCE.iwlwifi_firmware"
+NO_GENERIC_LICENSE[Firmware-iwlwifi-firmware] = "LICENSES/LICENCE.iwlwifi_firmware"
 NO_GENERIC_LICENSE[Firmware-ixp4xx] = "LICENSES/LICENSE.ixp4xx"
 NO_GENERIC_LICENSE[Firmware-kaweth] = "LICENSES/LICENCE.kaweth"
 NO_GENERIC_LICENSE[Firmware-keyspan] = "LICENSES/LICENCE.keyspan"
 NO_GENERIC_LICENSE[Firmware-lenovo] = "LICENSES/LICENCE.lenovo"
 NO_GENERIC_LICENSE[Firmware-linaro] = "LICENSES/LICENCE.linaro"
 NO_GENERIC_LICENSE[Firmware-Lontium] = "LICENSES/LICENSE.Lontium"
-NO_GENERIC_LICENSE[Firmware-mali_csffw] = "LICENSES/LICENCE.mali_csffw"
+NO_GENERIC_LICENSE[Firmware-mali-csffw] = "LICENSES/LICENCE.mali_csffw"
 NO_GENERIC_LICENSE[Firmware-Marvell] = "LICENSES/LICENCE.Marvell"
 NO_GENERIC_LICENSE[Firmware-mediatek] = "LICENSES/LICENCE.mediatek"
 NO_GENERIC_LICENSE[Firmware-mellanox] = "LICENSES/LICENSE.mellanox"
@@ -354,11 +354,11 @@ NO_GENERIC_LICENSE[Firmware-mga] = "LICENSES/LICENSE.mga"
 NO_GENERIC_LICENSE[Firmware-microchip] = "LICENSES/LICENCE.microchip"
 NO_GENERIC_LICENSE[Firmware-montage] = "LICENSES/LICENSE.montage"
 NO_GENERIC_LICENSE[Firmware-moxa] = "LICENSES/LICENCE.moxa"
-NO_GENERIC_LICENSE[Firmware-myri10ge_firmware] = "LICENSES/LICENCE.myri10ge_firmware"
+NO_GENERIC_LICENSE[Firmware-myri10ge-firmware] = "LICENSES/LICENCE.myri10ge_firmware"
 NO_GENERIC_LICENSE[Firmware-netronome] = "LICENSES/LICENCE.Netronome"
 NO_GENERIC_LICENSE[Firmware-nvidia] = "LICENSES/LICENCE.nvidia"
 NO_GENERIC_LICENSE[Firmware-nxp] = "LICENSES/LICENSE.nxp"
-NO_GENERIC_LICENSE[Firmware-nxp_mc_firmware] = "LICENSES/LICENSE.nxp_mc_firmware"
+NO_GENERIC_LICENSE[Firmware-nxp-mc-firmware] = "LICENSES/LICENSE.nxp_mc_firmware"
 NO_GENERIC_LICENSE[Firmware-OLPC] = "LICENSES/LICENCE.OLPC"
 NO_GENERIC_LICENSE[Firmware-ath9k-htc] = "LICENSES/LICENCE.open-ath9k-htc-firmware"
 NO_GENERIC_LICENSE[Firmware-phanfw] = "LICENSES/LICENCE.phanfw"
@@ -370,23 +370,23 @@ NO_GENERIC_LICENSE[Firmware-qcom-yamato] = "LICENSES/LICENSE.qcom_yamato"
 NO_GENERIC_LICENSE[Firmware-qed] = "LICENSES/LICENSE.qed"
 NO_GENERIC_LICENSE[Firmware-qla1280] = "LICENSES/LICENCE.qla1280"
 NO_GENERIC_LICENSE[Firmware-qla2xxx] = "LICENSES/LICENCE.qla2xxx"
-NO_GENERIC_LICENSE[Firmware-qualcommAthos_ar3k] = "LICENSES/LICENSE.QualcommAtheros_ar3k"
-NO_GENERIC_LICENSE[Firmware-qualcommAthos_ath10k] = "LICENSES/LICENSE.QualcommAtheros_ath10k"
+NO_GENERIC_LICENSE[Firmware-qualcommAthos-ar3k] = "LICENSES/LICENSE.QualcommAtheros_ar3k"
+NO_GENERIC_LICENSE[Firmware-qualcommAthos-ath10k] = "LICENSES/LICENSE.QualcommAtheros_ath10k"
 NO_GENERIC_LICENSE[Firmware-r8169] = "LICENSES/LICENSE.r8169"
-NO_GENERIC_LICENSE[Firmware-r8a779x_usb3] = "LICENSES/LICENCE.r8a779x_usb3"
+NO_GENERIC_LICENSE[Firmware-r8a779x-usb3] = "LICENSES/LICENCE.r8a779x_usb3"
 NO_GENERIC_LICENSE[Firmware-radeon] = "LICENSES/LICENSE.radeon"
-NO_GENERIC_LICENSE[Firmware-ralink_a_mediatek_company_firmware] = "LICENSES/LICENCE.ralink_a_mediatek_company_firmware"
+NO_GENERIC_LICENSE[Firmware-ralink-a-mediatek-company-firmware] = "LICENSES/LICENCE.ralink_a_mediatek_company_firmware"
 NO_GENERIC_LICENSE[Firmware-ralink-firmware] = "LICENSES/LICENCE.ralink-firmware.txt"
-NO_GENERIC_LICENSE[Firmware-r8a779g_pcie_phy] = "LICENSES/LICENCE.r8a779g_pcie_phy"
+NO_GENERIC_LICENSE[Firmware-r8a779g-pcie-phy] = "LICENSES/LICENCE.r8a779g_pcie_phy"
 NO_GENERIC_LICENSE[Firmware-rockchip] = "LICENSES/LICENCE.rockchip"
 NO_GENERIC_LICENSE[Firmware-rp2] = "LICENSES/LICENSE.rp2"
 NO_GENERIC_LICENSE[Firmware-rsi] = "LICENSES/LICENSE.rsi"
 NO_GENERIC_LICENSE[Firmware-rt1320] = "LICENSES/LICENSE.rt1320"
-NO_GENERIC_LICENSE[Firmware-rtlwifi_firmware] = "LICENSES/LICENCE.rtlwifi_firmware.txt"
+NO_GENERIC_LICENSE[Firmware-rtlwifi-firmware] = "LICENSES/LICENCE.rtlwifi_firmware.txt"
 NO_GENERIC_LICENSE[Firmware-s5p-mfc] = "LICENSES/LICENSE.s5p-mfc"
 NO_GENERIC_LICENSE[Firmware-sensoray] = "LICENSES/LICENCE.sensoray"
 NO_GENERIC_LICENSE[Firmware-siano] = "LICENSES/LICENCE.siano"
-NO_GENERIC_LICENSE[Firmware-imx-sdma_firmware] = "LICENSES/LICENSE.sdma_firmware"
+NO_GENERIC_LICENSE[Firmware-imx-sdma-firmware] = "LICENSES/LICENSE.sdma_firmware"
 NO_GENERIC_LICENSE[Firmware-tehuti] = "LICENSES/LICENSE.tehuti"
 NO_GENERIC_LICENSE[Firmware-ti-connectivity] = "LICENSES/LICENCE.ti-connectivity"
 NO_GENERIC_LICENSE[Firmware-ti-keystone] = "LICENSES/LICENCE.ti-keystone"
@@ -395,7 +395,7 @@ NO_GENERIC_LICENSE[Firmware-tigon] = "LICENSES/LICENCE.tigon"
 NO_GENERIC_LICENSE[Firmware-tlg2300] = "LICENSES/LICENSE.tlg2300"
 NO_GENERIC_LICENSE[Firmware-typhoon] = "LICENSES/LICENCE.typhoon"
 NO_GENERIC_LICENSE[Firmware-ueagle-atm4-firmware] = "LICENSES/LICENCE.ueagle-atm4-firmware"
-NO_GENERIC_LICENSE[Firmware-via_vt6656] = "LICENSES/LICENCE.via_vt6656"
+NO_GENERIC_LICENSE[Firmware-via-vt6656] = "LICENSES/LICENCE.via_vt6656"
 NO_GENERIC_LICENSE[Firmware-vxge] = "LICENSES/LICENSE.vxge"
 NO_GENERIC_LICENSE[Firmware-wfx] = "LICENSES/LICENCE.wf200"
 NO_GENERIC_LICENSE[Firmware-wl1251] = "LICENSES/LICENCE.wl1251"
@@ -403,7 +403,7 @@ NO_GENERIC_LICENSE[Firmware-xc4000] = "LICENSES/LICENCE.xc4000"
 NO_GENERIC_LICENSE[Firmware-xc5000] = "LICENSES/LICENCE.xc5000"
 NO_GENERIC_LICENSE[Firmware-xc5000c] = "LICENSES/LICENCE.xc5000c"
 NO_GENERIC_LICENSE[Firmware-xe] = "LICENSES/LICENSE.xe"
-NO_GENERIC_LICENSE[WHENCE] = "WHENCE"
+NO_GENERIC_LICENSE[Firmware-WHENCE] = "WHENCE"
 
 PE = "1"
 
@@ -835,8 +835,8 @@ PACKAGES =+ "${PN}-amphion-vpu-license ${PN}-amphion-vpu \
              "
 
 # For Amphion VPU
-LICENSE:${PN}-amphion-vpu = "Firmware-amphion_vpu"
-LICENSE:${PN}-amphion-vpu-license = "Firmware-amphion_vpu"
+LICENSE:${PN}-amphion-vpu = "LicenseRef-Firmware-amphion-vpu"
+LICENSE:${PN}-amphion-vpu-license = "LicenseRef-Firmware-amphion-vpu"
 
 FILES:${PN}-amphion-vpu = "${firmwaredir}/amphion/*"
 FILES:${PN}-amphion-vpu-license = " \
@@ -845,8 +845,8 @@ FILES:${PN}-amphion-vpu-license = " \
 RDEPENDS:${PN}-amphion-vpu += "${PN}-amphion-vpu-license"
 
 # For cw1200
-LICENSE:${PN}-cw1200 = "Firmware-cw1200"
-LICENSE:${PN}-cw1200-license = "Firmware-cw1200"
+LICENSE:${PN}-cw1200 = "LicenseRef-Firmware-cw1200"
+LICENSE:${PN}-cw1200-license = "LicenseRef-Firmware-cw1200"
 
 FILES:${PN}-cw1200 = " \
     ${firmwaredir}/sdd_sagrad_1091_1098.bin* \
@@ -857,12 +857,12 @@ FILES:${PN}-cw1200-license = "${firmwaredir}/LICENCE.cw1200"
 RDEPENDS:${PN}-cw1200 += "${PN}-cw1200-license"
 
 # For atheros
-LICENSE:${PN}-ar5523 = "Firmware-atheros_firmware"
-LICENSE:${PN}-ar9170 = "Firmware-atheros_firmware"
-LICENSE:${PN}-ath3k = "Firmware-atheros_firmware"
-LICENSE:${PN}-ath6k = "Firmware-atheros_firmware"
-LICENSE:${PN}-ath9k = "Firmware-atheros_firmware"
-LICENSE:${PN}-atheros-license = "Firmware-atheros_firmware"
+LICENSE:${PN}-ar5523 = "LicenseRef-Firmware-atheros-firmware"
+LICENSE:${PN}-ar9170 = "LicenseRef-Firmware-atheros-firmware"
+LICENSE:${PN}-ath3k = "LicenseRef-Firmware-atheros-firmware"
+LICENSE:${PN}-ath6k = "LicenseRef-Firmware-atheros-firmware"
+LICENSE:${PN}-ath9k = "LicenseRef-Firmware-atheros-firmware"
+LICENSE:${PN}-atheros-license = "LicenseRef-Firmware-atheros-firmware"
 
 FILES:${PN}-atheros-license = "${firmwaredir}/LICENCE.atheros_firmware"
 FILES:${PN}-ar5523 = " \
@@ -899,46 +899,46 @@ FILES:${PN}-carl9170 = " \
 LICENSE:${PN}-carl9170 = "GPL-2.0-or-later"
 
 # For QualCommAthos
-LICENSE:${PN}-ar3k = "Firmware-qualcommAthos_ar3k & Firmware-atheros_firmware"
-LICENSE:${PN}-ar3k-license = "Firmware-qualcommAthos_ar3k"
-LICENSE:${PN}-ath10k = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath10k-qca4019 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath10k-qca6174 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath10k-qca9377 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath10k-qca9887 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath10k-qca9888 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath10k-qca988x = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath10k-qca9984 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath10k-qca99x0 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath10k-wcn3990 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath10k-license = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath11k = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath11k-ipq5018 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath11k-ipq6018 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath11k-ipq8074 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath11k-qca2066 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath11k-qca6390 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath11k-qca6698aq = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath11k-qcn9074 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath11k-wcn6750 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath11k-wcn6855 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath12k = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath12k-ipq5424 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath12k-qcc2072 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath12k-qcn9274 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-ath12k-wcn7850 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-qca-qca2066 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-qca-qca61x4-serial = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-qca-qca61x4-usb = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-qca-qca6390 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-qca-qca6698 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-qca-qcc2072 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-qca-wcn3950 = "Firmware-qcom"
-LICENSE:${PN}-qca-wcn3988 = "Firmware-qcom"
-LICENSE:${PN}-qca-wcn399x = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-qca-wcn6750 = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-qca-wcn685x = "Firmware-qualcommAthos_ath10k"
-LICENSE:${PN}-qca-wcn7850 = "Firmware-qcom"
+LICENSE:${PN}-ar3k = "LicenseRef-Firmware-qualcommAthos-ar3k AND LicenseRef-Firmware-atheros-firmware"
+LICENSE:${PN}-ar3k-license = "LicenseRef-Firmware-qualcommAthos-ar3k"
+LICENSE:${PN}-ath10k = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath10k-qca4019 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath10k-qca6174 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath10k-qca9377 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath10k-qca9887 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath10k-qca9888 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath10k-qca988x = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath10k-qca9984 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath10k-qca99x0 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath10k-wcn3990 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath10k-license = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath11k = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath11k-ipq5018 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath11k-ipq6018 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath11k-ipq8074 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath11k-qca2066 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath11k-qca6390 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath11k-qca6698aq = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath11k-qcn9074 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath11k-wcn6750 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath11k-wcn6855 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath12k = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath12k-ipq5424 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath12k-qcc2072 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath12k-qcn9274 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-ath12k-wcn7850 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-qca-qca2066 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-qca-qca61x4-serial = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-qca-qca61x4-usb = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-qca-qca6390 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-qca-qca6698 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-qca-qcc2072 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-qca-wcn3950 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qca-wcn3988 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qca-wcn399x = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-qca-wcn6750 = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-qca-wcn685x = "LicenseRef-Firmware-qualcommAthos-ath10k"
+LICENSE:${PN}-qca-wcn7850 = "LicenseRef-Firmware-qcom"
 
 FILES:${PN}-ar3k-license = "${firmwaredir}/LICENSE.QualcommAtheros_ar3k"
 FILES:${PN}-ar3k = " \
@@ -1120,8 +1120,8 @@ RDEPENDS:${PN}-qca-wcn6750 += "${PN}-ath10k-license"
 RDEPENDS:${PN}-qca-wcn685x += "${PN}-ath10k-license"
 RDEPENDS:${PN}-qca-wcn7850 += "${PN}-qcom-license"
 # For ralink
-LICENSE:${PN}-ralink = "Firmware-ralink-firmware"
-LICENSE:${PN}-ralink-license = "Firmware-ralink-firmware"
+LICENSE:${PN}-ralink = "LicenseRef-Firmware-ralink-firmware"
+LICENSE:${PN}-ralink-license = "LicenseRef-Firmware-ralink-firmware"
 
 FILES:${PN}-ralink-license = "${firmwaredir}/LICENCE.ralink-firmware.txt"
 FILES:${PN}-ralink = " \
@@ -1131,10 +1131,10 @@ FILES:${PN}-ralink = " \
 RDEPENDS:${PN}-ralink += "${PN}-ralink-license"
 
 # For mediatek MT7601U
-LICENSE:${PN}-mt76x-license = "Firmware-ralink_a_mediatek_company_firmware"
+LICENSE:${PN}-mt76x-license = "LicenseRef-Firmware-ralink-a-mediatek-company-firmware"
 FILES:${PN}-mt76x-license = "${firmwaredir}/LICENCE.ralink_a_mediatek_company_firmware"
 
-LICENSE:${PN}-mt7601u = "Firmware-ralink_a_mediatek_company_firmware"
+LICENSE:${PN}-mt7601u = "LicenseRef-Firmware-ralink-a-mediatek-company-firmware"
 
 FILES:${PN}-mt7601u = " \
   ${firmwaredir}/mediatek/mt7601u.bin* \
@@ -1143,7 +1143,7 @@ FILES:${PN}-mt7601u = " \
 RDEPENDS:${PN}-mt7601u += "${PN}-mt76x-license"
 
 # For MediaTek Bluetooth USB driver 7650
-LICENSE:${PN}-mt7650 = "Firmware-ralink_a_mediatek_company_firmware"
+LICENSE:${PN}-mt7650 = "LicenseRef-Firmware-ralink-a-mediatek-company-firmware"
 
 FILES:${PN}-mt7650 = " \
   ${firmwaredir}/mediatek/mt7650.bin* \
@@ -1152,7 +1152,7 @@ FILES:${PN}-mt7650 = " \
 RDEPENDS:${PN}-mt7650 += "${PN}-mt76x-license"
 
 # For MediaTek MT76x2 Wireless MACs
-LICENSE:${PN}-mt76x2 = "Firmware-ralink_a_mediatek_company_firmware"
+LICENSE:${PN}-mt76x2 = "LicenseRef-Firmware-ralink-a-mediatek-company-firmware"
 
 FILES:${PN}-mt76x2 = " \
   ${firmwaredir}/mediatek/mt7662.bin* \
@@ -1163,7 +1163,7 @@ FILES:${PN}-mt76x2 = " \
 RDEPENDS:${PN}-mt76x2 += "${PN}-mt76x-license"
 
 # MediaTek MT7996/MT7992/MT7990 (mt7996e.ko)
-LICENSE:${PN}-mt7996 = "Firmware-mediatek"
+LICENSE:${PN}-mt7996 = "LicenseRef-Firmware-mediatek"
 
 FILES:${PN}-mt7996 = " \
   ${firmwaredir}/mediatek/mt7996 \
@@ -1171,8 +1171,8 @@ FILES:${PN}-mt7996 = " \
 RDEPENDS:${PN}-mt7996 += "${PN}-mediatek-license"
 
 # For MediaTek
-LICENSE:${PN}-mediatek = "Firmware-mediatek"
-LICENSE:${PN}-mediatek-license = "Firmware-mediatek"
+LICENSE:${PN}-mediatek = "LicenseRef-Firmware-mediatek"
+LICENSE:${PN}-mediatek-license = "LicenseRef-Firmware-mediatek"
 
 FILES:${PN}-mediatek = " \
   ${firmwaredir}/mediatek/* \
@@ -1185,8 +1185,8 @@ FILES:${PN}-mediatek-license = " \
 RDEPENDS:${PN}-mediatek += "${PN}-mediatek-license"
 
 # For Microchip
-LICENSE:${PN}-microchip = "Firmware-microchip"
-LICENSE:${PN}-microchip-license = "Firmware-microchip"
+LICENSE:${PN}-microchip = "LicenseRef-Firmware-microchip"
+LICENSE:${PN}-microchip-license = "LicenseRef-Firmware-microchip"
 
 FILES:${PN}-microchip = "${firmwaredir}/microchip/*"
 FILES:${PN}-microchip-license = " \
@@ -1195,8 +1195,8 @@ FILES:${PN}-microchip-license = " \
 RDEPENDS:${PN}-microchip += "${PN}-microchip-license"
 
 # For MOXA
-LICENSE:${PN}-moxa = "Firmware-moxa"
-LICENSE:${PN}-moxa-license = "Firmware-moxa"
+LICENSE:${PN}-moxa = "LicenseRef-Firmware-moxa"
+LICENSE:${PN}-moxa-license = "LicenseRef-Firmware-moxa"
 
 FILES:${PN}-moxa = "${firmwaredir}/moxa"
 FILES:${PN}-moxa-license = "${firmwaredir}/LICENCE.moxa"
@@ -1205,8 +1205,8 @@ RDEPENDS:${PN}-moxa += "${PN}-moxa-license"
 
 # For radeon
 
-LICENSE:${PN}-radeon = "Firmware-radeon"
-LICENSE:${PN}-radeon-license = "Firmware-radeon"
+LICENSE:${PN}-radeon = "LicenseRef-Firmware-radeon"
+LICENSE:${PN}-radeon-license = "LicenseRef-Firmware-radeon"
 
 FILES:${PN}-radeon-license = "${firmwaredir}/LICENSE.radeon"
 FILES:${PN}-radeon = " \
@@ -1216,34 +1216,34 @@ FILES:${PN}-radeon = " \
 RDEPENDS:${PN}-radeon += "${PN}-radeon-license"
 
 # For amdgpu
-LICENSE:${PN}-amdgpu = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-license = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-aldebaran = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-carrizo = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-cezanne = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-fiji = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-hawaii = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-navi10 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-navi14 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-navi21 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-navi22 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-navi23 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-navi24 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-navi31 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-navi32 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-oland = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-polaris10 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-polaris11 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-polaris12 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-raven = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-rembrandt = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-renoir = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-stoney = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-tonga = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-topaz = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-vega10 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-vega12 = "Firmware-amdgpu"
-LICENSE:${PN}-amdgpu-misc = "Firmware-amdgpu"
+LICENSE:${PN}-amdgpu = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-license = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-aldebaran = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-carrizo = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-cezanne = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-fiji = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-hawaii = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-navi10 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-navi14 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-navi21 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-navi22 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-navi23 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-navi24 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-navi31 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-navi32 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-oland = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-polaris10 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-polaris11 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-polaris12 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-raven = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-rembrandt = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-renoir = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-stoney = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-tonga = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-topaz = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-vega10 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-vega12 = "LicenseRef-Firmware-amdgpu"
+LICENSE:${PN}-amdgpu-misc = "LicenseRef-Firmware-amdgpu"
 
 FILES:${PN}-amdgpu-license = "${firmwaredir}/LICENSE.amdgpu"
 FILES:${PN}-amdgpu-aldebaran = "${firmwaredir}/amdgpu/aldebaran_*.bin*"
@@ -1321,10 +1321,10 @@ RDEPENDS:${PN}-amdgpu-vega12 += "${PN}-amdgpu-license"
 RDEPENDS:${PN}-amdgpu-misc += "${PN}-amdgpu-license"
 
 # For lontium
-LICENSE:${PN}-lt7911exc = "Firmware-Lontium"
-LICENSE:${PN}-lt8713sx = "Firmware-Lontium"
-LICENSE:${PN}-lt9611c = "Firmware-Lontium"
-LICENSE:${PN}-lt9611uxc = "Firmware-Lontium"
+LICENSE:${PN}-lt7911exc = "LicenseRef-Firmware-Lontium"
+LICENSE:${PN}-lt8713sx = "LicenseRef-Firmware-Lontium"
+LICENSE:${PN}-lt9611c = "LicenseRef-Firmware-Lontium"
+LICENSE:${PN}-lt9611uxc = "LicenseRef-Firmware-Lontium"
 
 FILES:${PN}-lontium-license = "${firmwaredir}/LICENSE.Lontium"
 FILES:${PN}-lt7911exc = "${firmwaredir}/Lontium/lt7911exc_fw.bin*"
@@ -1335,60 +1335,60 @@ FILES:${PN}-lt9611uxc = "${firmwaredir}/lt9611uxc_fw.bin* ${firmwaredir}/Lontium
 # For Arm Mali
 FILES:${PN}-mali-csffw-license = "${firmwaredir}/LICENCE.mali_csffw"
 
-LICENSE:${PN}-mali-csffw-arch108 = "Firmware-mali_csffw"
+LICENSE:${PN}-mali-csffw-arch108 = "LicenseRef-Firmware-mali-csffw"
 FILES:${PN}-mali-csffw-arch108 = "${firmwaredir}/arm/mali/arch10.8/mali_csffw.bin*"
 RDEPENDS:${PN}-mali-csffw-arch108 += "${PN}-mali-csffw-license"
 
-LICENSE:${PN}-mali-csffw-arch1010 = "Firmware-mali_csffw"
+LICENSE:${PN}-mali-csffw-arch1010 = "LicenseRef-Firmware-mali-csffw"
 FILES:${PN}-mali-csffw-arch1010 = "${firmwaredir}/arm/mali/arch10.10/mali_csffw.bin*"
 RDEPENDS:${PN}-mali-csffw-arch1010 += "${PN}-mali-csffw-license"
 
-LICENSE:${PN}-mali-csffw-arch1012 = "Firmware-mali_csffw"
+LICENSE:${PN}-mali-csffw-arch1012 = "LicenseRef-Firmware-mali-csffw"
 FILES:${PN}-mali-csffw-arch1012 = "${firmwaredir}/arm/mali/arch10.12/mali_csffw.bin*"
 RDEPENDS:${PN}-mali-csffw-arch1012 += "${PN}-mali-csffw-license"
 
-LICENSE:${PN}-mali-csffw-arch118 = "Firmware-mali_csffw"
+LICENSE:${PN}-mali-csffw-arch118 = "LicenseRef-Firmware-mali-csffw"
 FILES:${PN}-mali-csffw-arch118 = "${firmwaredir}/arm/mali/arch11.8/mali_csffw.bin*"
 RDEPENDS:${PN}-mali-csffw-arch118 += "${PN}-mali-csffw-license"
 
-LICENSE:${PN}-mali-csffw-arch128 = "Firmware-mali_csffw"
+LICENSE:${PN}-mali-csffw-arch128 = "LicenseRef-Firmware-mali-csffw"
 FILES:${PN}-mali-csffw-arch128 = "${firmwaredir}/arm/mali/arch12.8/mali_csffw.bin*"
 RDEPENDS:${PN}-mali-csffw-arch128 += "${PN}-mali-csffw-license"
 
-LICENSE:${PN}-mali-csffw-arch138 = "Firmware-mali_csffw"
+LICENSE:${PN}-mali-csffw-arch138 = "LicenseRef-Firmware-mali-csffw"
 FILES:${PN}-mali-csffw-arch138 = "${firmwaredir}/arm/mali/arch13.8/mali_csffw.bin*"
 RDEPENDS:${PN}-mali-csffw-arch138 += "${PN}-mali-csffw-license"
 
 # For marvell
-LICENSE:${PN}-pcie8897 = "Firmware-Marvell"
-LICENSE:${PN}-pcie8997 = "Firmware-Marvell"
-LICENSE:${PN}-sd8686 = "Firmware-Marvell"
-LICENSE:${PN}-sd8688 = "Firmware-Marvell"
-LICENSE:${PN}-sd8787 = "Firmware-Marvell"
-LICENSE:${PN}-sd8797 = "Firmware-Marvell"
-LICENSE:${PN}-sd8801 = "Firmware-Marvell"
-LICENSE:${PN}-sd8887 = "Firmware-Marvell"
-LICENSE:${PN}-sd8897 = "Firmware-Marvell"
-LICENSE:${PN}-sd8997 = "Firmware-Marvell"
-LICENSE:${PN}-usb8997 = "Firmware-Marvell"
-LICENSE:${PN}-cf8381 = "Firmware-Marvell"
-LICENSE:${PN}-cf8385 = "Firmware-Marvell"
-LICENSE:${PN}-gspi8682 = "Firmware-Marvell"
-LICENSE:${PN}-gspi8686 = "Firmware-Marvell"
-LICENSE:${PN}-gspi8688 = "Firmware-Marvell"
-LICENSE:${PN}-sd8385 = "Firmware-Marvell"
-LICENSE:${PN}-sd8682 = "Firmware-Marvell"
-LICENSE:${PN}-usb8388 = "Firmware-Marvell"
-LICENSE:${PN}-usb8682 = "Firmware-Marvell"
-LICENSE:${PN}-sd8977 = "Firmware-Marvell"
-LICENSE:${PN}-usb8766 = "Firmware-Marvell"
-LICENSE:${PN}-usb8797 = "Firmware-Marvell"
-LICENSE:${PN}-usb8801 = "Firmware-Marvell"
-LICENSE:${PN}-usb8897 = "Firmware-Marvell"
-LICENSE:${PN}-rvu-cptpf = "Firmware-Marvell"
-LICENSE:${PN}-mwl8k = "Firmware-Marvell"
-LICENSE:${PN}-mwlwifi = "Firmware-Marvell"
-LICENSE:${PN}-marvell-license = "Firmware-Marvell"
+LICENSE:${PN}-pcie8897 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-pcie8997 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8686 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8688 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8787 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8797 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8801 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8887 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8897 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8997 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-usb8997 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-cf8381 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-cf8385 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-gspi8682 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-gspi8686 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-gspi8688 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8385 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8682 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-usb8388 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-usb8682 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-sd8977 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-usb8766 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-usb8797 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-usb8801 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-usb8897 = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-rvu-cptpf = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-mwl8k = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-mwlwifi = "LicenseRef-Firmware-Marvell"
+LICENSE:${PN}-marvell-license = "LicenseRef-Firmware-Marvell"
 
 FILES:${PN}-marvell-license = "${firmwaredir}/LICENCE.Marvell"
 FILES:${PN}-pcie8897 = " \
@@ -1479,7 +1479,7 @@ RDEPENDS:${PN}-mwl8k += "${PN}-marvell-license"
 RDEPENDS:${PN}-mwlwifi += "${PN}-marvell-license"
 
 # For netronome
-LICENSE:${PN}-netronome = "Firmware-netronome"
+LICENSE:${PN}-netronome = "LicenseRef-Firmware-netronome"
 
 FILES:${PN}-netronome-license = " \
   ${firmwaredir}/LICENCE.Netronome \
@@ -1501,18 +1501,18 @@ FILES:${PN}-netronome = " \
 RDEPENDS:${PN}-netronome += "${PN}-netronome-license"
 
 # For NXP
-LICENSE:${PN}-nxp8987-sdio = "Firmware-nxp"
-LICENSE:${PN}-nxp8997-common = "Firmware-nxp"
-LICENSE:${PN}-nxp8997-pcie = "Firmware-nxp"
-LICENSE:${PN}-nxp8997-sdio = "Firmware-nxp"
-LICENSE:${PN}-nxp9098-common = "Firmware-nxp"
-LICENSE:${PN}-nxp9098-pcie = "Firmware-nxp"
-LICENSE:${PN}-nxp9098-sdio = "Firmware-nxp"
-LICENSE:${PN}-nxpiw416-sdio = "Firmware-nxp"
-LICENSE:${PN}-nxpiw612-sdio = "Firmware-nxp"
-LICENSE:${PN}-nxpiw61x-sdio = "Firmware-nxp"
-LICENSE:${PN}-nxp-sr1xx = "Firmware-nxp"
-LICENSE:${PN}-nxp-license = "Firmware-nxp"
+LICENSE:${PN}-nxp8987-sdio = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxp8997-common = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxp8997-pcie = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxp8997-sdio = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxp9098-common = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxp9098-pcie = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxp9098-sdio = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxpiw416-sdio = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxpiw612-sdio = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxpiw61x-sdio = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxp-sr1xx = "LicenseRef-Firmware-nxp"
+LICENSE:${PN}-nxp-license = "LicenseRef-Firmware-nxp"
 
 FILES:${PN}-nxp8987-sdio = "${firmwaredir}/nxp/*8987*"
 FILES:${PN}-nxp8997-common = " \
@@ -1543,8 +1543,8 @@ RDEPENDS:${PN}-nxpiw61x-sdio += "${PN}-nxp-license"
 RDEPENDS:${PN}-nxp-sr1xx += "${PN}-nxp-license"
 
 # For nxp-mc
-LICENSE:${PN}-nxp-mc = "Firmware-nxp_mc_firmware"
-LICENSE:${PN}-nxp-mc-license = "Firmware-nxp_mc_firmware"
+LICENSE:${PN}-nxp-mc = "LicenseRef-Firmware-nxp-mc-firmware"
+LICENSE:${PN}-nxp-mc-license = "LicenseRef-Firmware-nxp-mc-firmware"
 
 FILES:${PN}-nxp-mc = "${firmwaredir}/dpaa2/mc/*"
 FILES:${PN}-nxp-mc-license = " \
@@ -1553,10 +1553,10 @@ FILES:${PN}-nxp-mc-license = " \
 RDEPENDS:${PN}-nxp-mc += "${PN}-nxp-mc-license"
 
 # For Nvidia
-LICENSE:${PN}-nvidia-gpu = "Firmware-nvidia"
-LICENSE:${PN}-nvidia-tegra = "Firmware-nvidia"
-LICENSE:${PN}-nvidia-tegra-k1 = "Firmware-nvidia"
-LICENSE:${PN}-nvidia-license = "Firmware-nvidia"
+LICENSE:${PN}-nvidia-gpu = "LicenseRef-Firmware-nvidia"
+LICENSE:${PN}-nvidia-tegra = "LicenseRef-Firmware-nvidia"
+LICENSE:${PN}-nvidia-tegra-k1 = "LicenseRef-Firmware-nvidia"
+LICENSE:${PN}-nvidia-license = "LicenseRef-Firmware-nvidia"
 
 FILES:${PN}-nvidia-gpu = "${firmwaredir}/nvidia"
 FILES:${PN}-nvidia-tegra = " \
@@ -1575,8 +1575,8 @@ RDEPENDS:${PN}-nvidia-tegra += "${PN}-nvidia-license"
 RDEPENDS:${PN}-nvidia-tegra-k1 += "${PN}-nvidia-license"
 
 # For OLPC
-LICENSE:${PN}-olpc = "Firmware-OLPC"
-LICENSE:${PN}-olpc-license = "Firmware-OLPC"
+LICENSE:${PN}-olpc = "LicenseRef-Firmware-OLPC"
+LICENSE:${PN}-olpc-license = "LicenseRef-Firmware-OLPC"
 
 FILES:${PN}-olpc = " \
   ${firmwaredir}/libertas/lbtf_sdio.bin*	\
@@ -1588,8 +1588,8 @@ FILES:${PN}-olpc-license = "${firmwaredir}/LICENCE.OLPC"
 RDEPENDS:${PN}-olpc += "${PN}-olpc-license"
 
 # For phanfw
-LICENSE:${PN}-phanfw = "Firmware-phanfw"
-LICENSE:${PN}-phanfw-license = "Firmware-phanfw"
+LICENSE:${PN}-phanfw = "LicenseRef-Firmware-phanfw"
+LICENSE:${PN}-phanfw-license = "LicenseRef-Firmware-phanfw"
 
 FILES:${PN}-phanfw = "${firmwaredir}/phanfw.bin*"
 FILES:${PN}-phanfw-license = "${firmwaredir}/LICENCE.phanfw"
@@ -1597,8 +1597,8 @@ FILES:${PN}-phanfw-license = "${firmwaredir}/LICENCE.phanfw"
 RDEPENDS:${PN}-phanfw += "${PN}-phanfw-license"
 
 # For PowerVR
-LICENSE:${PN}-powervr = "Firmware-powervr"
-LICENSE:${PN}-powervr-license = "Firmware-powervr"
+LICENSE:${PN}-powervr = "LicenseRef-Firmware-powervr"
+LICENSE:${PN}-powervr-license = "LicenseRef-Firmware-powervr"
 
 FILES:${PN}-powervr = "${firmwaredir}/powervr"
 FILES:${PN}-powervr-license = "${firmwaredir}/LICENSE.powervr"
@@ -1606,8 +1606,8 @@ FILES:${PN}-powervr-license = "${firmwaredir}/LICENSE.powervr"
 RDEPENDS:${PN}-powervr += "${PN}-powervr-license"
 
 # For qla2xxx
-LICENSE:${PN}-qla2xxx = "Firmware-qla2xxx"
-LICENSE:${PN}-qla2xxx-license = "Firmware-qla2xxx"
+LICENSE:${PN}-qla2xxx = "LicenseRef-Firmware-qla2xxx"
+LICENSE:${PN}-qla2xxx-license = "LicenseRef-Firmware-qla2xxx"
 
 FILES:${PN}-qla2xxx = "${firmwaredir}/ql2*"
 FILES:${PN}-qla2xxx-license = "${firmwaredir}/LICENCE.qla2xxx"
@@ -1615,9 +1615,9 @@ FILES:${PN}-qla2xxx-license = "${firmwaredir}/LICENCE.qla2xxx"
 RDEPENDS:${PN}-qla2xxx += "${PN}-qla2xxx-license"
 
 # For RSI RS911x WiFi
-LICENSE:${PN}-rs9113 = "WHENCE"
-LICENSE:${PN}-rs9116 = "WHENCE"
-LICENSE:${PN}-rsi-91x = "WHENCE"
+LICENSE:${PN}-rs9113 = "LicenseRef-Firmware-WHENCE"
+LICENSE:${PN}-rs9116 = "LicenseRef-Firmware-WHENCE"
+LICENSE:${PN}-rsi-91x = "LicenseRef-Firmware-WHENCE"
 
 FILES:${PN}-rs9113 = " ${firmwaredir}/rsi/rs9113*.rps* "
 FILES:${PN}-rs9116 = " ${firmwaredir}/rsi/rs9116*.rps* "
@@ -1628,26 +1628,26 @@ RDEPENDS:${PN}-rs9116 += "${PN}-whence-license"
 RDEPENDS:${PN}-rsi-91x += "${PN}-whence-license"
 
 # For rtl
-LICENSE:${PN}-rtl8188 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8192cu = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8192ce = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8192su = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8261c = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8723 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8761 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8821 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8822 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8192 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8710 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8812 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8851 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8852 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8922 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8703 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl8814 = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl-license = "Firmware-rtlwifi_firmware"
-LICENSE:${PN}-rtl-nic = "WHENCE"
-LICENSE:${PN}-rtl8168 = "WHENCE"
+LICENSE:${PN}-rtl8188 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8192cu = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8192ce = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8192su = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8261c = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8723 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8761 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8821 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8822 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8192 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8710 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8812 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8851 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8852 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8922 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8703 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl8814 = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl-license = "LicenseRef-Firmware-rtlwifi-firmware"
+LICENSE:${PN}-rtl-nic = "LicenseRef-Firmware-WHENCE"
+LICENSE:${PN}-rtl8168 = "LicenseRef-Firmware-WHENCE"
 
 FILES:${PN}-rtl-license = " \
   ${firmwaredir}/LICENCE.rtlwifi_firmware.txt \
@@ -1738,8 +1738,8 @@ RDEPENDS:${PN}-rtl8168 += "${PN}-whence-license"
 RDEPENDS:${PN}-rtl-nic += "${PN}-whence-license"
 
 # For Silabs
-LICENSE:${PN}-wfx = "Firmware-wfx"
-LICENSE:${PN}-wfx-license = "Firmware-wfx"
+LICENSE:${PN}-wfx = "LicenseRef-Firmware-wfx"
+LICENSE:${PN}-wfx-license = "LicenseRef-Firmware-wfx"
 
 FILES:${PN}-wfx = " \
   ${firmwaredir}/wfx/*.pds*        \
@@ -1750,8 +1750,8 @@ FILES:${PN}-wfx-license = "${firmwaredir}/LICENCE.wf200"
 RDEPENDS:${PN}-wfx += "${PN}-wfx-license"
 
 # For TI wl1251
-LICENSE:${PN}-wl1251 = "Firmware-wl1251"
-LICENSE:${PN}-wl1251-license = "Firmware-wl1251"
+LICENSE:${PN}-wl1251 = "LicenseRef-Firmware-wl1251"
+LICENSE:${PN}-wl1251-license = "LicenseRef-Firmware-wl1251"
 
 FILES:${PN}-wl1251 = " \
   ${firmwaredir}/ti-connectivity/wl1251-fw.bin*         \
@@ -1762,11 +1762,11 @@ FILES:${PN}-wl1251-license = "${firmwaredir}/LICENCE.wl1251"
 RDEPENDS:${PN}-wl1251 += "${PN}-wl1251-license"
 
 # For ti-connectivity
-LICENSE:${PN}-wlcommon = "Firmware-ti-connectivity"
-LICENSE:${PN}-wl12xx = "Firmware-ti-connectivity"
-LICENSE:${PN}-wl18xx = "Firmware-ti-connectivity"
-LICENSE:${PN}-cc33xx = "Firmware-ti-connectivity"
-LICENSE:${PN}-ti-connectivity-license = "Firmware-ti-connectivity"
+LICENSE:${PN}-wlcommon = "LicenseRef-Firmware-ti-connectivity"
+LICENSE:${PN}-wl12xx = "LicenseRef-Firmware-ti-connectivity"
+LICENSE:${PN}-wl18xx = "LicenseRef-Firmware-ti-connectivity"
+LICENSE:${PN}-cc33xx = "LicenseRef-Firmware-ti-connectivity"
+LICENSE:${PN}-ti-connectivity-license = "LicenseRef-Firmware-ti-connectivity"
 
 FILES:${PN}-ti-connectivity-license = "${firmwaredir}/LICENCE.ti-connectivity"
 # wl18xx optionally needs wl1271-nvs.bin (which itself is a symlink to
@@ -1797,8 +1797,8 @@ RDEPENDS:${PN}-wl18xx = "${PN}-ti-connectivity-license ${PN}-wlcommon"
 RDEPENDS:${PN}-cc33xx = "${PN}-ti-connectivity-license"
 
 # For ti-keystone
-LICENSE:${PN}-ti-keystone = "Firmware-ti-keystone"
-LICENSE:${PN}-ti-keystone-license = "Firmware-ti-keystone"
+LICENSE:${PN}-ti-keystone = "LicenseRef-Firmware-ti-keystone"
+LICENSE:${PN}-ti-keystone-license = "LicenseRef-Firmware-ti-keystone"
 
 FILES:${PN}-ti-keystone = "${firmwaredir}/ti-keystone/*"
 FILES:${PN}-ti-keystone-license = " \
@@ -1807,11 +1807,11 @@ FILES:${PN}-ti-keystone-license = " \
 RDEPENDS:${PN}-ti-keystone += "${PN}-ti-keystone-license"
 
 # For ti-tspa-license
-LICENSE:${PN}-ti-tspa-license = "Firmware-ti-tspa"
+LICENSE:${PN}-ti-tspa-license = "LicenseRef-Firmware-ti-tspa"
 FILES:${PN}-ti-tspa-license = "${firmwaredir}/LICENCE.ti-tspa"
 
 # For ti-tas2563 - tas2563 firmware
-LICENSE:${PN}-ti-tas2563 = "Firmware-ti-tspa"
+LICENSE:${PN}-ti-tas2563 = "LicenseRef-Firmware-ti-tspa"
 FILES:${PN}-ti-tas2563 = "\
     ${firmwaredir}/INT8866RCA2.bin* \
     ${firmwaredir}/TAS2XXX3870.bin* \
@@ -1820,7 +1820,7 @@ FILES:${PN}-ti-tas2563 = "\
 RDEPENDS:${PN}-ti-tas2563 = "${PN}-ti-tspa-license"
 
 # For ti-tas257x - tas257x firmware
-LICENSE:${PN}-ti-tas257x = "Firmware-ti-tspa"
+LICENSE:${PN}-ti-tas257x = "LicenseRef-Firmware-ti-tspa"
 FILES:${PN}-ti-tas257x = "\
     ${firmwaredir}/tas257x-1amp-reg.bin*\
     ${firmwaredir}/tas2572-1-1amp-reg.bin* \
@@ -1832,14 +1832,14 @@ FILES:${PN}-ti-tas257x = "\
 RDEPENDS:${PN}-ti-tas257x = "${PN}-ti-tspa-license"
 
 # For ti-pcm6240 - pcm6240 firmware
-LICENSE:${PN}-ti-pcm6240 = "Firmware-ti-tspa"
+LICENSE:${PN}-ti-pcm6240 = "LicenseRef-Firmware-ti-tspa"
 FILES:${PN}-ti-pcm6240 = "\
     ${firmwaredir}/ti/pcm6240/pcm6240-i2c-1-2dev.bin* \
 "
 RDEPENDS:${PN}-ti-pcm6240 = "${PN}-ti-tspa-license"
 
 # For ti-tas2781 - tas2781 firmware
-LICENSE:${PN}-ti-tas2781 = "Firmware-ti-tspa"
+LICENSE:${PN}-ti-tas2781 = "LicenseRef-Firmware-ti-tspa"
 FILES:${PN}-ti-tas2781 = "\
     ${firmwaredir}/TAS2XXX*.bin* \
     ${firmwaredir}/TIAS2781*.bin* \
@@ -1849,7 +1849,7 @@ FILES:${PN}-ti-tas2781 = "\
 RDEPENDS:${PN}-ti-tas2781 = "${PN}-ti-tspa-license"
 
 # For ti-tas2783 - tas2783 firmware
-LICENSE:${PN}-ti-tas2783 = "Firmware-ti-tspa"
+LICENSE:${PN}-ti-tas2783 = "LicenseRef-Firmware-ti-tspa"
 FILES:${PN}-ti-tas2783 = "\
     ${firmwaredir}/1534-2-*.bin* \
     ${firmwaredir}/16F4-1-*.bin* \
@@ -1867,7 +1867,7 @@ FILES:${PN}-ti-tas2783 = "\
 RDEPENDS:${PN}-ti-tas2781 = "${PN}-ti-tspa-license"
 
 # For ti-vpe - Texas Instruments V4L2 driver for Video Processing Engine
-LICENSE:${PN}-ti-vpe = "Firmware-ti-tspa"
+LICENSE:${PN}-ti-vpe = "LicenseRef-Firmware-ti-tspa"
 FILES:${PN}-ti-vpe = "${firmwaredir}/ti/vpdma-1b8.bin*"
 RDEPENDS:${PN}-ti-vpe = "${PN}-ti-tspa-license"
 
@@ -1879,8 +1879,8 @@ FILES:${PN}-ti-usb-3410-5052 = "\
 "
 
 # For vt6656
-LICENSE:${PN}-vt6656 = "Firmware-via_vt6656"
-LICENSE:${PN}-vt6656-license = "Firmware-via_vt6656"
+LICENSE:${PN}-vt6656 = "LicenseRef-Firmware-via-vt6656"
+LICENSE:${PN}-vt6656-license = "LicenseRef-Firmware-via-vt6656"
 
 FILES:${PN}-vt6656-license = "${firmwaredir}/LICENCE.via_vt6656"
 FILES:${PN}-vt6656 = " \
@@ -1890,8 +1890,8 @@ FILES:${PN}-vt6656 = " \
 RDEPENDS:${PN}-vt6656 = "${PN}-vt6656-license"
 
 # For xc4000
-LICENSE:${PN}-xc4000 = "Firmware-xc4000"
-LICENSE:${PN}-xc4000-license = "Firmware-xc4000"
+LICENSE:${PN}-xc4000 = "LicenseRef-Firmware-xc4000"
+LICENSE:${PN}-xc4000-license = "LicenseRef-Firmware-xc4000"
 
 FILES:${PN}-xc4000 = "${firmwaredir}/dvb-fe-xc4000-1.4.1.fw*"
 FILES:${PN}-xc4000-license = "${firmwaredir}/LICENCE.xc4000"
@@ -1899,8 +1899,8 @@ FILES:${PN}-xc4000-license = "${firmwaredir}/LICENCE.xc4000"
 RDEPENDS:${PN}-xc4000 += "${PN}-xc4000-license"
 
 # For xc5000
-LICENSE:${PN}-xc5000 = "Firmware-xc5000"
-LICENSE:${PN}-xc5000-license = "Firmware-xc5000"
+LICENSE:${PN}-xc5000 = "LicenseRef-Firmware-xc5000"
+LICENSE:${PN}-xc5000-license = "LicenseRef-Firmware-xc5000"
 
 FILES:${PN}-xc5000 = "${firmwaredir}/dvb-fe-xc5000-1.6.114.fw*"
 FILES:${PN}-xc5000-license = "${firmwaredir}/LICENCE.xc5000"
@@ -1908,8 +1908,8 @@ FILES:${PN}-xc5000-license = "${firmwaredir}/LICENCE.xc5000"
 RDEPENDS:${PN}-xc5000 += "${PN}-xc5000-license"
 
 # For xc5000c
-LICENSE:${PN}-xc5000c = "Firmware-xc5000c"
-LICENSE:${PN}-xc5000c-license = "Firmware-xc5000c"
+LICENSE:${PN}-xc5000c = "LicenseRef-Firmware-xc5000c"
+LICENSE:${PN}-xc5000c-license = "LicenseRef-Firmware-xc5000c"
 
 FILES:${PN}-xc5000c = " \
   ${firmwaredir}/dvb-fe-xc5000c-4.1.30.7.fw* \
@@ -1922,7 +1922,7 @@ RDEPENDS:${PN}-xc5000c += "${PN}-xc5000c-license"
 
 # for i in `grep brcm WHENCE  | grep ^File | sed 's/File: brcm.//g'`; do pkg=`echo $i | sed 's/-[sp40].*//g; s/\.bin//g; s/brcmfmac/bcm/g; s/_hdr/-hdr/g; s/BCM/bcm-0bb4-0306/g'`; echo -e "             \${PN}-$pkg \\"; done  | sort -u
 
-LICENSE:${PN}-broadcom-license = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-broadcom-license = "LicenseRef-Firmware-broadcom-bcm43xx"
 FILES:${PN}-broadcom-license = "${firmwaredir}/LICENCE.broadcom_bcm43xx"
 
 # for i in `grep brcm WHENCE  | grep ^File | sed 's/File: brcm.//g'`; do pkg=`echo $i | sed 's/-[sp40].*//g; s/\.bin//g; s/brcmfmac/bcm/g; s/_hdr/-hdr/g; s/BCM/bcm-0bb4-0306/g'`; echo "$i - $pkg"; echo -e "FILES:\${PN}-$pkg = \"\${firmwaredir}/brcm/$i\""; done | grep ^FILES
@@ -1973,69 +1973,69 @@ FILES:${PN}-bcm54591 = "${firmwaredir}/brcm/brcmfmac54591-pcie.* \
   ${firmwaredir}/cypress/cyfmac54591-pcie.* \
 "
 
-# for i in `grep brcm WHENCE  | grep ^File | sed 's/File: brcm.//g'`; do pkg=`echo $i | sed 's/-[sp40].*//g; s/\.bin//g; s/brcmfmac/bcm/g; s/_hdr/-hdr/g; s/BCM/bcm-0bb4-0306/g'`; echo -e "LICENSE:\${PN}-$pkg = \"Firmware-broadcom_bcm43xx\"\nRDEPENDS_\${PN}-$pkg += \"\${PN}-broadcom-license\""; done
+# for i in `grep brcm WHENCE  | grep ^File | sed 's/File: brcm.//g'`; do pkg=`echo $i | sed 's/-[sp40].*//g; s/\.bin//g; s/brcmfmac/bcm/g; s/_hdr/-hdr/g; s/BCM/bcm-0bb4-0306/g'`; echo -e "LICENSE:\${PN}-$pkg = \"Firmware-broadcom-bcm43xx\"\nRDEPENDS_\${PN}-$pkg += \"\${PN}-broadcom-license\""; done
 # Currently 1st one and last 6 have cypress LICENSE
 
-LICENSE:${PN}-bcm43xx = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43xx = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43xx += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43xx-hdr = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43xx-hdr = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43xx-hdr += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4329-fullmac = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4329-fullmac = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4329-fullmac += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43236b = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43236b = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43236b += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4329 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4329 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4329 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4330 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4330 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4330 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4334 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4334 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4334 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4335 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4335 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4335 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4339 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4339 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4339 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43241b0 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43241b0 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43241b0 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43241b4 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43241b4 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43241b4 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43241b5 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43241b5 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43241b5 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43242a = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43242a = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43242a += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43012 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43012 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43012 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43143 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43143 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43143 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43430a0 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43430a0 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43430a0 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43455 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43455 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43455 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4350c2 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4350c2 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4350c2 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4350 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4350 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4350 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4356 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4356 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4356 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43569 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43569 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43569 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43570 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43570 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43570 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4358 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4358 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4358 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm43602 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm43602 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm43602 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4366b = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4366b = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4366b += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4366c = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4366c = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4366c += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm4371 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm4371 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm4371 += "${PN}-broadcom-license"
-LICENSE:${PN}-bcm54591 = "Firmware-broadcom_bcm43xx"
+LICENSE:${PN}-bcm54591 = "LicenseRef-Firmware-broadcom-bcm43xx"
 RDEPENDS:${PN}-bcm54591 += "${PN}-broadcom-license"
 
 # For broadcom cypress
 
-LICENSE:${PN}-cypress-license = "Firmware-cypress"
+LICENSE:${PN}-cypress-license = "LicenseRef-Firmware-cypress"
 FILES:${PN}-cypress-license = "${firmwaredir}/LICENCE.cypress"
 
 FILES:${PN}-bcm-0bb4-0306 = "${firmwaredir}/brcm/BCM-0bb4-0306.hcd*"
@@ -2059,21 +2059,21 @@ FILES:${PN}-bcm4373 = "${firmwaredir}/brcm/brcmfmac4373-sdio.bin* \
   ${firmwaredir}/cypress/cyfmac4373-sdio.clm_blob* \
 "
 
-LICENSE:${PN}-bcm-0bb4-0306 = "Firmware-cypress"
+LICENSE:${PN}-bcm-0bb4-0306 = "LicenseRef-Firmware-cypress"
 RDEPENDS:${PN}-bcm-0bb4-0306 += "${PN}-cypress-license"
-LICENSE:${PN}-bcm-0a5c-6410 = "Firmware-cypress"
+LICENSE:${PN}-bcm-0a5c-6410 = "LicenseRef-Firmware-cypress"
 RDEPENDS:${PN}-bcm-0a5c-6410 += "${PN}-bcm-0bb4-0306"
-LICENSE:${PN}-bcm43340 = "Firmware-cypress"
+LICENSE:${PN}-bcm43340 = "LicenseRef-Firmware-cypress"
 RDEPENDS:${PN}-bcm43340 += "${PN}-cypress-license"
-LICENSE:${PN}-bcm43362 = "Firmware-cypress"
+LICENSE:${PN}-bcm43362 = "LicenseRef-Firmware-cypress"
 RDEPENDS:${PN}-bcm43362 += "${PN}-cypress-license"
-LICENSE:${PN}-bcm43430 = "Firmware-cypress"
+LICENSE:${PN}-bcm43430 = "LicenseRef-Firmware-cypress"
 RDEPENDS:${PN}-bcm43430 += "${PN}-cypress-license"
-LICENSE:${PN}-bcm4354 = "Firmware-cypress"
+LICENSE:${PN}-bcm4354 = "LicenseRef-Firmware-cypress"
 RDEPENDS:${PN}-bcm4354 += "${PN}-cypress-license"
-LICENSE:${PN}-bcm4356-pcie = "Firmware-cypress"
+LICENSE:${PN}-bcm4356-pcie = "LicenseRef-Firmware-cypress"
 RDEPENDS:${PN}-bcm4356-pcie += "${PN}-cypress-license"
-LICENSE:${PN}-bcm4373 = "Firmware-cypress"
+LICENSE:${PN}-bcm4373 = "LicenseRef-Firmware-cypress"
 RDEPENDS:${PN}-bcm4373 += "${PN}-cypress-license"
 
 # For Broadcom bnx2
@@ -2081,8 +2081,8 @@ RDEPENDS:${PN}-bcm4373 += "${PN}-cypress-license"
 # which is a separate case to the other Broadcom firmwares since its
 # license is contained in the shared WHENCE file.
 
-LICENSE:${PN}-bnx2 = "WHENCE"
-LICENSE:${PN}-whence-license = "WHENCE"
+LICENSE:${PN}-bnx2 = "LicenseRef-Firmware-WHENCE"
+LICENSE:${PN}-whence-license = "LicenseRef-Firmware-WHENCE"
 
 FILES:${PN}-bnx2 = " \
     ${firmwaredir}/bnx2/bnx2-mips*.fw* \
@@ -2093,16 +2093,16 @@ FILES:${PN}-whence-license = "${firmwaredir}/WHENCE"
 RDEPENDS:${PN}-bnx2 += "${PN}-whence-license"
 RPROVIDES:${PN}-bnx2 = "${PN}-bnx2-mips"
 
-LICENSE:${PN}-bnx2x = "WHENCE"
+LICENSE:${PN}-bnx2x = "LicenseRef-Firmware-WHENCE"
 
 FILES:${PN}-bnx2x = "${firmwaredir}/bnx2x/bnx2x*.fw*"
 
 RDEPENDS:${PN}-bnx2x += "${PN}-whence-license"
 
 # For cirrus
-LICENSE:${PN}-cirrus = "Firmware-cirrus"
-LICENSE:${PN}-cirrus-cs42l45 = "Firmware-cirrus"
-LICENSE:${PN}-cirrus-license = "Firmware-cirrus"
+LICENSE:${PN}-cirrus = "LicenseRef-Firmware-cirrus"
+LICENSE:${PN}-cirrus-cs42l45 = "LicenseRef-Firmware-cirrus"
+LICENSE:${PN}-cirrus-license = "LicenseRef-Firmware-cirrus"
 
 FILES:${PN}-cirrus = " \
     ${firmwaredir}/cs42l43.bin* \
@@ -2118,8 +2118,8 @@ RDEPENDS:${PN}-cirrus += "${PN}-cirrus-license"
 RDEPENDS:${PN}-cirrus-cs42l45 += "${PN}-cirrus-license"
 
 # For cnm
-LICENSE:${PN}-cnm = "Firmware-cnm"
-LICENSE:${PN}-cnm-license = "Firmware-cnm"
+LICENSE:${PN}-cnm = "LicenseRef-Firmware-cnm"
+LICENSE:${PN}-cnm-license = "LicenseRef-Firmware-cnm"
 
 FILES:${PN}-cnm = "${firmwaredir}/cnm/*"
 FILES:${PN}-cnm-license = "${firmwaredir}/LICENCE.cnm"
@@ -2127,9 +2127,9 @@ FILES:${PN}-cnm-license = "${firmwaredir}/LICENCE.cnm"
 RDEPENDS:${PN}-cnm += "${PN}-cnm-license"
 
 # For imx-sdma
-LICENSE:${PN}-imx-sdma-imx6q       = "Firmware-imx-sdma_firmware"
-LICENSE:${PN}-imx-sdma-imx7d       = "Firmware-imx-sdma_firmware"
-LICENSE:${PN}-imx-sdma-license       = "Firmware-imx-sdma_firmware"
+LICENSE:${PN}-imx-sdma-imx6q       = "LicenseRef-Firmware-imx-sdma-firmware"
+LICENSE:${PN}-imx-sdma-imx7d       = "LicenseRef-Firmware-imx-sdma-firmware"
+LICENSE:${PN}-imx-sdma-license       = "LicenseRef-Firmware-imx-sdma-firmware"
 
 FILES:${PN}-imx-sdma-imx6q = "${firmwaredir}/imx/sdma/sdma-imx6q.bin*"
 
@@ -2145,32 +2145,32 @@ RDEPENDS:${PN}-imx-sdma-imx6q += "${PN}-imx-sdma-license"
 RDEPENDS:${PN}-imx-sdma-imx7d += "${PN}-imx-sdma-license"
 
 # For iwlwifi
-LICENSE:${PN}-iwlwifi           = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-135-6     = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-3160-7    = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-3160-8    = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-3160-9    = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-3160-10   = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-3160-12   = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-3160-13   = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-3160-16   = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-3160-17   = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-6000-4    = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-6000g2a-5 = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-6000g2a-6 = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-6000g2b-5 = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-6000g2b-6 = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-6050-4    = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-6050-5    = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-7260      = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-7265      = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-7265d     = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-8000c     = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-8265      = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-9000      = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-9260      = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-misc      = "Firmware-iwlwifi_firmware"
-LICENSE:${PN}-iwlwifi-license   = "Firmware-iwlwifi_firmware"
+LICENSE:${PN}-iwlwifi           = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-135-6     = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-3160-7    = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-3160-8    = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-3160-9    = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-3160-10   = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-3160-12   = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-3160-13   = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-3160-16   = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-3160-17   = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-6000-4    = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-6000g2a-5 = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-6000g2a-6 = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-6000g2b-5 = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-6000g2b-6 = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-6050-4    = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-6050-5    = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-7260      = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-7265      = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-7265d     = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-8000c     = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-8265      = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-9000      = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-9260      = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-misc      = "LicenseRef-Firmware-iwlwifi-firmware"
+LICENSE:${PN}-iwlwifi-license   = "LicenseRef-Firmware-iwlwifi-firmware"
 
 FILES:${PN}-iwlwifi-license = "${firmwaredir}/LICENCE.iwlwifi_firmware"
 FILES:${PN}-iwlwifi-135-6 = "${firmwaredir}/iwlwifi-135-6.ucode* ${firmwaredir}/intel/iwlwifi/iwlwifi-135-6.ucode*"
@@ -2244,15 +2244,15 @@ RREPLACES:${PN}-iwlwifi-7260 = "${PN}-iwlwifi-7260-7 ${PN}-iwlwifi-7260-8 ${PN}-
 RCONFLICTS:${PN}-iwlwifi-7260 = "${PN}-iwlwifi-7260-7 ${PN}-iwlwifi-7260-8 ${PN}-iwlwifi-7260-9"
 
 # For ibt
-LICENSE:${PN}-ibt-license = "Firmware-ibt_firmware"
-LICENSE:${PN}-ibt-hw-37-7 = "Firmware-ibt_firmware"
-LICENSE:${PN}-ibt-hw-37-8 = "Firmware-ibt_firmware"
-LICENSE:${PN}-ibt-11-5    = "Firmware-ibt_firmware"
-LICENSE:${PN}-ibt-12-16   = "Firmware-ibt_firmware"
-LICENSE:${PN}-ibt-17 = "Firmware-ibt_firmware"
-LICENSE:${PN}-ibt-18    = "Firmware-ibt_firmware"
-LICENSE:${PN}-ibt-20 = "Firmware-ibt_firmware"
-LICENSE:${PN}-ibt-misc    = "Firmware-ibt_firmware"
+LICENSE:${PN}-ibt-license = "LicenseRef-Firmware-ibt-firmware"
+LICENSE:${PN}-ibt-hw-37-7 = "LicenseRef-Firmware-ibt-firmware"
+LICENSE:${PN}-ibt-hw-37-8 = "LicenseRef-Firmware-ibt-firmware"
+LICENSE:${PN}-ibt-11-5    = "LicenseRef-Firmware-ibt-firmware"
+LICENSE:${PN}-ibt-12-16   = "LicenseRef-Firmware-ibt-firmware"
+LICENSE:${PN}-ibt-17 = "LicenseRef-Firmware-ibt-firmware"
+LICENSE:${PN}-ibt-18    = "LicenseRef-Firmware-ibt-firmware"
+LICENSE:${PN}-ibt-20 = "LicenseRef-Firmware-ibt-firmware"
+LICENSE:${PN}-ibt-misc    = "LicenseRef-Firmware-ibt-firmware"
 
 FILES:${PN}-ibt-license = "${firmwaredir}/LICENCE.ibt_firmware"
 FILES:${PN}-ibt-hw-37-7 = "${firmwaredir}/intel/ibt-hw-37.7*.bseq*"
@@ -2276,15 +2276,15 @@ RDEPENDS:${PN}-ibt-misc    = "${PN}-ibt-license"
 ALLOW_EMPTY:${PN}-ibt = "1"
 ALLOW_EMPTY:${PN}-ibt-misc = "1"
 
-LICENSE:${PN}-i915       = "Firmware-i915"
-LICENSE:${PN}-i915-license = "Firmware-i915"
+LICENSE:${PN}-i915       = "LicenseRef-Firmware-i915"
+LICENSE:${PN}-i915-license = "LicenseRef-Firmware-i915"
 FILES:${PN}-i915-license = "${firmwaredir}/LICENSE.i915"
 FILES:${PN}-i915         = "${firmwaredir}/i915"
 RDEPENDS:${PN}-i915      = "${PN}-i915-license"
 
 # For ice-enhanced
-LICENSE:${PN}-ice-enhanced         = "Firmware-ice_enhanced"
-LICENSE:${PN}-ice-enhanced-license = "Firmware-ice_enhanced"
+LICENSE:${PN}-ice-enhanced         = "LicenseRef-Firmware-ice-enhanced"
+LICENSE:${PN}-ice-enhanced-license = "LicenseRef-Firmware-ice-enhanced"
 
 FILES:${PN}-ice-enhanced           = " \
   ${firmwaredir}/intel/ice/ddp-comms/* \
@@ -2295,8 +2295,8 @@ FILES:${PN}-ice-enhanced-license   = " \
 "
 RDEPENDS:${PN}-ice-enhanced        = "${PN}-ice-enhanced-license"
 
-LICENSE:${PN}-ice       = "Firmware-ice"
-LICENSE:${PN}-ice-license = "Firmware-ice"
+LICENSE:${PN}-ice       = "LicenseRef-Firmware-ice"
+LICENSE:${PN}-ice-license = "LicenseRef-Firmware-ice"
 FILES:${PN}-ice-license = "${firmwaredir}/LICENSE.ice"
 FILES:${PN}-ice         = " \
   ${firmwaredir}/intel/ice/ddp/* \
@@ -2305,8 +2305,8 @@ FILES:${PN}-ice         = " \
 RDEPENDS:${PN}-ice      = "${PN}-ice-license"
 
 FILES:${PN}-adsp-sst-license      = "${firmwaredir}/LICENCE.adsp_sst"
-LICENSE:${PN}-adsp-sst            = "Firmware-adsp_sst"
-LICENSE:${PN}-adsp-sst-license    = "Firmware-adsp_sst"
+LICENSE:${PN}-adsp-sst            = "LicenseRef-Firmware-adsp-sst"
+LICENSE:${PN}-adsp-sst-license    = "LicenseRef-Firmware-adsp-sst"
 FILES:${PN}-adsp-sst              = "\
     ${firmwaredir}/intel/dsp_fw* \
     ${firmwaredir}/intel/avs/*/dsp_basefw.bin \
@@ -2319,148 +2319,148 @@ LICENSE:${PN}-snd-soc-avs = "Apache-2.0"
 FILES:${PN}-snd-soc-avs = "${firmwaredir}/intel/avs/*"
 
 # For QAT
-LICENSE:${PN}-qat         = "Firmware-qat"
-LICENSE:${PN}-qat-license = "Firmware-qat"
+LICENSE:${PN}-qat         = "LicenseRef-Firmware-qat"
+LICENSE:${PN}-qat-license = "LicenseRef-Firmware-qat"
 FILES:${PN}-qat-license   = "${firmwaredir}/LICENCE.qat_firmware"
 FILES:${PN}-qat           = "${firmwaredir}/qat*.bin* ${firmwaredir}/intel/qat/qat*.bin*"
 RDEPENDS:${PN}-qat        = "${PN}-qat-license"
 
-LICENSE:${PN}-qed         = "WHENCE"
+LICENSE:${PN}-qed         = "LicenseRef-Firmware-WHENCE"
 FILES:${PN}-qed           = "${firmwaredir}/qed/*"
 
-LICENSE:${PN}-linaro-license = "Firmware-linaro"
+LICENSE:${PN}-linaro-license = "LicenseRef-Firmware-linaro"
 FILES:${PN}-linaro-license   = "${firmwaredir}/LICENCE.linaro"
 
 # For QCOM VPU/GPU and SDM845
-LICENSE:${PN}-qcom-license = "Firmware-qcom"
-LICENSE:${PN}-qcom-2-license = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-yamato-license = "Firmware-qcom-yamato"
-LICENSE:${PN}-qcom-aic100 = "Firmware-qcom"
-LICENSE:${PN}-qcom-qdu100 = "Firmware-qcom"
-LICENSE:${PN}-qcom-venus-1.8 = "Firmware-qcom"
-LICENSE:${PN}-qcom-venus-4.2 = "Firmware-qcom"
-LICENSE:${PN}-qcom-venus-5.2 = "Firmware-qcom"
-LICENSE:${PN}-qcom-venus-5.4 = "Firmware-qcom"
-LICENSE:${PN}-qcom-venus-6.0 = "Firmware-qcom"
-LICENSE:${PN}-qcom-vpu = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a2xx = "Firmware-qcom Firmware-qcom-yamato"
-LICENSE:${PN}-qcom-adreno-a3xx = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a4xx = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a530 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a612 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a623 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a630 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a640 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a650 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a660 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a663 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a702 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a730 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-a740 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-g705 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-g709 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-g715 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-g800 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-g801 = "Firmware-qcom"
-LICENSE:${PN}-qcom-adreno-g802 = "Firmware-qcom"
-LICENSE:${PN}-qcom-apq8016-modem = "Firmware-qcom"
-LICENSE:${PN}-qcom-apq8016-wifi = "Firmware-qcom"
-LICENSE:${PN}-qcom-apq8096-audio = "Firmware-qcom"
-LICENSE:${PN}-qcom-apq8096-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-apq8096-modem = "Firmware-qcom"
-LICENSE:${PN}-qcom-glymur-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-glymur-audio = "Firmware-qcom-2 & Firmware-linaro"
-LICENSE:${PN}-qcom-glymur-compute = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-kaanapali-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-kaanapali-audio = "Firmware-qcom-2 & Firmware-linaro"
-LICENSE:${PN}-qcom-kaanapali-compute = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-kaanapali-soccp = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-qcm2290-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcm2290-audio = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcm2290-modem = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcm2290-wifi = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcm6490-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcm6490-audio = "Firmware-qcom & Firmware-linaro"
-LICENSE:${PN}-qcom-qcm6490-compute  = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcm6490-ipa  = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcm6490-wifi  = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcm6490-qupv3fw = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcs615-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcs615-audio = "Firmware-qcom & Firmware-linaro"
-LICENSE:${PN}-qcom-qcs615-compute = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcs615-qupv3fw = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcs6490-radxa-dragon-q6a-audio = "Firmware-qcom & Firmware-linaro"
-LICENSE:${PN}-qcom-qcs6490-radxa-dragon-q6a-compute = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcs6490-thundercomm-rubikpi3-audio = "Firmware-qcom & Firmware-linaro"
-LICENSE:${PN}-qcom-qcs8300-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-qcs8300-audio = "Firmware-qcom-2 & Firmware-linaro"
-LICENSE:${PN}-qcom-qcs8300-compute = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-qcs8300-generalpurpose = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-qcs8300-qupv3fw = "Firmware-qcom"
-LICENSE:${PN}-qcom-qrb4210-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-qrb4210-audio = "Firmware-qcom"
-LICENSE:${PN}-qcom-qrb4210-compute  = "Firmware-qcom"
-LICENSE:${PN}-qcom-qrb4210-modem = "Firmware-qcom"
-LICENSE:${PN}-qcom-qrb4210-wifi = "Firmware-qcom"
-LICENSE:${PN}-qcom-sa8775p-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-sa8775p-audio = "Firmware-qcom-2 & Firmware-linaro"
-LICENSE:${PN}-qcom-sa8775p-compute = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-sa8775p-generalpurpose = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-sa8775p-qupv3fw = "Firmware-qcom"
-LICENSE:${PN}-qcom-sc8280xp-lenovo-x13s-audio = "Firmware-qcom & Firmware-linaro"
-LICENSE:${PN}-qcom-sc8280xp-lenovo-x13s-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-sc8280xp-lenovo-x13s-compute = "Firmware-qcom"
-LICENSE:${PN}-qcom-sc8280xp-lenovo-x13s-sensors = "Firmware-qcom"
-LICENSE:${PN}-qcom-sc8280xp-lenovo-x13s-vpu = "Firmware-qcom"
-LICENSE:${PN}-qcom-sdm845-audio = "Firmware-qcom"
-LICENSE:${PN}-qcom-sdm845-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-sdm845-compute = "Firmware-qcom"
-LICENSE:${PN}-qcom-sdm845-modem = "Firmware-qcom"
-LICENSE:${PN}-qcom-sdm845-thundercomm-db845c-sensors = "Firmware-qcom"
-LICENSE:${PN}-qcom-sdx35-foxconn-firehose = "Firmware-qcom"
-LICENSE:${PN}-qcom-sdx61-foxconn-firehose = "Firmware-qcom"
-LICENSE:${PN}-qcom-shikra-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-shikra-compute = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-shikra-audio = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-shikra-modem = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-shikra-qupv3fw = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8150-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8250-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8250-audio = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8250-compute = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8250-thundercomm-rb5-sensors = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8350-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8450-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8450-audio-tplg = "Firmware-linaro"
-LICENSE:${PN}-qcom-sm8550-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8550-audio-tplg = "Firmware-linaro"
-LICENSE:${PN}-qcom-sm8650-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8650-audio-tplg = "Firmware-linaro"
-LICENSE:${PN}-qcom-sm8750-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-sm8750-audio = "Firmware-qcom-2 & Firmware-linaro"
-LICENSE:${PN}-qcom-sm8750-compute = "Firmware-qcom-2"
-LICENSE:${PN}-qcom-x1e80100-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-x1e80100-audio = "Firmware-qcom-2 & Firmware-linaro"
-LICENSE:${PN}-qcom-x1e80100-compute = "Firmware-qcom"
-LICENSE:${PN}-qcom-x1e80100-asus-vivobook-16-audio-tplg = "Firmware-linaro"
-LICENSE:${PN}-qcom-x1e80100-asus-vivobook-s15-audio-tplg = "Firmware-linaro"
-LICENSE:${PN}-qcom-x1e80100-asus-zenbook-a14-audio-tplg = "Firmware-linaro"
-LICENSE:${PN}-qcom-x1e80100-dell-inspiron-14-plus-7441-audio-tplg = "Firmware-linaro"
-LICENSE:${PN}-qcom-x1e80100-dell-latitude-7455-audio-tplg = "Firmware-linaro"
-LICENSE:${PN}-qcom-x1e80100-dell-xps13-9345-adreno = "Firmware-dell"
-LICENSE:${PN}-qcom-x1e80100-dell-xps13-9345-audio = "Firmware-dell & Firmware-linaro"
-LICENSE:${PN}-qcom-x1e80100-dell-xps13-9345-compute = "Firmware-dell"
-LICENSE:${PN}-qcom-x1e80100-hp-omnibook-x14-audio-tplg = "Firmware-linaro"
-LICENSE:${PN}-qcom-x1e80100-lenovo-t14s-g6-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-x1e80100-lenovo-t14s-g6-audio = "Firmware-qcom & Firmware-linaro"
-LICENSE:${PN}-qcom-x1e80100-lenovo-t14s-g6-compute = "Firmware-qcom"
-LICENSE:${PN}-qcom-x1e80100-lenovo-t14s-g6-vpu = "Firmware-qcom"
-LICENSE:${PN}-qcom-x1e80100-lenovo-yoga-slim7x-adreno = "Firmware-qcom"
-LICENSE:${PN}-qcom-x1e80100-lenovo-yoga-slim7x-audio = "Firmware-qcom & Firmware-linaro"
-LICENSE:${PN}-qcom-x1e80100-lenovo-yoga-slim7x-compute = "Firmware-qcom"
-LICENSE:${PN}-qcom-x1e80100-lenovo-yoga-slim7x-vpu = "Firmware-qcom"
-LICENSE:${PN}-qcom-x1e80100-qupv3fw = "Firmware-qcom"
-LICENSE:${PN}-qcom-x1p42100-adreno = "Firmware-qcom"
+LICENSE:${PN}-qcom-license = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-2-license = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-yamato-license = "LicenseRef-Firmware-qcom-yamato"
+LICENSE:${PN}-qcom-aic100 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qdu100 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-venus-1.8 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-venus-4.2 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-venus-5.2 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-venus-5.4 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-venus-6.0 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-vpu = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a2xx = "LicenseRef-Firmware-qcom AND LicenseRef-Firmware-qcom-yamato"
+LICENSE:${PN}-qcom-adreno-a3xx = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a4xx = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a530 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a612 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a623 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a630 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a640 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a650 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a660 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a663 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a702 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a730 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-a740 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-g705 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-g709 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-g715 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-g800 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-g801 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-adreno-g802 = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-apq8016-modem = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-apq8016-wifi = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-apq8096-audio = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-apq8096-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-apq8096-modem = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-glymur-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-glymur-audio = "LicenseRef-Firmware-qcom-2 AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-glymur-compute = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-kaanapali-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-kaanapali-audio = "LicenseRef-Firmware-qcom-2 AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-kaanapali-compute = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-kaanapali-soccp = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-qcm2290-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcm2290-audio = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcm2290-modem = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcm2290-wifi = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcm6490-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcm6490-audio = "LicenseRef-Firmware-qcom AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-qcm6490-compute  = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcm6490-ipa  = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcm6490-wifi  = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcm6490-qupv3fw = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcs615-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcs615-audio = "LicenseRef-Firmware-qcom AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-qcs615-compute = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcs615-qupv3fw = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcs6490-radxa-dragon-q6a-audio = "LicenseRef-Firmware-qcom AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-qcs6490-radxa-dragon-q6a-compute = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcs6490-thundercomm-rubikpi3-audio = "LicenseRef-Firmware-qcom AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-qcs8300-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qcs8300-audio = "LicenseRef-Firmware-qcom-2 AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-qcs8300-compute = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-qcs8300-generalpurpose = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-qcs8300-qupv3fw = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qrb4210-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qrb4210-audio = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qrb4210-compute  = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qrb4210-modem = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-qrb4210-wifi = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sa8775p-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sa8775p-audio = "LicenseRef-Firmware-qcom-2 AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-sa8775p-compute = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-sa8775p-generalpurpose = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-sa8775p-qupv3fw = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sc8280xp-lenovo-x13s-audio = "LicenseRef-Firmware-qcom AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-sc8280xp-lenovo-x13s-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sc8280xp-lenovo-x13s-compute = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sc8280xp-lenovo-x13s-sensors = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sc8280xp-lenovo-x13s-vpu = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sdm845-audio = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sdm845-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sdm845-compute = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sdm845-modem = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sdm845-thundercomm-db845c-sensors = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sdx35-foxconn-firehose = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sdx61-foxconn-firehose = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-shikra-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-shikra-compute = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-shikra-audio = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-shikra-modem = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-shikra-qupv3fw = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8150-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8250-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8250-audio = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8250-compute = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8250-thundercomm-rb5-sensors = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8350-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8450-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8450-audio-tplg = "LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-sm8550-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8550-audio-tplg = "LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-sm8650-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8650-audio-tplg = "LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-sm8750-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-sm8750-audio = "LicenseRef-Firmware-qcom-2 AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-sm8750-compute = "LicenseRef-Firmware-qcom-2"
+LICENSE:${PN}-qcom-x1e80100-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-x1e80100-audio = "LicenseRef-Firmware-qcom-2 AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-x1e80100-compute = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-x1e80100-asus-vivobook-16-audio-tplg = "LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-x1e80100-asus-vivobook-s15-audio-tplg = "LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-x1e80100-asus-zenbook-a14-audio-tplg = "LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-x1e80100-dell-inspiron-14-plus-7441-audio-tplg = "LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-x1e80100-dell-latitude-7455-audio-tplg = "LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-x1e80100-dell-xps13-9345-adreno = "LicenseRef-Firmware-dell"
+LICENSE:${PN}-qcom-x1e80100-dell-xps13-9345-audio = "LicenseRef-Firmware-dell AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-x1e80100-dell-xps13-9345-compute = "LicenseRef-Firmware-dell"
+LICENSE:${PN}-qcom-x1e80100-hp-omnibook-x14-audio-tplg = "LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-x1e80100-lenovo-t14s-g6-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-x1e80100-lenovo-t14s-g6-audio = "LicenseRef-Firmware-qcom AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-x1e80100-lenovo-t14s-g6-compute = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-x1e80100-lenovo-t14s-g6-vpu = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-x1e80100-lenovo-yoga-slim7x-adreno = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-x1e80100-lenovo-yoga-slim7x-audio = "LicenseRef-Firmware-qcom AND LicenseRef-Firmware-linaro"
+LICENSE:${PN}-qcom-x1e80100-lenovo-yoga-slim7x-compute = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-x1e80100-lenovo-yoga-slim7x-vpu = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-x1e80100-qupv3fw = "LicenseRef-Firmware-qcom"
+LICENSE:${PN}-qcom-x1p42100-adreno = "LicenseRef-Firmware-qcom"
 
 FILES:${PN}-qcom-license   = "${firmwaredir}/LICENSE.qcom ${firmwaredir}/qcom/NOTICE.txt"
 FILES:${PN}-qcom-2-license   = "${firmwaredir}/LICENSE.qcom-2"
@@ -2799,55 +2799,55 @@ RRECOMMENDS:${PN}-qcom-sc8280xp-lenovo-x13s-compute = "${PN}-qcom-sc8280xp-lenov
 RRECOMMENDS:${PN}-qcom-sc8280xp-lenovo-x13s-sensors = "${PN}-qcom-sc8280xp-lenovo-x13s-compat"
 RRECOMMENDS:${PN}-qcom-sc8280xp-lenovo-x13s-vpu = "${PN}-qcom-sc8280xp-lenovo-x13s-compat"
 
-LICENSE:${PN}-liquidui = "Firmware-cavium_liquidio"
+LICENSE:${PN}-liquidui = "LicenseRef-Firmware-cavium-liquidio"
 FILES:${PN}-liquidio = "${firmwaredir}/liquidio"
 
-LICENSE:${PN}-mellanox = "WHENCE"
+LICENSE:${PN}-mellanox = "LicenseRef-Firmware-WHENCE"
 FILES:${PN}-mellanox = "${firmwaredir}/mellanox"
 
-LICENSE:${PN}-prestera = "Firmware-Marvell"
+LICENSE:${PN}-prestera = "LicenseRef-Firmware-Marvell"
 FILES:${PN}-prestera = "${firmwaredir}/mrvl/prestera"
 RDEPENDS:${PN}-prestera = "${PN}-marvell-license"
 
 # For Rockchip
-LICENSE:${PN}-rockchip-dptx = "Firmware-rockchip"
+LICENSE:${PN}-rockchip-dptx = "LicenseRef-Firmware-rockchip"
 FILES:${PN}-rockchip-license = "${firmwaredir}/LICENCE.rockchip"
 FILES:${PN}-rockchip-dptx = "${firmwaredir}/rockchip/dptx.bin*"
 RDEPENDS:${PN}-rockchip-dptx = "${PN}-rockchip-license"
 
 # For Amlogic VDEC
-LICENSE:${PN}-amlogic-vdec = "Firmware-amlogic_vdec"
+LICENSE:${PN}-amlogic-vdec = "LicenseRef-Firmware-amlogic-vdec"
 FILES:${PN}-amlogic-vdec-license = "${firmwaredir}/LICENSE.amlogic_vdec"
 FILES:${PN}-amlogic-vdec = "${firmwaredir}/meson/vdec/*"
 RDEPENDS:${PN}-amlogic-vdec = "${PN}-amlogic-vdec-license"
 
 # For 3com typhoon
-LICENSE:${PN}-typhoon-license = "Firmware-typhoon"
-LICENSE:${PN}-typhoon = "Firmware-typhoon"
+LICENSE:${PN}-typhoon-license = "LicenseRef-Firmware-typhoon"
+LICENSE:${PN}-typhoon = "LicenseRef-Firmware-typhoon"
 FILES:${PN}-typhoon-license = "${firmwaredir}/LICENCE.typhoon"
 FILES:${PN}-typhoon = "${firmwaredir}/3com/typhoon.bin*"
 RDEPENDS:${PN}-typhoon = "${PN}-typhoon-license"
 
 # For ish - Intel Integrated Sensor Hub
-LICENSE:${PN}-intel-license = "Firmware-intel"
+LICENSE:${PN}-intel-license = "LicenseRef-Firmware-intel"
 FILES:${PN}-intel-license = "${firmwaredir}/LICENSE.intel"
 
-LICENSE:${PN}-ish-lnlm = "Firmware-intel"
+LICENSE:${PN}-ish-lnlm = "LicenseRef-Firmware-intel"
 FILES:${PN}-ish-lnlm = "${firmwaredir}/intel/ish/ish_lnlm.bin*"
 RDEPENDS:${PN}-ish-lnlm = "${PN}-intel-license"
 
 # For Dell ish - Intel Integrated Sensor Hub
-LICENSE:${PN}-dell-license = "Firmware-dell"
+LICENSE:${PN}-dell-license = "LicenseRef-Firmware-dell"
 FILES:${PN}-dell-license = "${firmwaredir}/LICENSE.dell"
 
-LICENSE:${PN}-ish-lnlm-39ceeaf8 = "Firmware-dell"
+LICENSE:${PN}-ish-lnlm-39ceeaf8 = "LicenseRef-Firmware-dell"
 FILES:${PN}-ish-lnlm-39ceeaf8 =  "\
     ${firmwaredir}/intel/ish/ish_lnlm_39ceeaf8.bin* \
     ${firmwaredir}/dell/ish/ish_lnlm_39ceeaf8_*.bin* \
 "
 RDEPENDS:${PN}-ish-lnlm-39ceeaf8 = "${PN}-dell-license"
 
-LICENSE:${PN}-ish-ptl-39ceeaf8 = "Firmware-dell"
+LICENSE:${PN}-ish-ptl-39ceeaf8 = "LicenseRef-Firmware-dell"
 FILES:${PN}-ish-ptl-39ceeaf8 =  "\
     ${firmwaredir}/intel/ish/ish_ptl_39ceeaf8.bin* \
     ${firmwaredir}/dell/ish/ish_ptl_39ceeaf8_*.bin* \
@@ -2855,27 +2855,27 @@ FILES:${PN}-ish-ptl-39ceeaf8 =  "\
 RDEPENDS:${PN}-ish-ptl-39ceeaf8 = "${PN}-dell-license"
 
 # For HP ish - Intel Integrated Sensor Hub
-LICENSE:${PN}-hp-license = "Firmware-HP"
+LICENSE:${PN}-hp-license = "LicenseRef-Firmware-HP"
 FILES:${PN}-hp-license = "${firmwaredir}/LICENSE.HP"
 
-LICENSE:${PN}-ish-lnlm-12128606 = "Firmware-HP"
+LICENSE:${PN}-ish-lnlm-12128606 = "LicenseRef-Firmware-HP"
 FILES:${PN}-ish-lnlm-12128606 = " \
     ${firmwaredir}/intel/ish/ish_lnlm_12128606_*.bin* \
     ${firmwaredir}/HP/ish/ish_lnlm_12128606_*.bin* \
 "
 RDEPENDS:${PN}-ish-lnlm-12128606 = "${PN}-hp-license"
 
-LICENSE:${PN}-ish-ptl-12128606 = "Firmware-HP"
+LICENSE:${PN}-ish-ptl-12128606 = "LicenseRef-Firmware-HP"
 FILES:${PN}-ish-ptl-12128606 = " \
     ${firmwaredir}/HP/ish/ish_ptl_12128606_*.bin* \
 "
 RDEPENDS:${PN}-ish-ptl-12128606 = "${PN}-hp-license"
 
 # For LENOVO ish - Intel Integrated Sensor Hub
-LICENSE:${PN}-lenovo-license = "Firmware-lenovo"
+LICENSE:${PN}-lenovo-license = "LicenseRef-Firmware-lenovo"
 FILES:${PN}-lenovo-license = "${firmwaredir}/LICENCE.lenovo"
 
-LICENSE:${PN}-ish-lnlm-53c4ffad = "Firmware-lenovo"
+LICENSE:${PN}-ish-lnlm-53c4ffad = "LicenseRef-Firmware-lenovo"
 FILES:${PN}-ish-lnlm-53c4ffad = "\
     ${firmwaredir}/intel/ish/ish_lnlm_53c4ffad_*.bin* \
     ${firmwaredir}/LENOVO/ish/ish_lnlm_lenovo_X1_2025_5.8.4.7720.bin* \
@@ -2884,59 +2884,59 @@ FILES:${PN}-ish-lnlm-53c4ffad = "\
 "
 RDEPENDS:${PN}-ish-lnlm-53c4ffad = "${PN}-lenovo-license"
 
-LICENSE:${PN}-ish-ptl = "Firmware-intel"
+LICENSE:${PN}-ish-ptl = "LicenseRef-Firmware-intel"
 FILES:${PN}-ish-ptl = "${firmwaredir}/intel/ish/ish_ptl.bin*"
 RDEPENDS:${PN}-ish-ptl = "${PN}-intel-license"
 
-LICENSE:${PN}-ish-ptl-53c4ffad = "Firmware-lenovo"
+LICENSE:${PN}-ish-ptl-53c4ffad = "LicenseRef-Firmware-lenovo"
 FILES:${PN}-ish-ptl-53c4ffad = "\
     ${firmwaredir}/intel/ish/ish_ptl_53c4ffad_*.bin* \
     ${firmwaredir}/LENOVO/ish/ish_ptl_lenovo_X1_2026_5.8.1.7782.bin* \
 "
 RDEPENDS:${PN}-ish-ptl-53c4ffad = "${PN}-lenovo-license"
 
-LICENSE:${PN}-ish-wcl = "Firmware-intel"
+LICENSE:${PN}-ish-wcl = "LicenseRef-Firmware-intel"
 FILES:${PN}-ish-wcl = "${firmwaredir}/intel/ish/ish_wcl.bin*"
 RDEPENDS:${PN}-ish-wcl = "${PN}-intel-license"
 
 # For advansys - AdvanSys SCSI
-LICENSE:${PN}-advansys-license = "Firmware-advansys"
+LICENSE:${PN}-advansys-license = "LicenseRef-Firmware-advansys"
 FILES:${PN}-advansys-license = "${firmwaredir}/LICENCE.advansys"
 
-LICENSE:${PN}-advansys = "Firmware-advansys"
+LICENSE:${PN}-advansys = "LicenseRef-Firmware-advansys"
 FILES:${PN}-advansys = "${firmwaredir}/advansys/*"
 RDEPENDS:${PN}-advansys = "${PN}-advansys-license"
 
 # For as21xxx
-LICENSE:${PN}-aeonsemi-license = "Firmware-aeonsemi"
+LICENSE:${PN}-aeonsemi-license = "LicenseRef-Firmware-aeonsemi"
 FILES:${PN}-aeonsemi-license = "${firmwaredir}/LICENSE.aeonsemi"
 
-LICENSE:${PN}-as21xxx = "Firmware-aeonsemi"
+LICENSE:${PN}-as21xxx = "LicenseRef-Firmware-aeonsemi"
 FILES:${PN}-as21xxx = "${firmwaredir}/aeonsemi/*"
 RDEPENDS:${PN}-as21xxx = "${PN}-aeonsemi-license"
 
 # For orinoco - Agere/Prism/Symbol Orinoco support
-LICENSE:${PN}-agere-license = "Firmware-agere"
+LICENSE:${PN}-agere-license = "LicenseRef-Firmware-agere"
 FILES:${PN}-agere-license = "${firmwaredir}/LICENCE.agere"
 
-LICENSE:${PN}-orinoco = "Firmware-agere"
+LICENSE:${PN}-orinoco = "LicenseRef-Firmware-agere"
 FILES:${PN}-orinoco = "${firmwaredir}/agere_*"
 RDEPENDS:${PN}-orinoco = "${PN}-agere-license"
 
 # For en8811h - Airoha 2.5G Ethernet Phy
-LICENSE:${PN}-airoha-license = "Firmware-airoha"
+LICENSE:${PN}-airoha-license = "LicenseRef-Firmware-airoha"
 FILES:${PN}-airoha-license = "${firmwaredir}/LICENSE.airoha"
 
-LICENSE:${PN}-an8811hb = "Firmware-airoha"
+LICENSE:${PN}-an8811hb = "LicenseRef-Firmware-airoha"
 FILES:${PN}-an8811hb = "${firmwaredir}/airoha/an8811hb/EthMD32*"
 RDEPENDS:${PN}-an8811hb = "${PN}-airoha-license"
 
-LICENSE:${PN}-en8811h = "Firmware-airoha"
+LICENSE:${PN}-en8811h = "LicenseRef-Firmware-airoha"
 FILES:${PN}-en8811h = "${firmwaredir}/airoha/EthMD32*"
 RDEPENDS:${PN}-en8811h = "${PN}-airoha-license"
 
 # For airoha-npu - Airoha Network Processor Unit driver
-LICENSE:${PN}-airoha-npu = "Firmware-airoha"
+LICENSE:${PN}-airoha-npu = "LicenseRef-Firmware-airoha"
 FILES:${PN}-airoha-npu = " \
     ${firmwaredir}/airoha/an7583_npu* \
     ${firmwaredir}/airoha/en7581_npu* \
@@ -2945,42 +2945,42 @@ FILES:${PN}-airoha-npu = " \
 RDEPENDS:${PN}-airoha-npu = "${PN}-airoha-license"
 
 # For ccp - Platform Security Processor (PSP) device
-LICENSE:${PN}-amd-sev-license = "Firmware-amd-sev"
+LICENSE:${PN}-amd-sev-license = "LicenseRef-Firmware-amd-sev"
 FILES:${PN}-amd-sev-license = "${firmwaredir}/LICENSE.amd-sev"
 
-LICENSE:${PN}-ccp = "Firmware-amd-sev"
+LICENSE:${PN}-ccp = "LicenseRef-Firmware-amd-sev"
 FILES:${PN}-ccp = "${firmwaredir}/amd/amd_sev*"
 RDEPENDS:${PN}-ccp = "${PN}-amd-sev-license"
 
 # For amdxdna - AMD Inference processor
-LICENSE:${PN}-amdnpu-license = "Firmware-amdnpu"
+LICENSE:${PN}-amdnpu-license = "LicenseRef-Firmware-amdnpu"
 FILES:${PN}-amdnpu-license = "${firmwaredir}/LICENSE.amdnpu"
 
-LICENSE:${PN}-amdxdna = "Firmware-amdnpu"
+LICENSE:${PN}-amdxdna = "LicenseRef-Firmware-amdnpu"
 FILES:${PN}-amdxdna = "${firmwaredir}/amdnpu/*"
 RDEPENDS:${PN}-amdxdna = "${PN}-amdnpu-license"
 
 # For amd_pmf - AMD Platform Management Framework TA
-LICENSE:${PN}-amd-pmf-license = "Firmware-amd_pmf"
+LICENSE:${PN}-amd-pmf-license = "LicenseRef-Firmware-amd-pmf"
 FILES:${PN}-amd-pmf-license = "${firmwaredir}/LICENSE.amd_pmf"
 
-LICENSE:${PN}-amd-pmf = "Firmware-amd_pmf"
+LICENSE:${PN}-amd-pmf = "LicenseRef-Firmware-amd-pmf"
 FILES:${PN}-amd-pmf = "${firmwaredir}/amdtee/*"
 RDEPENDS:${PN}-amd-pmf = "${PN}-amd-pmf-license"
 
 # For microcode_amd - AMD CPU Microcode Update Driver for Linux
-LICENSE:${PN}-amd-ucode-license = "Firmware-amd-ucode"
+LICENSE:${PN}-amd-ucode-license = "LicenseRef-Firmware-amd-ucode"
 FILES:${PN}-amd-ucode-license = "${firmwaredir}/LICENSE.amd-ucode"
 
-LICENSE:${PN}-microcode-amd = "Firmware-amd-ucode"
+LICENSE:${PN}-microcode-amd = "LicenseRef-Firmware-amd-ucode"
 FILES:${PN}-microcode-amd = "${firmwaredir}/amd-ucode/*"
 RDEPENDS:${PN}-microcode-amd = "${PN}-amd-ucode-license"
 
 # For amlogic - Amlogic SoC Firmware
-LICENSE:${PN}-amlogic-license = "Firmware-amlogic"
+LICENSE:${PN}-amlogic-license = "LicenseRef-Firmware-amlogic"
 FILES:${PN}-amlogic-license = "${firmwaredir}/LICENSE.amlogic"
 
-LICENSE:${PN}-amlogic = "Firmware-amlogic"
+LICENSE:${PN}-amlogic = "LicenseRef-Firmware-amlogic"
 FILES:${PN}-amlogic = "${firmwaredir}/amlogic/aml_*"
 RDEPENDS:${PN}-amlogic = "${PN}-amlogic-license"
 
@@ -2989,22 +2989,22 @@ LICENSE:${PN}-starfire = "GPL-2.0-only"
 FILES:${PN}-starfire = "${firmwaredir}/adaptec/starfire*"
 
 # For as102 - Abilis Systems Single DVB-T Receiver
-LICENSE:${PN}-abilis-license = "Firmware-Abilis"
+LICENSE:${PN}-abilis-license = "LicenseRef-Firmware-Abilis"
 FILES:${PN}-abilis-license = "${firmwaredir}/LICENCE.Abilis"
 
-LICENSE:${PN}-as102 = "Firmware-Abilis"
+LICENSE:${PN}-as102 = "LicenseRef-Firmware-Abilis"
 FILES:${PN}-as102 = "${firmwaredir}/as102_data*_st.hex*"
 RDEPENDS:${PN}-as102 = "${PN}-abilis-license"
 
 # For wilc1000 - Atmel 802.11n WLAN driver for WILC1000 & WILC3000
-LICENSE:${PN}-atmel-license = "Firmware-atmel"
+LICENSE:${PN}-atmel-license = "LicenseRef-Firmware-atmel"
 FILES:${PN}-atmel-license = "${firmwaredir}/LICENSE.atmel"
 
-LICENSE:${PN}-wilc1000 = "Firmware-atmel"
+LICENSE:${PN}-wilc1000 = "LicenseRef-Firmware-atmel"
 FILES:${PN}-wilc1000 = "${firmwaredir}/atmel/wilc1000*"
 RDEPENDS:${PN}-wilc1000 = "${PN}-atmel-license"
 
-LICENSE:${PN}-wilc3000 = "Firmware-atmel"
+LICENSE:${PN}-wilc3000 = "LicenseRef-Firmware-atmel"
 FILES:${PN}-wilc3000 = "${firmwaredir}/atmel/wilc3000*"
 RDEPENDS:${PN}-wilc3000 = "${PN}-atmel-license"
 
@@ -3017,42 +3017,42 @@ FILES:${PN}-dvb-ttpci = "${firmwaredir}/av7110/*"
 LICENSE:${PN}-dvb-ttpci = "GPL-2.0-or-later"
 
 # For bmi260 - Bosch BMI260 IMU configuration data
-LICENSE:${PN}-bmi260-license = "Firmware-bmi260"
+LICENSE:${PN}-bmi260-license = "LicenseRef-Firmware-bmi260"
 FILES:${PN}-bmi260-license = "${firmwaredir}/LICENSE.bmi260"
 
-LICENSE:${PN}-bmi260 = "Firmware-bmi260"
+LICENSE:${PN}-bmi260 = "LicenseRef-Firmware-bmi260"
 FILES:${PN}-bmi260 = "${firmwaredir}/bmi260-init-data.fw*"
 RDEPENDS:${PN}-bmi260 = "${PN}-bmi260-license"
 
 # For cdns-mhdp - Cadence MHDP8546 DP bridge
-LICENSE:${PN}-cadence-license = "Firmware-cadence"
+LICENSE:${PN}-cadence-license = "LicenseRef-Firmware-cadence"
 FILES:${PN}-cadence-license = "${firmwaredir}/LICENCE.cadence"
 
-LICENSE:${PN}-mhdp8546 = "Firmware-cadence"
+LICENSE:${PN}-mhdp8546 = "LicenseRef-Firmware-cadence"
 FILES:${PN}-mhdp8546 = "${firmwaredir}/cadence/mhdp8546.bin*"
 RDEPENDS:${PN}-mhdp8546 = "${PN}-cadence-license"
 
 # For nitrox - Cavium CNN55XX crypto driver
-LICENSE:${PN}-cavium-license = "Firmware-cavium"
+LICENSE:${PN}-cavium-license = "LicenseRef-Firmware-cavium"
 FILES:${PN}-cavium-license = "${firmwaredir}/LICENCE.cavium"
 
-LICENSE:${PN}-cnn55xx = "Firmware-cavium"
+LICENSE:${PN}-cnn55xx = "LicenseRef-Firmware-cavium"
 FILES:${PN}-cnn55xx = "${firmwaredir}/cavium/cnn55xx*"
 RDEPENDS:${PN}-cnn55xx = "${PN}-cavium-license"
 
 # For BFA/BNA - QLogic BR-series Adapter FC/FCOE drivers
-LICENSE:${PN}-bfa-license = "Firmware-bfa"
+LICENSE:${PN}-bfa-license = "LicenseRef-Firmware-bfa"
 FILES:${PN}-bfa-license = "${firmwaredir}/LICENSE.bfa"
 
-LICENSE:${PN}-cbfw = "Firmware-bfa"
+LICENSE:${PN}-cbfw = "LicenseRef-Firmware-bfa"
 FILES:${PN}-cbfw = "${firmwaredir}/cbfw-3.2.5.1.bin*"
 RDEPENDS:${PN}-cbfw = "${PN}-bfa-license"
 
-LICENSE:${PN}-ctfw = "Firmware-bfa"
+LICENSE:${PN}-ctfw = "LicenseRef-Firmware-bfa"
 FILES:${PN}-ctfw = "${firmwaredir}/ctfw-3.2.5.1.bin*"
 RDEPENDS:${PN}-ctfw = "${PN}-bfa-license"
 
-LICENSE:${PN}-ct2fw = "Firmware-bfa"
+LICENSE:${PN}-ct2fw = "LicenseRef-Firmware-bfa"
 FILES:${PN}-ct2fw = "${firmwaredir}/ct2fw-3.2.5.1.bin*"
 RDEPENDS:${PN}-ct2fw = "${PN}-bfa-license"
 
@@ -3066,15 +3066,15 @@ FILES:${PN}-pcnet-cs = " \
     ${firmwaredir}/cis/PE-200.cis* \
     ${firmwaredir}/cis/PE520.cis* \
 "
-LICENSE:${PN}-pcnet-cs = "GPL-2.0-only & MPL-1.1"
+LICENSE:${PN}-pcnet-cs = "GPL-2.0-only AND MPL-1.1"
 
 # For 3c589_cs - 3Com PCMCIA adapter
 FILES:${PN}-3c589-cs = "${firmwaredir}/cis/3CXEM556.cis*"
-LICENSE:${PN}-3c589-cs = "GPL-2.0-only & MPL-1.1"
+LICENSE:${PN}-3c589-cs = "GPL-2.0-only AND MPL-1.1"
 
 # For 3c574-cs - 3Com PCMCIA adapter
 FILES:${PN}-3c574-cs = "${firmwaredir}/cis/3CCFEM556.cis*"
-LICENSE:${PN}-3c574-cs = "GPL-2.0-only & MPL-1.1"
+LICENSE:${PN}-3c574-cs = "GPL-2.0-only AND MPL-1.1"
 
 # For serial_cs - Serial PCMCIA adapter (pcmcia-cs project)
 FILES:${PN}-serial-cs = " \
@@ -3083,7 +3083,7 @@ FILES:${PN}-serial-cs = " \
     ${firmwaredir}/cis/COMpad2.cis* \
     ${firmwaredir}/cis/COMpad4.cis* \
 "
-LICENSE:${PN}-serial-cs = "GPL-2.0-only & MPL-1.1"
+LICENSE:${PN}-serial-cs = "GPL-2.0-only AND MPL-1.1"
 
 # For Sierra Wireless serial_cs - Serial PCMCIA adapter
 FILES:${PN}-sw-serial = " \
@@ -3094,10 +3094,10 @@ FILES:${PN}-sw-serial = " \
 LICENSE:${PN}-sw-serial = "GPL-3.0-only"
 
 # For smsmdtv - Siano MDTV Core module
-LICENSE:${PN}-siano-license = "Firmware-siano"
+LICENSE:${PN}-siano-license = "LicenseRef-Firmware-siano"
 FILES:${PN}-siano-license = "${firmwaredir}/LICENCE.siano"
 
-LICENSE:${PN}-smsmdtv = "Firmware-siano"
+LICENSE:${PN}-smsmdtv = "LicenseRef-Firmware-siano"
 FILES:${PN}-smsmdtv = " \
     ${firmwaredir}/cmmb_vega_12mhz.inp* \
     ${firmwaredir}/cmmb_venice_12mhz.inp* \
@@ -3120,10 +3120,10 @@ FILES:${PN}-cpia2 = "${firmwaredir}/cpia2/*"
 LICENSE:${PN}-cpia2 = "GPL-2.0-or-later"
 
 # For snd-hda-codec-ca0132 - Creative Sound Core3D codec
-LICENSE:${PN}-ca0132-license = "Firmware-ca0132"
+LICENSE:${PN}-ca0132-license = "LicenseRef-Firmware-ca0132"
 FILES:${PN}-ca0132-license = "${firmwaredir}/LICENCE.ca0132"
 
-LICENSE:${PN}-ca0132 = "Firmware-ca0132"
+LICENSE:${PN}-ca0132 = "LicenseRef-Firmware-ca0132"
 FILES:${PN}-ca0132 = " \
     ${firmwaredir}/ctefx.bin* \
     ${firmwaredir}/ctspeq.bin* \
@@ -3131,26 +3131,26 @@ FILES:${PN}-ca0132 = " \
 RDEPENDS:${PN}-ca0132 = "${PN}-ca0132-license"
 
 # For cxgb3 - Chelsio Terminator 3 1G/10G Ethernet adapter
-LICENSE:${PN}-cxgb3-license = "Firmware-cxgb3"
+LICENSE:${PN}-cxgb3-license = "LicenseRef-Firmware-cxgb3"
 FILES:${PN}-cxgb3-license = "${firmwaredir}/LICENCE.cxgb3"
 
-LICENSE:${PN}-cxgb3 = "Firmware-cxgb3 & GPL-2.0-only"
+LICENSE:${PN}-cxgb3 = "LicenseRef-Firmware-cxgb3 AND GPL-2.0-only"
 FILES:${PN}-cxgb3 = "${firmwaredir}/cxgb3/*"
 RDEPENDS:${PN}-cxgb3 = "${PN}-cxgb3-license"
 
 # For cxgb4 - Chelsio Terminator 4/5/6 1/10/25/40/100G Ethernet adapter
-LICENSE:${PN}-chelsio-firmware-license = "Firmware-chelsio_firmware"
+LICENSE:${PN}-chelsio-firmware-license = "LicenseRef-Firmware-chelsio-firmware"
 FILES:${PN}-chelsio-firmware-license = "${firmwaredir}/LICENCE.chelsio_firmware"
 
-LICENSE:${PN}-cxgb4 = "Firmware-chelsio_firmware"
+LICENSE:${PN}-cxgb4 = "LicenseRef-Firmware-chelsio-firmware"
 FILES:${PN}-cxgb4 = "${firmwaredir}/cxgb4/*"
 RDEPENDS:${PN}-cxgb4 = "${PN}-chelsio-firmware-license"
 
 # For dabusb - Digital Audio Broadcasting (DAB) Receiver for USB and Linux
-LICENSE:${PN}-dabusb-license = "Firmware-dabusb"
+LICENSE:${PN}-dabusb-license = "LicenseRef-Firmware-dabusb"
 FILES:${PN}-dabusb-license = "${firmwaredir}/LICENCE.dabusb"
 
-LICENSE:${PN}-dabusb = "Firmware-dabusb"
+LICENSE:${PN}-dabusb = "LicenseRef-Firmware-dabusb"
 FILES:${PN}-dabusb = "${firmwaredir}/dabusb/*"
 RDEPENDS:${PN}-dabusb = "${PN}-dabusb-license"
 
@@ -3159,34 +3159,34 @@ LICENSE:${PN}-dsp56k = "GPL-2.0-or-later"
 FILES:${PN}-dsp56k = "${firmwaredir}/dsp56k/*"
 
 # For dib0700 - DiBcom dib0700 USB DVB bridge driver
-LICENSE:${PN}-dib0700-license = "Firmware-dib0700"
+LICENSE:${PN}-dib0700-license = "LicenseRef-Firmware-dib0700"
 FILES:${PN}-dib0700-license = "${firmwaredir}/LICENSE.dib0700"
 
-LICENSE:${PN}-dib0700 = "Firmware-dib0700"
+LICENSE:${PN}-dib0700 = "LicenseRef-Firmware-dib0700"
 FILES:${PN}-dib0700 = "${firmwaredir}/dvb-usb-dib0700-1.20.fw*"
 RDEPENDS:${PN}-dib0700 = "${PN}-dib0700-license"
 
 # For it9135 - ITEtech IT913x DVB-T USB driver
-LICENSE:${PN}-it913x-license = "Firmware-it913x"
+LICENSE:${PN}-it913x-license = "LicenseRef-Firmware-it913x"
 FILES:${PN}-it913x-license = "${firmwaredir}/LICENCE.it913x"
 
-LICENSE:${PN}-it9135 = "Firmware-it913x"
+LICENSE:${PN}-it9135 = "LicenseRef-Firmware-it913x"
 FILES:${PN}-it9135 = "${firmwaredir}/dvb-usb-it9135*"
 RDEPENDS:${PN}-it9135 = "${PN}-it913x-license"
 
 # For drxk - Micronas DRX-K demodulator driver
-LICENSE:${PN}-drxk-license = "Firmware-drxk"
+LICENSE:${PN}-drxk-license = "LicenseRef-Firmware-drxk"
 FILES:${PN}-drxk-license = "${firmwaredir}/LICENSE.drxk"
 
-LICENSE:${PN}-drxk = "Firmware-drxk"
+LICENSE:${PN}-drxk = "LicenseRef-Firmware-drxk"
 FILES:${PN}-drxk = "${firmwaredir}/dvb-usb-terratec-h5-drxk.fw*"
 RDEPENDS:${PN}-drxk = "${PN}-drxk-license"
 
 # For e100 - Intel PRO/100 Ethernet NIC
-LICENSE:${PN}-e100-license = "Firmware-e100"
+LICENSE:${PN}-e100-license = "LicenseRef-Firmware-e100"
 FILES:${PN}-e100-license = "${firmwaredir}/LICENCE.e100"
 
-LICENSE:${PN}-e100 = "Firmware-e100"
+LICENSE:${PN}-e100 = "LicenseRef-Firmware-e100"
 FILES:${PN}-e100 = "${firmwaredir}/e100/*"
 RDEPENDS:${PN}-e100 = "${PN}-e100-license"
 
@@ -3199,26 +3199,26 @@ LICENSE:${PN}-io-edgeport = "GPL-2.0-or-later"
 FILES:${PN}-io-edgeport = "${firmwaredir}/edgeport/*"
 
 # For emi26 - EMI 2|6 USB Audio interface
-LICENSE:${PN}-emi26-license = "Firmware-emi26"
+LICENSE:${PN}-emi26-license = "LicenseRef-Firmware-emi26"
 FILES:${PN}-emi26-license = "${firmwaredir}/LICENCE.emi26"
 
-LICENSE:${PN}-emi26 = "Firmware-emi26"
+LICENSE:${PN}-emi26 = "LicenseRef-Firmware-emi26"
 FILES:${PN}-emi26 = "${firmwaredir}/emi26/*"
 RDEPENDS:${PN}-emi26 = "${PN}-drxk-license"
 
 # For ene-ub6250 - ENE UB6250 SD card reader driver
-LICENSE:${PN}-ene-firmware-license = "Firmware-ene_firmware"
+LICENSE:${PN}-ene-firmware-license = "LicenseRef-Firmware-ene-firmware"
 FILES:${PN}-ene-firmware-license = "${firmwaredir}/LICENCE.ene_firmware"
 
-LICENSE:${PN}-ene-ub6250 = "Firmware-ene_firmware"
+LICENSE:${PN}-ene-ub6250 = "LicenseRef-Firmware-ene-firmware"
 FILES:${PN}-ene-ub6250 = "${firmwaredir}/ene-ub6250/*"
 RDEPENDS:${PN}-ene-ub6250 = "${PN}-ene-firmware-license"
 
 # For go7007-s2250
-LICENSE:${PN}-sensoray-license = "Firmware-sensoray"
+LICENSE:${PN}-sensoray-license = "LicenseRef-Firmware-sensoray"
 FILES:${PN}-sensoray-license = "${firmwaredir}/LICENCE.sensoray"
 
-LICENSE:${PN}-go7007-s2250 = "Firmware-sensoray"
+LICENSE:${PN}-go7007-s2250 = "LicenseRef-Firmware-sensoray"
 FILES:${PN}-go7007-s2250 = " \
     ${firmwaredir}/go7007/s2250* \
     ${firmwaredir}/s2250* \
@@ -3226,34 +3226,34 @@ FILES:${PN}-go7007-s2250 = " \
 RDEPENDS:${PN}-go7007-s2250 = "${PN}-sensoray-license"
 
 # For go7007
-LICENSE:${PN}-go7007-license = "Firmware-go7007"
+LICENSE:${PN}-go7007-license = "LicenseRef-Firmware-go7007"
 FILES:${PN}-go7007-license = "${firmwaredir}/LICENCE.go7007"
 
-LICENSE:${PN}-go7007 = "Firmware-go7007"
+LICENSE:${PN}-go7007 = "LicenseRef-Firmware-go7007"
 FILES:${PN}-go7007 = "${firmwaredir}/go7007/*"
 RDEPENDS:${PN}-go7007 = "${PN}-go7007-license"
 
 # For hfi1 - Intel OPA Gen 1 adapter
-LICENSE:${PN}-hfi1-license = "Firmware-hfi1_firmware"
+LICENSE:${PN}-hfi1-license = "LicenseRef-Firmware-hfi1-firmware"
 FILES:${PN}-hfi1-license = "${firmwaredir}/LICENSE.hfi1_firmware"
 
-LICENSE:${PN}-hfi1 = "Firmware-hfi1_firmware"
+LICENSE:${PN}-hfi1 = "LicenseRef-Firmware-hfi1-firmware"
 FILES:${PN}-hfi1 = "${firmwaredir}/hfi1_*"
 RDEPENDS:${PN}-hfi1 = "${PN}-hfi1-license"
 
 # For inside-secure - Inside Secure EIP197 crypto driver
-LICENSE:${PN}-inside-secure-license = "Firmware-inside-secure"
+LICENSE:${PN}-inside-secure-license = "LicenseRef-Firmware-inside-secure"
 FILES:${PN}-inside-secure-license = "${firmwaredir}/LICENCE.inside-secure"
 
-LICENSE:${PN}-inside-secure = "Firmware-inside-secure"
+LICENSE:${PN}-inside-secure = "LicenseRef-Firmware-inside-secure"
 FILES:${PN}-inside-secure = "${firmwaredir}/inside-secure/*"
 RDEPENDS:${PN}-inside-secure = "${PN}-inside-secure-license"
 
 # For snd_soc_catpt - Intel AudioDSP driver for HSW/BDW platforms
-LICENSE:${PN}-intcsst2-license = "Firmware-IntcSST2"
+LICENSE:${PN}-intcsst2-license = "LicenseRef-Firmware-IntcSST2"
 FILES:${PN}-intcsst2-license = "${firmwaredir}/LICENCE.IntcSST2"
 
-LICENSE:${PN}-snd-soc-catpt = "Firmware-IntcSST2"
+LICENSE:${PN}-snd-soc-catpt = "LicenseRef-Firmware-IntcSST2"
 FILES:${PN}-snd-soc-catpt = " \
     ${firmwaredir}/intel/catpt/bdw/dsp_basefw.bin* \
     ${firmwaredir}/intel/IntcSST2.bin* \
@@ -3261,36 +3261,36 @@ FILES:${PN}-snd-soc-catpt = " \
 RDEPENDS:${PN}-snd-soc-catpt = "${PN}-intcsst2-license"
 
 # For snd_intel_sst_core
-LICENSE:${PN}-fw-sst-0f28-license = "Firmware-fw_sst_0f28"
+LICENSE:${PN}-fw-sst-0f28-license = "LicenseRef-Firmware-fw-sst-0f28"
 FILES:${PN}-fw-sst-0f28-license = "${firmwaredir}/LICENCE.fw_sst_0f28"
 
-LICENSE:${PN}-snd-intel-sst-core = "Firmware-fw_sst_0f28"
+LICENSE:${PN}-snd-intel-sst-core = "LicenseRef-Firmware-fw-sst-0f28"
 FILES:${PN}-snd-intel-sst-core = "${firmwaredir}/intel/fw_sst_*"
 RDEPENDS:${PN}-snd-intel-sst-core = "${PN}-fw-sst-0f28-license"
 
 # For atomisp - Intel IPU2 (Image Processing Unit 2) driver
-LICENSE:${PN}-ivsc-license = "Firmware-ivsc"
+LICENSE:${PN}-ivsc-license = "LicenseRef-Firmware-ivsc"
 FILES:${PN}-ivsc-license = "${firmwaredir}/LICENSE.ivsc"
 
-LICENSE:${PN}-atomisp = "Firmware-ivsc"
+LICENSE:${PN}-atomisp = "LicenseRef-Firmware-ivsc"
 FILES:${PN}-atomisp = "${firmwaredir}/intel/ipu/shisp_240*"
 RDEPENDS:${PN}-atomisp = "${PN}-ivsc-license"
 
 # For intel-ipu6-isys - Intel IPU6 (Image Processing Unit 6) driver
-LICENSE:${PN}-intel-ipu6-isys = "Firmware-ivsc"
+LICENSE:${PN}-intel-ipu6-isys = "LicenseRef-Firmware-ivsc"
 FILES:${PN}-intel-ipu6-isys = "${firmwaredir}/intel/ipu/ipu6*"
 RDEPENDS:${PN}-intel-ipu6-isys = "${PN}-ivsc-license"
 
 # For mei-vsc-hw - Intel Visual Sensing Controller
-LICENSE:${PN}-mei-vsc-hw = "Firmware-ivsc"
+LICENSE:${PN}-mei-vsc-hw = "LicenseRef-Firmware-ivsc"
 FILES:${PN}-mei-vsc-hw = "${firmwaredir}/intel/vsc/*"
 RDEPENDS:${PN}-mei-vsc-hw = "${PN}-ivsc-license"
 
 # For ipu3-imgu - Intel IPU3 (3rd Gen Image Processing Unit) driver
-LICENSE:${PN}-ipu3-firmware-license = "Firmware-ipu3_firmware"
+LICENSE:${PN}-ipu3-firmware-license = "LicenseRef-Firmware-ipu3-firmware"
 FILES:${PN}-ipu3-firmware-license = "${firmwaredir}/LICENSE.ipu3_firmware"
 
-LICENSE:${PN}-ipu3-imgu = "Firmware-ipu3_firmware"
+LICENSE:${PN}-ipu3-imgu = "LicenseRef-Firmware-ipu3-firmware"
 FILES:${PN}-ipu3-imgu = " \
     ${firmwaredir}/intel/ipu/irci_irci_ecr-master_20161208_0213_20170112_1500.bin* \
     ${firmwaredir}/intel/ipu3-fw.bin* \
@@ -3299,15 +3299,15 @@ FILES:${PN}-ipu3-imgu = " \
 RDEPENDS:${PN}-ipu3-imgu = "${PN}-ipu3-firmware-license"
 
 # For intel-ipu7-isys - Intel IPU7 (Image Processing Unit 7) driver
-LICENSE:${PN}-intel-ipu7-isys = "Firmware-intel"
+LICENSE:${PN}-intel-ipu7-isys = "LicenseRef-Firmware-intel"
 FILES:${PN}-intel-ipu7-isys = "${firmwaredir}/intel/ipu/ipu7*"
 RDEPENDS:${PN}-intel-ipu7-isys = "${PN}-intel-license"
 
 # For intel_vpu - Intel NPU driver
-LICENSE:${PN}-intel-vpu-license = "Firmware-intel_vpu"
+LICENSE:${PN}-intel-vpu-license = "LicenseRef-Firwmare-intel-vpu"
 FILES:${PN}-intel-vpu-license = "${firmwaredir}/LICENSE.intel_vpu"
 
-LICENSE:${PN}-intel-vpu = "Firmware-intel_vpu"
+LICENSE:${PN}-intel-vpu = "LicenseRef-Firwmare-intel-vpu"
 FILES:${PN}-intel-vpu = "${firmwaredir}/intel/vpu/*"
 RDEPENDS:${PN}-intel-vpu = "${PN}-intel-vpu-license"
 
@@ -3316,26 +3316,26 @@ LICENSE:${PN}-isci = "GPL-2.0-only"
 FILES:${PN}-isci = "${firmwaredir}/isci/*"
 
 # For ixp4xx-npe - Intel IXP4xx XScale Network Processing Engine (NPE) Firmware
-LICENSE:${PN}-ixp4xx-license = "Firmware-ixp4xx"
+LICENSE:${PN}-ixp4xx-license = "LicenseRef-Firmware-ixp4xx"
 FILES:${PN}-ixp4xx-license = "${firmwaredir}/LICENSE.ixp4xx"
 
-LICENSE:${PN}-ixp4xx-npe = "Firmware-ixp4xx"
+LICENSE:${PN}-ixp4xx-npe = "LicenseRef-Firmware-ixp4xx"
 FILES:${PN}-ixp4xx-npe = "${firmwaredir}/ixp4xx/*"
 RDEPENDS:${PN}-ixp4xx-npe = "${PN}-ixp4xx-license"
 
 # For kaweth - USB KLSI KL5USB101-based Ethernet device
-LICENSE:${PN}-kaweth-license = "Firmware-kaweth"
+LICENSE:${PN}-kaweth-license = "LicenseRef-Firmware-kaweth"
 FILES:${PN}-kaweth-license = "${firmwaredir}/LICENCE.kaweth"
 
-LICENSE:${PN}-kaweth = "Firmware-kaweth"
+LICENSE:${PN}-kaweth = "LicenseRef-Firmware-kaweth"
 FILES:${PN}-kaweth = "${firmwaredir}/kaweth/*"
 RDEPENDS:${PN}-kaweth = "${PN}-kaweth-license"
 
 # For keyspan - USB Keyspan USA-xxx serial device
-LICENSE:${PN}-keyspan-license = "Firmware-keyspan"
+LICENSE:${PN}-keyspan-license = "LicenseRef-Firmware-keyspan"
 FILES:${PN}-keyspan-license = "${firmwaredir}/LICENCE.keyspan"
 
-LICENSE:${PN}-keyspan = "Firmware-keyspan"
+LICENSE:${PN}-keyspan = "LicenseRef-Firmware-keyspan"
 FILES:${PN}-keyspan = "${firmwaredir}/keyspan/*"
 RDEPENDS:${PN}-keyspan = "${PN}-keyspan-license"
 
@@ -3344,18 +3344,18 @@ LICENSE:${PN}-keyspan-pda = "GPL-2.0-or-later"
 FILES:${PN}-keyspan-pda = "${firmwaredir}/keyspan_pda/*"
 
 # For mga - Matrox G200/G400/G550
-LICENSE:${PN}-mga-license = "Firmware-mga"
+LICENSE:${PN}-mga-license = "LicenseRef-Firmware-mga"
 FILES:${PN}-mga-license = "${firmwaredir}/LICENSE.mga"
 
-LICENSE:${PN}-mga = "Firmware-mga"
+LICENSE:${PN}-mga = "LicenseRef-Firmware-mga"
 FILES:${PN}-mga = "${firmwaredir}/matrox/*"
 RDEPENDS:${PN}-mga = "${PN}-mga-license"
 
 # For myri10ge - Myri10GE 10GbE NIC driver
-LICENSE:${PN}-myri10ge-firmware-license = "Firmware-myri10ge_firmware"
+LICENSE:${PN}-myri10ge-firmware-license = "LicenseRef-Firmware-myri10ge-firmware"
 FILES:${PN}-myri10ge-firmware-license = "${firmwaredir}/LICENCE.myri10ge_firmware"
 
-LICENSE:${PN}-myri10ge = "Firmware-myri10ge_firmware"
+LICENSE:${PN}-myri10ge = "LicenseRef-Firmware-myri10ge-firmware"
 FILES:${PN}-myri10ge = "${firmwaredir}/myri10ge_*"
 RDEPENDS:${PN}-myri10ge = "${PN}-myri10ge-firmware-license"
 
@@ -3364,10 +3364,10 @@ LICENSE:${PN}-smc91c92-cs = "GPL-1.0-only"
 FILES:${PN}-smc91c92-cs = "${firmwaredir}/ositech/Xilinx7OD.bin*"
 
 # For qla1280 - Qlogic QLA 1240/1x80/1x160 SCSI support
-LICENSE:${PN}-qla1280-license = "Firmware-qla1280"
+LICENSE:${PN}-qla1280-license = "LicenseRef-Firmware-qla1280"
 FILES:${PN}-qla1280-license = "${firmwaredir}/LICENCE.qla1280"
 
-LICENSE:${PN}-qla1280 = "Firmware-qla1280"
+LICENSE:${PN}-qla1280 = "LicenseRef-Firmware-qla1280"
 FILES:${PN}-qla1280 = " \
     ${firmwaredir}/qlogic/1040.bin* \
     ${firmwaredir}/qlogic/1280.bin* \
@@ -3376,26 +3376,26 @@ FILES:${PN}-qla1280 = " \
 RDEPENDS:${PN}-qla1280 = "${PN}-qla1280-license"
 
 # For ib_qib - QLogic Infiniband
-LICENSE:${PN}-ib-qib-license = "Firmware-ib_qib"
+LICENSE:${PN}-ib-qib-license = "LicenseRef-Firmware-ib-qib"
 FILES:${PN}-ib-qib-license = "${firmwaredir}/LICENSE.ib_qib"
 
-LICENSE:${PN}-ib-qib = "Firmware-ib_qib"
+LICENSE:${PN}-ib-qib = "LicenseRef-Firmware-ib-qib"
 FILES:${PN}-ib-qib = "${firmwaredir}/qlogic/sd7220.fw*"
 RDEPENDS:${PN}-ib-qib = "${PN}-ib-qib-license"
 
 # For xhci-rcar - Renesas R-Car Gen2/3 USB 3.0 host controller driver
-LICENSE:${PN}-r8a779x-usb3-license = "Firmware-r8a779x_usb3"
+LICENSE:${PN}-r8a779x-usb3-license = "LicenseRef-Firmware-r8a779x-usb3"
 FILES:${PN}-r8a779x-usb3-license = "${firmwaredir}/LICENCE.r8a779x_usb3"
 
-LICENSE:${PN}-xhci-rcar = "Firmware-r8a779x_usb3"
+LICENSE:${PN}-xhci-rcar = "LicenseRef-Firmware-r8a779x-usb3"
 FILES:${PN}-xhci-rcar = "${firmwaredir}/r8a779x_usb3_*"
 RDEPENDS:${PN}-xhci-rcar = "${PN}-r8a779x-usb3-license"
 
 # For pcie-rcar-gen4 - Renesas R-Car Gen4 PCIe driver
-LICENSE:${PN}-r8a779g-pcie-phy-license = "Firmware-r8a779g_pcie_phy"
+LICENSE:${PN}-r8a779g-pcie-phy-license = "LicenseRef-Firmware-r8a779g-pcie-phy"
 FILES:${PN}-r8a779g-pcie-phy-license = "${firmwaredir}/LICENCE.r8a779g_pcie_phy"
 
-LICENSE:${PN}-pcie-rcar = "Firmware-r8a779g_pcie_phy"
+LICENSE:${PN}-pcie-rcar = "LicenseRef-Firmware-r8a779g-pcie-phy"
 FILES:${PN}-pcie-rcar = "${firmwaredir}/rcar_gen4_pcie.bin*"
 RDEPENDS:${PN}-pcie-rcar = "${PN}-r8a779g-pcie-phy-license"
 
@@ -3404,26 +3404,26 @@ LICENSE:${PN}-r128 = "MIT"
 FILES:${PN}-r128 = "${firmwaredir}/r128/*"
 
 # For rt1320 - Realtek rt1320 ASoC audio driver.
-LICENSE:${PN}-rt1320-license = "Firmware-rt1320"
+LICENSE:${PN}-rt1320-license = "LicenseRef-Firmware-rt1320"
 FILES:${PN}-rt1320-license = "${firmwaredir}/LICENSE.rt1320"
 
-LICENSE:${PN}-rt1320 = "Firmware-rt1320"
+LICENSE:${PN}-rt1320 = "LicenseRef-Firmware-rt1320"
 FILES:${PN}-rt1320 = "${firmwaredir}/realtek/rt1320/*"
 RDEPENDS:${PN}-rt1320 = "${PN}-rt1320-license"
 
 # For rp2 - Comtrol RocketPort 2 serial driver
-LICENSE:${PN}-rp2-license = "Firmware-rp2"
+LICENSE:${PN}-rp2-license = "LicenseRef-Firmware-rp2"
 FILES:${PN}-rp2-license = "${firmwaredir}/LICENSE.rp2"
 
-LICENSE:${PN}-rp2 = "Firmware-rp2"
+LICENSE:${PN}-rp2 = "LicenseRef-Firmware-rp2"
 FILES:${PN}-rp2 = "${firmwaredir}/rp2.fw*"
 RDEPENDS:${PN}-rp2 = "${PN}-rp2-license"
 
 # For s5p-mfc - Samsung MFC video encoder/decoder driver
-LICENSE:${PN}-s5p-mfc-license = "Firmware-s5p-mfc"
+LICENSE:${PN}-s5p-mfc-license = "LicenseRef-Firmware-s5p-mfc"
 FILES:${PN}-s5p-mfc-license = "${firmwaredir}/LICENSE.s5p-mfc"
 
-LICENSE:${PN}-s5p-mfc = "Firmware-s5p-mfc"
+LICENSE:${PN}-s5p-mfc = "LicenseRef-Firmware-s5p-mfc"
 FILES:${PN}-s5p-mfc = "${firmwaredir}/s5p-mfc*"
 RDEPENDS:${PN}-s5p-mfc = "${PN}-s5p-mfc-license"
 
@@ -3432,54 +3432,54 @@ LICENSE:${PN}-snd-sb16-csp = "GPL-2.0-or-later"
 FILES:${PN}-snd-sb16-csp = "${firmwaredir}/sb16/*"
 
 # For slicoss - Alacritech IS-NIC products
-LICENSE:${PN}-alacritech-license = "Firmware-alacritech"
+LICENSE:${PN}-alacritech-license = "LicenseRef-Firmware-alacritech"
 FILES:${PN}-alacritech-license = "${firmwaredir}/LICENCE.alacritech"
 
-LICENSE:${PN}-slicoss = "Firmware-alacritech"
+LICENSE:${PN}-slicoss = "LicenseRef-Firmware-alacritech"
 FILES:${PN}-slicoss = "${firmwaredir}/slicoss/*"
 RDEPENDS:${PN}-slicoss = "${PN}-alacritech-license"
 
-LICENSE:${PN}-sxg = "Firmware-alacritech"
+LICENSE:${PN}-sxg = "LicenseRef-Firmware-alacritech"
 FILES:${PN}-sxg = "${firmwaredir}/sxg/*"
 RDEPENDS:${PN}-sxg = "${PN}-alacritech-license"
 
 # For tehuti - Tehuti Networks 10G Ethernet
-LICENSE:${PN}-tehuti-license = "Firmware-tehuti"
+LICENSE:${PN}-tehuti-license = "LicenseRef-Firmware-tehuti"
 FILES:${PN}-tehuti-license = "${firmwaredir}/LICENSE.tehuti"
 
-LICENSE:${PN}-tehuti = "Firmware-tehuti"
+LICENSE:${PN}-tehuti = "LicenseRef-Firmware-tehuti"
 FILES:${PN}-tehuti = "${firmwaredir}/tehuti/*"
 RDEPENDS:${PN}-tehuti = "${PN}-tehuti-license"
 
 # For tg3 - Broadcom Tigon3 based gigabit Ethernet cards
-LICENSE:${PN}-tigon-license = "Firmware-tigon"
+LICENSE:${PN}-tigon-license = "LicenseRef-Firmware-tigon"
 FILES:${PN}-tigon-license = "${firmwaredir}/LICENCE.tigon"
 
-LICENSE:${PN}-tg3 = "Firmware-tigon"
+LICENSE:${PN}-tg3 = "LicenseRef-Firmware-tigon"
 FILES:${PN}-tg3 = "${firmwaredir}/tigon/*"
 RDEPENDS:${PN}-tg3 = "${PN}-tigon-license"
 
 # For tlg2300 - Telgent 2300 V4L/DVB driver.
-LICENSE:${PN}-tlg2300-license = "Firmware-tlg2300"
+LICENSE:${PN}-tlg2300-license = "LicenseRef-Firmware-tlg2300"
 FILES:${PN}-tlg2300-license = "${firmwaredir}/LICENSE.tlg2300"
 
-LICENSE:${PN}-tlg2300 = "Firmware-tlg2300"
+LICENSE:${PN}-tlg2300 = "LicenseRef-Firmware-tlg2300"
 FILES:${PN}-tlg2300 = "${firmwaredir}/tlg2300*"
 RDEPENDS:${PN}-tlg2300 = "${PN}-tlg2300-license"
 
 # For Mont-TSSE - Mont-TSSE(TM) Crypto Algorithm Accelerator Driver
-LICENSE:${PN}-montage-license = "Firmware-montage"
+LICENSE:${PN}-montage-license = "LicenseRef-Firmware-montage"
 FILES:${PN}-montage-license = "${firmwaredir}/LICENSE.montage"
 
-LICENSE:${PN}-mont-tsse = "Firmware-montage"
+LICENSE:${PN}-mont-tsse = "LicenseRef-Firmware-montage"
 FILES:${PN}-mont-tsse = "${firmwaredir}/tsse_firmware.bin*"
 RDEPENDS:${PN}-mont-tsse = "${PN}-montage-license"
 
 # For ueagle-atm - Driver for USB ADSL Modems based on Eagle IV Chipset
-LICENSE:${PN}-ueagle-atm4-firmware-license = "Firmware-ueagle-atm4-firmware"
+LICENSE:${PN}-ueagle-atm4-firmware-license = "LicenseRef-Firmware-ueagle-atm4-firmware"
 FILES:${PN}-ueagle-atm4-firmware-license = "${firmwaredir}/LICENCE.ueagle-atm4-firmware"
 
-LICENSE:${PN}-ueagle-atm = "Firmware-ueagle-atm4-firmware"
+LICENSE:${PN}-ueagle-atm = "LicenseRef-Firmware-ueagle-atm4-firmware"
 FILES:${PN}-ueagle-atm = " \
     ${firmwaredir}/ueagle-atm/CMV4p.bin.v2* \
     ${firmwaredir}/ueagle-atm/DSP4p.bin* \
@@ -3492,30 +3492,30 @@ LICENSE:${PN}-usbdux = "GPL-2.0-or-later"
 FILES:${PN}-usbdux = "${firmwaredir}/usbdux*"
 
 # For cx231xx - Conexant Cx23100/101/102 USB broadcast A/V decoder
-LICENSE:${PN}-conexant-license = "Firmware-conexant"
+LICENSE:${PN}-conexant-license = "LicenseRef-Firmware-conexant"
 FILES:${PN}-conexant-license = "${firmwaredir}/LICENSE.conexant"
 
-LICENSE:${PN}-cx231xx = "Firmware-conexant"
+LICENSE:${PN}-cx231xx = "LicenseRef-Firmware-conexant"
 FILES:${PN}-cx231xx = "${firmwaredir}/v4l-cx231xx*"
 RDEPENDS:${PN}-cx231xx = "${PN}-conexant-license"
 
-LICENSE:${PN}-cx23418 = "Firmware-conexant"
+LICENSE:${PN}-cx23418 = "LicenseRef-Firmware-conexant"
 FILES:${PN}-cx23418 = "${firmwaredir}/v4l-cx23418*"
 RDEPENDS:${PN}-cx23418 = "${PN}-conexant-license"
 
-LICENSE:${PN}-cx23885 = "Firmware-conexant"
+LICENSE:${PN}-cx23885 = "LicenseRef-Firmware-conexant"
 FILES:${PN}-cx23885 = "${firmwaredir}/v4l-cx23885*"
 RDEPENDS:${PN}-cx23885 = "${PN}-conexant-license"
 
-LICENSE:${PN}-cx23840 = "Firmware-conexant"
+LICENSE:${PN}-cx23840 = "LicenseRef-Firmware-conexant"
 FILES:${PN}-cx23840 = "${firmwaredir}/v4l-cx25840*"
 RDEPENDS:${PN}-cx23840 = "${PN}-conexant-license"
 
 # For vxge - Exar X3100 Series 10GbE PCIe I/O Virtualized Server Adapter
-LICENSE:${PN}-vxge-license = "Firmware-vxge"
+LICENSE:${PN}-vxge-license = "LicenseRef-Firmware-vxge"
 FILES:${PN}-vxge-license = "${firmwaredir}/LICENSE.vxge"
 
-LICENSE:${PN}-vxge = "Firmware-vxge"
+LICENSE:${PN}-vxge = "LicenseRef-Firmware-vxge"
 FILES:${PN}-vxge = "${firmwaredir}/vxge/*"
 RDEPENDS:${PN}-vxge = "${PN}-vxge-license"
 
@@ -3523,114 +3523,114 @@ RDEPENDS:${PN}-vxge = "${PN}-vxge-license"
 LICENSE:${PN}-whiteheat = "GPL-2.0-only"
 FILES:${PN}-whiteheat = "${firmwaredir}/whiteheat*"
 
-LICENSE:${PN}-wil6210 = "Firmware-qualcommAthos_ath10k"
+LICENSE:${PN}-wil6210 = "LicenseRef-Firmware-qualcommAthos-ath10k"
 FILES:${PN}-wil6210 = "${firmwaredir}/wil6210*"
 RDEPENDS:${PN}-wil6210 = "${PN}-ath10k-license"
 
 # For xe - Intel Graphics driver
-LICENSE:${PN}-xe-license = "Firmware-xe"
+LICENSE:${PN}-xe-license = "LicenseRef-Firmware-xe"
 FILES:${PN}-xe-license = "${firmwaredir}/LICENSE.xe"
 
-LICENSE:${PN}-xe = "Firmware-xe"
+LICENSE:${PN}-xe = "LicenseRef-Firmware-xe"
 FILES:${PN}-xe = "${firmwaredir}/xe/*"
 RDEPENDS:${PN}-xe = "${PN}-xe-license"
 
 # For other firmwares
 # Maybe split out to separate packages when needed.
 LICENSE:${PN} = "\
-    Firmware-Abilis \
-    & Firmware-aeonsemi \
-    & Firmware-agere \
-    & Firmware-airoha \
-    & Firmware-alacritech \
-    & Firmware-amdgpu \
-    & Firmware-amdisp \
-    & Firmware-amdnpu \
-    & Firmware-amd_pmf \
-    & Firmware-amd-sev \
-    & Firmware-amd-ucode \
-    & Firmware-amlogic \
-    & Firmware-amlogic_vdec \
-    & Firmware-atmel \
-    & Firmware-bfa \
-    & Firmware-bmi260 \
-    & Firmware-bnx2 \
-    & Firmware-bnx2x \
-    & Firmware-ca0132 \
-    & Firmware-cavium \
-    & Firmware-chelsio_firmware \
-    & Firmware-cirrus \
-    & Firmware-cnm \
-    & Firmware-conexant \
-    & Firmware-cw1200 \
-    & Firmware-cw1200-sdd \
-    & Firmware-cxgb3 \
-    & Firmware-dabusb \
-    & Firmware-dell \
-    & Firmware-dib0700 \
-    & Firmware-drxk \
-    & Firmware-e100 \
-    & Firmware-emi26 \
-    & Firmware-ene_firmware \
-    & Firmware-fw_sst_0f28 \
-    & Firmware-go7007 \
-    & Firmware-hfi1_firmware \
-    & Firmware-HP \
-    & Firmware-ib_qib \
-    & Firmware-ibt_firmware \
-    & Firmware-inside-secure \
-    & Firmware-intel \
-    & Firmware-intel_vpu \
-    & Firmware-ipu3_firmware \
-    & Firmware-it913x \
-    & Firmware-ivsc \
-    & Firmware-ixp4xx \
-    & Firmware-IntcSST2 \
-    & Firmware-kaweth \
-    & Firmware-keyspan \
-    & Firmware-lenovo \
-    & Firmware-mellanox \
-    & Firmware-mga \
-    & Firmware-montage \
-    & Firmware-moxa \
-    & Firmware-myri10ge_firmware \
-    & Firmware-nvidia \
-    & Firmware-nxp \
-    & Firmware-OLPC \
-    & Firmware-ath9k-htc \
-    & Firmware-phanfw \
-    & Firmware-qat \
-    & Firmware-qcom \
-    & Firmware-qed \
-    & Firmware-qla1280 \
-    & Firmware-qla2xxx \
-    & Firmware-r8169 \
-    & Firmware-r8a779x_usb3 \
-    & Firmware-radeon \
-    & Firmware-ralink_a_mediatek_company_firmware \
-    & Firmware-ralink-firmware \
-    & Firmware-rp2 \
-    & Firmware-rsi \
-    & Firmware-rt1320 \
-    & Firmware-imx-sdma_firmware \
-    & Firmware-s5p-mfc \
-    & Firmware-sensoray \
-    & Firmware-siano \
-    & Firmware-tehuti \
-    & Firmware-ti-connectivity \
-    & Firmware-ti-keystone \
-    & Firmware-ti-tspa \
-    & Firmware-tigon \
-    & Firmware-tlg2300 \
-    & Firmware-typhoon \
-    & Firmware-ueagle-atm4-firmware \
-    & Firmware-vxge \
-    & Firmware-wl1251 \
-    & Firmware-xc4000 \
-    & Firmware-xc5000 \
-    & Firmware-xc5000c \
-    & Firmware-xe \
-    & WHENCE \
+    LicenseRef-Firmware-Abilis \
+    AND LicenseRef-Firmware-aeonsemi \
+    AND LicenseRef-Firmware-agere \
+    AND LicenseRef-Firmware-airoha \
+    AND LicenseRef-Firmware-alacritech \
+    AND LicenseRef-Firmware-amdgpu \
+    AND LicenseRef-Firmware-amdisp \
+    AND LicenseRef-Firmware-amdnpu \
+    AND LicenseRef-Firmware-amd-pmf \
+    AND LicenseRef-Firmware-amd-sev \
+    AND LicenseRef-Firmware-amd-ucode \
+    AND LicenseRef-Firmware-amlogic \
+    AND LicenseRef-Firmware-amlogic-vdec \
+    AND LicenseRef-Firmware-atmel \
+    AND LicenseRef-Firmware-bfa \
+    AND LicenseRef-Firmware-bmi260 \
+    AND LicenseRef-Firmware-bnx2 \
+    AND LicenseRef-Firmware-bnx2x \
+    AND LicenseRef-Firmware-ca0132 \
+    AND LicenseRef-Firmware-cavium \
+    AND LicenseRef-Firmware-chelsio-firmware \
+    AND LicenseRef-Firmware-cirrus \
+    AND LicenseRef-Firmware-cnm \
+    AND LicenseRef-Firmware-conexant \
+    AND LicenseRef-Firmware-cw1200 \
+    AND LicenseRef-Firmware-cw1200-sdd \
+    AND LicenseRef-Firmware-cxgb3 \
+    AND LicenseRef-Firmware-dabusb \
+    AND LicenseRef-Firmware-dell \
+    AND LicenseRef-Firmware-dib0700 \
+    AND LicenseRef-Firmware-drxk \
+    AND LicenseRef-Firmware-e100 \
+    AND LicenseRef-Firmware-emi26 \
+    AND LicenseRef-Firmware-ene-firmware \
+    AND LicenseRef-Firmware-fw-sst-0f28 \
+    AND LicenseRef-Firmware-go7007 \
+    AND LicenseRef-Firmware-hfi1-firmware \
+    AND LicenseRef-Firmware-HP \
+    AND LicenseRef-Firmware-ib-qib \
+    AND LicenseRef-Firmware-ibt-firmware \
+    AND LicenseRef-Firmware-inside-secure \
+    AND LicenseRef-Firmware-intel \
+    AND LicenseRef-Firwmare-intel-vpu \
+    AND LicenseRef-Firmware-ipu3-firmware \
+    AND LicenseRef-Firmware-it913x \
+    AND LicenseRef-Firmware-ivsc \
+    AND LicenseRef-Firmware-ixp4xx \
+    AND LicenseRef-Firmware-IntcSST2 \
+    AND LicenseRef-Firmware-kaweth \
+    AND LicenseRef-Firmware-keyspan \
+    AND LicenseRef-Firmware-lenovo \
+    AND LicenseRef-Firmware-mellanox \
+    AND LicenseRef-Firmware-mga \
+    AND LicenseRef-Firmware-montage \
+    AND LicenseRef-Firmware-moxa \
+    AND LicenseRef-Firmware-myri10ge-firmware \
+    AND LicenseRef-Firmware-nvidia \
+    AND LicenseRef-Firmware-nxp \
+    AND LicenseRef-Firmware-OLPC \
+    AND LicenseRef-Firmware-ath9k-htc \
+    AND LicenseRef-Firmware-phanfw \
+    AND LicenseRef-Firmware-qat \
+    AND LicenseRef-Firmware-qcom \
+    AND LicenseRef-Firmware-qed \
+    AND LicenseRef-Firmware-qla1280 \
+    AND LicenseRef-Firmware-qla2xxx \
+    AND LicenseRef-Firmware-r8169 \
+    AND LicenseRef-Firmware-r8a779x-usb3 \
+    AND LicenseRef-Firmware-radeon \
+    AND LicenseRef-Firmware-ralink-a-mediatek-company-firmware \
+    AND LicenseRef-Firmware-ralink-firmware \
+    AND LicenseRef-Firmware-rp2 \
+    AND LicenseRef-Firmware-rsi \
+    AND LicenseRef-Firmware-rt1320 \
+    AND LicenseRef-Firmware-imx-sdma-firmware \
+    AND LicenseRef-Firmware-s5p-mfc \
+    AND LicenseRef-Firmware-sensoray \
+    AND LicenseRef-Firmware-siano \
+    AND LicenseRef-Firmware-tehuti \
+    AND LicenseRef-Firmware-ti-connectivity \
+    AND LicenseRef-Firmware-ti-keystone \
+    AND LicenseRef-Firmware-ti-tspa \
+    AND LicenseRef-Firmware-tigon \
+    AND LicenseRef-Firmware-tlg2300 \
+    AND LicenseRef-Firmware-typhoon \
+    AND LicenseRef-Firmware-ueagle-atm4-firmware \
+    AND LicenseRef-Firmware-vxge \
+    AND LicenseRef-Firmware-wl1251 \
+    AND LicenseRef-Firmware-xc4000 \
+    AND LicenseRef-Firmware-xc5000 \
+    AND LicenseRef-Firmware-xc5000c \
+    AND LicenseRef-Firmware-xe \
+    AND LicenseRef-Firmware-WHENCE \
 "
 
 # The goal for this recipe is to creata bunch of breakout packages for the
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 06/22] meta-selftest: Add NO_GENERIC_LICENSE
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (4 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 05/22] linux-firmware: Convert to SPDX license strings Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 07/22] convert-spdx-licenses: Convert to valid SPDX expressions Joshua Watt
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Adds NO_GENERIC_LICENSE for a non-SPDX license identifier, since it is
now enforced that licenses are either SPDX license identifiers, have a
matching generic license, or use NO_GENERIC_LICENSE

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 .../recipes-test/license/incompatible-nonspdx-license.bb         | 1 +
 1 file changed, 1 insertion(+)

diff --git a/meta-selftest/recipes-test/license/incompatible-nonspdx-license.bb b/meta-selftest/recipes-test/license/incompatible-nonspdx-license.bb
index 142d73158e..128f313e1f 100644
--- a/meta-selftest/recipes-test/license/incompatible-nonspdx-license.bb
+++ b/meta-selftest/recipes-test/license/incompatible-nonspdx-license.bb
@@ -1,5 +1,6 @@
 SUMMARY = "Recipe with a non-SPDX license"
 DESCRIPTION = "Is licensed with a non-SPDX license to be used for testing"
 LICENSE = "FooLicense"
+NO_GENERIC_LICENSE[FooLicense] = "LICENSE"
 
 EXCLUDE_FROM_WORLD = "1"
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 07/22] convert-spdx-licenses: Convert to valid SPDX expressions
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (5 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 06/22] meta-selftest: Add NO_GENERIC_LICENSE Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 08/22] gcc-common.inc: Remove LICENSE Joshua Watt
                   ` (14 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Reworks the script to re-write LICENSE lines as valid SPDX license
expressions in addition to remapping the license names

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 scripts/contrib/convert-spdx-licenses.py | 254 +++++++++++++++--------
 1 file changed, 162 insertions(+), 92 deletions(-)

diff --git a/scripts/contrib/convert-spdx-licenses.py b/scripts/contrib/convert-spdx-licenses.py
index 13cf12a33f..39cbbb28e5 100755
--- a/scripts/contrib/convert-spdx-licenses.py
+++ b/scripts/contrib/convert-spdx-licenses.py
@@ -7,113 +7,175 @@
 # SPDX-License-Identifier: GPL-2.0-only
 #
 
-import re
+
+from abc import abstractmethod, ABC
+from enum import Enum
+from pathlib import Path
+import json
+import mimetypes
 import os
+import re
+import shutil
 import sys
 import tempfile
-import shutil
-import mimetypes
+
+THIS_DIR = Path(__file__).parent
+
+sys.path.insert(0, str(THIS_DIR.parent.parent / "meta" / "lib"))
+import oe.spdx_license
 
 if len(sys.argv) < 2:
     print("Please specify a directory to run the conversion script against.")
     sys.exit(1)
 
-license_map = {
-"AGPL-3" : "AGPL-3.0-only",
-"AGPL-3+" : "AGPL-3.0-or-later",
-"AGPLv3" : "AGPL-3.0-only",
-"AGPLv3+" : "AGPL-3.0-or-later",
-"AGPLv3.0" : "AGPL-3.0-only",
-"AGPLv3.0+" : "AGPL-3.0-or-later",
-"AGPL-3.0" : "AGPL-3.0-only",
-"AGPL-3.0+" : "AGPL-3.0-or-later",
-"BSD-0-Clause" : "0BSD",
-"GPL-1" : "GPL-1.0-only",
-"GPL-1+" : "GPL-1.0-or-later",
-"GPLv1" : "GPL-1.0-only",
-"GPLv1+" : "GPL-1.0-or-later",
-"GPLv1.0" : "GPL-1.0-only",
-"GPLv1.0+" : "GPL-1.0-or-later",
-"GPL-1.0" : "GPL-1.0-only",
-"GPL-1.0+" : "GPL-1.0-or-later",
-"GPL-2" : "GPL-2.0-only",
-"GPL-2+" : "GPL-2.0-or-later",
-"GPLv2" : "GPL-2.0-only",
-"GPLv2+" : "GPL-2.0-or-later",
-"GPLv2.0" : "GPL-2.0-only",
-"GPLv2.0+" : "GPL-2.0-or-later",
-"GPL-2.0" : "GPL-2.0-only",
-"GPL-2.0+" : "GPL-2.0-or-later",
-"GPL-3" : "GPL-3.0-only",
-"GPL-3+" : "GPL-3.0-or-later",
-"GPLv3" : "GPL-3.0-only",
-"GPLv3+" : "GPL-3.0-or-later",
-"GPLv3.0" : "GPL-3.0-only",
-"GPLv3.0+" : "GPL-3.0-or-later",
-"GPL-3.0" : "GPL-3.0-only",
-"GPL-3.0+" : "GPL-3.0-or-later",
-"LGPLv2" : "LGPL-2.0-only",
-"LGPLv2+" : "LGPL-2.0-or-later",
-"LGPLv2.0" : "LGPL-2.0-only",
-"LGPLv2.0+" : "LGPL-2.0-or-later",
-"LGPL-2.0" : "LGPL-2.0-only",
-"LGPL-2.0+" : "LGPL-2.0-or-later",
-"LGPL2.1" : "LGPL-2.1-only",
-"LGPL2.1+" : "LGPL-2.1-or-later",
-"LGPLv2.1" : "LGPL-2.1-only",
-"LGPLv2.1+" : "LGPL-2.1-or-later",
-"LGPL-2.1" : "LGPL-2.1-only",
-"LGPL-2.1+" : "LGPL-2.1-or-later",
-"LGPLv3" : "LGPL-3.0-only",
-"LGPLv3+" : "LGPL-3.0-or-later",
-"LGPL-3.0" : "LGPL-3.0-only",
-"LGPL-3.0+" : "LGPL-3.0-or-later",
-"MPL-1" : "MPL-1.0",
-"MPLv1" : "MPL-1.0",
-"MPLv1.1" : "MPL-1.1",
-"MPLv2" : "MPL-2.0",
-"MIT-X" : "MIT",
-"MIT-style" : "MIT",
-"openssl" : "OpenSSL",
-"PSF" : "PSF-2.0",
-"PSFv2" : "PSF-2.0",
-"Python-2" : "Python-2.0",
-"Apachev2" : "Apache-2.0",
-"Apache-2" : "Apache-2.0",
-"Artisticv1" : "Artistic-1.0",
-"Artistic-1" : "Artistic-1.0",
-"AFL-2" : "AFL-2.0",
-"AFL-1" : "AFL-1.2",
-"AFLv2" : "AFL-2.0",
-"AFLv1" : "AFL-1.2",
-"CDDLv1" : "CDDL-1.0",
-"CDDL-1" : "CDDL-1.0",
-"EPLv1.0" : "EPL-1.0",
-"FreeType" : "FTL",
-"Nauman" : "Naumen",
-"tcl" : "TCL",
-"vim" : "Vim",
-"SGIv1" : "SGI-OpenGL",
+LICENSE_MAP = {
+    "AGPL-3": "AGPL-3.0-only",
+    "AGPL-3+": "AGPL-3.0-or-later",
+    "AGPLv3": "AGPL-3.0-only",
+    "AGPLv3+": "AGPL-3.0-or-later",
+    "AGPLv3.0": "AGPL-3.0-only",
+    "AGPLv3.0+": "AGPL-3.0-or-later",
+    "AGPL-3.0": "AGPL-3.0-only",
+    "AGPL-3.0+": "AGPL-3.0-or-later",
+    "BSD-0-Clause": "0BSD",
+    "GPL-1": "GPL-1.0-only",
+    "GPL-1+": "GPL-1.0-or-later",
+    "GPLv1": "GPL-1.0-only",
+    "GPLv1+": "GPL-1.0-or-later",
+    "GPLv1.0": "GPL-1.0-only",
+    "GPLv1.0+": "GPL-1.0-or-later",
+    "GPL-1.0": "GPL-1.0-only",
+    "GPL-1.0+": "GPL-1.0-or-later",
+    "GPL-2": "GPL-2.0-only",
+    "GPL-2+": "GPL-2.0-or-later",
+    "GPLv2": "GPL-2.0-only",
+    "GPLv2+": "GPL-2.0-or-later",
+    "GPLv2.0": "GPL-2.0-only",
+    "GPLv2.0+": "GPL-2.0-or-later",
+    "GPL-2.0": "GPL-2.0-only",
+    "GPL-2.0+": "GPL-2.0-or-later",
+    "GPL-3": "GPL-3.0-only",
+    "GPL-3+": "GPL-3.0-or-later",
+    "GPLv3": "GPL-3.0-only",
+    "GPLv3+": "GPL-3.0-or-later",
+    "GPLv3.0": "GPL-3.0-only",
+    "GPLv3.0+": "GPL-3.0-or-later",
+    "GPL-3.0": "GPL-3.0-only",
+    "GPL-3.0+": "GPL-3.0-or-later",
+    "LGPLv2": "LGPL-2.0-only",
+    "LGPLv2+": "LGPL-2.0-or-later",
+    "LGPLv2.0": "LGPL-2.0-only",
+    "LGPLv2.0+": "LGPL-2.0-or-later",
+    "LGPL-2.0": "LGPL-2.0-only",
+    "LGPL-2.0+": "LGPL-2.0-or-later",
+    "LGPL2.1": "LGPL-2.1-only",
+    "LGPL2.1+": "LGPL-2.1-or-later",
+    "LGPLv2.1": "LGPL-2.1-only",
+    "LGPLv2.1+": "LGPL-2.1-or-later",
+    "LGPL-2.1": "LGPL-2.1-only",
+    "LGPL-2.1+": "LGPL-2.1-or-later",
+    "LGPLv3": "LGPL-3.0-only",
+    "LGPLv3+": "LGPL-3.0-or-later",
+    "LGPL-3.0": "LGPL-3.0-only",
+    "LGPL-3.0+": "LGPL-3.0-or-later",
+    "MPL-1": "MPL-1.0",
+    "MPLv1": "MPL-1.0",
+    "MPLv1.1": "MPL-1.1",
+    "MPLv2": "MPL-2.0",
+    "MIT-X": "MIT",
+    "MIT-style": "MIT",
+    "openssl": "OpenSSL",
+    "PSF": "PSF-2.0",
+    "PSFv2": "PSF-2.0",
+    "Python-2": "Python-2.0",
+    "Apachev2": "Apache-2.0",
+    "Apache-2": "Apache-2.0",
+    "Artisticv1": "Artistic-1.0",
+    "Artistic-1": "Artistic-1.0",
+    "AFL-2": "AFL-2.0",
+    "AFL-1": "AFL-1.2",
+    "AFLv2": "AFL-2.0",
+    "AFLv1": "AFL-1.2",
+    "CDDLv1": "CDDL-1.0",
+    "CDDL-1": "CDDL-1.0",
+    "EPLv1.0": "EPL-1.0",
+    "FreeType": "FTL",
+    "Nauman": "Naumen",
+    "tcl": "TCL",
+    "vim": "Vim",
+    "SGIv1": "SGI-OpenGL",
+    "Apache-2.0-with-LLVM-exception": "Apache-2.0 WITH LLVM-exception",
+    "GPL-3-with-bison-exception": "GPL-3.0-or-later WITH Bison-exception-2.2",
+    "GPL-2.0-with-Linux-syscall-note": "GPL-2.0-only WITH Linux-syscall-note",
 }
 
+
+LINE_RE = re.compile(r'^(?P<var>LICENSE[\s:].*=.*)"(?P<expression>.*)"')
+
+
+def convert_unknown(node):
+    node.children = [convert_unknown(c) for c in node.children]
+
+    if not isinstance(node, oe.spdx_license.UnknownId):
+        return node
+
+    if node.ident.startswith("$"):
+        return node
+
+    if node.ident in LICENSE_MAP:
+        return oe.spdx_license.parse(LICENSE_MAP[node.ident])
+
+    ident = re.sub(r"[^a-zA-Z0-9\.\-]", "-", node.ident)
+
+    return oe.spdx_license.LicenseRef("LicenseRef-" + ident, ident, token=node.token)
+
+
 def processfile(fn):
-    print("processing file '%s'" % fn)
+    # print("processing file '%s'" % fn)
     try:
         fh, abs_path = tempfile.mkstemp()
+        if os.path.basename(fn) == "bitbake.conf":
+            return
+
         modified = False
-        with os.fdopen(fh, 'w') as new_file:
+        with os.fdopen(fh, "w") as new_file:
             with open(fn, "r") as old_file:
-                for line in old_file:
-                    if not line.startswith("LICENSE"):
+                for lineno, line in enumerate(old_file):
+                    m = LINE_RE.match(line)
+                    if m is None:
+                        new_file.write(line)
+                        continue
+
+                    if "[doc]" in m.group("var"):
+                        new_file.write(line)
+                        continue
+
+                    expression = (
+                        m.group("expression").replace("|", " OR ").replace("&", " AND ")
+                    ).strip()
+                    if not expression or expression == "CLOSED":
                         new_file.write(line)
                         continue
-                    orig = line
-                    for license in sorted(license_map, key=len, reverse=True):
-                        for ending in ['"', "'", " ", ")"]:
-                            line = line.replace(license + ending, license_map[license] + ending)
-                    if orig != line:
-                        modified = True
-                    new_file.write(line)
+
+                    try:
+                        t = oe.spdx_license.parse(expression, allow_unknown=True)
+                        if t is None:
+                            new_file.write(line)
+                            continue
+                        t = convert_unknown(t)
+                    except oe.spdx_license.ParseError as e:
+                        print(f"Cannot convert {fn}:{lineno + 1}")
+                        print(e.format())
+                        new_file.write(line)
+                        continue
+
+                    if t.to_string() == expression:
+                        new_file.write(line)
+                        continue
+
+                    new_line = m.group("var") + '"' + t.sort().to_string() + '"\n'
+                    new_file.write(new_line)
+                    modified = True
         new_file.close()
         if modified:
             shutil.copymode(fn, abs_path)
@@ -122,8 +184,9 @@ def processfile(fn):
     except UnicodeDecodeError:
         pass
 
+
 ourname = os.path.basename(sys.argv[0])
-ourversion = "0.01"
+ourversion = "0.02"
 
 if os.path.isfile(sys.argv[1]):
     processfile(sys.argv[1])
@@ -138,7 +201,14 @@ for targetdir in sys.argv[1:]:
             fn = os.path.join(root, name)
             if os.path.islink(fn):
                 continue
-            if "/.git/" in fn or fn.endswith(".html") or fn.endswith(".patch") or fn.endswith(".m4") or fn.endswith(".diff") or fn.endswith(".orig"):
+            if (
+                "/.git/" in fn
+                or fn.endswith(".html")
+                or fn.endswith(".patch")
+                or fn.endswith(".m4")
+                or fn.endswith(".diff")
+                or fn.endswith(".orig")
+            ):
                 continue
             processfile(fn)
 
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 08/22] gcc-common.inc: Remove LICENSE
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (6 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 07/22] convert-spdx-licenses: Convert to valid SPDX expressions Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 09/22] gcc: Update license Joshua Watt
                   ` (13 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Removes the LICENSE expression from gcc-common.inc; the format is not an
SPDX identifier and is not necessary since the gcc recipes already have
a valid LICENSE identifier

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/recipes-devtools/gcc/gcc-common.inc | 1 -
 1 file changed, 1 deletion(-)

diff --git a/meta/recipes-devtools/gcc/gcc-common.inc b/meta/recipes-devtools/gcc/gcc-common.inc
index 8d95698743..a7f01cd045 100644
--- a/meta/recipes-devtools/gcc/gcc-common.inc
+++ b/meta/recipes-devtools/gcc/gcc-common.inc
@@ -2,7 +2,6 @@ SUMMARY = "GNU cc and gcc C compilers"
 HOMEPAGE = "http://www.gnu.org/software/gcc/"
 DESCRIPTION = "The GNU Compiler Collection includes front ends for C, C++, Objective-C, Fortran, Ada, Go, and D, as well as libraries for these languages (libstdc++,...). GCC was originally written as the compiler for the GNU operating system."
 SECTION = "devel"
-LICENSE = "GPL"
 
 NATIVEDEPS = ""
 
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 09/22] gcc: Update license
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (7 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 08/22] gcc-common.inc: Remove LICENSE Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 10/22] xz: Replace deprecated SPDX identifier Joshua Watt
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

GPL-3.0-with-GCC-exception is a deprecated license ID, so replace it
with "GPL-3.0-or-later WITH GCC-exception-3.1".

Also, the LICENSE expression in gcc.inc appears to be incomplete,
missing GPL-2.0-or-later, LGPL-2.1-or-later, and LGPL-3.0-or-later, even
though the checksums for their corresponding license files are clearly
checked in LIC_FILES_CHKSUM.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/recipes-devtools/gcc/gcc-16.1.inc       | 2 +-
 meta/recipes-devtools/gcc/gcc-runtime.inc    | 4 ++--
 meta/recipes-devtools/gcc/libgcc-initial.inc | 2 +-
 meta/recipes-devtools/gcc/libgcc.inc         | 8 ++++----
 meta/recipes-devtools/gcc/libgfortran.inc    | 6 +++---
 5 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/meta/recipes-devtools/gcc/gcc-16.1.inc b/meta/recipes-devtools/gcc/gcc-16.1.inc
index 4598aff045..a82e993f08 100644
--- a/meta/recipes-devtools/gcc/gcc-16.1.inc
+++ b/meta/recipes-devtools/gcc/gcc-16.1.inc
@@ -16,7 +16,7 @@ TOOLCHAIN_NATIVE = "gcc"
 DEPENDS =+ "mpfr gmp libmpc zlib zstd flex-native"
 NATIVEDEPS = "mpfr-native gmp-native libmpc-native zlib-native flex-native zstd-native"
 
-LICENSE = "GPL-3.0-with-GCC-exception & GPL-3.0-only"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later AND GPL-3.0-or-later WITH GCC-exception-3.1 AND LGPL-3.0-or-later"
 
 LIC_FILES_CHKSUM = "\
     file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
diff --git a/meta/recipes-devtools/gcc/gcc-runtime.inc b/meta/recipes-devtools/gcc/gcc-runtime.inc
index e305180c64..cb62fab489 100644
--- a/meta/recipes-devtools/gcc/gcc-runtime.inc
+++ b/meta/recipes-devtools/gcc/gcc-runtime.inc
@@ -4,11 +4,11 @@ SUMMARY = "Runtime libraries from GCC"
 
 # Over-ride the LICENSE set by gcc-${PV}.inc to remove "& GPLv3"
 # All gcc-runtime packages are now covered by the runtime exception.
-LICENSE = "GPL-3.0-with-GCC-exception"
+LICENSE = "GPL-3.0-or-later WITH GCC-exception-3.1"
 
 CXXFLAGS:remove = "-fvisibility-inlines-hidden"
 CFLAGS:append = " -Wno-error=discarded-qualifiers"
- 
+
 EXTRA_OECONF_PATHS = "\
     --with-gxx-include-dir=${includedir}/c++/${BINV} \
     --with-sysroot=/not/exist \
diff --git a/meta/recipes-devtools/gcc/libgcc-initial.inc b/meta/recipes-devtools/gcc/libgcc-initial.inc
index ce100d7ddc..d067f7eb00 100644
--- a/meta/recipes-devtools/gcc/libgcc-initial.inc
+++ b/meta/recipes-devtools/gcc/libgcc-initial.inc
@@ -31,7 +31,7 @@ require libgcc-common.inc
 
 DEPENDS = "virtual/cross-cc"
 
-LICENSE = "GPL-3.0-with-GCC-exception"
+LICENSE = "GPL-3.0-or-later WITH GCC-exception-3.1"
 
 PACKAGES = ""
 
diff --git a/meta/recipes-devtools/gcc/libgcc.inc b/meta/recipes-devtools/gcc/libgcc.inc
index 74e8746b42..e92dadf021 100644
--- a/meta/recipes-devtools/gcc/libgcc.inc
+++ b/meta/recipes-devtools/gcc/libgcc.inc
@@ -32,10 +32,10 @@ PACKAGES = "\
 
 # All libgcc source is marked with the exception.
 #
-LICENSE:${PN} = "GPL-3.0-with-GCC-exception"
-LICENSE:${PN}-dev = "GPL-3.0-with-GCC-exception"
-LICENSE:${PN}-dbg = "GPL-3.0-with-GCC-exception"
-LICENSE:${PN}-src = "GPL-3.0-with-GCC-exception"
+LICENSE:${PN} = "GPL-3.0-or-later WITH GCC-exception-3.1"
+LICENSE:${PN}-dev = "GPL-3.0-or-later WITH GCC-exception-3.1"
+LICENSE:${PN}-dbg = "GPL-3.0-or-later WITH GCC-exception-3.1"
+LICENSE:${PN}-src = "GPL-3.0-or-later WITH GCC-exception-3.1"
 
 FILES:${PN}-dev = "\
     ${base_libdir}/libgcc*.so \
diff --git a/meta/recipes-devtools/gcc/libgfortran.inc b/meta/recipes-devtools/gcc/libgfortran.inc
index fa6aecaaa3..1726b40c6a 100644
--- a/meta/recipes-devtools/gcc/libgfortran.inc
+++ b/meta/recipes-devtools/gcc/libgfortran.inc
@@ -60,9 +60,9 @@ PACKAGES = "\
     libgfortran-staticdev \
 "
 
-LICENSE:${PN} = "GPL-3.0-with-GCC-exception"
-LICENSE:${PN}-dev = "GPL-3.0-with-GCC-exception"
-LICENSE:${PN}-dbg = "GPL-3.0-with-GCC-exception"
+LICENSE:${PN} = "GPL-3.0-or-later WITH GCC-exception-3.1"
+LICENSE:${PN}-dev = "GPL-3.0-or-later WITH GCC-exception-3.1"
+LICENSE:${PN}-dbg = "GPL-3.0-or-later WITH GCC-exception-3.1"
 
 FILES:${PN} = "${libdir}/libgfortran.so.*"
 FILES:${PN}-dev = "\
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 10/22] xz: Replace deprecated SPDX identifier
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (8 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 09/22] gcc: Update license Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 11/22] autoconf-archive: " Joshua Watt
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

The GPL-3.0-with-autoconf-exception license is a deprecated SPDX license
identifier, so replace it with "GPL-3.0-or-later WITH
Autoconf-exception-macro"

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/recipes-extended/xz/xz_5.8.3.bb | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/meta/recipes-extended/xz/xz_5.8.3.bb b/meta/recipes-extended/xz/xz_5.8.3.bb
index 0c0886fa7a..b76b1726e4 100644
--- a/meta/recipes-extended/xz/xz_5.8.3.bb
+++ b/meta/recipes-extended/xz/xz_5.8.3.bb
@@ -10,11 +10,11 @@ PROVIDES += "xz-decompress"
 # packages, and the LGPL bits are under lib/, which appears to be used for
 # libgnu, which appears to be used for DOS builds. So we're left with
 # GPL-2.0-or-later and 0BSD.
-LICENSE = "GPL-2.0-or-later & GPL-3.0-with-autoconf-exception & LGPL-2.1-or-later & 0BSD"
-LICENSE:${PN} = "0BSD & GPL-2.0-or-later"
-LICENSE:${PN}-dev = "0BSD & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND GPL-3.0-or-later WITH Autoconf-exception-macro AND LGPL-2.1-or-later AND 0BSD"
+LICENSE:${PN} = "0BSD AND GPL-2.0-or-later"
+LICENSE:${PN}-dev = "0BSD AND GPL-2.0-or-later"
 LICENSE:${PN}-staticdev = "GPL-2.0-or-later"
-LICENSE:${PN}-doc = "0BSD & GPL-2.0-or-later"
+LICENSE:${PN}-doc = "0BSD AND GPL-2.0-or-later"
 LICENSE:${PN}-dbg = "GPL-2.0-or-later"
 LICENSE:${PN}-locale = "GPL-2.0-or-later"
 LICENSE:liblzma = "0BSD"
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 11/22] autoconf-archive: Replace deprecated SPDX identifier
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (9 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 10/22] xz: Replace deprecated SPDX identifier Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 12/22] gnu-config: " Joshua Watt
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

GPL-3.0-with-autoconf-exception is deprecated. Replace it with
"GPL-3.0-or-later WITH Autoconf-exception-3.0"

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 .../autoconf-archive/autoconf-archive_2024.10.16.bb             | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta/recipes-devtools/autoconf-archive/autoconf-archive_2024.10.16.bb b/meta/recipes-devtools/autoconf-archive/autoconf-archive_2024.10.16.bb
index 46d1b91d65..c243d632c3 100644
--- a/meta/recipes-devtools/autoconf-archive/autoconf-archive_2024.10.16.bb
+++ b/meta/recipes-devtools/autoconf-archive/autoconf-archive_2024.10.16.bb
@@ -1,7 +1,7 @@
 SUMMARY = "a collection of freely re-usable Autoconf macros"
 HOMEPAGE = "http://www.gnu.org/software/autoconf-archive/"
 SECTION = "devel"
-LICENSE = "GPL-3.0-with-autoconf-exception"
+LICENSE = "GPL-3.0-or-later WITH Autoconf-exception-3.0"
 LIC_FILES_CHKSUM = "file://COPYING;md5=11cc2d3ee574f9d6b7ee797bdce4d423 \
     file://COPYING.EXCEPTION;md5=fdef168ebff3bc2f13664c365a5fb515"
 
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 12/22] gnu-config: Replace deprecated SPDX identifier
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (10 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 11/22] autoconf-archive: " Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 13/22] libglvnd: " Joshua Watt
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

GPL-3.0-with-autoconf-exception is deprecated. Replace it with
"GPL-3.0-or-later WITH Autoconf-exception-generic-3.0"

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/recipes-devtools/gnu-config/gnu-config_git.bb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta/recipes-devtools/gnu-config/gnu-config_git.bb b/meta/recipes-devtools/gnu-config/gnu-config_git.bb
index 5d82be87da..d5b4189573 100644
--- a/meta/recipes-devtools/gnu-config/gnu-config_git.bb
+++ b/meta/recipes-devtools/gnu-config/gnu-config_git.bb
@@ -2,7 +2,7 @@ SUMMARY = "gnu-configize"
 DESCRIPTION = "Tool that installs the GNU config.guess / config.sub into a directory tree"
 HOMEPAGE = "https://git.savannah.gnu.org/cgit/config.git"
 SECTION = "devel"
-LICENSE = "GPL-3.0-with-autoconf-exception"
+LICENSE = "GPL-3.0-or-later WITH Autoconf-exception-generic-3.0"
 LIC_FILES_CHKSUM = "file://config.guess;beginline=9;endline=29;md5=10922f9231863a06f6efb67691fa46e0"
 
 DEPENDS:class-native = "hostperl-runtime-native"
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 13/22] libglvnd: Replace deprecated SPDX identifier
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (11 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 12/22] gnu-config: " Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 14/22] flac: " Joshua Watt
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

GPL-3.0-with-autoconf-exception is a deprecated license identifier.
Replace it with "GPL-3.0-or-later WITH Autoconf-exception-macro".

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/recipes-graphics/libglvnd/libglvnd_1.7.0.bb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta/recipes-graphics/libglvnd/libglvnd_1.7.0.bb b/meta/recipes-graphics/libglvnd/libglvnd_1.7.0.bb
index c76763f811..e2cdd81b46 100644
--- a/meta/recipes-graphics/libglvnd/libglvnd_1.7.0.bb
+++ b/meta/recipes-graphics/libglvnd/libglvnd_1.7.0.bb
@@ -2,7 +2,7 @@ SUMMARY = "the GL Vendor-Neutral Dispatch library"
 DESCRIPTION = "libglvnd is a vendor-neutral dispatch layer for arbitrating \
 OpenGL API calls between multiple vendors."
 HOMEPAGE = "https://gitlab.freedesktop.org/glvnd/libglvnd"
-LICENSE = "MIT & BSD-1-Clause & BSD-3-Clause & GPL-3.0-with-autoconf-exception"
+LICENSE = "MIT AND BSD-1-Clause AND BSD-3-Clause AND GPL-3.0-or-later WITH Autoconf-exception-macro"
 LIC_FILES_CHKSUM = "file://README.md;beginline=323;md5=7ac5f0111f648b92fe5427efeb08e8c4"
 
 SRC_URI = "git://gitlab.freedesktop.org/glvnd/libglvnd.git;protocol=https;branch=master"
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 14/22] flac: Replace deprecated SPDX identifier
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (12 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 13/22] libglvnd: " Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 15/22] libgit2: " Joshua Watt
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

GFDL-1.3 is a deprecated SPDX license identifier. Replace it with
"GFDL-1.3-no-invariants-or-later".

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/recipes-multimedia/flac/flac_1.5.0.bb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta/recipes-multimedia/flac/flac_1.5.0.bb b/meta/recipes-multimedia/flac/flac_1.5.0.bb
index d55e157a9d..d982825f7f 100644
--- a/meta/recipes-multimedia/flac/flac_1.5.0.bb
+++ b/meta/recipes-multimedia/flac/flac_1.5.0.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "FLAC stands for Free Lossless Audio Codec, a lossless audio compr
 HOMEPAGE = "https://xiph.org/flac/"
 BUGTRACKER = "https://github.com/xiph/flac/issues"
 SECTION = "libs"
-LICENSE = "GFDL-1.3 & GPL-2.0-or-later & LGPL-2.1-or-later & BSD-3-Clause"
+LICENSE = "GFDL-1.3-no-invariants-or-later AND GPL-2.0-or-later AND LGPL-2.1-or-later AND BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://COPYING.FDL;md5=802e79e394e372d01e863e3f4058cf40 \
                     file://src/Makefile.am;beginline=1;endline=17;md5=9c882153132df8f3a1cb1a8ca1f2350f \
                     file://COPYING.GPL;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 15/22] libgit2: Replace deprecated SPDX identifier
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (13 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 14/22] flac: " Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 16/22] Fix up licenses Joshua Watt
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

GPL-2.0-with-GCC-exception is a deprecated SPDX license identifier.
Replace it with "GPL-2.0-only WITH GCC-exception-2.0"

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/recipes-support/libgit2/libgit2_1.9.4.bb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta/recipes-support/libgit2/libgit2_1.9.4.bb b/meta/recipes-support/libgit2/libgit2_1.9.4.bb
index e46e5d49fd..10999f972e 100644
--- a/meta/recipes-support/libgit2/libgit2_1.9.4.bb
+++ b/meta/recipes-support/libgit2/libgit2_1.9.4.bb
@@ -1,6 +1,6 @@
 SUMMARY = "the Git linkable library"
 HOMEPAGE = "http://libgit2.github.com/"
-LICENSE = "GPL-2.0-with-GCC-exception & MIT & OpenSSL & BSD-3-Clause & Zlib & ISC & LGPL-2.1-or-later & CC0-1.0 & BSD-2-Clause"
+LICENSE = "GPL-2.0-only WITH GCC-exception-2.0 AND MIT AND OpenSSL AND BSD-3-Clause AND Zlib AND ISC AND LGPL-2.1-or-later AND CC0-1.0 AND BSD-2-Clause"
 LIC_FILES_CHKSUM = "file://COPYING;md5=8eacfdc17c8f4d219e131a073973b97d"
 
 DEPENDS = "curl openssl zlib libssh2 libgcrypt libpcre2"
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 16/22] Fix up licenses
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (14 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 15/22] libgit2: " Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 17/22] lib: oe: license: Rework package licenses matching Joshua Watt
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Fixes up several locations where the convert-spdx-license script could
not automatically fix up the license

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/recipes-core/gettext/gettext_1.0.bb          | 2 +-
 meta/recipes-core/util-linux/util-linux_2.42.2.bb | 4 ++--
 meta/recipes-devtools/cmake/cmake-native_4.4.0.bb | 2 +-
 meta/recipes-devtools/cmake/cmake_4.4.0.bb        | 2 +-
 meta/recipes-devtools/fmt/fmt_12.2.0.bb           | 2 +-
 meta/recipes-graphics/cairo/cairo_1.18.4.bb       | 4 ++--
 meta/recipes-graphics/libsdl2/libsdl2_2.32.10.bb  | 2 +-
 meta/recipes-support/libcap/libcap_2.78.bb        | 6 +++---
 8 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/meta/recipes-core/gettext/gettext_1.0.bb b/meta/recipes-core/gettext/gettext_1.0.bb
index 08b4819f27..8a11a55570 100644
--- a/meta/recipes-core/gettext/gettext_1.0.bb
+++ b/meta/recipes-core/gettext/gettext_1.0.bb
@@ -8,7 +8,7 @@ LICENSE = "GPL-3.0-or-later & LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=c678957b0c8e964aa6c70fd77641a71e"
 
 # without libxml in PACKAGECONFIG vendor copy of the lib will be used
-LICENSE:append = " ${@bb.utils.contains('PACKAGECONFIG', 'libxml', '', '& MIT', d)}"
+LICENSE:append = " ${@bb.utils.contains('PACKAGECONFIG', 'libxml', '', 'AND MIT', d)}"
 LIC_FILES_CHKSUM:append = " ${@bb.utils.contains('PACKAGECONFIG', 'libxml', '', 'file://libtextstyle/lib/libxml/COPYING;md5=2044417e2e5006b65a8b9067b683fcf1', d)}"
 # without glib in PACKAGECONFIG vendor copy of the lib will be used
 LIC_FILES_CHKSUM:append = " ${@bb.utils.contains('PACKAGECONFIG', 'glib', '', 'file://libtextstyle/lib/glib/ghash.c;md5=e3159f5ac38dfe77af5cc0ee104dab2d;beginline=10;endline=27', d)}"
diff --git a/meta/recipes-core/util-linux/util-linux_2.42.2.bb b/meta/recipes-core/util-linux/util-linux_2.42.2.bb
index 4943d5c7ab..b3d466dc80 100644
--- a/meta/recipes-core/util-linux/util-linux_2.42.2.bb
+++ b/meta/recipes-core/util-linux/util-linux_2.42.2.bb
@@ -2,10 +2,10 @@ require util-linux.inc
 
 # Most of the applications and the libraries are linked with libcommon.la,
 # which uses these licenses
-LIBCOMMON_LICENSES = "LGPL-2.1-or-later & BSD-2-Clause & BSD-3-Clause & MIT"
+LIBCOMMON_LICENSES = "LGPL-2.1-or-later AND BSD-2-Clause AND BSD-3-Clause AND MIT"
 
 # The default license is GPL-2.0-or-later
-DEFAULT_LICENSES = "GPL-2.0-or-later & ${LIBCOMMON_LICENSES}"
+DEFAULT_LICENSES = "GPL-2.0-or-later AND ${LIBCOMMON_LICENSES}"
 
 LICENSE = "GPL-1.0-or-later & GPL-2.0-only & GPL-2.0-or-later & LGPL-2.1-or-later & BSD-2-Clause & BSD-3-Clause & BSD-4-Clause-UC & MIT & EUPL-1.2"
 LICENSE:${PN}-bash-completion = "GPL-2.0-or-later"
diff --git a/meta/recipes-devtools/cmake/cmake-native_4.4.0.bb b/meta/recipes-devtools/cmake/cmake-native_4.4.0.bb
index 840a2fddb9..fe1136bd6c 100644
--- a/meta/recipes-devtools/cmake/cmake-native_4.4.0.bb
+++ b/meta/recipes-devtools/cmake/cmake-native_4.4.0.bb
@@ -7,7 +7,7 @@ SRC_URI += "file://OEToolchainConfig.cmake \
             file://environment.d-cmake.sh \
             "
 
-LICENSE:append = " & BSD-1-Clause & MIT & BSD-2-Clause & curl & Apache-2.0"
+LICENSE:append = " AND BSD-1-Clause AND MIT AND BSD-2-Clause AND curl AND Apache-2.0"
 LIC_FILES_CHKSUM:append = " \
     file://Utilities/cmjsoncpp/LICENSE;md5=5d73c165a0f9e86a1342f32d19ec5926 \
     file://Utilities/cmlibarchive/COPYING;md5=7ce08437ff7f5e24d72e666313ae4084 \
diff --git a/meta/recipes-devtools/cmake/cmake_4.4.0.bb b/meta/recipes-devtools/cmake/cmake_4.4.0.bb
index e6abc06c85..6265316fd9 100644
--- a/meta/recipes-devtools/cmake/cmake_4.4.0.bb
+++ b/meta/recipes-devtools/cmake/cmake_4.4.0.bb
@@ -11,7 +11,7 @@ SRC_URI:append:class-nativesdk = " \
     file://environment.d-cmake.sh \
 "
 
-LICENSE:append = " & BSD-1-Clause & MIT"
+LICENSE:append = " AND BSD-1-Clause AND MIT"
 LIC_FILES_CHKSUM:append = " \
     file://Utilities/cmjsoncpp/LICENSE;md5=5d73c165a0f9e86a1342f32d19ec5926 \
     file://Utilities/cmlibrhash/COPYING;md5=a8c2a557a5c53b1c12cddbee98c099af \
diff --git a/meta/recipes-devtools/fmt/fmt_12.2.0.bb b/meta/recipes-devtools/fmt/fmt_12.2.0.bb
index ca8fcb66ec..d68684e4f6 100644
--- a/meta/recipes-devtools/fmt/fmt_12.2.0.bb
+++ b/meta/recipes-devtools/fmt/fmt_12.2.0.bb
@@ -1,7 +1,7 @@
 SUMMARY = "open-source formatting library for C++"
 DESCRIPTION = "{fmt} is an open-source formatting library for C++. It can be used as a safe and fast alternative to (s)printf and iostreams."
 HOMEPAGE = "https://fmt.dev"
-LICENSE = "MIT-with-fmt-exception"
+LICENSE = "MIT WITH fmt-exception"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=6ec080902ed8f82f5a97ed13e8042634 \
                     file://doc/LICENSE-exception;md5=b9257785fc4f3803a4b71b76c1412729"
 
diff --git a/meta/recipes-graphics/cairo/cairo_1.18.4.bb b/meta/recipes-graphics/cairo/cairo_1.18.4.bb
index 3f6d02f8d4..0ed81166b5 100644
--- a/meta/recipes-graphics/cairo/cairo_1.18.4.bb
+++ b/meta/recipes-graphics/cairo/cairo_1.18.4.bb
@@ -19,8 +19,8 @@ LICENSE:${PN}-script-interpreter = "MPL-1.1 | LGPL-2.1-only"
 LICENSE:${PN}-perf-utils = "GPL-3.0-or-later"
 # Adapt the licenses for cairo-dbg and cairo-src depending on whether
 # cairo-trace is being built.
-LICENSE:${PN}-dbg = "(MPL-1.1 | LGPL-2.1-only)${@bb.utils.contains('PACKAGECONFIG', 'trace', ' & GPL-3.0-or-later', '', d)}"
-LICENSE:${PN}-src = "(MPL-1.1 | LGPL-2.1-only)${@bb.utils.contains('PACKAGECONFIG', 'trace', ' & GPL-3.0-or-later', '', d)}"
+LICENSE:${PN}-dbg = "(MPL-1.1 OR LGPL-2.1-only)${@bb.utils.contains('PACKAGECONFIG', 'trace', ' AND GPL-3.0-or-later', '', d)}"
+LICENSE:${PN}-src = "(MPL-1.1 OR LGPL-2.1-only)${@bb.utils.contains('PACKAGECONFIG', 'trace', ' AND GPL-3.0-or-later', '', d)}"
 
 LIC_FILES_CHKSUM = "file://COPYING;md5=e73e999e0c72b5ac9012424fa157ad77 \
                     ${@bb.utils.contains('PACKAGECONFIG', 'trace', 'file://util/cairo-trace/COPYING-GPL-3;md5=d32239bcb673463ab874e80d47fae504', '', d)}"
diff --git a/meta/recipes-graphics/libsdl2/libsdl2_2.32.10.bb b/meta/recipes-graphics/libsdl2/libsdl2_2.32.10.bb
index 880bf56167..091ce8ed8b 100644
--- a/meta/recipes-graphics/libsdl2/libsdl2_2.32.10.bb
+++ b/meta/recipes-graphics/libsdl2/libsdl2_2.32.10.bb
@@ -16,7 +16,7 @@ LIC_FILES_CHKSUM = "\
 "
 
 # arm-neon adds MIT license
-LICENSE:append = " ${@bb.utils.contains('PACKAGECONFIG', 'arm-neon', '& MIT', '', d)}"
+LICENSE:append = " ${@bb.utils.contains('PACKAGECONFIG', 'arm-neon', 'AND MIT', '', d)}"
 LIC_FILES_CHKSUM:append = " ${@bb.utils.contains('PACKAGECONFIG', 'arm-neon', 'file://src/video/arm/pixman-arm-neon-asm.h;md5=9a9cc1e51abbf1da58f4d9528ec9d49b;beginline=1;endline=24', '', d)}"
 
 PROVIDES = "virtual/libsdl2"
diff --git a/meta/recipes-support/libcap/libcap_2.78.bb b/meta/recipes-support/libcap/libcap_2.78.bb
index 85cd8004f1..d804e94244 100644
--- a/meta/recipes-support/libcap/libcap_2.78.bb
+++ b/meta/recipes-support/libcap/libcap_2.78.bb
@@ -5,7 +5,7 @@ users, without giving them full root permissions."
 HOMEPAGE = "http://sites.google.com/site/fullycapable/"
 
 # The library is BSD | GPLv2, the PAM module is BSD | LGPLv2+
-LICENSE = "(BSD-3-Clause | GPL-2.0-only) & (BSD-3-Clause | LGPL-2.0-or-later)"
+LICENSE = "(BSD-3-Clause OR GPL-2.0-only) AND (BSD-3-Clause OR LGPL-2.0-or-later)"
 LIC_FILES_CHKSUM = "file://License;md5=2965a646645b72ecee859b43c592dcaa \
                     file://pam_cap/License;md5=905326f41d3d1f8df21943f9a4ed6b50 \
                     "
@@ -108,8 +108,8 @@ do_install_ptest() {
 FILES:${PN} += "${base_libdir}/security/*.so"
 
 # The license of the main package depends on whether PAM is enabled or not
-LICENSE:${PN} = "(BSD-3-Clause | GPL-2.0-only)${@bb.utils.contains('PACKAGECONFIG', 'pam', ' & (BSD-3-Clause | LGPL-2.0-or-later)', '', d)}"
-LICENSE:${PN}-dev = "(BSD-3-Clause | GPL-2.0-only)"
+LICENSE:${PN} = "(BSD-3-Clause OR GPL-2.0-only)${@bb.utils.contains('PACKAGECONFIG', 'pam', ' AND (BSD-3-Clause OR LGPL-2.0-or-later)', '', d)}"
+LICENSE:${PN}-dev = "BSD-3-Clause OR GPL-2.0-only"
 
 BBCLASSEXTEND = "native nativesdk"
 
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 17/22] lib: oe: license: Rework package licenses matching
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (15 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 16/22] Fix up licenses Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 18/22] classes/go-mod-update-modules: Switch to SPDX license Joshua Watt
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Reworks the way that package licenses matching works with the
INCOMPATIBLE_LICENSE and INCOMPATIBLE_LICENSE_EXCEPTIONS variable to
make it compatible with SPDX license expressions.

The primary wrinkle that makes this more difficult that the previous
code is that SPDX license exceptions are a combination of an actual
license WITH an exception (e.g. "GPL-3.0-or-later WITH
GCC-exception-3.1") where as previously this was a distinct license
(e.g. "GPL-3.0-with-GCC-exception"). This meant that the previous code
implicitly ignored *any* licenses with an exception that was listed in
INCOMPATIBLE_LICENSE. The new code tries to make this more precise,
while not breaking the way that INCOMPATIBLE_LICENSE and
INCOMPATIBLE_LICENSE_EXCEPTIONS work. Now, a license in
INCOMPATIBLE_LICENSE will match the LHS of a license with an exception,
but an exception listed in INCOMPATIBLE_LICENSE_EXCEPTIONS will match
the RHS, allowing the license *only* if it has that exception.

Practically speaking, this means that end users using
INCOMPATIBLE_LICENSE may now need to add the SPDX exceptions they are
willing to allow to INCOMPATIBLE_LICENSE_EXCEPTIONS in order to maintain
their builds. For example, to disallow all GPLv3 except for those with
the GCC exception, use:

    INCOMPATIBLE_LICENSE = "GPL-3.0* LGPL-3.0*"
    INCOMPATIBLE_LICENSE_EXCEPTIONS = "GCC-exception-3.1"

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/classes-recipe/license_image.bbclass     |  29 ++--
 meta/lib/oe/license.py                        | 136 ++++++++++++++----
 .../oeqa/selftest/cases/incompatible_lic.py   |  24 ++++
 3 files changed, 147 insertions(+), 42 deletions(-)

diff --git a/meta/classes-recipe/license_image.bbclass b/meta/classes-recipe/license_image.bbclass
index 258082c82a..7d00b1ae53 100644
--- a/meta/classes-recipe/license_image.bbclass
+++ b/meta/classes-recipe/license_image.bbclass
@@ -118,24 +118,27 @@ def write_license_files(d, license_manifest, pkg_dic, rootfs):
     pkgarchs.reverse()
     incompatible_packages = []
 
-    exceptions = (d.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS") or "").split()
+    allow_licenses = (d.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS") or "").split()
     with open(license_manifest, "w") as license_file:
         for pkg in sorted(pkg_dic):
-            remaining_bad_licenses = oe.license.apply_pkg_license_exception(pkg, bad_licenses, exceptions)
-            incompatible_licenses = oe.license.incompatible_pkg_license(d, remaining_bad_licenses, pkg_dic[pkg]["LICENSE"])
-            if incompatible_licenses:
-                incompatible_packages.append("%s (%s)" % (pkg, ' '.join(incompatible_licenses)))
-            else:
-                incompatible_licenses = oe.license.incompatible_pkg_license(d, bad_licenses, pkg_dic[pkg]["LICENSE"])
-                if incompatible_licenses:
-                    oe.qa.handle_error('license-exception', "Including %s with incompatible license(s) %s into the image, because it has been allowed by exception list." %(pkg, ' '.join(incompatible_licenses)), d)
             try:
-                (pkg_dic[pkg]["LICENSE"], pkg_dic[pkg]["LICENSES"]) = \
-                    oe.license.manifest_licenses(d, pkg_dic[pkg]["LICENSE"],
-                    remaining_bad_licenses)
-            except oe.license.LicenseError as exc:
+                node = oe.license.parse_legacy_license(d, pkg_dic[pkg]["LICENSE"])
+            except oe.spdx_license.ParseError as exc:
                 bb.fatal(exc.format(prefix=d.getVar("P") + ": "))
 
+            pkg_allow_licenses = oe.license.filter_pkg_license_list(pkg, allow_licenses)
+
+            if node:
+                if incompatible_licenses := oe.license.license_allowed(node, bad_licenses, pkg_allow_licenses):
+                    incompatible_packages.append("%s (%s)" % (pkg, ' '.join(n.to_string() for n in incompatible_licenses)))
+                elif incompatible_licenses := oe.license.license_allowed(node, bad_licenses, []):
+                    oe.qa.handle_error('license-exception', "Including %s with incompatible license(s) %s into the image, because it has been allowed by exception list." %
+                                       (pkg, ' '.join(n.to_string() for n in incompatible_licenses)), d)
+
+            (pkg_dic[pkg]["LICENSE"], pkg_dic[pkg]["LICENSES"]) = \
+                oe.license.manifest_licenses(d, pkg_dic[pkg]["LICENSE"],
+                                             bad_licenses, pkg_allow_licenses)
+
             if not "IMAGE_MANIFEST" in pkg_dic[pkg]:
                 # Rootfs manifest
                 license_file.write("PACKAGE NAME: %s\n" % pkg)
diff --git a/meta/lib/oe/license.py b/meta/lib/oe/license.py
index 9e59d82f8d..e4a860eff9 100644
--- a/meta/lib/oe/license.py
+++ b/meta/lib/oe/license.py
@@ -18,6 +18,71 @@ def license_ok(license, dont_want_licenses):
             return False
     return True
 
+def check_license_list(node, lst):
+    """
+    Checks a license node against a list if license identifiers. Returns True
+    if the node is in the list, and False if not
+    """
+    result = []
+    for i in lst:
+        if lic := oe.spdx_license.get_license(i):
+            if isinstance(node, oe.spdx_license.Identifier) and node.ident == lic["licenseId"]:
+                return True
+
+            if isinstance(node, oe.spdx_license.WithOp) and node.license.ident == lic["licenseId"]:
+                return True
+
+        elif lic := oe.spdx_license.get_exception(i):
+            if isinstance(node, oe.spdx_license.WithOp) and node.exception.ident == lic["licenseExceptionId"]:
+                return True
+
+        else:
+            if not i.startswith("LicenseRef-"):
+                # For legacy license matching
+                lic = "LicenseRef-" + i
+            else:
+                lic = i
+
+            if isinstance(node, oe.spdx_license.Identifier) and node.ident == lic:
+                return True
+
+    return False
+
+def license_allowed(node, disallowed, allowed):
+    """
+    Filters an SPDX license expression abstract syntax tree based on a list of
+    allowed and disallowed licenses, search through AND and OR conjunctions to
+    check for any path that allows the license to be allowed. If an individual
+    license is in the allowed list, or not in the disallowed list, it is
+    allowed. If the expression is not allowed, returns a list of nodes from the
+    expression for the licenses that caused the license to not be
+    allowed. If the expression is allowed, an empty list is returned.
+    """
+    def walk(n):
+        if isinstance(n, oe.spdx_license.AndOp):
+            return walk(n.left) + walk(n.right)
+
+        if isinstance(n, oe.spdx_license.OrOp):
+            lst = walk(n.left)
+            if not lst:
+                return []
+            return walk(n.right)
+
+        if isinstance(n, oe.spdx_license.CompoundExpression):
+            return walk(n.child)
+
+        if isinstance(n, (oe.spdx_license.WithOp, oe.spdx_license.Identifier)):
+            if check_license_list(n, allowed):
+                return []
+            if check_license_list(n, disallowed):
+                return [n]
+            return []
+
+        raise Exception(f"Unknown node type {n.__class__.__name__}")
+
+    return walk(node)
+
+
 def obsolete_license_list():
     return ["AGPL-3", "AGPL-3+", "AGPLv3", "AGPLv3+", "AGPLv3.0", "AGPLv3.0+", "AGPL-3.0", "AGPL-3.0+", "BSD-0-Clause",
             "GPL-1", "GPL-1+", "GPLv1", "GPLv1+", "GPLv1.0", "GPLv1.0+", "GPL-1.0", "GPL-1.0+", "GPL-2", "GPL-2+", "GPLv2",
@@ -101,7 +166,7 @@ def is_included(d, licensestr, include_licenses=None, exclude_licenses=None):
     else:
         return True, included
 
-def manifest_licenses(d, licensestr, dont_want_licenses):
+def manifest_licenses(d, licensestr, disallowed, allowed):
     """Given a license string and dont_want_licenses list,
        return license string filtered and a list of licenses"""
 
@@ -111,13 +176,20 @@ def manifest_licenses(d, licensestr, dont_want_licenses):
     def walk_license(node):
         nonlocal licenses
         if isinstance(node, oe.spdx_license.Identifier):
-            if license_ok(node.ident, dont_want_licenses):
-                licenses.append(node.ident)
+            if not license_allowed(node, disallowed, allowed):
+                licenses.append(node.to_string())
                 return node
+            return None
 
+        if isinstance(node, oe.spdx_license.WithOp):
+            if not license_allowed(node, disallowed, allowed):
+                licenses.append(node.license.to_string())
+                licenses.append(node.exception.to_string())
+                return node
             return None
 
         old_children = node.children
+
         node.children = []
 
         for child in old_children:
@@ -134,12 +206,6 @@ def manifest_licenses(d, licensestr, dont_want_licenses):
             if node.right is None:
                 return node.left
 
-        # The left side (the license side) of a WITH can be removed, but not
-        # the right (the exception)
-        if isinstance(node, oe.spdx_license.WithOp):
-            if node.license is None:
-                return None
-
         # If one of the above cases doesn't catch everything, raise an error
         if not all(node.children):
             node.children = old_children
@@ -172,11 +238,6 @@ def list_licenses(licensestr, d):
     walk_license(parse_legacy_license(d, licensestr))
     return set(licenses)
 
-def apply_pkg_license_exception(pkg, bad_licenses, exceptions):
-    """Return remaining bad licenses after removing any package exceptions"""
-
-    return [lic for lic in bad_licenses if pkg + ':' + lic not in exceptions]
-
 def return_spdx(d, license):
     """
     This function returns the spdx mapping of a license if it exists.
@@ -215,12 +276,6 @@ def expand_wildcard_licenses(d, wildcard_licenses):
 
     return list(licenses)
 
-def incompatible_license_contains(d, license, truevalue, falsevalue):
-    license = canonical_license(d, license)
-    bad_licenses = (d.getVar('INCOMPATIBLE_LICENSE') or "").split()
-    bad_licenses = expand_wildcard_licenses(d, bad_licenses)
-    return truevalue if license in bad_licenses else falsevalue
-
 def incompatible_pkg_license(d, dont_want_licenses, license):
     def walk_license(node):
         if isinstance(node, oe.spdx_license.Identifier):
@@ -486,6 +541,23 @@ def check_license_format(d):
             oe.qa.handle_error("license-format",
                             f'{pn}: {v} value has an invalid format:\n{e.format()}\n', d)
 
+def filter_pkg_license_list(pkg, lst):
+    """
+    Given a list of license IDs and a package, returns the list of license IDs
+    that apply to the package by looking for a package prefix
+    """
+    pkg_lst = []
+    for e in lst:
+        if ":" not in e:
+            pkg_lst.append(e)
+            continue
+
+        p, l = e.split(":", 1)
+        if pkg == p:
+            pkg_lst.append(l)
+
+    return pkg_lst
+
 def skip_incompatible_package_licenses(d, pkgs):
     if not pkgs:
         return {}
@@ -507,21 +579,27 @@ def skip_incompatible_package_licenses(d, pkgs):
 
     bad_licenses = expand_wildcard_licenses(d, bad_licenses)
 
-    exceptions = (d.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS") or "").split()
+    allow_licenses = (d.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS") or "").split()
 
-    for lic_exception in exceptions:
-        if ":" in lic_exception:
-            lic_exception = lic_exception.split(":")[1]
-        if lic_exception in obsolete_license_list():
-            bb.fatal("Obsolete license %s used in INCOMPATIBLE_LICENSE_EXCEPTIONS" % lic_exception)
+    for lic in allow_licenses:
+        if ":" in lic:
+            lic = lic.split(":")[1]
+        if lic in obsolete_license_list():
+            bb.fatal("Obsolete license %s used in INCOMPATIBLE_LICENSE_EXCEPTIONS" % lic)
 
     skipped_pkgs = {}
     for pkg in pkgs:
-        remaining_bad_licenses = apply_pkg_license_exception(pkg, bad_licenses, exceptions)
+        pkg_lic = d.getVar("LICENSE:%s" % pkg) if pkg else None
+        if not pkg_lic:
+            pkg_lic = d.getVar('LICENSE')
+
+        node = parse_legacy_license(d, pkg_lic)
+        if not node:
+            continue
 
-        incompatible_lic = incompatible_license(d, remaining_bad_licenses, pkg)
+        incompatible_lic = license_allowed(node, bad_licenses, filter_pkg_license_list(pkg, allow_licenses))
         if incompatible_lic:
-            skipped_pkgs[pkg] = incompatible_lic
+            skipped_pkgs[pkg] = [lic.to_string() for lic in incompatible_lic]
 
     return skipped_pkgs
 
diff --git a/meta/lib/oeqa/selftest/cases/incompatible_lic.py b/meta/lib/oeqa/selftest/cases/incompatible_lic.py
index 5467640cdd..406f92e37b 100644
--- a/meta/lib/oeqa/selftest/cases/incompatible_lic.py
+++ b/meta/lib/oeqa/selftest/cases/incompatible_lic.py
@@ -3,6 +3,7 @@
 #
 # SPDX-License-Identifier: MIT
 #
+import textwrap
 from oeqa.selftest.case import OESelftestTestCase
 from oeqa.utils.commands import bitbake
 from oeqa.core.decorator.data import skipIfNotFeature
@@ -135,6 +136,25 @@ NO_GENERIC_LICENSE[SomeLicense] = "COPYING"
 
         bitbake('core-image-minimal')
 
+    def test_spdx_exception(self):
+        # Change bash license to have an SPDX exception, which will fail
+        self.write_config(self.default_config() + textwrap.dedent(
+            """\
+            LICENSE:pn-bash = "GPL-3.0-or-later WITH GCC-exception-3.1"
+            """))
+
+        result = bitbake('core-image-minimal', ignore_status=True)
+        error_msg = "ERROR: core-image-minimal-1.0-r0 do_rootfs: Some packages cannot be installed into the image because they have incompatible licenses:\n\tbash (GPL-3.0-or-later WITH GCC-exception-3.1)"
+
+        # The SPDX exception can be explicitly allowed in INCOMPATIBLE_LICENSE_EXCEPTIONS
+        self.write_config(self.default_config() + textwrap.dedent(
+            """\
+            LICENSE:pn-bash = "GPL-3.0-or-later WITH GCC-exception-3.1"
+            INCOMPATIBLE_LICENSE_EXCEPTIONS:pn-core-image-minimal = "GCC-exception-3.1"
+            ERROR_QA:remove:pn-core-image-minimal = "license-exception"
+            """))
+        bitbake('core-image-minimal')
+
 class NoGPL3InImagesTests(OESelftestTestCase):
     def test_core_image_minimal(self):
         self.write_config("""
@@ -150,6 +170,10 @@ require conf/distro/include/no-gplv3.inc
 IMAGE_CLASSES += "testimage"
 INCOMPATIBLE_LICENSE:pn-core-image-full-cmdline = "GPL-3.0* LGPL-3.0*"
 INCOMPATIBLE_LICENSE:pn-core-image-weston = "GPL-3.0* LGPL-3.0*"
+INCOMPATIBLE_LICENSE_EXCEPTIONS:pn-core-image-full-cmdline = "GCC-exception-3.1"
+INCOMPATIBLE_LICENSE_EXCEPTIONS:pn-core-image-weston = "GCC-exception-3.1"
+ERROR_QA:remove:pn-core-image-weston = "license-exception"
+ERROR_QA:remove:pn-core-image-full-cmdline = "license-exception"
 
 require conf/distro/include/no-gplv3.inc
 """)
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 18/22] classes/go-mod-update-modules: Switch to SPDX license
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (16 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 17/22] lib: oe: license: Rework package licenses matching Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 19/22] license: Remove tidy_licenses() Joshua Watt
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Changes the license generation to use SPDX "AND" instead of "&"

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta/classes-recipe/go-mod-update-modules.bbclass | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta/classes-recipe/go-mod-update-modules.bbclass b/meta/classes-recipe/go-mod-update-modules.bbclass
index 0083588a25..0dda716c65 100644
--- a/meta/classes-recipe/go-mod-update-modules.bbclass
+++ b/meta/classes-recipe/go-mod-update-modules.bbclass
@@ -92,7 +92,7 @@ python do_update_modules() {
         licenses_filename = os.path.join(thisdir, f"{bpn}-licenses.inc")
         with open(licenses_filename, "w") as f:
             f.write(notice)
-            f.write(f'LICENSE += "& {" & ".join(tidy_licenses(licenses))}"\n\n')
+            f.write(f'LICENSE += "AND {" AND ".join(tidy_licenses(licenses))}"\n\n')
             f.write('LIC_FILES_CHKSUM += "\\\n')
             for lic in sorted(lic_files_chksum, key=fold_uri):
                 f.write('    ' + lic + ' \\\n')
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 19/22] license: Remove tidy_licenses()
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (17 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 18/22] classes/go-mod-update-modules: Switch to SPDX license Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 20/22] meta-selftest: Change license on test recipes Joshua Watt
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Removes the tidy_licenses() API in favor of calling .sort() on a SPDX
license AST. Reworks the recipetool API that passes around licenses to
use SPDX license AST nodes instead of a list of licenses.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 .../go-mod-update-modules.bbclass             |  21 ++--
 meta/files/license-hashes.csv                 |   4 +-
 meta/lib/oe/license.py                        |  13 --
 meta/lib/oe/license_finder.py                 |  10 +-
 meta/lib/oeqa/selftest/cases/devtool.py       |   5 +-
 meta/lib/oeqa/selftest/cases/recipetool.py    | 106 ++++++++--------
 scripts/lib/recipetool/create.py              | 116 +++++++++---------
 scripts/lib/recipetool/create_npm.py          |  13 +-
 8 files changed, 141 insertions(+), 147 deletions(-)

diff --git a/meta/classes-recipe/go-mod-update-modules.bbclass b/meta/classes-recipe/go-mod-update-modules.bbclass
index 0dda716c65..3a0f0a3377 100644
--- a/meta/classes-recipe/go-mod-update-modules.bbclass
+++ b/meta/classes-recipe/go-mod-update-modules.bbclass
@@ -14,7 +14,6 @@ do_update_modules[network] = "1"
 
 python do_update_modules() {
     import subprocess, tempfile, json, re, urllib.parse
-    from oe.license import tidy_licenses
     from oe.license_finder import find_licenses_up
 
     def unescape_path(path):
@@ -75,24 +74,28 @@ python do_update_modules() {
             mod_dir = pkg['Module']['Dir']
             path = os.path.relpath(mod_dir, mod_cache_dir)
 
-            for name, file, md5 in find_licenses_up(pkg_dir, mod_dir, d, first_only=True, extra_hashes=extra_hashes):
-                lic_files[os.path.join(path, file)] = (name, md5)
+            for node, file, md5 in find_licenses_up(pkg_dir, mod_dir, d, first_only=True, extra_hashes=extra_hashes):
+                lic_files[os.path.join(path, file)] = (node, md5)
 
-        licenses = set()
+        licenses = []
         lic_files_chksum = []
         for lic_file in lic_files:
-            license_name, license_md5 = lic_files[lic_file]
-            if license_name == "Unknown":
+            node, license_md5 = lic_files[lic_file]
+            if isinstance(node, oe.spdx_license.UnknownId):
                 bb.warn(f"Unknown license: {lic_file} {license_md5}")
 
-            licenses.add(lic_files[lic_file][0])
+            licenses.append(node)
             lic_files_chksum.append(
-                f'file://pkg/mod/{lic_file};md5={license_md5};spdx={urllib.parse.quote_plus(license_name)}')
+                f'file://pkg/mod/{lic_file};md5={license_md5};spdx={urllib.parse.quote_plus(node.to_string())}')
 
         licenses_filename = os.path.join(thisdir, f"{bpn}-licenses.inc")
         with open(licenses_filename, "w") as f:
             f.write(notice)
-            f.write(f'LICENSE += "AND {" AND ".join(tidy_licenses(licenses))}"\n\n')
+            f.write('LICENSE += "AND')
+            if licenses:
+                f.write(' ')
+                f.write(oe.spdx_license.AndOp.join(licenses).sort().to_string())
+            f.write('"\n\n')
             f.write('LIC_FILES_CHKSUM += "\\\n')
             for lic in sorted(lic_files_chksum, key=fold_uri):
                 f.write('    ' + lic + ' \\\n')
diff --git a/meta/files/license-hashes.csv b/meta/files/license-hashes.csv
index 5e81dbcdec..1895f4d377 100644
--- a/meta/files/license-hashes.csv
+++ b/meta/files/license-hashes.csv
@@ -18,7 +18,7 @@
 2d5025d4aa3495befef8f17206a5b0a1,LGPL-2.1-only
 3214f080875748938ba060314b4f727d,LGPL-2.0-only
 37acb030ba070680be4a9fcb57f2735a,MIT
-385c55653886acac3821999a3ccd17b3,Artistic-1.0 | GPL-2.0-only
+385c55653886acac3821999a3ccd17b3,Artistic-1.0 OR GPL-2.0-only
 38be95f95200434dc208e2ee3dab5081,BSD-3-Clause
 393a5ca445f6965873eca0259a17f833,GPL-2.0-only
 3b83ef96387f14655fc854ddc3c6bd57,Apache-2.0
@@ -71,7 +71,7 @@ b376d29a53c9573006b9970709231431,MIT
 b5f72aef53d3b2b432702c30b0215666,BSD-3-Clause
 b66384e7137e41a9b1904ef4d39703b6,Apache-2.0
 bbb461211a33b134d42ed5ee802b37ff,LGPL-2.1-only
-bfe1f75d606912a4111c90743d6c7325,MPL-1.1-only
+bfe1f75d606912a4111c90743d6c7325,MPL-1.1
 c93c0550bd3173f4504b2cbd8991e50b,GPL-2.0-only
 d014fb11a34eb67dc717fdcfc97e60ed,GFDL-1.2-only
 d0b68be4a2dc957aaf09144970bc6696,MIT
diff --git a/meta/lib/oe/license.py b/meta/lib/oe/license.py
index e4a860eff9..a1dce143dd 100644
--- a/meta/lib/oe/license.py
+++ b/meta/lib/oe/license.py
@@ -602,16 +602,3 @@ def skip_incompatible_package_licenses(d, pkgs):
             skipped_pkgs[pkg] = [lic.to_string() for lic in incompatible_lic]
 
     return skipped_pkgs
-
-def tidy_licenses(value):
-    """
-    Flat, split and sort licenses.
-    """
-    def _choose(a, b):
-        str_a, str_b  = sorted((" AND ".join(a), " AND ".join(b)), key=str.casefold)
-        return ["(%s OR %s)" % (str_a, str_b)]
-
-    if not isinstance(value, str):
-        value = " AND ".join(value)
-
-    return sorted(list(set(flattened_licenses(None, value, _choose))), key=str.casefold)
diff --git a/meta/lib/oe/license_finder.py b/meta/lib/oe/license_finder.py
index 4f2bb661fd..6f071f7c56 100644
--- a/meta/lib/oe/license_finder.py
+++ b/meta/lib/oe/license_finder.py
@@ -13,6 +13,8 @@ import re
 import bb
 import bb.utils
 
+import oe.spdx_license
+
 logger = logging.getLogger("BitBake.OE.LicenseFinder")
 
 def _load_hash_csv(d):
@@ -180,10 +182,14 @@ def match_licenses(licfiles, srctree, d, extra_hashes={}):
             crunched_md5 = _crunch_license(resolved_licfile)
             license = md5sums.get(crunched_md5, None)
             if not license:
-                license = 'Unknown'
+                rel_fn = os.path.relpath(licfile, srctree + "/..")
+                license = oe.spdx_license.UnknownId("Unknown")
                 logger.info("Please add the following line for '%s' to a 'license-hashes.csv' " \
                     "and replace `Unknown` with the license:\n" \
-                    "%s,Unknown" % (os.path.relpath(licfile, srctree + "/.."), md5value))
+                    "%s,Unknown" % (rel_fn, md5value))
+
+        if isinstance(license, str):
+            license = oe.spdx_license.parse(license)
 
         licenses.append((license, os.path.relpath(licfile, srctree), md5value))
 
diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py
index b2cd13e9a5..792ccfed26 100644
--- a/meta/lib/oeqa/selftest/cases/devtool.py
+++ b/meta/lib/oeqa/selftest/cases/devtool.py
@@ -172,10 +172,7 @@ class DevtoolTestCase(OESelftestTestCase):
                     if needvalue is None:
                         self.fail('Variable %s should not appear in recipe, but value is being set to "%s"' % (var, value))
                     if isinstance(needvalue, set):
-                        if var == 'LICENSE':
-                            value = set(value.split(' & '))
-                        else:
-                            value = set(value.split())
+                        value = set(value.split())
                     self.assertEqual(value, needvalue, 'values for %s do not match' % var)
 
 
diff --git a/meta/lib/oeqa/selftest/cases/recipetool.py b/meta/lib/oeqa/selftest/cases/recipetool.py
index 0369782683..5a9fc8ea67 100644
--- a/meta/lib/oeqa/selftest/cases/recipetool.py
+++ b/meta/lib/oeqa/selftest/cases/recipetool.py
@@ -10,6 +10,8 @@ import shutil
 import tempfile
 import urllib.parse
 
+import oe.spdx_license
+
 from oeqa.utils.commands import runCmd, bitbake, get_bb_var
 from oeqa.utils.commands import get_bb_vars, create_temp_layer
 from oeqa.selftest.cases import devtool
@@ -406,7 +408,7 @@ class RecipetoolCreateTests(RecipetoolBase):
             self.fail('recipetool did not create recipe file; output:\n%s\ndirlist:\n%s' % (result.output, str(dirlist)))
         self.assertEqual(dirlist[0], 'socat_%s.bb' % pv, 'Recipe file incorrectly named')
         checkvars = {}
-        checkvars['LICENSE'] = set(['Unknown', 'GPL-2.0-only'])
+        checkvars['LICENSE'] = 'GPL-2.0-only AND Unknown'
         checkvars['LIC_FILES_CHKSUM'] = set(['file://COPYING.OpenSSL;md5=5c9bccc77f67a8328ef4ebaf468116f4', 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263'])
         # We don't check DEPENDS since they are variable for this recipe depending on what's in the sysroot
         checkvars['S'] = None
@@ -422,7 +424,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
-        checkvars['LICENSE'] = set(['LGPL-2.1-only', 'MPL-1.1-only'])
+        checkvars['LICENSE'] = 'LGPL-2.1-only AND MPL-1.1'
         checkvars['SRC_URI'] = 'http://taglib.github.io/releases/taglib-${PV}.tar.gz'
         checkvars['SRC_URI[sha256sum]'] = 'b6d1a5a610aae6ff39d93de5efd0fdc787aa9e9dc1e7026fa4c961b26563526b'
         checkvars['DEPENDS'] = set(['boost', 'zlib'])
@@ -445,7 +447,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         checkvars = {}
         checkvars['SUMMARY'] = 'Node Server Example'
         checkvars['HOMEPAGE'] = 'https://github.com/savoirfairelinux/node-server-example#readme'
-        checkvars['LICENSE'] = 'BSD-3-Clause & ISC & MIT & Unknown'
+        checkvars['LICENSE'] = 'BSD-3-Clause AND ISC AND MIT AND Unknown'
         urls = []
         urls.append('npm://registry.npmjs.org/;package=@savoirfairelinux/node-server-example;version=${PV}')
         urls.append('npmsw://${THISDIR}/${BPN}/npm-shrinkwrap.json')
@@ -469,7 +471,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         result = runCmd(cmd)
         self.assertTrue(os.path.isfile(recipefile), msg="recipe %s not created for command %s, output %s" % (recipefile, " ".join(cmd), result.output))
         checkvars = {}
-        checkvars['LICENSE'] = set(['Apache-2.0', "Unknown"])
+        checkvars['LICENSE'] = 'Apache-2.0 AND Unknown'
         checkvars['SRC_URI'] = 'git://github.com/mesonbuild/meson;protocol=https;branch=0.52'
         inherits = ['setuptools3']
         self._test_recipe_contents(recipefile, checkvars, inherits)
@@ -487,7 +489,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         result = runCmd('recipetool create --no-pypi -o %s %s' % (temprecipe, srcuri))
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
-        checkvars['LICENSE'] = set(['MIT'])
+        checkvars['LICENSE'] = 'MIT'
         checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=16a934f165e8c3245f241e77d401bb88'
         checkvars['SRC_URI'] = 'https://files.pythonhosted.org/packages/84/30/80932401906eaf787f2e9bd86dc458f1d2e75b064b4c187341f29516945c/python-magic-${PV}.tar.gz'
         checkvars['SRC_URI[sha256sum]'] = 'f3765c0f582d2dfc72c15f3b5a82aecfae9498bd29ca840d72f37d7bd38bfcd5'
@@ -505,7 +507,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
-        checkvars['LICENSE'] = set(['MIT'])
+        checkvars['LICENSE'] = 'MIT'
         checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=16a934f165e8c3245f241e77d401bb88'
         checkvars['SRC_URI[sha256sum]'] = 'f3765c0f582d2dfc72c15f3b5a82aecfae9498bd29ca840d72f37d7bd38bfcd5'
         checkvars['PYPI_PACKAGE'] = pn
@@ -527,7 +529,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
-        checkvars['LICENSE'] = set(['MIT'])
+        checkvars['LICENSE'] = 'MIT'
         checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=16a934f165e8c3245f241e77d401bb88'
         checkvars['SRC_URI[sha256sum]'] = 'f3765c0f582d2dfc72c15f3b5a82aecfae9498bd29ca840d72f37d7bd38bfcd5'
         checkvars['PYPI_PACKAGE'] = pn
@@ -541,7 +543,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         runCmd('recipetool create -o %s %s --version %s' % (temprecipe, srcuri, pv))
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
-        checkvars['LICENSE'] = set(['MIT'])
+        checkvars['LICENSE'] = 'MIT'
         checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=16a934f165e8c3245f241e77d401bb88'
         checkvars['SRC_URI[sha256sum]'] = 'f3765c0f582d2dfc72c15f3b5a82aecfae9498bd29ca840d72f37d7bd38bfcd5'
         checkvars['PYPI_PACKAGE'] = pn
@@ -568,7 +570,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         recipefile = os.path.join(temprecipe, '%s_%s.bb' % (pn, latest_pv))
         # Do not check LIC_FILES_CHKSUM and SRC_URI checksum here to avoid having updating the test on each release
         checkvars = {}
-        checkvars['LICENSE'] = set(['MIT'])
+        checkvars['LICENSE'] = 'MIT'
         checkvars['PYPI_PACKAGE'] = pn
         inherits = ['setuptools3', "pypi"]
         self._test_recipe_contents(recipefile, checkvars, inherits)
@@ -588,7 +590,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
         checkvars['SUMMARY'] = 'A library for working with the color formats defined by HTML and CSS.'
-        checkvars['LICENSE'] = set(['BSD-3-Clause'])
+        checkvars['LICENSE'] = 'BSD-3-Clause'
         checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=702b1ef12cf66832a88f24c8f2ee9c19'
         checkvars['SRC_URI[sha256sum]'] = 'c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a'
         inherits = ['python_setuptools_build_meta', 'pypi']
@@ -611,7 +613,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
         checkvars['SUMMARY'] = 'A linter for YAML files.'
-        checkvars['LICENSE'] = set(['GPL-3.0-only'])
+        checkvars['LICENSE'] = 'GPL-3.0-only'
         checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=1ebbd3e34237af26da5dc08a4e440464'
         checkvars['SRC_URI[sha256sum]'] = '81f7c0c5559becc8049470d86046b36e96113637bcbe4753ecef06977c00245d'
         inherits = ['python_setuptools_build_meta', 'pypi']
@@ -633,7 +635,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
         checkvars['SUMMARY'] = 'Sphinx SVG to PDF or PNG converter extension'
-        checkvars['LICENSE'] = set(['BSD-2-Clause'])
+        checkvars['LICENSE'] = 'BSD-2-Clause'
         checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE.txt;md5=b11cf936853a71258d4b57bb1849a3f9'
         checkvars['SRC_URI[sha256sum]'] = 'ab9c8f1080391e231812d20abf2657a69ee35574563b1014414f953964a95fa3'
         inherits = ['python_setuptools_build_meta', 'pypi']
@@ -655,7 +657,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
         checkvars['SUMMARY'] = 'Simple module to parse ISO 8601 dates'
-        checkvars['LICENSE'] = set(['MIT'])
+        checkvars['LICENSE'] = 'MIT'
         checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=aab31f2ef7ba214a5a341eaa47a7f367'
         checkvars['SRC_URI[sha256sum]'] = '6b1d3829ee8921c4301998c909f7829fa9ed3cbdac0d3b16af2d743aed1ba8df'
         inherits = ['python_poetry_core', 'pypi']
@@ -700,7 +702,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         checkvars = {}
         checkvars['SUMMARY'] = 'An implementation of JSON Schema validation for Python'
         checkvars['HOMEPAGE'] = 'https://github.com/python-jsonschema/jsonschema'
-        checkvars['LICENSE'] = set(['MIT'])
+        checkvars['LICENSE'] = 'MIT'
         checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=7a60a81c146ec25599a3e1dabb8610a8 file://json/LICENSE;md5=9d4de43111d33570c8fe49b4cb0e01af'
         checkvars['SRC_URI[sha256sum]'] = 'ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf'
         inherits = ['python_hatchling', 'pypi']
@@ -722,7 +724,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
         checkvars['HOMEPAGE'] = 'https://github.com/pydantic/pydantic-core'
-        checkvars['LICENSE'] = set(['MIT'])
+        checkvars['LICENSE'] = 'MIT'
         checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=ab599c188b4a314d2856b3a55030c75c'
         checkvars['SRC_URI[sha256sum]'] = '6d30226dfc816dd0fdf120cae611dd2215117e4f9b124af8c60ab9093b6e8e71'
         inherits = ['python_maturin', 'pypi']
@@ -759,7 +761,7 @@ class RecipetoolCreateTests(RecipetoolBase):
         result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
         self.assertTrue(os.path.isfile(recipefile))
         checkvars = {}
-        checkvars['LICENSE'] = set(['Apache-2.0'])
+        checkvars['LICENSE'] = 'Apache-2.0'
         checkvars['SRC_URI'] = 'https://github.com/mesonbuild/meson/releases/download/${PV}/meson-${PV}.tar.gz'
         inherits = ['setuptools3']
         self._test_recipe_contents(recipefile, checkvars, inherits)
@@ -934,26 +936,26 @@ class RecipetoolTests(RecipetoolBase):
 
         extravalues = {
             # Duplicate and missing licenses
-            'LICENSE': 'Zlib & BSD-2-Clause & Zlib',
+            'LICENSE': 'Zlib AND BSD-2-Clause AND Zlib',
             'LIC_FILES_CHKSUM': [
                 'file://README.md;md5=0123456789abcdef0123456789abcd'
             ]
         }
         lines_before = []
         handled = []
-        licvalues = handle_license_vars(srctree, lines_before, handled, extravalues, d)
+        licnode = handle_license_vars(srctree, lines_before, handled, extravalues, d)
         expected_lines_before = [
             '# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is',
             '# your responsibility to verify that the values are complete and correct.',
-            '# NOTE: Original package / source metadata indicates license is: BSD-2-Clause & Zlib',
+            '# NOTE: Original package / source metadata indicates license is: BSD-2-Clause AND Zlib',
             '#',
-            '# NOTE: multiple licenses have been detected; they have been separated with &',
+            '# NOTE: multiple licenses have been detected; they have been separated with AND',
             '# in the LICENSE value for now since it is a reasonable assumption that all',
             '# of the licenses apply. If instead there is a choice between the multiple',
-            '# licenses then you should change the value to separate the licenses with |',
-            '# instead of &. If there is any doubt, check the accompanying documentation',
+            '# licenses then you should change the value to separate the licenses with OR',
+            '# instead of AND. If there is any doubt, check the accompanying documentation',
             '# to determine which situation is applicable.',
-            'LICENSE = "Apache-2.0 & BSD-2-Clause & BSD-3-Clause & ISC & MIT & Zlib"',
+            'LICENSE = "Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND Zlib"',
             'LIC_FILES_CHKSUM = "file://LICENSE;md5=0835ade698e0bcf8506ecda2f7b4f302 \\\n'
             '                    file://LICENSE.Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10 \\\n'
             '                    file://LICENSE.BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9 \\\n'
@@ -963,36 +965,32 @@ class RecipetoolTests(RecipetoolBase):
             ''
         ]
         self.assertEqual(lines_before, expected_lines_before)
-        expected_licvalues = [
-            ('MIT', 'LICENSE', '0835ade698e0bcf8506ecda2f7b4f302'),
-            ('Apache-2.0', 'LICENSE.Apache-2.0', '89aea4e17d99a7cacdbeed46a0096b10'),
-            ('BSD-3-Clause', 'LICENSE.BSD-3-Clause', '550794465ba0ec5312d6919e203a55f9'),
-            ('ISC', 'LICENSE.ISC', 'f3b90e78ea0cffb20bf5cca7947a896d'),
-            ('MIT', 'LICENSE.MIT', '0835ade698e0bcf8506ecda2f7b4f302')
-        ]
-        self.assertEqual(handled, [('license', expected_licvalues)])
+        expected_licvalue = oe.spdx_license.parse("Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND Zlib")
+        self.assertEqual(len(handled), 1)
+        self.assertEqual(handled[0][0], "license")
+        self.assertEqual(handled[0][1].to_string(), expected_licvalue.to_string())
         self.assertEqual(extravalues, {})
-        self.assertEqual(licvalues, expected_licvalues)
+        self.assertEqual(licnode.to_string(), expected_licvalue.to_string())
 
 
     def test_recipetool_split_pkg_licenses(self):
         from create import split_pkg_licenses
         licvalues = [
             # Duplicate licenses
-            ('BSD-2-Clause', 'x/COPYING', None),
-            ('BSD-2-Clause', 'x/LICENSE', None),
+            (oe.spdx_license.parse('BSD-2-Clause'), 'x/COPYING', None),
+            (oe.spdx_license.parse('BSD-2-Clause'), 'x/LICENSE', None),
             # Multiple licenses
-            ('MIT', 'x/a/LICENSE.MIT', None),
-            ('ISC', 'x/a/LICENSE.ISC', None),
+            (oe.spdx_license.parse('MIT'), 'x/a/LICENSE.MIT', None),
+            (oe.spdx_license.parse('ISC'), 'x/a/LICENSE.ISC', None),
             # Alternative licenses
-            ('(MIT | ISC)', 'x/b/LICENSE', None),
+            (oe.spdx_license.parse('(MIT OR ISC)'), 'x/b/LICENSE', None),
             # Alternative licenses without brackets
-            ('MIT | BSD-2-Clause', 'x/c/LICENSE', None),
+            (oe.spdx_license.parse('MIT OR BSD-2-Clause'), 'x/c/LICENSE', None),
             # Multi licenses with alternatives
-            ('MIT', 'x/d/COPYING', None),
-            ('MIT | BSD-2-Clause', 'x/d/LICENSE', None),
+            (oe.spdx_license.parse('MIT'), 'x/d/COPYING', None),
+            (oe.spdx_license.parse('MIT OR BSD-2-Clause'), 'x/d/LICENSE', None),
             # Multi licenses with alternatives and brackets
-            ('Apache-2.0 & ((MIT | ISC) & BSD-3-Clause)', 'x/e/LICENSE', None)
+            (oe.spdx_license.parse('Apache-2.0 AND ((MIT OR ISC) AND BSD-3-Clause)'), 'x/e/LICENSE', None)
         ]
         packages = {
             '${PN}': '',
@@ -1013,23 +1011,23 @@ class RecipetoolTests(RecipetoolBase):
         outlines = []
         outlicenses = split_pkg_licenses(licvalues, packages, outlines, fallback_licenses)
         expected_outlicenses = {
-            '${PN}': ['BSD-2-Clause'],
-            'a': ['ISC', 'MIT'],
-            'b': ['(ISC | MIT)'],
-            'c': ['(BSD-2-Clause | MIT)'],
-            'd': ['(BSD-2-Clause | MIT)', 'MIT'],
-            'e': ['(ISC | MIT)', 'Apache-2.0', 'BSD-3-Clause'],
-            'f': ['BSD-3-Clause'],
-            'g': ['Unknown']
+            '${PN}': 'BSD-2-Clause',
+            'a': 'ISC AND MIT',
+            'b': 'ISC OR MIT',
+            'c': 'BSD-2-Clause OR MIT',
+            'd': 'MIT AND (BSD-2-Clause OR MIT)',
+            'e': 'Apache-2.0 AND BSD-3-Clause AND (ISC OR MIT)',
+            'f': 'BSD-3-Clause',
+            'g': 'Unknown',
         }
         self.assertEqual(outlicenses, expected_outlicenses)
         expected_outlines = [
             'LICENSE:${PN} = "BSD-2-Clause"',
-            'LICENSE:a = "ISC & MIT"',
-            'LICENSE:b = "(ISC | MIT)"',
-            'LICENSE:c = "(BSD-2-Clause | MIT)"',
-            'LICENSE:d = "(BSD-2-Clause | MIT) & MIT"',
-            'LICENSE:e = "(ISC | MIT) & Apache-2.0 & BSD-3-Clause"',
+            'LICENSE:a = "ISC AND MIT"',
+            'LICENSE:b = "ISC OR MIT"',
+            'LICENSE:c = "BSD-2-Clause OR MIT"',
+            'LICENSE:d = "MIT AND (BSD-2-Clause OR MIT)"',
+            'LICENSE:e = "Apache-2.0 AND BSD-3-Clause AND (ISC OR MIT)"',
             'LICENSE:f = "BSD-3-Clause"',
             'LICENSE:g = "Unknown"'
         ]
diff --git a/scripts/lib/recipetool/create.py b/scripts/lib/recipetool/create.py
index 5126a4824e..7fc740b149 100644
--- a/scripts/lib/recipetool/create.py
+++ b/scripts/lib/recipetool/create.py
@@ -18,7 +18,8 @@ from urllib.parse import urlparse, urldefrag, urlsplit
 import hashlib
 import bb.fetch2
 logger = logging.getLogger('recipetool')
-from oe.license import tidy_licenses
+import oe.license
+import oe.spdx_license
 from oe.license_finder import find_licenses
 
 tinfoil = None
@@ -794,7 +795,7 @@ def create_recipe(args):
         if name_pv and not realpv:
             realpv = name_pv
 
-    licvalues = handle_license_vars(srctree_use, lines_before, handled, extravalues, tinfoil.config_data)
+    handle_license_vars(srctree_use, lines_before, handled, extravalues, tinfoil.config_data)
 
     if not outfile:
         if not pn:
@@ -957,36 +958,40 @@ def handle_license_vars(srctree, lines_before, handled, extravalues, d):
         # Someone else has already handled the license vars, just return their value
         return lichandled[0][1]
 
-    licvalues = find_licenses(srctree, d)
-    licenses = []
+    lines = []
     lic_files_chksum = []
     lic_unknown = []
-    lines = []
-    if licvalues:
-        for licvalue in licvalues:
-            license = licvalue[0]
-            lics = tidy_licenses(fixup_license(license))
-            lics = [lic for lic in lics if lic not in licenses]
-            if len(lics):
-                licenses.extend(lics)
-            lic_files_chksum.append('file://%s;md5=%s' % (licvalue[1], licvalue[2]))
-            if license == 'Unknown':
-                lic_unknown.append(licvalue[1])
-        if lic_unknown:
-            lines.append('#')
-            lines.append('# The following license files were not able to be identified and are')
-            lines.append('# represented as "Unknown" below, you will need to check them yourself:')
-            for licfile in lic_unknown:
-                lines.append('#   %s' % licfile)
-
-    extra_license = tidy_licenses(extravalues.pop('LICENSE', ''))
-    if extra_license:
-        if licenses == ['Unknown']:
-            licenses = extra_license
-        else:
-            for item in extra_license:
-                if item not in licenses:
-                    licenses.append(item)
+    lic_nodes = []
+    for node, licfile, md5 in find_licenses(srctree, d):
+        if isinstance(node, oe.spdx_license.UnknownId):
+            lic_unknown.append(licfile)
+
+        lic_files_chksum.append(f"file://{licfile};md5={md5}")
+        lic_nodes.append(node)
+
+    if lic_unknown:
+        lines.append('#')
+        lines.append('# The following license files were not able to be identified and are')
+        lines.append('# represented as "Unknown" below, you will need to check them yourself:')
+        for licfile in lic_unknown:
+            lines.append('#   %s' % licfile)
+
+    node = None
+    if lic_nodes:
+        node = oe.spdx_license.AndOp.join(lic_nodes).sort()
+
+    extra_license = None
+    new_license = False
+    if expression := extravalues.pop('LICENSE', '').strip():
+        extra_license = oe.license.parse_legacy_license(d, expression).sort()
+
+        if extra_license:
+            if not node or isinstance(node, oe.spdx_license.UnknownId):
+                node = extra_license
+            else:
+                node = oe.spdx_license.AndOp.join([node, extra_license]).sort()
+                new_license = True
+
     extra_lic_files_chksum = split_value(extravalues.pop('LIC_FILES_CHKSUM', []))
     for item in extra_lic_files_chksum:
         if item not in lic_files_chksum:
@@ -996,7 +1001,8 @@ def handle_license_vars(srctree, lines_before, handled, extravalues, d):
         # We are going to set the vars, so prepend the standard disclaimer
         lines.insert(0, '# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is')
         lines.insert(1, '# your responsibility to verify that the values are complete and correct.')
-    else:
+
+    if not node:
         # Without LIC_FILES_CHKSUM we set LICENSE = "CLOSED" to allow the
         # user to get started easily
         lines.append('# Unable to find any files that looked like license statements. Check the accompanying')
@@ -1006,21 +1012,20 @@ def handle_license_vars(srctree, lines_before, handled, extravalues, d):
         lines.append('# this is not accurate with respect to the licensing of the software being built (it')
         lines.append('# will not be in most cases) you must specify the correct value before using this')
         lines.append('# recipe for anything other than initial testing/development!')
-        licenses = ['CLOSED']
 
-    if extra_license and sorted(licenses) != sorted(extra_license):
-        lines.append('# NOTE: Original package / source metadata indicates license is: %s' % ' & '.join(extra_license))
+    if new_license:
+        lines.append('# NOTE: Original package / source metadata indicates license is: %s' % extra_license.to_string())
 
-    if len(licenses) > 1:
+    if not isinstance(node, oe.spdx_license.Identifier):
         lines.append('#')
-        lines.append('# NOTE: multiple licenses have been detected; they have been separated with &')
+        lines.append('# NOTE: multiple licenses have been detected; they have been separated with AND')
         lines.append('# in the LICENSE value for now since it is a reasonable assumption that all')
         lines.append('# of the licenses apply. If instead there is a choice between the multiple')
-        lines.append('# licenses then you should change the value to separate the licenses with |')
-        lines.append('# instead of &. If there is any doubt, check the accompanying documentation')
+        lines.append('# licenses then you should change the value to separate the licenses with OR')
+        lines.append('# instead of AND. If there is any doubt, check the accompanying documentation')
         lines.append('# to determine which situation is applicable.')
 
-    lines.append('LICENSE = "%s"' % ' & '.join(sorted(licenses, key=str.casefold)))
+    lines.append('LICENSE = "%s"' % (node.to_string() if node else 'CLOSED'))
     lines.append('LIC_FILES_CHKSUM = "%s"' % ' \\\n                    '.join(lic_files_chksum))
     lines.append('')
 
@@ -1034,8 +1039,8 @@ def handle_license_vars(srctree, lines_before, handled, extravalues, d):
     else:
         lines_before[pos:pos+1] = lines
 
-    handled.append(('license', licvalues))
-    return licvalues
+    handled.append(('license', node))
+    return node
 
 def split_pkg_licenses(licvalues, packages, outlines, fallback_licenses=None, pn='${PN}'):
     """
@@ -1044,33 +1049,30 @@ def split_pkg_licenses(licvalues, packages, outlines, fallback_licenses=None, pn
     package-specific LICENSE values.
     """
     pkglicenses = {pn: []}
-    for license, licpath, _ in licvalues:
-        license = fixup_license(license)
+    for node, licpath, _ in licvalues:
         for pkgname, pkgpath in packages.items():
             if licpath.startswith(pkgpath + '/'):
-                if pkgname in pkglicenses:
-                    pkglicenses[pkgname].append(license)
-                else:
-                    pkglicenses[pkgname] = [license]
+                pkglicenses.setdefault(pkgname, []).append(node)
                 break
         else:
             # Accumulate on the main package
-            pkglicenses[pn].append(license)
+            pkglicenses[pn].append(node)
+
     outlicenses = {}
     for pkgname in packages:
-        # Assume AND operator between license files
-        license = ' & '.join(list(set(pkglicenses.get(pkgname, ['Unknown'])))) or 'Unknown'
-        if license == 'Unknown' and fallback_licenses and pkgname in fallback_licenses:
-            license = fallback_licenses[pkgname]
-        licenses = tidy_licenses(license)
-        license = ' & '.join(licenses)
-        outlines.append('LICENSE:%s = "%s"' % (pkgname, license))
-        outlicenses[pkgname] = licenses
+        if pkgname in pkglicenses:
+            lic = oe.spdx_license.AndOp.join(pkglicenses[pkgname]).sort().to_string()
+        elif fallback_licenses and pkgname in fallback_licenses:
+            lic = fallback_licenses[pkgname]
+        else:
+            lic = "Unknown"
+        outlines.append(f'LICENSE:{pkgname} = "{lic}"')
+        outlicenses[pkgname] = lic
     return outlicenses
 
 def generate_common_licenses_chksums(common_licenses, d):
     lic_files_chksums = []
-    for license in tidy_licenses(common_licenses):
+    for license in common_licenses:
         licfile = '${COMMON_LICENSE_DIR}/' + license
         md5value = bb.utils.md5_file(d.expand(licfile))
         lic_files_chksums.append('file://%s;md5=%s' % (licfile, md5value))
diff --git a/scripts/lib/recipetool/create_npm.py b/scripts/lib/recipetool/create_npm.py
index 4d316d9a55..bf53edc08e 100644
--- a/scripts/lib/recipetool/create_npm.py
+++ b/scripts/lib/recipetool/create_npm.py
@@ -160,19 +160,19 @@ class NpmRecipeHandler(RecipeHandler):
         _get_package_licenses(srctree, "${PN}")
 
         return licfiles, packages, fallback_licenses
-    
-    # Handle the peer dependencies   
+
+    # Handle the peer dependencies
     def _handle_peer_dependency(self, shrinkwrap_file):
         """Check if package has peer dependencies and show warning if it is the case"""
         with open(shrinkwrap_file, "r") as f:
             shrinkwrap = json.load(f)
-        
+
         packages = shrinkwrap.get("packages", {})
         peer_deps = packages.get("", {}).get("peerDependencies", {})
-        
+
         for peer_dep in peer_deps:
             peer_dep_yocto_name = npm_package(peer_dep)
-            bb.warn(peer_dep + " is a peer dependencie of the actual package. " + 
+            bb.warn(peer_dep + " is a peer dependencie of the actual package. " +
             "Please add this peer dependencie to the RDEPENDS variable as %s and generate its recipe with devtool"
             % peer_dep_yocto_name)
 
@@ -283,7 +283,8 @@ class NpmRecipeHandler(RecipeHandler):
         (licfiles, packages, fallback_licenses) = self._handle_licenses(srctree, shrinkwrap_file, dev)
         licvalues = match_licenses(licfiles, srctree, d)
         split_pkg_licenses(licvalues, packages, lines_after, fallback_licenses)
-        fallback_licenses_flat = [license for sublist in fallback_licenses.values() for license in sublist]
+        fallback_licenses_flat = set(license for sublist in fallback_licenses.values() for license in sublist)
+        fallback_licesens_flat = sorted(fallback_licenses_flat).sort()
         extravalues["LIC_FILES_CHKSUM"] = generate_common_licenses_chksums(fallback_licenses_flat, d)
         extravalues["LICENSE"] = fallback_licenses_flat
 
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 20/22] meta-selftest: Change license on test recipes
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (18 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 19/22] license: Remove tidy_licenses() Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 21/22] Convert licenses to SPDX expressions Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 22/22] meta-selftest: libxpm: Fix license Joshua Watt
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

The "CLOSED" license now issues a warning that it should be replaced
with a LicenseRef, so remove it from the test file in favor of declaring
an MIT license

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta-selftest/recipes-test/devtool/devtool-patch-overrides.bb  | 3 ++-
 meta-selftest/recipes-test/devtool/devtool-test-ignored.bb     | 3 ++-
 meta-selftest/recipes-test/devtool/devtool-test-localonly.bb   | 3 ++-
 .../recipes-test/devtool/devtool-test-long-filename.bb         | 3 ++-
 meta-selftest/recipes-test/devtool/devtool-test-reset-re++.bb  | 3 ++-
 meta-selftest/recipes-test/devtool/devtool-test-subdir.bb      | 3 ++-
 meta-selftest/recipes-test/logging-test/logging-test.bb        | 3 ++-
 meta-selftest/recipes-test/sysroot-test/sysroot-la-test_1.0.bb | 3 ++-
 meta-selftest/recipes-test/sysroot-test/sysroot-pc-test_1.0.bb | 3 ++-
 .../recipes-test/sysroot-test/sysroot-shebang-test_1.0.bb      | 3 ++-
 .../recipes-test/sysroot-test/sysroot-test-arch1_1.0.bb        | 3 ++-
 .../recipes-test/sysroot-test/sysroot-test-arch2_1.0.bb        | 3 ++-
 meta-selftest/recipes-test/sysroot-test/sysroot-test_1.0.bb    | 3 ++-
 13 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/meta-selftest/recipes-test/devtool/devtool-patch-overrides.bb b/meta-selftest/recipes-test/devtool/devtool-patch-overrides.bb
index f12bee0b3d..467df669df 100644
--- a/meta-selftest/recipes-test/devtool/devtool-patch-overrides.bb
+++ b/meta-selftest/recipes-test/devtool/devtool-patch-overrides.bb
@@ -1,5 +1,6 @@
 SUMMARY = "devtool test for overrides and patches"
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 INHIBIT_DEFAULT_DEPS = "1"
 EXCLUDE_FROM_WORLD = "1"
 
diff --git a/meta-selftest/recipes-test/devtool/devtool-test-ignored.bb b/meta-selftest/recipes-test/devtool/devtool-test-ignored.bb
index c7740eb118..6ea4fa71fb 100644
--- a/meta-selftest/recipes-test/devtool/devtool-test-ignored.bb
+++ b/meta-selftest/recipes-test/devtool/devtool-test-ignored.bb
@@ -1,4 +1,5 @@
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 INHIBIT_DEFAULT_DEPS = "1"
 
 SRC_URI = "file://${BPN}.tar.gz \
diff --git a/meta-selftest/recipes-test/devtool/devtool-test-localonly.bb b/meta-selftest/recipes-test/devtool/devtool-test-localonly.bb
index 54463fed98..aad3a62f1f 100644
--- a/meta-selftest/recipes-test/devtool/devtool-test-localonly.bb
+++ b/meta-selftest/recipes-test/devtool/devtool-test-localonly.bb
@@ -1,4 +1,5 @@
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 INHIBIT_DEFAULT_DEPS = "1"
 
 SRC_URI = "file://file1 \
diff --git a/meta-selftest/recipes-test/devtool/devtool-test-long-filename.bb b/meta-selftest/recipes-test/devtool/devtool-test-long-filename.bb
index 3653403a2e..ce0a468403 100644
--- a/meta-selftest/recipes-test/devtool/devtool-test-long-filename.bb
+++ b/meta-selftest/recipes-test/devtool/devtool-test-long-filename.bb
@@ -1,4 +1,5 @@
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 INHIBIT_DEFAULT_DEPS = "1"
 
 SRC_URI = "file://${BPN}.tar.gz \
diff --git a/meta-selftest/recipes-test/devtool/devtool-test-reset-re++.bb b/meta-selftest/recipes-test/devtool/devtool-test-reset-re++.bb
index 0146be4c52..fbfb456bf9 100644
--- a/meta-selftest/recipes-test/devtool/devtool-test-reset-re++.bb
+++ b/meta-selftest/recipes-test/devtool/devtool-test-reset-re++.bb
@@ -1,4 +1,5 @@
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 INHIBIT_DEFAULT_DEPS = "1"
 
 SRC_URI = "file://file1"
diff --git a/meta-selftest/recipes-test/devtool/devtool-test-subdir.bb b/meta-selftest/recipes-test/devtool/devtool-test-subdir.bb
index 966142431b..0351a1e3bb 100644
--- a/meta-selftest/recipes-test/devtool/devtool-test-subdir.bb
+++ b/meta-selftest/recipes-test/devtool/devtool-test-subdir.bb
@@ -1,4 +1,5 @@
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 INHIBIT_DEFAULT_DEPS = "1"
 
 SRC_URI = "file://devtool-test-subdir.tar.gz \
diff --git a/meta-selftest/recipes-test/logging-test/logging-test.bb b/meta-selftest/recipes-test/logging-test/logging-test.bb
index ac3fb46f45..b08678ac58 100644
--- a/meta-selftest/recipes-test/logging-test/logging-test.bb
+++ b/meta-selftest/recipes-test/logging-test/logging-test.bb
@@ -1,5 +1,6 @@
 SUMMARY = "Destined to fail"
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 
 deltask do_patch
 INHIBIT_DEFAULT_DEPS = "1"
diff --git a/meta-selftest/recipes-test/sysroot-test/sysroot-la-test_1.0.bb b/meta-selftest/recipes-test/sysroot-test/sysroot-la-test_1.0.bb
index 21f06782fb..76ea0e895d 100644
--- a/meta-selftest/recipes-test/sysroot-test/sysroot-la-test_1.0.bb
+++ b/meta-selftest/recipes-test/sysroot-test/sysroot-la-test_1.0.bb
@@ -1,5 +1,6 @@
 SUMMARY = "Produce a broken la file"
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 INHIBIT_DEFAULT_DEPS = "1"
 
 EXCLUDE_FROM_WORLD = "1"
diff --git a/meta-selftest/recipes-test/sysroot-test/sysroot-pc-test_1.0.bb b/meta-selftest/recipes-test/sysroot-test/sysroot-pc-test_1.0.bb
index e748310fc4..ee1c99a97e 100644
--- a/meta-selftest/recipes-test/sysroot-test/sysroot-pc-test_1.0.bb
+++ b/meta-selftest/recipes-test/sysroot-test/sysroot-pc-test_1.0.bb
@@ -1,5 +1,6 @@
 SUMMARY = "Produce a broken pc file"
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 INHIBIT_DEFAULT_DEPS = "1"
 
 EXCLUDE_FROM_WORLD = "1"
diff --git a/meta-selftest/recipes-test/sysroot-test/sysroot-shebang-test_1.0.bb b/meta-selftest/recipes-test/sysroot-test/sysroot-shebang-test_1.0.bb
index 106ddd5426..3926bd9bf2 100644
--- a/meta-selftest/recipes-test/sysroot-test/sysroot-shebang-test_1.0.bb
+++ b/meta-selftest/recipes-test/sysroot-test/sysroot-shebang-test_1.0.bb
@@ -1,5 +1,6 @@
 SUMMARY = "Check that shebang does not exceed 256 characters"
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 INHIBIT_DEFAULT_DEPS = "1"
 
 EXCLUDE_FROM_WORLD = "1"
diff --git a/meta-selftest/recipes-test/sysroot-test/sysroot-test-arch1_1.0.bb b/meta-selftest/recipes-test/sysroot-test/sysroot-test-arch1_1.0.bb
index 36a682c53d..9e5c72e5b1 100644
--- a/meta-selftest/recipes-test/sysroot-test/sysroot-test-arch1_1.0.bb
+++ b/meta-selftest/recipes-test/sysroot-test/sysroot-test-arch1_1.0.bb
@@ -1,4 +1,5 @@
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 
 PROVIDES = "virtual/sysroot-test"
 INHIBIT_DEFAULT_DEPS = "1"
diff --git a/meta-selftest/recipes-test/sysroot-test/sysroot-test-arch2_1.0.bb b/meta-selftest/recipes-test/sysroot-test/sysroot-test-arch2_1.0.bb
index 67172f3cab..d84b8c6282 100644
--- a/meta-selftest/recipes-test/sysroot-test/sysroot-test-arch2_1.0.bb
+++ b/meta-selftest/recipes-test/sysroot-test/sysroot-test-arch2_1.0.bb
@@ -1,4 +1,5 @@
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 
 PROVIDES = "virtual/sysroot-test"
 INHIBIT_DEFAULT_DEPS = "1"
diff --git a/meta-selftest/recipes-test/sysroot-test/sysroot-test_1.0.bb b/meta-selftest/recipes-test/sysroot-test/sysroot-test_1.0.bb
index 560487c159..dc265dbe35 100644
--- a/meta-selftest/recipes-test/sysroot-test/sysroot-test_1.0.bb
+++ b/meta-selftest/recipes-test/sysroot-test/sysroot-test_1.0.bb
@@ -1,5 +1,6 @@
 SUMMARY = "Virtual provider sysroot test"
-LICENSE = "CLOSED"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
 INHIBIT_DEFAULT_DEPS = "1"
 DEPENDS = "virtual/sysroot-test"
 
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 21/22] Convert licenses to SPDX expressions
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (19 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 20/22] meta-selftest: Change license on test recipes Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  2026-07-14 18:31 ` [OE-core][PATCH 22/22] meta-selftest: libxpm: Fix license Joshua Watt
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

Automatically convert all licenses to valid SPDX license expressions
using convert-spdx-licenses.py

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 .../python/python3-guessing-game_git.bb       |  2 +-
 .../python3-guessing-game_git.bb.upgraded     |  2 +-
 .../sysdig/sysdig-selftest_0.28.0.bb          |  2 +-
 .../recipes-test/aspell/aspell_0.0.0.1.bb     |  2 +-
 .../license/incompatible-license-alias.bb     |  2 +-
 .../license/incompatible-licenses.bb          |  2 +-
 .../license/incompatible-nonspdx-license.bb   |  2 +-
 meta/recipes-bsp/alsa-state/alsa-state.bb     |  2 +-
 meta/recipes-bsp/gnu-efi/gnu-efi_4.0.4.bb     |  2 +-
 meta/recipes-bsp/usbutils/usbutils_019.bb     |  4 +--
 meta/recipes-connectivity/avahi/avahi_0.9.bb  |  2 +-
 meta/recipes-connectivity/bluez5/bluez5.inc   |  2 +-
 .../connman/connman-gnome_0.7.bb              |  2 +-
 .../nfs-utils/nfs-utils_2.9.1.bb              |  2 +-
 .../openssh/openssh_10.4p1.bb                 |  2 +-
 meta/recipes-connectivity/ppp/ppp_2.5.3.bb    |  2 +-
 .../slirp/libslirp_4.9.3.bb                   |  2 +-
 .../socat/socat_1.8.1.3.bb                    |  3 +-
 meta/recipes-core/busybox/busybox.inc         |  2 +-
 meta/recipes-core/dbus/dbus-glib_0.114.bb     |  2 +-
 meta/recipes-core/dbus/dbus_1.16.2.bb         |  2 +-
 .../recipes-core/dropbear/dropbear_2026.92.bb |  2 +-
 meta/recipes-core/gettext/gettext_1.0.bb      |  2 +-
 meta/recipes-core/glib-2.0/glib.inc           |  2 +-
 meta/recipes-core/glibc/glibc-common.inc      |  2 +-
 .../initscripts/init-system-helpers_1.69.bb   |  2 +-
 meta/recipes-core/kbd/kbd_2.10.0.bb           |  4 +--
 meta/recipes-core/libxcrypt/libxcrypt.inc     |  2 +-
 meta/recipes-core/musl/bsd-headers.bb         |  2 +-
 meta/recipes-core/musl/musl-locales_git.bb    |  2 +-
 meta/recipes-core/musl/musl-utils.bb          |  2 +-
 meta/recipes-core/newlib/newlib.inc           |  2 +-
 meta/recipes-core/picolibc/picolibc.inc       |  2 +-
 .../sysfsutils/sysfsutils_2.1.1.bb            |  2 +-
 meta/recipes-core/systemd/systemd.inc         |  2 +-
 meta/recipes-core/udev/eudev_3.2.14.bb        |  2 +-
 .../util-linux/util-linux_2.42.2.bb           | 36 +++++++++----------
 .../btrfs-tools/btrfs-tools_7.0.bb            |  2 +-
 meta/recipes-devtools/ccache/ccache_4.13.6.bb |  2 +-
 .../cdrtools/cdrtools-native_3.01.bb          |  2 +-
 meta/recipes-devtools/clang/common.inc        |  2 +-
 meta/recipes-devtools/clang/llvm_git.bb       |  2 +-
 .../clang/nativesdk-clang-glue.bb             |  2 +-
 .../debugedit/debugedit_5.3.bb                |  2 +-
 .../docbook-xml/docbook-xml-dtd4_4.5.bb       |  2 +-
 meta/recipes-devtools/e2fsprogs/e2fsprogs.inc |  2 +-
 .../elfutils/elfutils_0.195.bb                | 10 +++---
 .../erofs-utils/erofs-utils_1.9.2.bb          |  2 +-
 meta/recipes-devtools/expect/expect_5.45.4.bb |  2 +-
 .../fastfloat/fastfloat_8.2.10.bb             |  2 +-
 meta/recipes-devtools/flex/flex_2.6.4.bb      |  2 +-
 meta/recipes-devtools/gcc/gcc-sanitizers.inc  |  2 +-
 meta/recipes-devtools/gdb/gdb.inc             |  2 +-
 meta/recipes-devtools/git/git_2.55.0.bb       |  2 +-
 .../i2c-tools/i2c-tools_4.4.bb                |  2 +-
 .../libtool/libtool-2.5.4.inc                 |  2 +-
 .../log4cplus/log4cplus_2.2.0.1.bb            |  2 +-
 meta/recipes-devtools/orc/orc_0.4.42.bb       |  2 +-
 .../perl-cross/perlcross_1.6.4.bb             |  2 +-
 .../perl/libmodule-build-perl_0.4234.bb       |  2 +-
 .../perl/libtest-fatal-perl_0.018.bb          |  2 +-
 .../perl/libtest-needs-perl_0.002010.bb       |  2 +-
 .../perl/libtest-warnings-perl_0.038.bb       |  2 +-
 .../recipes-devtools/perl/libxml-perl_0.08.bb |  2 +-
 .../perl/libxml-simple-perl_2.25.bb           |  2 +-
 meta/recipes-devtools/perl/perl_5.42.2.bb     |  2 +-
 .../python/python-pycryptodome.inc            |  2 +-
 .../python/python3-cryptography-vectors.bb    |  2 +-
 .../python/python3-cryptography.bb            |  2 +-
 .../python/python3-docutils_0.23.bb           |  4 +--
 .../python/python3-dtc_1.8.1.bb               |  2 +-
 .../python/python3-idna_3.18.bb               |  2 +-
 .../python/python3-lxml_6.1.1.bb              |  2 +-
 .../python/python3-maturin_1.14.1.bb          |  2 +-
 .../python/python3-numpy_2.5.0.bb             |  2 +-
 .../python/python3-packaging_26.2.bb          |  2 +-
 .../python/python3-pip_26.1.2.bb              |  2 +-
 .../python/python3-poetry-core_2.4.1.bb       |  2 +-
 .../python/python3-pycairo_1.29.0.bb          |  2 +-
 .../python/python3-roman-numerals_4.1.0.bb    |  2 +-
 .../python/python3-sphinx-rtd-theme_3.1.0.bb  |  2 +-
 .../python/python3-sphinx_9.1.0.bb            |  2 +-
 .../python/python3-subunit_1.4.4.bb           |  2 +-
 .../python/python3-uv-build_0.11.28.bb        |  2 +-
 .../qemu/python3-qemu-qmp_0.0.6.bb            |  2 +-
 meta/recipes-devtools/qemu/qemu.inc           |  2 +-
 .../rpm-sequoia/rpm-sequoia_1.10.2.bb         |  2 +-
 meta/recipes-devtools/ruby/ruby_4.0.5.bb      |  2 +-
 meta/recipes-devtools/rust/cargo_1.96.1.bb    |  2 +-
 .../recipes-devtools/rust/libstd-rs_1.96.1.bb |  2 +-
 meta/recipes-devtools/rust/rust_1.96.1.bb     |  2 +-
 meta/recipes-devtools/strace/strace_7.1.bb    |  2 +-
 .../subversion/subversion_1.14.5.bb           |  2 +-
 meta/recipes-devtools/swig/swig_4.4.1.bb      |  2 +-
 .../systemd-bootchart_235.bb                  |  2 +-
 .../tcf-agent/tcf-agent_1.11.0.bb             |  2 +-
 meta/recipes-devtools/tcltk/tcl_9.0.4.bb      |  2 +-
 meta/recipes-devtools/tcltk8/tcl8_8.6.18.bb   |  2 +-
 .../valgrind/valgrind_3.27.1.bb               |  2 +-
 .../acpica/acpica_20260408.bb                 |  2 +-
 meta/recipes-extended/bzip2/bzip2_1.0.8.bb    |  4 +--
 meta/recipes-extended/cronie/cronie_1.7.2.bb  |  2 +-
 meta/recipes-extended/gawk/gawk_5.4.1.bb      |  2 +-
 meta/recipes-extended/hdparm/hdparm_9.65.bb   |  6 ++--
 .../iputils/iputils_20250605.bb               |  2 +-
 .../jansson/jansson_2.15.1.bb                 |  2 +-
 meta/recipes-extended/less/less_704.bb        |  2 +-
 meta/recipes-extended/libidn/libidn2_2.3.8.bb |  4 +--
 meta/recipes-extended/ltp/ltp_20260529.bb     |  2 +-
 meta/recipes-extended/man-db/man-db_2.13.1.bb |  2 +-
 .../man-pages/man-pages_6.18.bb               |  2 +-
 meta/recipes-extended/mdadm/mdadm_4.6.bb      |  2 +-
 meta/recipes-extended/pam/libpam_1.7.2.bb     |  2 +-
 .../perl/libconvert-asn1-perl_0.34.bb         |  2 +-
 .../perl/libtimedate-perl_2.30.bb             |  2 +-
 .../perl/libxml-namespacesupport-perl_1.12.bb |  2 +-
 .../perl/libxml-sax-base-perl_1.09.bb         |  2 +-
 .../perl/libxml-sax-perl_1.02.bb              |  2 +-
 meta/recipes-extended/pigz/pigz_2.8.bb        |  2 +-
 meta/recipes-extended/procps/procps_4.0.6.bb  |  2 +-
 meta/recipes-extended/quota/quota_4.11.bb     |  2 +-
 .../shadow/shadow-sysroot_4.6.bb              |  2 +-
 meta/recipes-extended/sudo/sudo.inc           |  2 +-
 meta/recipes-extended/timezone/timezone.inc   |  2 +-
 meta/recipes-extended/zstd/zstd_1.5.7.bb      |  2 +-
 .../gi-docgen/gi-docgen_2026.1.bb             |  2 +-
 .../gnome/adwaita-icon-theme_50.0.bb          |  2 +-
 .../gobject-introspection_1.86.0.bb           |  2 +-
 meta/recipes-gnome/gtk+/gtk+3_3.24.52.bb      |  2 +-
 meta/recipes-gnome/gtk+/gtk4_4.22.4.bb        |  2 +-
 meta/recipes-graphics/cairo/cairo_1.18.4.bb   | 12 +++----
 .../cantarell-fonts_0.303.1.bb                |  2 +-
 .../fontconfig/fontconfig_2.18.2.bb           |  2 +-
 .../freetype/freetype_2.14.3.bb               |  2 +-
 .../glslang/glslang_1.4.350.1.bb              |  2 +-
 .../jpeg/libjpeg-turbo_3.2.0.bb               |  2 +-
 .../libmatchbox/libmatchbox_1.14.bb           |  2 +-
 .../libsdl2/libsdl2_2.32.10.bb                |  2 +-
 .../recipes-graphics/mesa/mesa-demos_9.0.0.bb |  2 +-
 meta/recipes-graphics/piglit/piglit_git.bb    |  2 +-
 .../spir/spirv-headers_1.4.350.1.bb           |  2 +-
 .../vulkan/vulkan-headers_1.4.350.1.bb        |  2 +-
 .../vulkan-validation-layers_1.4.350.1.bb     |  2 +-
 .../xorg-font/encodings_1.1.0.bb              |  2 +-
 .../xorg-font/font-util_1.4.2.bb              |  2 +-
 .../xorg-font/xorg-minimal-fonts.bb           |  2 +-
 .../xorg-lib/libx11-compose-data_1.8.12.bb    |  2 +-
 .../xorg-lib/libx11_1.8.13.bb                 |  2 +-
 .../xorg-lib/libxfont2_2.0.8.bb               |  2 +-
 .../xorg-lib/libxfont_1.5.4.bb                |  2 +-
 meta/recipes-graphics/xorg-lib/libxi_1.8.3.bb |  2 +-
 .../xorg-lib/libxkbcommon_1.13.2.bb           |  2 +-
 .../recipes-graphics/xorg-lib/libxmu_1.3.1.bb |  2 +-
 meta/recipes-graphics/xorg-lib/libxt_1.3.1.bb |  2 +-
 .../xorg-lib/pixman_0.46.4.bb                 |  2 +-
 .../xorg-lib/xkeyboard-config_2.48.bb         |  2 +-
 .../xorg-xserver/xserver-xorg.inc             |  2 +-
 .../xwayland/xwayland_24.1.13.bb              |  2 +-
 meta/recipes-kernel/dtc/dtc_1.8.1.bb          |  2 +-
 .../kern-tools/kern-tools-native_git.bb       |  2 +-
 meta/recipes-kernel/kmod/kmod_34.2.bb         |  2 +-
 .../libtraceevent/libtraceevent_1.9.0.bb      |  2 +-
 .../linux/linux-yocto-fitimage.bb             |  2 +-
 meta/recipes-kernel/linux/linux-yocto.inc     |  2 +-
 .../recipes-kernel/lttng/babeltrace2_2.1.2.bb |  2 +-
 .../lttng/lttng-modules_2.15.2.bb             |  2 +-
 .../lttng/lttng-tools_2.15.1.bb               |  2 +-
 meta/recipes-kernel/lttng/lttng-ust_2.15.1.bb |  2 +-
 .../alsa/alsa-lib_1.2.16.1.bb                 |  2 +-
 .../alsa/alsa-plugins_1.2.12.bb               |  2 +-
 .../alsa/alsa-tools_1.2.15.bb                 |  2 +-
 .../recipes-multimedia/ffmpeg/ffmpeg_8.1.2.bb |  2 +-
 .../gstreamer1.0-plugins-bad_1.28.4.bb        |  2 +-
 .../gstreamer1.0-plugins-ugly_1.28.4.bb       |  2 +-
 meta/recipes-multimedia/libtiff/tiff_4.7.2.bb |  2 +-
 .../pulseaudio/pulseaudio.inc                 |  2 +-
 meta/recipes-multimedia/sbc/sbc_2.2.bb        |  2 +-
 meta/recipes-rt/rt-tests/rt-tests_git.bb      |  2 +-
 .../matchbox-desktop/matchbox-desktop_2.3.bb  |  2 +-
 meta/recipes-sato/pcmanfm/pcmanfm_1.3.2.bb    |  2 +-
 .../sato-screenshot/sato-screenshot_0.3.bb    |  2 +-
 meta/recipes-sato/webkit/webkitgtk_2.52.5.bb  |  2 +-
 .../recipes-support/aspell/aspell_0.60.8.2.bb |  2 +-
 meta/recipes-support/attr/acl_2.4.0.bb        |  2 +-
 meta/recipes-support/attr/attr_2.6.0.bb       |  2 +-
 meta/recipes-support/boost/boost-1.91.0.inc   |  2 +-
 .../ca-certificates_20260601.bb               |  2 +-
 .../debianutils/debianutils_5.23.2.bb         |  2 +-
 meta/recipes-support/gmp/gmp_6.3.0.bb         |  2 +-
 meta/recipes-support/gnupg/gnupg_2.5.20.bb    |  2 +-
 meta/recipes-support/gnutls/gnutls_3.8.13.bb  |  2 +-
 .../recipes-support/gnutls/libtasn1_4.21.0.bb |  2 +-
 meta/recipes-support/gpgme/gpgme_2.1.2.bb     |  4 +--
 meta/recipes-support/hwdata/hwdata_0.409.bb   |  2 +-
 meta/recipes-support/icu/icu_78.3.bb          |  2 +-
 .../libassuan/libassuan_3.0.2.bb              |  2 +-
 .../libatomic-ops/libatomic-ops_7.10.0.bb     |  2 +-
 meta/recipes-support/libbsd/libbsd_0.12.2.bb  |  2 +-
 meta/recipes-support/libcap-ng/libcap-ng.inc  |  2 +-
 .../libevent/libevent_2.1.13.bb               |  2 +-
 meta/recipes-support/libfm/libfm_1.3.2.bb     |  2 +-
 .../libgcrypt/libgcrypt_1.12.2.bb             |  6 ++--
 .../libgpg-error/libgpg-error_1.61.bb         |  2 +-
 meta/recipes-support/libical/libical_4.0.3.bb |  2 +-
 .../libjitterentropy_3.6.3.bb                 |  2 +-
 meta/recipes-support/libksba/libksba_1.8.0.bb |  4 +--
 meta/recipes-support/libmd/libmd_1.2.0.bb     |  2 +-
 .../recipes-support/libpcre/libpcre2_10.47.bb |  2 +-
 .../libunistring/libunistring_1.4.2.bb        |  2 +-
 .../recipes-support/liburcu/liburcu_0.15.6.bb |  2 +-
 meta/recipes-support/lz4/lz4_1.10.0.bb        |  2 +-
 meta/recipes-support/nettle/nettle_4.0.bb     |  2 +-
 .../recipes-support/numactl/numactl_2.0.19.bb |  2 +-
 meta/recipes-support/re2c/re2c_4.5.1.bb       |  2 +-
 meta/recipes-support/taglib/taglib_2.3.bb     |  2 +-
 meta/recipes-support/utfcpp/utfcpp_4.1.1.bb   |  4 +--
 meta/recipes-support/vte/vte_0.84.0.bb        |  2 +-
 meta/recipes-support/xxhash/xxhash_0.8.3.bb   |  2 +-
 218 files changed, 257 insertions(+), 256 deletions(-)

diff --git a/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb b/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb
index 12afec8b1b..a942d7d517 100644
--- a/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb
+++ b/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Wrap a version of the guessing game from The Rust Book \
 to run in Python using pyo3."
 HOMEPAGE = "https://www.maturin.rs/tutorial"
 SECTION = "devel/python"
-LICENSE = "MIT & Apache-2.0"
+LICENSE = "Apache-2.0 AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE-APACHE;md5=1836efb2eb779966696f473ee8540542 \
                     file://LICENSE-MIT;md5=85fd3b67069cff784d98ebfc7d5c0797"
 
diff --git a/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb.upgraded b/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb.upgraded
index 194a8efe83..4676c32037 100644
--- a/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb.upgraded
+++ b/meta-selftest/recipes-devtools/python/python3-guessing-game_git.bb.upgraded
@@ -3,7 +3,7 @@ DESCRIPTION = "Wrap a version of the guessing game from The Rust Book \
 to run in Python using pyo3."
 HOMEPAGE = "https://www.maturin.rs/tutorial"
 SECTION = "devel/python"
-LICENSE = "MIT & Apache-2.0"
+LICENSE = "Apache-2.0 AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE-APACHE;md5=1836efb2eb779966696f473ee8540542 \
                     file://LICENSE-MIT;md5=85fd3b67069cff784d98ebfc7d5c0797"
 
diff --git a/meta-selftest/recipes-extended/sysdig/sysdig-selftest_0.28.0.bb b/meta-selftest/recipes-extended/sysdig/sysdig-selftest_0.28.0.bb
index ea9a78dd1b..d30668826e 100644
--- a/meta-selftest/recipes-extended/sysdig/sysdig-selftest_0.28.0.bb
+++ b/meta-selftest/recipes-extended/sysdig/sysdig-selftest_0.28.0.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Sysdig is open source, system-level exploration: capture \
 system state and activity from a running Linux instance, then save, \
 filter and analyze."
 HOMEPAGE = "http://www.sysdig.org/"
-LICENSE = "Apache-2.0 & (MIT | GPL-2.0-only)"
+LICENSE = "Apache-2.0 AND (GPL-2.0-only OR MIT)"
 LIC_FILES_CHKSUM = "file://COPYING;md5=f8fee3d59797546cffab04f3b88b2d44"
 
 inherit cmake pkgconfig
diff --git a/meta-selftest/recipes-test/aspell/aspell_0.0.0.1.bb b/meta-selftest/recipes-test/aspell/aspell_0.0.0.1.bb
index e1e473fe80..9b7e10f6bd 100644
--- a/meta-selftest/recipes-test/aspell/aspell_0.0.0.1.bb
+++ b/meta-selftest/recipes-test/aspell/aspell_0.0.0.1.bb
@@ -6,7 +6,7 @@ SUMMARY = "GNU Aspell spell-checker"
 SECTION = "console/utils"
 HOMEPAGE = "https://ftp.gnu.org/gnu/aspell/"
 
-LICENSE = "LGPL-2.0-only | LGPL-2.1-only"
+LICENSE = "LGPL-2.0-only OR LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=7fbc338309ac38fefcd64b04bb903e34"
 
 SRC_URI = "${GNU_MIRROR}/aspell/aspell-${PV}.tar.gz"
diff --git a/meta-selftest/recipes-test/license/incompatible-license-alias.bb b/meta-selftest/recipes-test/license/incompatible-license-alias.bb
index 1af99e7809..45ebbb7407 100644
--- a/meta-selftest/recipes-test/license/incompatible-license-alias.bb
+++ b/meta-selftest/recipes-test/license/incompatible-license-alias.bb
@@ -1,5 +1,5 @@
 SUMMARY = "Recipe with an alias of an SPDX license"
 DESCRIPTION = "Is licensed with an alias of an SPDX license to be used for testing"
-LICENSE = "GPLv3"
+LICENSE = "GPL-3.0-only"
 
 EXCLUDE_FROM_WORLD = "1"
diff --git a/meta-selftest/recipes-test/license/incompatible-licenses.bb b/meta-selftest/recipes-test/license/incompatible-licenses.bb
index 47bd8d7c00..2e73ac6407 100644
--- a/meta-selftest/recipes-test/license/incompatible-licenses.bb
+++ b/meta-selftest/recipes-test/license/incompatible-licenses.bb
@@ -1,5 +1,5 @@
 SUMMARY = "Recipe with multiple SPDX licenses"
 DESCRIPTION = "Is licensed with multiple SPDX licenses to be used for testing"
-LICENSE = "GPL-2.0-only & GPL-3.0-only & LGPL-3.0-only"
+LICENSE = "GPL-2.0-only AND GPL-3.0-only AND LGPL-3.0-only"
 
 EXCLUDE_FROM_WORLD = "1"
diff --git a/meta-selftest/recipes-test/license/incompatible-nonspdx-license.bb b/meta-selftest/recipes-test/license/incompatible-nonspdx-license.bb
index 128f313e1f..4c9c3bb308 100644
--- a/meta-selftest/recipes-test/license/incompatible-nonspdx-license.bb
+++ b/meta-selftest/recipes-test/license/incompatible-nonspdx-license.bb
@@ -1,6 +1,6 @@
 SUMMARY = "Recipe with a non-SPDX license"
 DESCRIPTION = "Is licensed with a non-SPDX license to be used for testing"
-LICENSE = "FooLicense"
+LICENSE = "LicenseRef-FooLicense"
 NO_GENERIC_LICENSE[FooLicense] = "LICENSE"
 
 EXCLUDE_FROM_WORLD = "1"
diff --git a/meta/recipes-bsp/alsa-state/alsa-state.bb b/meta/recipes-bsp/alsa-state/alsa-state.bb
index 9452a1a4ce..8e93c564a6 100644
--- a/meta/recipes-bsp/alsa-state/alsa-state.bb
+++ b/meta/recipes-bsp/alsa-state/alsa-state.bb
@@ -8,7 +8,7 @@ SUMMARY = "Alsa scenario files to enable alsa state restoration"
 HOMEPAGE = "http://www.alsa-project.org/"
 DESCRIPTION = "Alsa Scenario Files - an init script and state files to restore \
 sound state at system boot and save it at system shut down."
-LICENSE = "MIT & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND MIT"
 LIC_FILES_CHKSUM = " \
     file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420 \
     file://alsa-state-init;beginline=3;endline=4;md5=3ff7ecbf534d7d503941abe8e268ef50 \
diff --git a/meta/recipes-bsp/gnu-efi/gnu-efi_4.0.4.bb b/meta/recipes-bsp/gnu-efi/gnu-efi_4.0.4.bb
index 0f493b8414..9075487b92 100644
--- a/meta/recipes-bsp/gnu-efi/gnu-efi_4.0.4.bb
+++ b/meta/recipes-bsp/gnu-efi/gnu-efi_4.0.4.bb
@@ -2,7 +2,7 @@ SUMMARY = "Libraries for producing EFI binaries"
 HOMEPAGE = "http://sourceforge.net/projects/gnu-efi/"
 DESCRIPTION = "GNU-EFI aims to Develop EFI applications for ARM-64, ARM-32, x86_64, IA-64 (IPF), IA-32 (x86), and MIPS platforms using the GNU toolchain and the EFI development environment."
 SECTION = "devel"
-LICENSE = "GPL-2.0-or-later & BSD-2-Clause"
+LICENSE = "BSD-2-Clause AND GPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://gnuefi/crt0-efi-arm.S;beginline=4;endline=16;md5=8b0a86085b86eda7a3c7e8a1eb7ec753 \
                     file://gnuefi/crt0-efi-aarch64.S;beginline=4;endline=16;md5=8b0a86085b86eda7a3c7e8a1eb7ec753 \
                     file://inc/efishellintf.h;beginline=13;endline=20;md5=ee14c1530c341a7050837adead6bc9a5 \
diff --git a/meta/recipes-bsp/usbutils/usbutils_019.bb b/meta/recipes-bsp/usbutils/usbutils_019.bb
index 6aa5c5f5c2..164445ac4e 100644
--- a/meta/recipes-bsp/usbutils/usbutils_019.bb
+++ b/meta/recipes-bsp/usbutils/usbutils_019.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Contains the lsusb utility for inspecting the devices connected t
 HOMEPAGE = "http://www.linux-usb.org"
 SECTION = "base"
 
-LICENSE = "GPL-2.0-or-later & (GPL-2.0-only | GPL-3.0-only) & CC0-1.0 & LGPL-2.1-or-later & MIT"
+LICENSE = "CC0-1.0 AND GPL-2.0-or-later AND LGPL-2.1-or-later AND MIT AND (GPL-2.0-only OR GPL-3.0-only)"
 LIC_FILES_CHKSUM = "file://LICENSES/CC0-1.0.txt;md5=cf1af55fc6f5b9a23e12086005298dcd \
 		    file://LICENSES/GPL-2.0-only.txt;md5=c89d4ad08368966d8df5a90ea96bebe4 \
 		    file://LICENSES/GPL-2.0-or-later.txt;md5=c89d4ad08368966d8df5a90ea96bebe4 \
@@ -25,7 +25,7 @@ ALTERNATIVE_PRIORITY = "100"
 # The binaries are mostly GPL-2.0-or-later apart from lsusb.py which is
 # GPL-2.0-only or GPL-3.0-only.
 LICENSE:${PN} = "GPL-2.0-or-later"
-LICENSE:${PN}-python = "GPL-2.0-only | GPL-3.0-only"
+LICENSE:${PN}-python = "GPL-2.0-only OR GPL-3.0-only"
 
 RRECOMMENDS:${PN} = "udev-hwdb"
 
diff --git a/meta/recipes-connectivity/avahi/avahi_0.9.bb b/meta/recipes-connectivity/avahi/avahi_0.9.bb
index 308ddc1822..7cf0eb2b71 100644
--- a/meta/recipes-connectivity/avahi/avahi_0.9.bb
+++ b/meta/recipes-connectivity/avahi/avahi_0.9.bb
@@ -11,7 +11,7 @@ SECTION = "network"
 
 # major part is under LGPL-2.1-or-later, but several .dtd, .xsl, initscripts and
 # python scripts are under GPL-2.0-or-later
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=2d5025d4aa3495befef8f17206a5b0a1 \
                     file://avahi-common/address.h;endline=25;md5=b1d1d2cda1c07eb848ea7d6215712d9d \
                     file://avahi-core/dns.h;endline=23;md5=6fe82590b81aa0ddea5095b548e2fdcb \
diff --git a/meta/recipes-connectivity/bluez5/bluez5.inc b/meta/recipes-connectivity/bluez5/bluez5.inc
index 6a98d769dd..a1f20f4432 100644
--- a/meta/recipes-connectivity/bluez5/bluez5.inc
+++ b/meta/recipes-connectivity/bluez5/bluez5.inc
@@ -2,7 +2,7 @@ SUMMARY = "Linux Bluetooth Stack Userland V5"
 DESCRIPTION = "Linux Bluetooth stack V5 userland components.  These include a system configurations, daemons, tools and system libraries."
 HOMEPAGE = "http://www.bluez.org"
 SECTION = "libs"
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e \
                     file://COPYING.LIB;md5=fb504b67c50331fc78734fed90fb0e09 \
                     file://src/main.c;beginline=1;endline=24;md5=0ad83ca0dc37ab08af448777c581e7ac"
diff --git a/meta/recipes-connectivity/connman/connman-gnome_0.7.bb b/meta/recipes-connectivity/connman/connman-gnome_0.7.bb
index 8bfc1540b3..0c6e823ea2 100644
--- a/meta/recipes-connectivity/connman/connman-gnome_0.7.bb
+++ b/meta/recipes-connectivity/connman/connman-gnome_0.7.bb
@@ -1,7 +1,7 @@
 SUMMARY = "GTK+ frontend for the ConnMan network connection manager"
 HOMEPAGE = "http://connman.net/"
 SECTION = "libs/network"
-LICENSE = "GPL-2.0-only & LGPL-2.1-only"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=eb723b61539feef013de476e68b5c50a \
                     file://properties/main.c;beginline=1;endline=20;md5=50c77c81871308b033ab7a1504626afb \
                     file://common/connman-dbus.c;beginline=1;endline=20;md5=de6b485c0e717a0236402d220187717a"
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils_2.9.1.bb b/meta/recipes-connectivity/nfs-utils/nfs-utils_2.9.1.bb
index 6f00bee0d8..06e4fcb6e0 100644
--- a/meta/recipes-connectivity/nfs-utils/nfs-utils_2.9.1.bb
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils_2.9.1.bb
@@ -4,7 +4,7 @@ NFS server and related tools."
 HOMEPAGE = "http://nfs.sourceforge.net/"
 SECTION = "console/network"
 
-LICENSE = "MIT & GPL-2.0-or-later & BSD-3-Clause"
+LICENSE = "BSD-3-Clause AND GPL-2.0-or-later AND MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=95f3a93a5c3c7888de623b46ea085a84"
 
 # util-linux for libblkid
diff --git a/meta/recipes-connectivity/openssh/openssh_10.4p1.bb b/meta/recipes-connectivity/openssh/openssh_10.4p1.bb
index da08a97fca..f8cedb8c8e 100644
--- a/meta/recipes-connectivity/openssh/openssh_10.4p1.bb
+++ b/meta/recipes-connectivity/openssh/openssh_10.4p1.bb
@@ -5,7 +5,7 @@ Ssh (Secure Shell) is a program for logging into a remote machine \
 and for executing commands on a remote machine."
 HOMEPAGE = "http://www.openssh.com/"
 SECTION = "console/network"
-LICENSE = "BSD-2-Clause & BSD-3-Clause & ISC & MIT"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT"
 LIC_FILES_CHKSUM = "file://LICENCE;md5=78ffb36e5a48c0d8c5648603a3b6c8eb"
 
 DEPENDS = "zlib openssl virtual/crypt"
diff --git a/meta/recipes-connectivity/ppp/ppp_2.5.3.bb b/meta/recipes-connectivity/ppp/ppp_2.5.3.bb
index 88217f03b1..3718fabbe8 100644
--- a/meta/recipes-connectivity/ppp/ppp_2.5.3.bb
+++ b/meta/recipes-connectivity/ppp/ppp_2.5.3.bb
@@ -5,7 +5,7 @@ SECTION = "console/network"
 HOMEPAGE = "http://samba.org/ppp/"
 BUGTRACKER = "http://ppp.samba.org/cgi-bin/ppp-bugs"
 DEPENDS = "libpcap virtual/crypt"
-LICENSE = "BSD-2-Clause & GPL-2.0-or-later & LGPL-2.0-or-later & RSA-MD & MIT"
+LICENSE = "BSD-2-Clause AND GPL-2.0-or-later AND LGPL-2.0-or-later AND MIT AND RSA-MD"
 LIC_FILES_CHKSUM = "file://pppd/ccp.c;beginline=1;endline=25;md5=f0463bd67ae70535c709fca554089bd8 \
                     file://pppd/tdb.c;beginline=1;endline=27;md5=4ca3a9991b011038d085d6675ae7c4e6 \
                     file://chat/chat.c;beginline=1;endline=1;md5=234d7d4edd08962c0144e4604050e0b6 \
diff --git a/meta/recipes-connectivity/slirp/libslirp_4.9.3.bb b/meta/recipes-connectivity/slirp/libslirp_4.9.3.bb
index 734e59a59b..a13b4b55ab 100644
--- a/meta/recipes-connectivity/slirp/libslirp_4.9.3.bb
+++ b/meta/recipes-connectivity/slirp/libslirp_4.9.3.bb
@@ -1,7 +1,7 @@
 SUMMARY = "A general purpose TCP-IP emulator"
 DESCRIPTION = "A general purpose TCP-IP emulator used by virtual machine hypervisors to provide virtual networking services."
 HOMEPAGE = "https://gitlab.freedesktop.org/slirp/libslirp"
-LICENSE = "BSD-3-Clause & MIT"
+LICENSE = "BSD-3-Clause AND MIT"
 LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=f95a9bf4a7e411164fe843697ccda59e \
                     file://LICENSE;md5=cfea6044642fd63b90ce9d79f5db64d9"
 
diff --git a/meta/recipes-connectivity/socat/socat_1.8.1.3.bb b/meta/recipes-connectivity/socat/socat_1.8.1.3.bb
index 636c75b117..e485c7d28d 100644
--- a/meta/recipes-connectivity/socat/socat_1.8.1.3.bb
+++ b/meta/recipes-connectivity/socat/socat_1.8.1.3.bb
@@ -5,7 +5,8 @@ HOMEPAGE = "http://www.dest-unreach.org/socat/"
 
 SECTION = "console/network"
 
-LICENSE = "GPL-2.0-with-OpenSSL-exception"
+# https://github.com/spdx/license-list-XML/issues/3009
+LICENSE = "LicenseRef-GPL-2.0-with-OpenSSL-exception"
 LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
                     file://README;beginline=252;endline=282;md5=338c05eadd013872abb1d6e198e10a3f"
 
diff --git a/meta/recipes-core/busybox/busybox.inc b/meta/recipes-core/busybox/busybox.inc
index bacbe7616d..6d4c9fb28a 100644
--- a/meta/recipes-core/busybox/busybox.inc
+++ b/meta/recipes-core/busybox/busybox.inc
@@ -8,7 +8,7 @@ DEPENDS += "${@bb.utils.contains('DISTRO_FEATURES', 'selinux', 'libselinux', '',
 
 # bzip2 applet in busybox is based on lightly-modified bzip2-1.0.4 source
 # the GPL is version 2 only
-LICENSE = "GPL-2.0-only & bzip2-1.0.6"
+LICENSE = "GPL-2.0-only AND bzip2-1.0.6"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=de10de48642ab74318e893a61105afbb \
                     file://archival/libarchive/bz/LICENSE;md5=28e3301eae987e8cfe19988e98383dae"
 
diff --git a/meta/recipes-core/dbus/dbus-glib_0.114.bb b/meta/recipes-core/dbus/dbus-glib_0.114.bb
index cc15cafe49..c6824d5688 100644
--- a/meta/recipes-core/dbus/dbus-glib_0.114.bb
+++ b/meta/recipes-core/dbus/dbus-glib_0.114.bb
@@ -2,7 +2,7 @@ SUMMARY = "High level language (GLib) binding for D-Bus"
 DESCRIPTION = "GLib bindings for the D-Bus message bus that integrate \
 the D-Bus library with the GLib thread abstraction and main loop."
 HOMEPAGE = "https://www.freedesktop.org/Software/dbus"
-LICENSE = "(AFL-2.1 & LGPL-2.0-or-later & MIT) | (GPL-2.0-or-later & LGPL-2.0-or-later & MIT)"
+LICENSE = "AFL-2.1 AND LGPL-2.0-or-later AND MIT OR GPL-2.0-or-later AND LGPL-2.0-or-later AND MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=267b04646da5ce3ea2df7a38a07c3f0b \
                     file://LICENSES/AFL-2.1.txt;md5=f3ad2f482ec639b440413665cfb9e714 \
                     file://LICENSES/GPL-2.0-or-later.txt;md5=3d26203303a722dedc6bf909d95ba815 \
diff --git a/meta/recipes-core/dbus/dbus_1.16.2.bb b/meta/recipes-core/dbus/dbus_1.16.2.bb
index 7425bd2364..bfb0f22f95 100644
--- a/meta/recipes-core/dbus/dbus_1.16.2.bb
+++ b/meta/recipes-core/dbus/dbus_1.16.2.bb
@@ -5,7 +5,7 @@ SECTION = "base"
 
 inherit meson pkgconfig gettext upstream-version-is-even ptest-gnome
 
-LICENSE = "AFL-2.1 | GPL-2.0-or-later"
+LICENSE = "AFL-2.1 OR GPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=eb0ffc69a965797a3d6686baa153ef05 \
                     file://dbus/dbus.h;beginline=6;endline=22;md5=df4251a6c6e15e6a9e3c77b2ac30065d \
                     "
diff --git a/meta/recipes-core/dropbear/dropbear_2026.92.bb b/meta/recipes-core/dropbear/dropbear_2026.92.bb
index 44a4dcde03..4d9a9e10eb 100644
--- a/meta/recipes-core/dropbear/dropbear_2026.92.bb
+++ b/meta/recipes-core/dropbear/dropbear_2026.92.bb
@@ -6,7 +6,7 @@ SECTION = "console/network"
 # some files are from other projects and have others license terms:
 #   public domain, OpenSSH 3.5p1, OpenSSH3.6.1p2, PuTTY
 # The 'public-domain' file is headered as MIT
-LICENSE = "MIT & BSD-3-Clause & BSD-2-Clause & WTFPL & Unlicense"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause AND MIT AND Unlicense AND WTFPL"
 LIC_FILES_CHKSUM = " \
     file://LICENSE;md5=25cf44512b7bc8966a48b6b1a9b7605f \
     file://libtomcrypt/LICENSE;md5=71baacc459522324ef3e2b9e052e8180 \
diff --git a/meta/recipes-core/gettext/gettext_1.0.bb b/meta/recipes-core/gettext/gettext_1.0.bb
index 8a11a55570..696fcc3bb7 100644
--- a/meta/recipes-core/gettext/gettext_1.0.bb
+++ b/meta/recipes-core/gettext/gettext_1.0.bb
@@ -4,7 +4,7 @@ These tools include a set of conventions about how programs should be written to
 naming organization for the message catalogs themselves, a runtime library supporting the retrieval of translated messages, and \
 a few stand-alone programs to massage in various ways the sets of translatable and already translated strings."
 SECTION = "libs"
-LICENSE = "GPL-3.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-3.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=c678957b0c8e964aa6c70fd77641a71e"
 
 # without libxml in PACKAGECONFIG vendor copy of the lib will be used
diff --git a/meta/recipes-core/glib-2.0/glib.inc b/meta/recipes-core/glib-2.0/glib.inc
index d49ae13168..fafb7e3391 100644
--- a/meta/recipes-core/glib-2.0/glib.inc
+++ b/meta/recipes-core/glib-2.0/glib.inc
@@ -4,7 +4,7 @@ HOMEPAGE = "https://developer.gnome.org/glib/"
 
 # pcre is under BSD;
 # docs/reference/COPYING is with a 'public domain'-like license!
-LICENSE = "LGPL-2.1-or-later & BSD-3-Clause & GCR-docs"
+LICENSE = "BSD-3-Clause AND GCR-docs AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=41890f71f740302b785c27661123bff5 \
                     file://glib/glib.h;beginline=4;endline=17;md5=72f7cc2847407f65d8981ef112e4e630 \
                     file://LICENSES/LGPL-2.1-or-later.txt;md5=41890f71f740302b785c27661123bff5 \
diff --git a/meta/recipes-core/glibc/glibc-common.inc b/meta/recipes-core/glibc/glibc-common.inc
index 2eedd2950e..4722440447 100644
--- a/meta/recipes-core/glibc/glibc-common.inc
+++ b/meta/recipes-core/glibc/glibc-common.inc
@@ -2,7 +2,7 @@ SUMMARY = "GLIBC (GNU C Library)"
 DESCRIPTION = "The GNU C Library is used as the system C library in most systems with the Linux kernel."
 HOMEPAGE = "http://www.gnu.org/software/libc/libc.html"
 SECTION = "libs"
-LICENSE = "GPL-2.0-only & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-or-later"
 
 LIC_FILES_CHKSUM ?= "file://LICENSES;md5=df6e0948b55669789c30764c5fd9bc41 \
       file://COPYINGv2;md5=570a9b3749dd0463a1778803b12a6dce \
diff --git a/meta/recipes-core/initscripts/init-system-helpers_1.69.bb b/meta/recipes-core/initscripts/init-system-helpers_1.69.bb
index c4843747b7..50fa17befb 100644
--- a/meta/recipes-core/initscripts/init-system-helpers_1.69.bb
+++ b/meta/recipes-core/initscripts/init-system-helpers_1.69.bb
@@ -13,7 +13,7 @@ specific to systemd at all. Maintainers of other init systems are welcome to \
 include their helpers in this package."
 HOMEPAGE = "https://salsa.debian.org/debian/init-system-helpers"
 SECTION = "base"
-LICENSE = "BSD-3-Clause & GPL-2.0-only"
+LICENSE = "BSD-3-Clause AND GPL-2.0-only"
 LIC_FILES_CHKSUM = "file://debian/copyright;md5=c4ec20aa158fa9de26ee1accf78dcaae"
 
 SRCREV = "592518fcedf96c9b763f214a9acbdc1109aaa385"
diff --git a/meta/recipes-core/kbd/kbd_2.10.0.bb b/meta/recipes-core/kbd/kbd_2.10.0.bb
index 5a877b9c04..fbdc1c3c19 100644
--- a/meta/recipes-core/kbd/kbd_2.10.0.bb
+++ b/meta/recipes-core/kbd/kbd_2.10.0.bb
@@ -3,12 +3,12 @@ HOMEPAGE = "http://www.kbd-project.org/"
 DESCRIPTION = "The kbd project contains tools for managing Linux console (Linux console, virtual terminals, keyboard, etc.) - mainly, what they do is loading console fonts and keyboard maps."
 
 # consolefonts and keymaps contain also some public domain and author notice licenses
-LICENSE = "GPL-2.0-or-later & LGPL-2.0-or-later & GPL-3.0-or-later"
+LICENSE = "GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-2.0-or-later"
 LIC_FILES_CHKSUM = " \
     file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
     file://data/keymaps/pine/en.map;beginline=2;endline=15;md5=20914a59c0546a7b77ebf959bc88ad5d \
 "
-LICENSE:${PN} = "GPL-2.0-or-later & LGPL-2.0-or-later"
+LICENSE:${PN} = "GPL-2.0-or-later AND LGPL-2.0-or-later"
 LICENSE:${PN}-consolefonts = "GPL-2.0-or-later"
 LICENSE:${PN}-consoletrans = "GPL-2.0-or-later"
 LICENSE:${PN}-keymaps-pine = "GPL-3.0-or-later"
diff --git a/meta/recipes-core/libxcrypt/libxcrypt.inc b/meta/recipes-core/libxcrypt/libxcrypt.inc
index a86735255f..0a51851bf9 100644
--- a/meta/recipes-core/libxcrypt/libxcrypt.inc
+++ b/meta/recipes-core/libxcrypt/libxcrypt.inc
@@ -2,7 +2,7 @@ SUMMARY = "Extended cryptographic library (from glibc)"
 DESCRIPTION = "Forked code from glibc libary to extract only crypto part."
 HOMEPAGE = "https://github.com/besser82/libxcrypt"
 SECTION = "libs"
-LICENSE = "LGPL-2.1-only & 0BSD & BSD-3-Clause"
+LICENSE = "0BSD AND BSD-3-Clause AND LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://LICENSING;md5=b65434749329c34b5d32c2df3f1b4112 \
                     file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c \
                     "
diff --git a/meta/recipes-core/musl/bsd-headers.bb b/meta/recipes-core/musl/bsd-headers.bb
index ad9ba81e4f..3a3d37be7d 100644
--- a/meta/recipes-core/musl/bsd-headers.bb
+++ b/meta/recipes-core/musl/bsd-headers.bb
@@ -2,7 +2,7 @@
 # Released under the MIT license (see COPYING.MIT for the terms)
 
 SUMMARY = "BSD compatible headers"
-LICENSE = "BSD-3-Clause & BSD-2-Clause"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://sys-queue.h;beginline=1;endline=32;md5=c6352b0f03bb448600456547d334b56f"
 SECTION = "devel"
 
diff --git a/meta/recipes-core/musl/musl-locales_git.bb b/meta/recipes-core/musl/musl-locales_git.bb
index f8369509e7..3485b0781e 100644
--- a/meta/recipes-core/musl/musl-locales_git.bb
+++ b/meta/recipes-core/musl/musl-locales_git.bb
@@ -3,7 +3,7 @@
 #
 SUMMARY = "Locales support for musl"
 HOMEPAGE = "https://git.adelielinux.org/adelie/musl-locales/-/wikis/home"
-LICENSE = "MIT & LGPL-3.0-or-later"
+LICENSE = "LGPL-3.0-or-later AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=cf5713fba707073020b1db2acaa73e78 \
                     file://LICENSE.MIT;md5=a4f1c6864a83ddf4b754cdab7d593523"
 
diff --git a/meta/recipes-core/musl/musl-utils.bb b/meta/recipes-core/musl/musl-utils.bb
index 4b685640c8..9a49820a3c 100644
--- a/meta/recipes-core/musl/musl-utils.bb
+++ b/meta/recipes-core/musl/musl-utils.bb
@@ -3,7 +3,7 @@
 
 SUMMARY = "getconf, getent and iconv implementations for musl"
 HOMEPAGE = "https://git.alpinelinux.org/cgit/aports/tree/main/musl"
-LICENSE = "BSD-2-Clause & GPL-2.0-or-later"
+LICENSE = "BSD-2-Clause AND GPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=9d08215e611db87b357e8674b4b42564"
 SECTION = "utils"
 
diff --git a/meta/recipes-core/newlib/newlib.inc b/meta/recipes-core/newlib/newlib.inc
index 56e9eeb099..4336f1bfdb 100644
--- a/meta/recipes-core/newlib/newlib.inc
+++ b/meta/recipes-core/newlib/newlib.inc
@@ -3,7 +3,7 @@ HOMEPAGE = "https://sourceware.org/newlib/"
 DESCRIPTION = "C library intended for use on embedded systems. It is a conglomeration of several library parts, all under free software licenses that make them easily usable on embedded products."
 SECTION = "libs"
 
-LICENSE = "GPL-2.0-only & LGPL-3.0-only & GPL-3.0-only & LGPL-2.0-only & BSD-2-Clause & BSD-3-Clause & TCL & Apache-2.0-with-LLVM-exception"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause AND GPL-2.0-only AND GPL-3.0-only AND LGPL-2.0-only AND LGPL-3.0-only AND TCL AND Apache-2.0 WITH LLVM-exception"
 LIC_FILES_CHKSUM = " \
 		file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
 		file://COPYING3.LIB;md5=6a6a8e020838b23406c81b19c1d46df6 \
diff --git a/meta/recipes-core/picolibc/picolibc.inc b/meta/recipes-core/picolibc/picolibc.inc
index ffbc90b660..750098ca60 100644
--- a/meta/recipes-core/picolibc/picolibc.inc
+++ b/meta/recipes-core/picolibc/picolibc.inc
@@ -5,7 +5,7 @@ SECTION = "libs"
 
 # Newlib based code but GPL related bits removed, test/printf-tests.c and test/testcases.c
 # are GPLv2 and GeneratePicolibcCrossFile.sh is AGPL3 but not part of the artifacts.
-LICENSE = "BSD-2-Clause & BSD-3-Clause"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause"
 LIC_FILES_CHKSUM = " \
 		file://COPYING.picolibc;md5=e44132dded508048efb22b15ccd40d7d \
 		"
diff --git a/meta/recipes-core/sysfsutils/sysfsutils_2.1.1.bb b/meta/recipes-core/sysfsutils/sysfsutils_2.1.1.bb
index 5040d8864e..f1975e46a6 100644
--- a/meta/recipes-core/sysfsutils/sysfsutils_2.1.1.bb
+++ b/meta/recipes-core/sysfsutils/sysfsutils_2.1.1.bb
@@ -2,7 +2,7 @@ SUMMARY = "Tools for working with sysfs"
 DESCRIPTION = "Tools for working with the sysfs virtual filesystem.  The tool 'systool' can query devices by bus, class and topology."
 HOMEPAGE = "http://linux-diag.sourceforge.net/Sysfsutils.html"
 
-LICENSE = "GPL-2.0-only & LGPL-2.1-only"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-only"
 LICENSE:${PN} = "GPL-2.0-only"
 LICENSE:libsysfs = "LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=dcc19fa9307a50017fca61423a7d9754 \
diff --git a/meta/recipes-core/systemd/systemd.inc b/meta/recipes-core/systemd/systemd.inc
index f107c4c5da..efd7826684 100644
--- a/meta/recipes-core/systemd/systemd.inc
+++ b/meta/recipes-core/systemd/systemd.inc
@@ -10,7 +10,7 @@ state, maintains mount and automount points and implements an \
 elaborate transactional dependency-based service control logic. It can \
 work as a drop-in replacement for sysvinit."
 
-LICENSE = "GPL-2.0-only & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-or-later"
 LICENSE:libsystemd = "LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://LICENSE.GPL2;md5=c09786363500a9acc29b147e6e72d2c6 \
                     file://LICENSE.LGPL2.1;md5=be0aaf4a380f73f7e00b420a007368f2"
diff --git a/meta/recipes-core/udev/eudev_3.2.14.bb b/meta/recipes-core/udev/eudev_3.2.14.bb
index a2d222e655..3e4972694a 100644
--- a/meta/recipes-core/udev/eudev_3.2.14.bb
+++ b/meta/recipes-core/udev/eudev_3.2.14.bb
@@ -1,7 +1,7 @@
 SUMMARY = "eudev is a fork of systemd's udev"
 HOMEPAGE = "https://github.com/eudev-project/eudev"
 DESCRIPTION = "eudev is Gentoo's fork of udev, systemd's device file manager for the Linux kernel. It manages device nodes in /dev and handles all user space actions when adding or removing devices."
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LICENSE:libudev = "LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
 
diff --git a/meta/recipes-core/util-linux/util-linux_2.42.2.bb b/meta/recipes-core/util-linux/util-linux_2.42.2.bb
index b3d466dc80..65577e6e6c 100644
--- a/meta/recipes-core/util-linux/util-linux_2.42.2.bb
+++ b/meta/recipes-core/util-linux/util-linux_2.42.2.bb
@@ -7,37 +7,37 @@ LIBCOMMON_LICENSES = "LGPL-2.1-or-later AND BSD-2-Clause AND BSD-3-Clause AND MI
 # The default license is GPL-2.0-or-later
 DEFAULT_LICENSES = "GPL-2.0-or-later AND ${LIBCOMMON_LICENSES}"
 
-LICENSE = "GPL-1.0-or-later & GPL-2.0-only & GPL-2.0-or-later & LGPL-2.1-or-later & BSD-2-Clause & BSD-3-Clause & BSD-4-Clause-UC & MIT & EUPL-1.2"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause AND BSD-4-Clause-UC AND EUPL-1.2 AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.1-or-later AND MIT"
 LICENSE:${PN}-bash-completion = "GPL-2.0-or-later"
 LICENSE:${PN}-dev = "${LIBCOMMON_LICENSES}"
 # All dynamic packages use ${DEFAULT_LICENSES} with the following exceptions
-LICENSE:${PN}-cal = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
-LICENSE:${PN}-col = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-cal = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-col = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
 LICENSE:${PN}-colcrt = "BSD-4-Clause-UC"
-LICENSE:${PN}-colrm = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
-LICENSE:${PN}-column = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
-LICENSE:${PN}-coresched = "EUPL-1.2 & ${LIBCOMMON_LICENSES}"
-LICENSE:${PN}-fdisk = "GPL-1.0-or-later & ${DEFAULT_LICENSES}"
+LICENSE:${PN}-colrm = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-column = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-coresched = "EUPL-1.2 AND ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-fdisk = "GPL-1.0-or-later AND ${DEFAULT_LICENSES}"
 LICENSE:${PN}-fsfreeze = "GPL-1.0-or-later"
-LICENSE:${PN}-hexdump = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
-LICENSE:${PN}-kill = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-hexdump = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-kill = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
 LICENSE:${PN}-libblkid = "${LIBCOMMON_LICENSES}"
 LICENSE:${PN}-libfdisk = "${LIBCOMMON_LICENSES}"
 LICENSE:${PN}-libmount = "${LIBCOMMON_LICENSES}"
 LICENSE:${PN}-libsmartcols = "${LIBCOMMON_LICENSES}"
-LICENSE:${PN}-logger = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-logger = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
 LICENSE:${PN}-look = "BSD-4-Clause-UC"
-LICENSE:${PN}-lscpu = "GPL-2.0-only & ${DEFAULT_LICENSES}"
-LICENSE:${PN}-mesg = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
-LICENSE:${PN}-nsenter = "GPL-2.0-only & ${DEFAULT_LICENSES}"
+LICENSE:${PN}-lscpu = "GPL-2.0-only AND ${DEFAULT_LICENSES}"
+LICENSE:${PN}-mesg = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-nsenter = "GPL-2.0-only AND ${DEFAULT_LICENSES}"
 LICENSE:${PN}-renice = "BSD-4-Clause-UC"
 LICENSE:${PN}-rev = "BSD-4-Clause-UC"
-LICENSE:${PN}-script = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-script = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
 LICENSE:${PN}-ul = "BSD-4-Clause-UC"
-LICENSE:${PN}-vipw = "BSD-4-Clause-UC & ${DEFAULT_LICENSES}"
-LICENSE:${PN}-wall = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
-LICENSE:${PN}-whereis = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
-LICENSE:${PN}-write = "BSD-4-Clause-UC & ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-vipw = "BSD-4-Clause-UC AND ${DEFAULT_LICENSES}"
+LICENSE:${PN}-wall = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-whereis = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
+LICENSE:${PN}-write = "BSD-4-Clause-UC AND ${LIBCOMMON_LICENSES}"
 
 LIC_FILES_CHKSUM = "file://README.licensing;md5=55e895a80bdd4ffc65e167a76d2e7569 \
                     file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
diff --git a/meta/recipes-devtools/btrfs-tools/btrfs-tools_7.0.bb b/meta/recipes-devtools/btrfs-tools/btrfs-tools_7.0.bb
index 72b5575703..912d20cae7 100644
--- a/meta/recipes-devtools/btrfs-tools/btrfs-tools_7.0.bb
+++ b/meta/recipes-devtools/btrfs-tools/btrfs-tools_7.0.bb
@@ -7,7 +7,7 @@ btrfs and an utility (btrfs-convert) to make a btrfs filesystem from an ext3."
 
 HOMEPAGE = "https://btrfs.wiki.kernel.org"
 
-LICENSE = "GPL-2.0-only & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = " \
     file://COPYING;md5=fcb02dc552a041dee27e4b85c7396067 \
     file://libbtrfsutil/COPYING;md5=4fbd65380cdd255951079008b364516c \
diff --git a/meta/recipes-devtools/ccache/ccache_4.13.6.bb b/meta/recipes-devtools/ccache/ccache_4.13.6.bb
index 789440f761..21bd193c20 100644
--- a/meta/recipes-devtools/ccache/ccache_4.13.6.bb
+++ b/meta/recipes-devtools/ccache/ccache_4.13.6.bb
@@ -6,7 +6,7 @@ Objective-C and Objective-C++."
 HOMEPAGE = "http://ccache.samba.org"
 SECTION = "devel"
 
-LICENSE = "GPL-3.0-or-later & MIT & BSL-1.0 & ISC"
+LICENSE = "BSL-1.0 AND GPL-3.0-or-later AND ISC AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE.adoc;md5=e89f26e9f97d14068047871bdb2b3118 \
                     file://src/third_party/cpp-httplib/httplib.h;endline=6;md5=663aca6f84e7d67ade228aad32afc0ea \
                     file://src/third_party/win32-compat/win32/mktemp.c;endline=17;md5=d287e9c1f1cd2bb2bd164490e1cf449a \
diff --git a/meta/recipes-devtools/cdrtools/cdrtools-native_3.01.bb b/meta/recipes-devtools/cdrtools/cdrtools-native_3.01.bb
index fb7c29e242..231f5cdd28 100644
--- a/meta/recipes-devtools/cdrtools/cdrtools-native_3.01.bb
+++ b/meta/recipes-devtools/cdrtools/cdrtools-native_3.01.bb
@@ -5,7 +5,7 @@ SUMMARY = "A set of tools for CD recording, including cdrecord"
 HOMEPAGE = "http://sourceforge.net/projects/cdrtools/"
 DESCRIPTION = "cdrecord tool is Highly portable CD/DVD/BluRay command line recording software."
 SECTION = "console/utils"
-LICENSE = "GPL-2.0-only & CDDL-1.0 & LGPL-2.1-or-later"
+LICENSE = "CDDL-1.0 AND GPL-2.0-only AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=32f68170be424c2cd64804337726b312"
 
 DEPENDS += "gnu-config-native"
diff --git a/meta/recipes-devtools/clang/common.inc b/meta/recipes-devtools/clang/common.inc
index 441ea099a9..4e9400757c 100644
--- a/meta/recipes-devtools/clang/common.inc
+++ b/meta/recipes-devtools/clang/common.inc
@@ -3,7 +3,7 @@ FILESEXTRAPATHS =. "${FILE_DIRNAME}/clang:"
 LIC_FILES_CHKSUM = "file://llvm/LICENSE.TXT;md5=${LLVMMD5SUM} \
                     file://clang/LICENSE.TXT;md5=${CLANGMD5SUM} \
 "
-LICENSE = "Apache-2.0-with-LLVM-exception"
+LICENSE = "Apache-2.0 WITH LLVM-exception"
 
 # Snapshot
 #RELEASE ?= "108df0694cc12fa496f63faa3a8762e7cc1a3b37"
diff --git a/meta/recipes-devtools/clang/llvm_git.bb b/meta/recipes-devtools/clang/llvm_git.bb
index 96ea383731..bfdf4cfcd9 100644
--- a/meta/recipes-devtools/clang/llvm_git.bb
+++ b/meta/recipes-devtools/clang/llvm_git.bb
@@ -3,7 +3,7 @@
 
 SUMMARY = "The LLVM Compiler Infrastructure"
 HOMEPAGE = "http://llvm.org"
-LICENSE = "Apache-2.0-with-LLVM-exception"
+LICENSE = "Apache-2.0 WITH LLVM-exception"
 SECTION = "devel"
 
 require common-clang.inc
diff --git a/meta/recipes-devtools/clang/nativesdk-clang-glue.bb b/meta/recipes-devtools/clang/nativesdk-clang-glue.bb
index d113b6cd9a..08a637924c 100644
--- a/meta/recipes-devtools/clang/nativesdk-clang-glue.bb
+++ b/meta/recipes-devtools/clang/nativesdk-clang-glue.bb
@@ -3,7 +3,7 @@
 
 SUMMARY = "SDK Cross compiler wrappers for LLVM based C/C++ compiler"
 HOMEPAGE = "http://clang.llvm.org/"
-LICENSE = "Apache-2.0-with-LLVM-exception"
+LICENSE = "Apache-2.0 WITH LLVM-exception"
 LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0-with-LLVM-exception;md5=0bcd48c3bdfef0c9d9fd17726e4b7dab"
 SECTION = "devel"
 
diff --git a/meta/recipes-devtools/debugedit/debugedit_5.3.bb b/meta/recipes-devtools/debugedit/debugedit_5.3.bb
index 7732dde52a..6b5f2aa99e 100644
--- a/meta/recipes-devtools/debugedit/debugedit_5.3.bb
+++ b/meta/recipes-devtools/debugedit/debugedit_5.3.bb
@@ -4,7 +4,7 @@ debuginfo and source file distributions, collect build-ids and rewrite \
 source paths in DWARF data for debugging, tracing and profiling."
 HOMEPAGE = "https://sourceware.org/debugedit/"
 
-LICENSE = "GPL-2.0-only & GPL-3.0-only & LGPL-2.1-only"
+LICENSE = "GPL-2.0-only AND GPL-3.0-only AND LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
                     file://COPYING.LIB;md5=2d5025d4aa3495befef8f17206a5b0a1 \
                     file://COPYING3;md5=d32239bcb673463ab874e80d47fae504"
diff --git a/meta/recipes-devtools/docbook-xml/docbook-xml-dtd4_4.5.bb b/meta/recipes-devtools/docbook-xml/docbook-xml-dtd4_4.5.bb
index ea0861823d..a53159bf1d 100644
--- a/meta/recipes-devtools/docbook-xml/docbook-xml-dtd4_4.5.bb
+++ b/meta/recipes-devtools/docbook-xml/docbook-xml-dtd4_4.5.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Document type definitions for verification of XML data \
 files against the DocBook rule set."
 HOMEPAGE = "https://docbook.org"
 
-LICENSE = "DocBook"
+LICENSE = "LicenseRef-DocBook"
 NO_GENERIC_LICENSE[DocBook] = "LICENSE-OASIS"
 
 LIC_FILES_CHKSUM = "file://docbook-4.5/docbookx.dtd;beginline=15;endline=30;md5=ab12da76ad94a41d04e1587693ebd9b6 \
diff --git a/meta/recipes-devtools/e2fsprogs/e2fsprogs.inc b/meta/recipes-devtools/e2fsprogs/e2fsprogs.inc
index cce6e5f1ac..e83e8b6afa 100644
--- a/meta/recipes-devtools/e2fsprogs/e2fsprogs.inc
+++ b/meta/recipes-devtools/e2fsprogs/e2fsprogs.inc
@@ -3,7 +3,7 @@ DESCRIPTION = "The Ext2 Filesystem Utilities (e2fsprogs) contain all of the stan
 fixing, configuring , and debugging ext2 filesystems."
 HOMEPAGE = "http://e2fsprogs.sourceforge.net/"
 
-LICENSE = "GPL-2.0-only & LGPL-2.0-only & BSD-3-Clause & MIT"
+LICENSE = "BSD-3-Clause AND GPL-2.0-only AND LGPL-2.0-only AND MIT"
 LICENSE:e2fsprogs-dumpe2fs = "GPL-2.0-only"
 LICENSE:e2fsprogs-e2fsck = "GPL-2.0-only"
 LICENSE:e2fsprogs-mke2fs = "GPL-2.0-only"
diff --git a/meta/recipes-devtools/elfutils/elfutils_0.195.bb b/meta/recipes-devtools/elfutils/elfutils_0.195.bb
index bfc648d69f..2093e1e924 100644
--- a/meta/recipes-devtools/elfutils/elfutils_0.195.bb
+++ b/meta/recipes-devtools/elfutils/elfutils_0.195.bb
@@ -2,7 +2,7 @@ SUMMARY = "Utilities and libraries for handling compiled object files"
 HOMEPAGE = "https://sourceware.org/elfutils"
 DESCRIPTION = "elfutils is a collection of utilities and libraries to read, create and modify ELF binary files, find and handle DWARF debug data, symbols, thread state and stacktraces for processes and core files on GNU/Linux."
 SECTION = "base"
-LICENSE = "( GPL-2.0-or-later | LGPL-3.0-or-later ) & GPL-3.0-or-later"
+LICENSE = "GPL-3.0-or-later AND (GPL-2.0-or-later OR LGPL-3.0-or-later)"
 LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504 \
                     file://debuginfod/debuginfod-client.c;endline=28;md5=6b7b0a4b25197d7f2e12b2f4aa1c86b8 \
                     "
@@ -120,10 +120,10 @@ PACKAGES =+ "${PN}-binutils libelf libasm libdw libdebuginfod"
 # are GPLv3+."
 LICENSE:${PN}-binutils = "GPL-3.0-or-later"
 LICENSE:${PN} = "GPL-3.0-or-later"
-LICENSE:libelf = "GPL-2.0-or-later | LGPL-3.0-or-later"
-LICENSE:libasm = "GPL-2.0-or-later | LGPL-3.0-or-later"
-LICENSE:libdw = "GPL-2.0-or-later | LGPL-3.0-or-later"
-LICENSE:libdebuginfod = "GPL-2.0-or-later | LGPL-3.0-or-later"
+LICENSE:libelf = "GPL-2.0-or-later OR LGPL-3.0-or-later"
+LICENSE:libasm = "GPL-2.0-or-later OR LGPL-3.0-or-later"
+LICENSE:libdw = "GPL-2.0-or-later OR LGPL-3.0-or-later"
+LICENSE:libdebuginfod = "GPL-2.0-or-later OR LGPL-3.0-or-later"
 
 FILES:${PN} += "${datadir}/fish"
 FILES:${PN}-binutils = "\
diff --git a/meta/recipes-devtools/erofs-utils/erofs-utils_1.9.2.bb b/meta/recipes-devtools/erofs-utils/erofs-utils_1.9.2.bb
index 801da3d6c9..3119627adf 100644
--- a/meta/recipes-devtools/erofs-utils/erofs-utils_1.9.2.bb
+++ b/meta/recipes-devtools/erofs-utils/erofs-utils_1.9.2.bb
@@ -1,5 +1,5 @@
 SUMMARY = "Tools for erofs filesystems"
-LICENSE = "(GPL-2.0-or-later | MIT) & MIT"
+LICENSE = "MIT AND (GPL-2.0-or-later OR MIT)"
 SECTION = "base"
 LIC_FILES_CHKSUM = "file://COPYING;md5=63afa010baddc7d0905f9c31ac759f51"
 HOMEPAGE = "https://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git/tree/README"
diff --git a/meta/recipes-devtools/expect/expect_5.45.4.bb b/meta/recipes-devtools/expect/expect_5.45.4.bb
index f24dd3b7c8..42b210ad97 100644
--- a/meta/recipes-devtools/expect/expect_5.45.4.bb
+++ b/meta/recipes-devtools/expect/expect_5.45.4.bb
@@ -8,7 +8,7 @@ structures to direct the dialogue. In addition, the user can take control and \
 interact directly when desired, afterward returning control to the script. \
 "
 HOMEPAGE = "http://sourceforge.net/projects/expect/"
-LICENSE = "PD"
+LICENSE = "LicenseRef-PD"
 SECTION = "devel"
 
 LIC_FILES_CHKSUM = "file://license.terms;md5=fbf2de7e9102505b1439db06fc36ce5c"
diff --git a/meta/recipes-devtools/fastfloat/fastfloat_8.2.10.bb b/meta/recipes-devtools/fastfloat/fastfloat_8.2.10.bb
index f537bab56c..3a5635bdeb 100644
--- a/meta/recipes-devtools/fastfloat/fastfloat_8.2.10.bb
+++ b/meta/recipes-devtools/fastfloat/fastfloat_8.2.10.bb
@@ -1,6 +1,6 @@
 SUMMARY = "fast_float number parsing library: 4x faster than strtod"
 HOMEPAGE = "https://github.com/fastfloat/fast_float"
-LICENSE = "Apache-2.0 & BSL-1.0 & MIT"
+LICENSE = "Apache-2.0 AND BSL-1.0 AND MIT"
 LIC_FILES_CHKSUM = " \
 	file://LICENSE-MIT;md5=32b11d50c7d9788d4270f6a83f3e68eb \
 	file://LICENSE-APACHE;md5=81db248e90379bcfc0582b578b009bc3 \
diff --git a/meta/recipes-devtools/flex/flex_2.6.4.bb b/meta/recipes-devtools/flex/flex_2.6.4.bb
index bbaa6f3998..ca040442af 100644
--- a/meta/recipes-devtools/flex/flex_2.6.4.bb
+++ b/meta/recipes-devtools/flex/flex_2.6.4.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Flex is a fast lexical analyser generator.  Flex is a tool for ge
 lexical patterns in text."
 HOMEPAGE = "http://sourceforge.net/projects/flex/"
 SECTION = "devel"
-LICENSE = "BSD-3-Clause & LGPL-2.0-or-later"
+LICENSE = "BSD-3-Clause AND LGPL-2.0-or-later"
 LICENSE:${PN}-libfl = "BSD-3-Clause"
 
 DEPENDS = "${@bb.utils.contains('PTEST_ENABLED', '1', 'bison-native flex-native', '', d)}"
diff --git a/meta/recipes-devtools/gcc/gcc-sanitizers.inc b/meta/recipes-devtools/gcc/gcc-sanitizers.inc
index 6c81d30243..db89a733de 100644
--- a/meta/recipes-devtools/gcc/gcc-sanitizers.inc
+++ b/meta/recipes-devtools/gcc/gcc-sanitizers.inc
@@ -1,6 +1,6 @@
 require gcc-configure-common.inc
 
-LICENSE = "NCSA | MIT"
+LICENSE = "MIT OR NCSA"
 
 LIC_FILES_CHKSUM = "\
     file://libsanitizer/LICENSE.TXT;md5=0249c37748936faf5b1efd5789587909 \
diff --git a/meta/recipes-devtools/gdb/gdb.inc b/meta/recipes-devtools/gdb/gdb.inc
index cbb5885459..52c6fc531e 100644
--- a/meta/recipes-devtools/gdb/gdb.inc
+++ b/meta/recipes-devtools/gdb/gdb.inc
@@ -1,4 +1,4 @@
-LICENSE = "GPL-2.0-only & GPL-3.0-only & LGPL-2.0-only & LGPL-3.0-only"
+LICENSE = "GPL-2.0-only AND GPL-3.0-only AND LGPL-2.0-only AND LGPL-3.0-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
 		    file://COPYING3;md5=d32239bcb673463ab874e80d47fae504 \
 		    file://COPYING3.LIB;md5=6a6a8e020838b23406c81b19c1d46df6 \
diff --git a/meta/recipes-devtools/git/git_2.55.0.bb b/meta/recipes-devtools/git/git_2.55.0.bb
index 9198bb06c9..426cc13371 100644
--- a/meta/recipes-devtools/git/git_2.55.0.bb
+++ b/meta/recipes-devtools/git/git_2.55.0.bb
@@ -2,7 +2,7 @@ SUMMARY = "Distributed version control system"
 HOMEPAGE = "http://git-scm.com"
 DESCRIPTION = "Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency."
 SECTION = "console/utils"
-LICENSE = "GPL-2.0-only & GPL-2.0-or-later & BSD-3-Clause & MIT & LGPL-2.1-or-later"
+LICENSE = "BSD-3-Clause AND GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.1-or-later AND MIT"
 DEPENDS = "openssl zlib"
 
 PROVIDES:append:class-native = " git-replacement-native"
diff --git a/meta/recipes-devtools/i2c-tools/i2c-tools_4.4.bb b/meta/recipes-devtools/i2c-tools/i2c-tools_4.4.bb
index 55d434ed21..2e1a37e0ec 100644
--- a/meta/recipes-devtools/i2c-tools/i2c-tools_4.4.bb
+++ b/meta/recipes-devtools/i2c-tools/i2c-tools_4.4.bb
@@ -2,7 +2,7 @@ SUMMARY = "Set of i2c tools for linux"
 HOMEPAGE = "https://i2c.wiki.kernel.org/index.php/I2C_Tools"
 DESCRIPTION = "The i2c-tools package contains a heterogeneous set of I2C tools for Linux: a bus probing tool, a chip dumper, register-level SMBus access helpers, EEPROM decoding scripts, EEPROM programming tools, and a python module for SMBus access. All versions of Linux are supported, as long as I2C support is included in the kernel."
 SECTION = "base"
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe \
                     file://COPYING.LGPL;md5=4fbd65380cdd255951079008b364516c"
 
diff --git a/meta/recipes-devtools/libtool/libtool-2.5.4.inc b/meta/recipes-devtools/libtool/libtool-2.5.4.inc
index 4d9a822de2..c646ed33d6 100644
--- a/meta/recipes-devtools/libtool/libtool-2.5.4.inc
+++ b/meta/recipes-devtools/libtool/libtool-2.5.4.inc
@@ -4,7 +4,7 @@ Libtool hides the complexity of generating special library types \
 (such as shared libraries) behind a consistent interface."
 HOMEPAGE = "http://www.gnu.org/software/libtool/libtool.html"
 SECTION = "devel"
-LICENSE = "GPL-2.0-only & LGPL-2.1-only"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=570a9b3749dd0463a1778803b12a6dce \
     file://libltdl/COPYING.LIB;md5=4bf661c1e3793e55c8d1051bc5e0ae21 "
 
diff --git a/meta/recipes-devtools/log4cplus/log4cplus_2.2.0.1.bb b/meta/recipes-devtools/log4cplus/log4cplus_2.2.0.1.bb
index 9ba83d8d64..a10dd175a2 100644
--- a/meta/recipes-devtools/log4cplus/log4cplus_2.2.0.1.bb
+++ b/meta/recipes-devtools/log4cplus/log4cplus_2.2.0.1.bb
@@ -4,7 +4,7 @@ HOMEPAGE = "https://github.com/log4cplus/log4cplus"
 DESCRIPTION = "log4cplus is a simple to use C++ logging API providing thread-safe, flexible, and arbitrarily granular control over log management and configuration. It is modelled after the Java log4j API."
 BUGTRACKER = "https://github.com/log4cplus/log4cplus/issues"
 
-LICENSE = "Apache-2.0 & BSD-2-Clause"
+LICENSE = "Apache-2.0 AND BSD-2-Clause"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=41e8e060c26822886b592ab4765c756b"
 
 # Replace dots with underscores to match GitHub's tag format (e.g., 2.2.0.1 -> REL_2_2_0_1)
diff --git a/meta/recipes-devtools/orc/orc_0.4.42.bb b/meta/recipes-devtools/orc/orc_0.4.42.bb
index 55b8db28aa..89e879e1cc 100644
--- a/meta/recipes-devtools/orc/orc_0.4.42.bb
+++ b/meta/recipes-devtools/orc/orc_0.4.42.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Optimised Inner Loop Runtime Compiler"
 HOMEPAGE = "http://gstreamer.freedesktop.org/modules/orc.html"
 DESCRIPTION = "Optimised Inner Loop Runtime Compiler is a Library and set of tools for compiling and executing SIMD assembly language-like programs that operate on arrays of data."
-LICENSE = "BSD-2-Clause & BSD-3-Clause"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://COPYING;md5=1400bd9d09e8af56b9ec982b3d85797e"
 
 SRC_URI = "http://gstreamer.freedesktop.org/src/orc/orc-${PV}.tar.xz"
diff --git a/meta/recipes-devtools/perl-cross/perlcross_1.6.4.bb b/meta/recipes-devtools/perl-cross/perlcross_1.6.4.bb
index bb6c1b908a..bc5bb4f4d7 100644
--- a/meta/recipes-devtools/perl-cross/perlcross_1.6.4.bb
+++ b/meta/recipes-devtools/perl-cross/perlcross_1.6.4.bb
@@ -3,7 +3,7 @@ HOMEPAGE = "https://github.com/arsv/perl-cross"
 DESCRIPTION = "perl-cross provides configure script, top-level Makefile and some auxiliary files for perl, \
 with the primary emphasis on cross-compiling the source."
 SECTION = "devel"
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 # README.md is taken from https://github.com/arsv/perl-cross/blob/master/README.md
 # but is not provided inside the release tarballs
 LIC_FILES_CHKSUM = "file://${UNPACKDIR}/README.md;md5=252fcce2026b765fee1ad74d2fb07a3b"
diff --git a/meta/recipes-devtools/perl/libmodule-build-perl_0.4234.bb b/meta/recipes-devtools/perl/libmodule-build-perl_0.4234.bb
index b27a8c15e6..1c01a59f5d 100644
--- a/meta/recipes-devtools/perl/libmodule-build-perl_0.4234.bb
+++ b/meta/recipes-devtools/perl/libmodule-build-perl_0.4234.bb
@@ -10,7 +10,7 @@ SECTION = "libs"
 
 HOMEPAGE = "https://metacpan.org/release/Module-Build"
 
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 LIC_FILES_CHKSUM = "file://README;beginline=881;endline=886;md5=3027f56c664545e54678c26b7f1ac19c"
 
 SRC_URI = "${CPAN_MIRROR}/authors/id/L/LE/LEONT/Module-Build-${PV}.tar.gz \
diff --git a/meta/recipes-devtools/perl/libtest-fatal-perl_0.018.bb b/meta/recipes-devtools/perl/libtest-fatal-perl_0.018.bb
index a128567ec7..68940567ac 100644
--- a/meta/recipes-devtools/perl/libtest-fatal-perl_0.018.bb
+++ b/meta/recipes-devtools/perl/libtest-fatal-perl_0.018.bb
@@ -5,7 +5,7 @@ exception-throwing code with about the same amount of typing."
 HOMEPAGE = "https://github.com/rjbs/Test-Fatal"
 BUGTRACKER = "https://github.com/rjbs/Test-Fatal/issues"
 SECTION = "libs"
-LICENSE = "Artistic-1.0-Perl | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0-Perl OR GPL-1.0-or-later"
 
 LIC_FILES_CHKSUM = "file://LICENSE;md5=f7fc7d4b26ddae0843b09ba56109e65a"
 
diff --git a/meta/recipes-devtools/perl/libtest-needs-perl_0.002010.bb b/meta/recipes-devtools/perl/libtest-needs-perl_0.002010.bb
index 0045e575af..fe437386b6 100644
--- a/meta/recipes-devtools/perl/libtest-needs-perl_0.002010.bb
+++ b/meta/recipes-devtools/perl/libtest-needs-perl_0.002010.bb
@@ -6,7 +6,7 @@ that are found but fail to compile will exit with an error rather than skip."
 
 HOMEPAGE = "https://metacpan.org/release/Test-Needs"
 SECTION = "libs"
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 
 CPAN_NAME = "Test-Needs"
 CPAN_AUTHOR = "HAARG"
diff --git a/meta/recipes-devtools/perl/libtest-warnings-perl_0.038.bb b/meta/recipes-devtools/perl/libtest-warnings-perl_0.038.bb
index 2eccf40999..58f819846f 100644
--- a/meta/recipes-devtools/perl/libtest-warnings-perl_0.038.bb
+++ b/meta/recipes-devtools/perl/libtest-warnings-perl_0.038.bb
@@ -9,7 +9,7 @@ demonstration.)"
 HOMEPAGE = "https://github.com/karenetheridge/Test-Warnings"
 BUGTRACKER = "https://rt.cpan.org/Public/Dist/Display.html?Name=Test-Warnings"
 SECTION = "libs"
-LICENSE = "Artistic-1.0-Perl | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0-Perl OR GPL-1.0-or-later"
 
 LIC_FILES_CHKSUM = "file://LICENCE;md5=f98106ac3cc05d9cbebcdb8fbf7b7815"
 
diff --git a/meta/recipes-devtools/perl/libxml-perl_0.08.bb b/meta/recipes-devtools/perl/libxml-perl_0.08.bb
index 728b606ed2..7f92f92436 100644
--- a/meta/recipes-devtools/perl/libxml-perl_0.08.bb
+++ b/meta/recipes-devtools/perl/libxml-perl_0.08.bb
@@ -5,7 +5,7 @@ XML::Grove and others."
 HOMEPAGE = "https://metacpan.org/dist/libxml-perl/"
 SUMMARY = "Collection of Perl modules for working with XML"
 SECTION = "libs"
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 
 LIC_FILES_CHKSUM = "file://README;beginline=33;endline=35;md5=1705549eef7577a3d6ba71123a1f0ce8"
 
diff --git a/meta/recipes-devtools/perl/libxml-simple-perl_2.25.bb b/meta/recipes-devtools/perl/libxml-simple-perl_2.25.bb
index f5fd2d3f0e..d4f0062cc6 100644
--- a/meta/recipes-devtools/perl/libxml-simple-perl_2.25.bb
+++ b/meta/recipes-devtools/perl/libxml-simple-perl_2.25.bb
@@ -6,7 +6,7 @@ on top of an underlying XML parsing module to maintain XML files \
 where the original uses plain Perl or SAX parsers."
 HOMEPAGE = "https://metacpan.org/release/MARKOV/XML-LibXML-Simple-0.93/view/lib/XML/LibXML/Simple.pod"
 SECTION = "libs"
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=cf206df8c9fe775f1d4c484386491eac"
 DEPENDS += "libxml-parser-perl"
 
diff --git a/meta/recipes-devtools/perl/perl_5.42.2.bb b/meta/recipes-devtools/perl/perl_5.42.2.bb
index f1f026579b..30e707df0a 100644
--- a/meta/recipes-devtools/perl/perl_5.42.2.bb
+++ b/meta/recipes-devtools/perl/perl_5.42.2.bb
@@ -2,7 +2,7 @@ SUMMARY = "Perl scripting language"
 HOMEPAGE = "http://www.perl.org/"
 DESCRIPTION = "Perl is a highly capable, feature-rich programming language"
 SECTION = "devel"
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 LIC_FILES_CHKSUM = "file://Copying;md5=8f7dd0873e59530abbb36503972afcdb \
                     file://Artistic;md5=71a4d5d9acc18c0952a6df2218bb68da \
                     "
diff --git a/meta/recipes-devtools/python/python-pycryptodome.inc b/meta/recipes-devtools/python/python-pycryptodome.inc
index 466da553e7..a0181874cd 100644
--- a/meta/recipes-devtools/python/python-pycryptodome.inc
+++ b/meta/recipes-devtools/python/python-pycryptodome.inc
@@ -2,7 +2,7 @@ SUMMARY = "Cryptographic library for Python"
 DESCRIPTION = "PyCryptodome is a self-contained Python package of low-level\
  cryptographic primitives."
 HOMEPAGE = "http://www.pycryptodome.org"
-LICENSE = "Unlicense & BSD-2-Clause"
+LICENSE = "BSD-2-Clause AND Unlicense"
 LIC_FILES_CHKSUM = "file://LICENSE.rst;md5=29242a70410a4eeff488a28164e7ab93"
 
 inherit pypi
diff --git a/meta/recipes-devtools/python/python3-cryptography-vectors.bb b/meta/recipes-devtools/python/python3-cryptography-vectors.bb
index fe4307a4d9..f5dd5757a4 100644
--- a/meta/recipes-devtools/python/python3-cryptography-vectors.bb
+++ b/meta/recipes-devtools/python/python3-cryptography-vectors.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Test vectors for the cryptography package."
 HOMEPAGE = "https://cryptography.io/"
 SECTION = "devel/python"
-LICENSE = "Apache-2.0 | BSD-3-Clause"
+LICENSE = "Apache-2.0 OR BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=8c3617db4fb6fae01f1d253ab91511e4 \
                     file://LICENSE.APACHE;md5=4e168cce331e5c827d4c2b68a6200e1b \
                     file://LICENSE.BSD;md5=5ae30ba4123bc4f2fa49aa0b0dce887b"
diff --git a/meta/recipes-devtools/python/python3-cryptography.bb b/meta/recipes-devtools/python/python3-cryptography.bb
index 4730c34997..aad95dfab8 100644
--- a/meta/recipes-devtools/python/python3-cryptography.bb
+++ b/meta/recipes-devtools/python/python3-cryptography.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Provides cryptographic recipes and primitives to python developers"
 HOMEPAGE = "https://cryptography.io/"
 SECTION = "devel/python"
-LICENSE = "Apache-2.0 | BSD-3-Clause"
+LICENSE = "Apache-2.0 OR BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=8c3617db4fb6fae01f1d253ab91511e4 \
                     file://LICENSE.APACHE;md5=4e168cce331e5c827d4c2b68a6200e1b \
                     file://LICENSE.BSD;md5=5ae30ba4123bc4f2fa49aa0b0dce887b \
diff --git a/meta/recipes-devtools/python/python3-docutils_0.23.bb b/meta/recipes-devtools/python/python3-docutils_0.23.bb
index 91592d470c..27ed6c5514 100644
--- a/meta/recipes-devtools/python/python3-docutils_0.23.bb
+++ b/meta/recipes-devtools/python/python3-docutils_0.23.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Docutils is a modular system for processing documentation into useful formats"
 HOMEPAGE = "http://docutils.sourceforge.net"
 SECTION = "devel/python"
-LICENSE = "CC0-1.0 & BSD-2-Clause & GPL-3.0-only"
+LICENSE = "BSD-2-Clause AND CC0-1.0 AND GPL-3.0-only"
 LIC_FILES_CHKSUM = "file://COPYING.rst;md5=ce467b04b35c7ac3429b6908fc8b318e"
 
 SRC_URI[sha256sum] = "746f5060322511280a1e50eb76846ed6bf2342984b2ac04dc42caa1a8d78799e"
@@ -11,6 +11,6 @@ inherit pypi python_flit_core
 RDEPENDS:${PN} += "python3-pprint"
 
 # We don't install the emacs lisp, which is the only piece of GPLv3
-LICENSE:${PN} = "CC0-1.0 & BSD-2-Clause"
+LICENSE:${PN} = "BSD-2-Clause AND CC0-1.0"
 
 BBCLASSEXTEND = "native nativesdk"
diff --git a/meta/recipes-devtools/python/python3-dtc_1.8.1.bb b/meta/recipes-devtools/python/python3-dtc_1.8.1.bb
index 314107883f..1576b233eb 100644
--- a/meta/recipes-devtools/python/python3-dtc_1.8.1.bb
+++ b/meta/recipes-devtools/python/python3-dtc_1.8.1.bb
@@ -2,7 +2,7 @@ SUMMARY = "Python Library for the Device Tree Compiler"
 HOMEPAGE = "https://devicetree.org/"
 DESCRIPTION = "A python library for the Device Tree Compiler, a tool used to manipulate Device Tree files which contain a data structure for describing hardware."
 SECTION = "bootloader"
-LICENSE = "GPL-2.0-only | BSD-2-Clause"
+LICENSE = "BSD-2-Clause OR GPL-2.0-only"
 
 DEPENDS = "flex-native bison-native swig-native python3-setuptools-scm-native libyaml dtc"
 
diff --git a/meta/recipes-devtools/python/python3-idna_3.18.bb b/meta/recipes-devtools/python/python3-idna_3.18.bb
index 3d5e79d0f7..cac86a8594 100644
--- a/meta/recipes-devtools/python/python3-idna_3.18.bb
+++ b/meta/recipes-devtools/python/python3-idna_3.18.bb
@@ -1,6 +1,6 @@
 SUMMARY = "Internationalised Domain Names in Applications"
 HOMEPAGE = "https://github.com/kjd/idna"
-LICENSE = "BSD-3-Clause & Python-2.0 & Unicode-TOU"
+LICENSE = "BSD-3-Clause AND Python-2.0 AND Unicode-TOU"
 LIC_FILES_CHKSUM = "file://LICENSE.md;md5=9a6c29079fc90c29d80332f44d2625f2"
 
 SRC_URI[sha256sum] = "ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848"
diff --git a/meta/recipes-devtools/python/python3-lxml_6.1.1.bb b/meta/recipes-devtools/python/python3-lxml_6.1.1.bb
index 77386ebdd0..4ca7f08b39 100644
--- a/meta/recipes-devtools/python/python3-lxml_6.1.1.bb
+++ b/meta/recipes-devtools/python/python3-lxml_6.1.1.bb
@@ -6,7 +6,7 @@ significantly to offer support for XPath, RelaxNG, XML Schema, XSLT, \
 C14N and much more."
 HOMEPAGE = "https://lxml.de/"
 SECTION = "devel/python"
-LICENSE = "BSD-3-Clause & GPL-2.0-only & MIT & PSF-2.0"
+LICENSE = "BSD-3-Clause AND GPL-2.0-only AND MIT AND PSF-2.0"
 LIC_FILES_CHKSUM = "file://LICENSES.txt;md5=e4c045ebad958ead4b48008f70838403 \
                     file://doc/licenses/elementtree.txt;md5=eb34d036a6e3d56314ee49a6852ac891 \
                     file://doc/licenses/BSD.txt;md5=700a1fc17f4797d4f2d34970c8ee694b \
diff --git a/meta/recipes-devtools/python/python3-maturin_1.14.1.bb b/meta/recipes-devtools/python/python3-maturin_1.14.1.bb
index b690a57772..88ba336022 100644
--- a/meta/recipes-devtools/python/python3-maturin_1.14.1.bb
+++ b/meta/recipes-devtools/python/python3-maturin_1.14.1.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Build and publish crates with pyo3, rust-cpython, cffi bindings and rust binaries as python packages"
 HOMEPAGE = "https://github.com/pyo3/maturin"
 SECTION = "devel/python"
-LICENSE = "MIT | Apache-2.0"
+LICENSE = "Apache-2.0 OR MIT"
 LIC_FILES_CHKSUM = "file://license-apache;md5=1836efb2eb779966696f473ee8540542 \
                     file://license-mit;md5=85fd3b67069cff784d98ebfc7d5c0797"
 
diff --git a/meta/recipes-devtools/python/python3-numpy_2.5.0.bb b/meta/recipes-devtools/python/python3-numpy_2.5.0.bb
index 32c1acafdd..43ecdb2c42 100644
--- a/meta/recipes-devtools/python/python3-numpy_2.5.0.bb
+++ b/meta/recipes-devtools/python/python3-numpy_2.5.0.bb
@@ -2,7 +2,7 @@ SUMMARY = "A sophisticated Numeric Processing Package for Python"
 HOMEPAGE = "https://numpy.org/"
 DESCRIPTION = "NumPy is the fundamental package needed for scientific computing with Python."
 SECTION = "devel/python"
-LICENSE = "BSD-3-Clause & BSD-2-Clause & PSF-2.0 & Apache-2.0 & MIT"
+LICENSE = "Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND MIT AND PSF-2.0"
 LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=26080bf81b2662c7119d3ef28ae197fd"
 
 SRCNAME = "numpy"
diff --git a/meta/recipes-devtools/python/python3-packaging_26.2.bb b/meta/recipes-devtools/python/python3-packaging_26.2.bb
index eadd70602a..81ae6f2732 100644
--- a/meta/recipes-devtools/python/python3-packaging_26.2.bb
+++ b/meta/recipes-devtools/python/python3-packaging_26.2.bb
@@ -1,6 +1,6 @@
 SUMMARY = "Core utilities for Python packages"
 HOMEPAGE = "https://github.com/pypa/packaging"
-LICENSE = "Apache-2.0 | BSD-2-Clause"
+LICENSE = "Apache-2.0 OR BSD-2-Clause"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=faadaedca9251a90b205c9167578ce91"
 
 SRC_URI[sha256sum] = "ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661"
diff --git a/meta/recipes-devtools/python/python3-pip_26.1.2.bb b/meta/recipes-devtools/python/python3-pip_26.1.2.bb
index dd1895ed55..9a02409298 100644
--- a/meta/recipes-devtools/python/python3-pip_26.1.2.bb
+++ b/meta/recipes-devtools/python/python3-pip_26.1.2.bb
@@ -1,7 +1,7 @@
 SUMMARY = "The PyPA recommended tool for installing Python packages"
 HOMEPAGE = "https://pypi.org/project/pip"
 SECTION = "devel/python"
-LICENSE = "MIT & Apache-2.0 & MPL-2.0 & LGPL-2.1-only & BSD-3-Clause & PSF-2.0 & BSD-2-Clause"
+LICENSE = "Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND LGPL-2.1-only AND MIT AND MPL-2.0 AND PSF-2.0"
 LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=63ec52baf95163b597008bb46db68030 \
                     file://src/pip/_vendor/cachecontrol/LICENSE.txt;md5=6572692148079ebbbd800be4b9f36c6d \
                     file://src/pip/_vendor/certifi/LICENSE;md5=11618cb6a975948679286b1211bd573c \
diff --git a/meta/recipes-devtools/python/python3-poetry-core_2.4.1.bb b/meta/recipes-devtools/python/python3-poetry-core_2.4.1.bb
index a428214b87..d063f7e23c 100644
--- a/meta/recipes-devtools/python/python3-poetry-core_2.4.1.bb
+++ b/meta/recipes-devtools/python/python3-poetry-core_2.4.1.bb
@@ -4,7 +4,7 @@ HOMEPAGE = "https://github.com/python-poetry/poetry-core"
 BUGTRACKER = "https://github.com/python-poetry/poetry-core"
 CHANGELOG = "https://github.com/python-poetry/poetry-core/blob/master/CHANGELOG.md"
 
-LICENSE = "Apache-2.0 & BSD-2-Clause & BSD-3-Clause & MIT"
+LICENSE = "Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND MIT"
 LIC_FILES_CHKSUM = "\
     file://LICENSE;md5=78c39cfd009863ae44237a7ab1f9cedc \
     file://src/poetry/core/_vendor/fastjsonschema/LICENSE;md5=18950e8362b69c0c617b42b8bd8e7532 \
diff --git a/meta/recipes-devtools/python/python3-pycairo_1.29.0.bb b/meta/recipes-devtools/python/python3-pycairo_1.29.0.bb
index 9b78e4f3d3..2d018e676a 100644
--- a/meta/recipes-devtools/python/python3-pycairo_1.29.0.bb
+++ b/meta/recipes-devtools/python/python3-pycairo_1.29.0.bb
@@ -2,7 +2,7 @@ SUMMARY = "Python bindings for the Cairo canvas library"
 HOMEPAGE = "http://cairographics.org/pycairo"
 BUGTRACKER = "http://bugs.freedesktop.org"
 SECTION = "python-devel"
-LICENSE = "LGPL-2.1-only & MPL-1.1"
+LICENSE = "LGPL-2.1-only AND MPL-1.1"
 LIC_FILES_CHKSUM = "file://COPYING;md5=f3713ca2c28d9312ad718520b6dc3eee \
                     file://COPYING-LGPL-2.1;md5=fad9b3332be894bab9bc501572864b29 \
                     file://COPYING-MPL-1.1;md5=bfe1f75d606912a4111c90743d6c7325"
diff --git a/meta/recipes-devtools/python/python3-roman-numerals_4.1.0.bb b/meta/recipes-devtools/python/python3-roman-numerals_4.1.0.bb
index 4cab76a2b1..08af23d765 100644
--- a/meta/recipes-devtools/python/python3-roman-numerals_4.1.0.bb
+++ b/meta/recipes-devtools/python/python3-roman-numerals_4.1.0.bb
@@ -1,6 +1,6 @@
 SUMMARY = "Manipulate roman numerals"
 HOMEPAGE = "https://github.com/AA-Turner/roman-numerals/"
-LICENSE = "0BSD & CC0-1.0"
+LICENSE = "0BSD AND CC0-1.0"
 LIC_FILES_CHKSUM = "file://LICENCE.rst;md5=bfcc8b16e42929aafeb9d414360bc2fd"
 
 SRC_URI[sha256sum] = "1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2"
diff --git a/meta/recipes-devtools/python/python3-sphinx-rtd-theme_3.1.0.bb b/meta/recipes-devtools/python/python3-sphinx-rtd-theme_3.1.0.bb
index 77fcae2546..927664c5fb 100644
--- a/meta/recipes-devtools/python/python3-sphinx-rtd-theme_3.1.0.bb
+++ b/meta/recipes-devtools/python/python3-sphinx-rtd-theme_3.1.0.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Sphinx Theme reader"
 HOMEPAGE = "https://github.com/readthedocs/sphinx_rtd_theme"
 SECTION = "devel/python"
-LICENSE = "MIT & OFL-1.1"
+LICENSE = "MIT AND OFL-1.1"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=a1db7d4ef426c2935227264e1d4ae8f9 \
                     file://OFL-License.txt;md5=4534c22e0147eadb6828bd9fe86d4868 \
                     file://Apache-License-2.0.txt;md5=8a75796f0ef19c3f601d69857f5a9a5b"
diff --git a/meta/recipes-devtools/python/python3-sphinx_9.1.0.bb b/meta/recipes-devtools/python/python3-sphinx_9.1.0.bb
index 76f904d708..dcf769724f 100644
--- a/meta/recipes-devtools/python/python3-sphinx_9.1.0.bb
+++ b/meta/recipes-devtools/python/python3-sphinx_9.1.0.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Python documentation generator"
 HOMEPAGE = "http://sphinx-doc.org/"
 SECTION = "devel/python"
-LICENSE = "BSD-2-Clause & MIT"
+LICENSE = "BSD-2-Clause AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE.rst;md5=e30c37a2b7fb0afa3adc0d72b85e8b04"
 
 SRC_URI[sha256sum] = "7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb"
diff --git a/meta/recipes-devtools/python/python3-subunit_1.4.4.bb b/meta/recipes-devtools/python/python3-subunit_1.4.4.bb
index 269b057427..0ff02ef3b8 100644
--- a/meta/recipes-devtools/python/python3-subunit_1.4.4.bb
+++ b/meta/recipes-devtools/python/python3-subunit_1.4.4.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Python implementation of subunit test streaming protocol"
 HOMEPAGE = "https://pypi.org/project/python-subunit/"
 SECTION = "devel/python"
-LICENSE = "Apache-2.0 | BSD-3-Clause"
+LICENSE = "Apache-2.0 OR BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://COPYING;beginline=1;endline=20;md5=b1121e68d06c8d9ea544fcd895df0d39"
 
 PYPI_PACKAGE = "python-subunit"
diff --git a/meta/recipes-devtools/python/python3-uv-build_0.11.28.bb b/meta/recipes-devtools/python/python3-uv-build_0.11.28.bb
index 08ab097482..9523f573ed 100644
--- a/meta/recipes-devtools/python/python3-uv-build_0.11.28.bb
+++ b/meta/recipes-devtools/python/python3-uv-build_0.11.28.bb
@@ -1,7 +1,7 @@
 SUMMARY = "The build backend part of an 'An extremely fast Python package and project manager, written in Rust.'"
 HOMEPAGE = "https://pypi.org/project/uv-build/"
 
-LICENSE = "Apache-2.0 & BSD-2-Clause & MIT"
+LICENSE = "Apache-2.0 AND BSD-2-Clause AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE-APACHE;md5=86d3f3a95c324c9479bd8986968f4327 \
                     file://LICENSE-MIT;md5=45674e482567aa99fe883d3270b11184 \
                     file://crates/uv-build/LICENSE-APACHE;md5=86d3f3a95c324c9479bd8986968f4327 \
diff --git a/meta/recipes-devtools/qemu/python3-qemu-qmp_0.0.6.bb b/meta/recipes-devtools/qemu/python3-qemu-qmp_0.0.6.bb
index 4b3bbe6670..4092b3e8b7 100644
--- a/meta/recipes-devtools/qemu/python3-qemu-qmp_0.0.6.bb
+++ b/meta/recipes-devtools/qemu/python3-qemu-qmp_0.0.6.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "An asyncio library for communicating with QEMU Monitor Protocol (
 This library was split out of the QEMU source tree to provide a reference QMP \
 implementation usable both within and outside of the QEMU source tree."
 HOMEPAGE = "https://gitlab.com/qemu-project/python-qemu-qmp"
-LICENSE = "LGPL-2.0-only & GPL-2.0-only"
+LICENSE = "GPL-2.0-only AND LGPL-2.0-only"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=4cf66a4984120007c9881cc871cf49db"
 
 inherit pypi python_setuptools_build_meta
diff --git a/meta/recipes-devtools/qemu/qemu.inc b/meta/recipes-devtools/qemu/qemu.inc
index 0fb77250f8..6fca6bc499 100644
--- a/meta/recipes-devtools/qemu/qemu.inc
+++ b/meta/recipes-devtools/qemu/qemu.inc
@@ -5,7 +5,7 @@ of different hardware and device models for the machine, enabling it to run \
 a variety of guest operating systems"
 HOMEPAGE = "http://qemu.org"
 BUGTRACKER = "https://gitlab.com/qemu-project/qemu/-/issues"
-LICENSE = "GPL-2.0-only & LGPL-2.1-only"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-only"
 
 DEPENDS += "bison-native meson-native ninja-native"
 
diff --git a/meta/recipes-devtools/rpm-sequoia/rpm-sequoia_1.10.2.bb b/meta/recipes-devtools/rpm-sequoia/rpm-sequoia_1.10.2.bb
index a6b32bb007..0251b0b92c 100644
--- a/meta/recipes-devtools/rpm-sequoia/rpm-sequoia_1.10.2.bb
+++ b/meta/recipes-devtools/rpm-sequoia/rpm-sequoia_1.10.2.bb
@@ -4,7 +4,7 @@ HOMEPAGE = "https://sequoia-pgp.org/"
 # The license line is taken verbatim from Fedora's specfile
 # with formatting differences for Yocto. (AND -> &, OR -> |)
 # https://src.fedoraproject.org/rpms/rust-rpm-sequoia/blob/rawhide/f/rust-rpm-sequoia.spec
-LICENSE = "LGPL-2.0-or-later & Apache-2.0 & BSL-1.0 & MIT & Unicode-DFS-2016 & (Apache-2.0 | MIT) & (MIT | Apache-2.0 | Zlib) & (Unlicense | MIT)"
+LICENSE = "Apache-2.0 AND BSL-1.0 AND LGPL-2.0-or-later AND MIT AND Unicode-DFS-2016 AND (Apache-2.0 OR MIT) AND (Apache-2.0 OR MIT OR Zlib) AND (MIT OR Unlicense)"
 
 LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=f0ff5ff7747cf7d394079c6ae87f5f0c"
 
diff --git a/meta/recipes-devtools/ruby/ruby_4.0.5.bb b/meta/recipes-devtools/ruby/ruby_4.0.5.bb
index a0981bf622..fef3e351a2 100644
--- a/meta/recipes-devtools/ruby/ruby_4.0.5.bb
+++ b/meta/recipes-devtools/ruby/ruby_4.0.5.bb
@@ -6,7 +6,7 @@ It is simple, straight-forward, and extensible. \
 "
 HOMEPAGE = "http://www.ruby-lang.org/"
 SECTION = "devel/ruby"
-LICENSE = "Ruby | BSD-2-Clause | BSD-3-Clause | GPL-2.0-only | ISC | MIT | BSL-1.0 | Apache-2.0"
+LICENSE = "Apache-2.0 OR BSD-2-Clause OR BSD-3-Clause OR BSL-1.0 OR GPL-2.0-only OR ISC OR MIT OR Ruby"
 LIC_FILES_CHKSUM = "file://COPYING;md5=7674b1080a488809841b13eb57ffb719 \
                     file://BSDL;md5=8b50bc6de8f586dc66790ba11d064d75 \
                     file://GPL;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
diff --git a/meta/recipes-devtools/rust/cargo_1.96.1.bb b/meta/recipes-devtools/rust/cargo_1.96.1.bb
index f16688fc76..adc1f0d331 100644
--- a/meta/recipes-devtools/rust/cargo_1.96.1.bb
+++ b/meta/recipes-devtools/rust/cargo_1.96.1.bb
@@ -1,6 +1,6 @@
 SUMMARY = "Cargo, a package manager for Rust."
 HOMEPAGE = "https://crates.io"
-LICENSE = "MIT | Apache-2.0"
+LICENSE = "Apache-2.0 OR MIT"
 SECTION = "devel"
 
 DEPENDS = "openssl zlib curl ca-certificates libssh2"
diff --git a/meta/recipes-devtools/rust/libstd-rs_1.96.1.bb b/meta/recipes-devtools/rust/libstd-rs_1.96.1.bb
index 2a5e977a5e..1ecd6bff3f 100644
--- a/meta/recipes-devtools/rust/libstd-rs_1.96.1.bb
+++ b/meta/recipes-devtools/rust/libstd-rs_1.96.1.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Rust standard libaries"
 HOMEPAGE = "http://www.rust-lang.org"
 SECTION = "devel"
-LICENSE = "(MIT | Apache-2.0) & Unicode-3.0"
+LICENSE = "Unicode-3.0 AND (Apache-2.0 OR MIT)"
 LIC_FILES_CHKSUM = "file://../../COPYRIGHT;md5=11a3899825f4376896e438c8c753f8dc"
 
 require rust-source.inc
diff --git a/meta/recipes-devtools/rust/rust_1.96.1.bb b/meta/recipes-devtools/rust/rust_1.96.1.bb
index 8b0f1d1459..fa8777826f 100644
--- a/meta/recipes-devtools/rust/rust_1.96.1.bb
+++ b/meta/recipes-devtools/rust/rust_1.96.1.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Rust compiler and runtime libaries"
 HOMEPAGE = "http://www.rust-lang.org"
 SECTION = "devel"
-LICENSE = "(MIT | Apache-2.0) & Unicode-3.0"
+LICENSE = "Unicode-3.0 AND (Apache-2.0 OR MIT)"
 LIC_FILES_CHKSUM = "file://COPYRIGHT;md5=11a3899825f4376896e438c8c753f8dc"
 
 inherit rust
diff --git a/meta/recipes-devtools/strace/strace_7.1.bb b/meta/recipes-devtools/strace/strace_7.1.bb
index c4ca3a7f27..b5c6543da0 100644
--- a/meta/recipes-devtools/strace/strace_7.1.bb
+++ b/meta/recipes-devtools/strace/strace_7.1.bb
@@ -2,7 +2,7 @@ SUMMARY = "System call tracing tool"
 HOMEPAGE = "http://strace.io"
 DESCRIPTION = "strace is a diagnostic, debugging and instructional userspace utility for Linux. It is used to monitor and tamper with interactions between processes and the Linux kernel, which include system calls, signal deliveries, and changes of process state."
 SECTION = "console/utils"
-LICENSE = "LGPL-2.1-or-later & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=9259131ce5420f9790214be1c20a83a9"
 
 SRC_URI = "${GITHUB_BASE_URI}/download/v${PV}/strace-${PV}.tar.xz \
diff --git a/meta/recipes-devtools/subversion/subversion_1.14.5.bb b/meta/recipes-devtools/subversion/subversion_1.14.5.bb
index 05f80b3319..f6a5b9950f 100644
--- a/meta/recipes-devtools/subversion/subversion_1.14.5.bb
+++ b/meta/recipes-devtools/subversion/subversion_1.14.5.bb
@@ -2,7 +2,7 @@ SUMMARY = "Subversion (svn) version control system client"
 HOMEPAGE = "http://subversion.apache.org"
 DESCRIPTION = "Subversion is an open source version control system."
 SECTION = "console/network"
-LICENSE = "Apache-2.0 & MIT"
+LICENSE = "Apache-2.0 AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=6487ae7094d359fa90fb9c4096e52e2b"
 
 DEPENDS = "apr-util serf sqlite3 file lz4 expat"
diff --git a/meta/recipes-devtools/swig/swig_4.4.1.bb b/meta/recipes-devtools/swig/swig_4.4.1.bb
index f71a92d931..842a7b0945 100644
--- a/meta/recipes-devtools/swig/swig_4.4.1.bb
+++ b/meta/recipes-devtools/swig/swig_4.4.1.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "SWIG is a compiler that makes it easy to integrate C and C++ \
 code with other languages including Perl, Tcl, Ruby, Python, Java, Guile, \
 Mzscheme, Chicken, OCaml, Pike, and C#."
 HOMEPAGE = "http://swig.sourceforge.net/"
-LICENSE = "BSD-3-Clause & GPL-3.0-only"
+LICENSE = "BSD-3-Clause AND GPL-3.0-only"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=e7807a6282784a7dde4c846626b08fc6 \
                     file://LICENSE-GPL;md5=d32239bcb673463ab874e80d47fae504 \
                     file://LICENSE-UNIVERSITIES;md5=8ce9dcc8f7c994de4a408b205c72ba08"
diff --git a/meta/recipes-devtools/systemd-bootchart/systemd-bootchart_235.bb b/meta/recipes-devtools/systemd-bootchart/systemd-bootchart_235.bb
index 31f3add89f..a8976f8a3e 100644
--- a/meta/recipes-devtools/systemd-bootchart/systemd-bootchart_235.bb
+++ b/meta/recipes-devtools/systemd-bootchart/systemd-bootchart_235.bb
@@ -4,7 +4,7 @@ DESCRIPTION = "For systemd-bootchart, several proc debug interfaces are required
 below is optional, for additional info: \
   CONFIG_SCHED_DEBUG"
 HOMEPAGE = "https://github.com/systemd/systemd-bootchart"
-LICENSE = "LGPL-2.1-only & GPL-2.0-only"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://LICENSE.LGPL2.1;md5=4fbd65380cdd255951079008b364516c \
                     file://LICENSE.GPL2;md5=751419260aa954499f7abaabaa882bbe"
 
diff --git a/meta/recipes-devtools/tcf-agent/tcf-agent_1.11.0.bb b/meta/recipes-devtools/tcf-agent/tcf-agent_1.11.0.bb
index 6e9c7fc0ad..b04c7aea06 100644
--- a/meta/recipes-devtools/tcf-agent/tcf-agent_1.11.0.bb
+++ b/meta/recipes-devtools/tcf-agent/tcf-agent_1.11.0.bb
@@ -3,7 +3,7 @@ HOMEPAGE = "http://wiki.eclipse.org/TCF"
 DESCRIPTION = "TCF is a vendor-neutral, lightweight, extensible network protocol mainly for communicating with embedded systems (targets)."
 BUGTRACKER = "https://bugs.eclipse.org/bugs/"
 
-LICENSE = "EPL-1.0 | BSD-3-Clause"
+LICENSE = "BSD-3-Clause OR EPL-1.0"
 LIC_FILES_CHKSUM = "file://edl-v10.html;md5=522a390a83dc186513f0500543ad3679"
 
 SRCREV = "3051a4806ac4b041ec7c49ffc6d07f0014b8480c"
diff --git a/meta/recipes-devtools/tcltk/tcl_9.0.4.bb b/meta/recipes-devtools/tcltk/tcl_9.0.4.bb
index 8cabd77d7f..5b4809ed6b 100644
--- a/meta/recipes-devtools/tcltk/tcl_9.0.4.bb
+++ b/meta/recipes-devtools/tcltk/tcl_9.0.4.bb
@@ -4,7 +4,7 @@ DESCRIPTION = "Tool Command Language, is an open-source multi-purpose C library
 SECTION = "devel/tcltk"
 
 # http://www.tcl.tk/software/tcltk/license.html
-LICENSE = "TCL & BSD-3-Clause"
+LICENSE = "BSD-3-Clause AND TCL"
 LIC_FILES_CHKSUM = "file://license.terms;md5=058f6229798281bbcac4239c788cfa38 \
     file://compat/license.terms;md5=058f6229798281bbcac4239c788cfa38 \
     file://library/license.terms;md5=058f6229798281bbcac4239c788cfa38 \
diff --git a/meta/recipes-devtools/tcltk8/tcl8_8.6.18.bb b/meta/recipes-devtools/tcltk8/tcl8_8.6.18.bb
index 545c1cdc60..0382d4239c 100644
--- a/meta/recipes-devtools/tcltk8/tcl8_8.6.18.bb
+++ b/meta/recipes-devtools/tcltk8/tcl8_8.6.18.bb
@@ -4,7 +4,7 @@ DESCRIPTION = "Tool Command Language, is an open-source multi-purpose C library
 SECTION = "devel/tcltk"
 
 # http://www.tcl.tk/software/tcltk/license.html
-LICENSE = "TCL & BSD-3-Clause"
+LICENSE = "BSD-3-Clause AND TCL"
 LIC_FILES_CHKSUM = "file://license.terms;md5=058f6229798281bbcac4239c788cfa38 \
     file://compat/license.terms;md5=058f6229798281bbcac4239c788cfa38 \
     file://library/license.terms;md5=058f6229798281bbcac4239c788cfa38 \
diff --git a/meta/recipes-devtools/valgrind/valgrind_3.27.1.bb b/meta/recipes-devtools/valgrind/valgrind_3.27.1.bb
index 1b08f2fc5f..829b6c96a8 100644
--- a/meta/recipes-devtools/valgrind/valgrind_3.27.1.bb
+++ b/meta/recipes-devtools/valgrind/valgrind_3.27.1.bb
@@ -2,7 +2,7 @@ SUMMARY = "Valgrind memory debugger and instrumentation framework"
 HOMEPAGE = "http://valgrind.org/"
 DESCRIPTION = "Valgrind is an instrumentation framework for building dynamic analysis tools. There are Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in detail."
 BUGTRACKER = "http://valgrind.org/support/bug_reports.html"
-LICENSE = "GPL-2.0-only & GPL-2.0-or-later & BSD-3-Clause"
+LICENSE = "BSD-3-Clause AND GPL-2.0-only AND GPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=1ebbd3e34237af26da5dc08a4e440464 \
                     file://include/pub_tool_basics.h;beginline=6;endline=29;md5=9ba449d120f6845e6a432073278d6e3a \
                     file://include/valgrind.h;beginline=1;endline=56;md5=993563aaa122558df9c5d743de074d04 \
diff --git a/meta/recipes-extended/acpica/acpica_20260408.bb b/meta/recipes-extended/acpica/acpica_20260408.bb
index 4c65630015..1e6326720f 100644
--- a/meta/recipes-extended/acpica/acpica_20260408.bb
+++ b/meta/recipes-extended/acpica/acpica_20260408.bb
@@ -9,7 +9,7 @@ ACPI tables."
 HOMEPAGE = "https://www.intel.com/content/www/us/en/developer/topic-technology/open/acpica/overview.html"
 SECTION = "console/tools"
 
-LICENSE = "Intel | BSD-3-Clause | GPL-2.0-only"
+LICENSE = "BSD-3-Clause OR GPL-2.0-only OR Intel"
 LIC_FILES_CHKSUM = "file://source/compiler/aslcompile.c;beginline=7;endline=150;md5=4877caee45a613e9706946c3205a6fb9"
 
 COMPATIBLE_HOST = "(i.86|x86_64|arm|aarch64).*-linux"
diff --git a/meta/recipes-extended/bzip2/bzip2_1.0.8.bb b/meta/recipes-extended/bzip2/bzip2_1.0.8.bb
index 36267e5073..39f0f6749d 100644
--- a/meta/recipes-extended/bzip2/bzip2_1.0.8.bb
+++ b/meta/recipes-extended/bzip2/bzip2_1.0.8.bb
@@ -4,14 +4,14 @@ Huffman coding. Compression is generally considerably better than that achieved
 LZ77/LZ78-based compressors, and approaches the performance of the PPM family of statistical compressors."
 HOMEPAGE = "https://sourceware.org/bzip2/"
 SECTION = "console/utils"
-LICENSE = "bzip2-1.0.6 & GPL-3.0-or-later & Apache-2.0 & MS-PL & BSD-3-Clause & Zlib"
+LICENSE = "Apache-2.0 AND BSD-3-Clause AND GPL-3.0-or-later AND MS-PL AND Zlib AND bzip2-1.0.6"
 LICENSE:${PN} = "bzip2-1.0.6"
 LICENSE:${PN}-dev = "bzip2-1.0.6"
 LICENSE:${PN}-dbg = "bzip2-1.0.6"
 LICENSE:${PN}-doc = "bzip2-1.0.6"
 LICENSE:${PN}-src = "bzip2-1.0.6"
 LICENSE:libbz2 = "bzip2-1.0.6"
-LICENSE:${PN}-ptest = "bzip2-1.0.6 & GPL-3.0-or-later & Apache-2.0 & MS-PL & BSD-3-Clause & Zlib"
+LICENSE:${PN}-ptest = "Apache-2.0 AND BSD-3-Clause AND GPL-3.0-or-later AND MS-PL AND Zlib AND bzip2-1.0.6"
 
 LIC_FILES_CHKSUM = "file://LICENSE;beginline=4;endline=37;md5=600af43c50f1fcb82e32f19b32df4664 \
                     file://${UNPACKDIR}/bzip2-tests/commons-compress/LICENSE.txt;md5=86d3f3a95c324c9479bd8986968f4327 \
diff --git a/meta/recipes-extended/cronie/cronie_1.7.2.bb b/meta/recipes-extended/cronie/cronie_1.7.2.bb
index b250717ab8..d480407bc4 100644
--- a/meta/recipes-extended/cronie/cronie_1.7.2.bb
+++ b/meta/recipes-extended/cronie/cronie_1.7.2.bb
@@ -7,7 +7,7 @@ HOMEPAGE = "https://github.com/cronie-crond/cronie/"
 BUGTRACKER = "https://bugzilla.redhat.com"
 
 # Internet Systems Consortium License
-LICENSE = "ISC & BSD-3-Clause & BSD-2-Clause & GPL-2.0-or-later"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause AND GPL-2.0-or-later AND ISC"
 LIC_FILES_CHKSUM = "file://COPYING;md5=dd2a592170760e1386c769e1043b3722 \
                     file://src/cron.c;endline=20;md5=b425c334265026177128353a142633b4 \
                     file://src/popen.c;beginline=3;endline=31;md5=edd50742d8def712e9472dba353668a9"
diff --git a/meta/recipes-extended/gawk/gawk_5.4.1.bb b/meta/recipes-extended/gawk/gawk_5.4.1.bb
index 8e8bc34152..56930498e3 100644
--- a/meta/recipes-extended/gawk/gawk_5.4.1.bb
+++ b/meta/recipes-extended/gawk/gawk_5.4.1.bb
@@ -6,7 +6,7 @@ HOMEPAGE = "https://www.gnu.org/software/gawk/"
 BUGTRACKER  = "bug-gawk@gnu.org"
 SECTION = "console/utils"
 
-LICENSE = "GPL-3.0-or-later & AGPL-3.0-or-later"
+LICENSE = "AGPL-3.0-or-later AND GPL-3.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504 \
                     file://support/pma.c;md5=bb0026ee5e8b950e67d670dd2d60cc93;beginline=8;endline=19 \
                     file://support/pma.h;md5=bb0026ee5e8b950e67d670dd2d60cc93;beginline=8;endline=19"
diff --git a/meta/recipes-extended/hdparm/hdparm_9.65.bb b/meta/recipes-extended/hdparm/hdparm_9.65.bb
index e541d58fa5..0c84801c43 100644
--- a/meta/recipes-extended/hdparm/hdparm_9.65.bb
+++ b/meta/recipes-extended/hdparm/hdparm_9.65.bb
@@ -4,9 +4,9 @@ DESCRIPTION = "hdparm is a Linux shell utility for viewing \
 and manipulating various IDE drive and driver parameters."
 SECTION = "console/utils"
 
-LICENSE = "BSD-2-Clause & GPL-2.0-only & hdparm"
-LICENSE:${PN} = "BSD-2-Clause & hdparm"
-LICENSE:${PN}-dbg = "BSD-2-Clause & hdparm"
+LICENSE = "BSD-2-Clause AND GPL-2.0-only AND hdparm"
+LICENSE:${PN} = "BSD-2-Clause AND hdparm"
+LICENSE:${PN}-dbg = "BSD-2-Clause AND hdparm"
 LICENSE:wiper = "GPL-2.0-only"
 
 LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=495d03e50dc6c89d6a30107ab0df5b03 \
diff --git a/meta/recipes-extended/iputils/iputils_20250605.bb b/meta/recipes-extended/iputils/iputils_20250605.bb
index baeda55659..cdebf28ca3 100644
--- a/meta/recipes-extended/iputils/iputils_20250605.bb
+++ b/meta/recipes-extended/iputils/iputils_20250605.bb
@@ -4,7 +4,7 @@ tracepath, tracepath6, ping, ping6 and arping."
 HOMEPAGE = "https://github.com/iputils/iputils"
 SECTION = "console/network"
 
-LICENSE = "BSD-3-Clause & GPL-2.0-or-later"
+LICENSE = "BSD-3-Clause AND GPL-2.0-or-later"
 
 LIC_FILES_CHKSUM = "file://LICENSE;md5=627cc07ec86a45951d43e30658bbd819"
 
diff --git a/meta/recipes-extended/jansson/jansson_2.15.1.bb b/meta/recipes-extended/jansson/jansson_2.15.1.bb
index 60bbc5ba6d..517dd6023b 100644
--- a/meta/recipes-extended/jansson/jansson_2.15.1.bb
+++ b/meta/recipes-extended/jansson/jansson_2.15.1.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Jansson is a C library for encoding, decoding and manipulating JSON data"
 HOMEPAGE = "http://www.digip.org/jansson/"
 BUGTRACKER = "https://github.com/akheron/jansson/issues"
-LICENSE = "MIT & dtoa"
+LICENSE = "MIT AND dtoa"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=d9911525d4128bee234ee2d3ccaa2537"
 
 GITHUB_BASE_URI = "https://github.com/akheron/jansson/releases"
diff --git a/meta/recipes-extended/less/less_704.bb b/meta/recipes-extended/less/less_704.bb
index 500a39b327..dc841a9ae6 100644
--- a/meta/recipes-extended/less/less_704.bb
+++ b/meta/recipes-extended/less/less_704.bb
@@ -19,7 +19,7 @@ SECTION = "console/utils"
 # --Mark
 #
 
-LICENSE = "GPL-3.0-or-later | BSD-2-Clause"
+LICENSE = "BSD-2-Clause OR GPL-3.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=1ebbd3e34237af26da5dc08a4e440464 \
                     file://LICENSE;md5=bee5763a5e2bccdcdbd9bfe982ffc82b \
                     "
diff --git a/meta/recipes-extended/libidn/libidn2_2.3.8.bb b/meta/recipes-extended/libidn/libidn2_2.3.8.bb
index a53ac47d66..37703aa929 100644
--- a/meta/recipes-extended/libidn/libidn2_2.3.8.bb
+++ b/meta/recipes-extended/libidn/libidn2_2.3.8.bb
@@ -2,7 +2,7 @@ SUMMARY = "Internationalized Domain Name support library"
 DESCRIPTION = "Implementation of the Stringprep, Punycode and IDNA specifications defined by the IETF Internationalized Domain Names (IDN) working group."
 HOMEPAGE = "http://www.gnu.org/software/libidn/"
 SECTION = "libs"
-LICENSE = "(GPL-2.0-or-later | LGPL-3.0-only) & GPL-3.0-or-later & Unicode-DFS-2016"
+LICENSE = "GPL-3.0-or-later AND Unicode-DFS-2016 AND (GPL-2.0-or-later OR LGPL-3.0-only)"
 LIC_FILES_CHKSUM = "file://COPYING;md5=1ebbd3e34237af26da5dc08a4e440464 \
                     file://COPYING.LESSERv3;md5=3000208d539ec061b899bce1d9ce9404 \
                     file://COPYINGv2;md5=570a9b3749dd0463a1778803b12a6dce \
@@ -27,7 +27,7 @@ do_install:append() {
 	sed -i -e 's|-L${STAGING_LIBDIR}||' -e 's/  */ /g' ${D}${libdir}/pkgconfig/libidn2.pc
 }
 
-LICENSE:${PN} = "(GPL-2.0-or-later | LGPL-3.0-only) & Unicode-DFS-2016"
+LICENSE:${PN} = "Unicode-DFS-2016 AND (GPL-2.0-or-later OR LGPL-3.0-only)"
 LICENSE:${PN}-bin = "GPL-3.0-or-later"
 
 BBCLASSEXTEND = "native nativesdk"
diff --git a/meta/recipes-extended/ltp/ltp_20260529.bb b/meta/recipes-extended/ltp/ltp_20260529.bb
index e863503200..0fc3946aa4 100644
--- a/meta/recipes-extended/ltp/ltp_20260529.bb
+++ b/meta/recipes-extended/ltp/ltp_20260529.bb
@@ -2,7 +2,7 @@ SUMMARY = "Linux Test Project"
 DESCRIPTION = "The Linux Test Project is a joint project with SGI, IBM, OSDL, and Bull with a goal to deliver test suites to the open source community that validate the reliability, robustness, and stability of Linux. The Linux Test Project is a collection of tools for testing the Linux kernel and related features."
 HOMEPAGE = "https://linux-test-project.github.io/"
 SECTION = "console/utils"
-LICENSE = "GPL-2.0-only & GPL-2.0-or-later & LGPL-2.0-or-later & LGPL-2.1-or-later & BSD-2-Clause"
+LICENSE = "BSD-2-Clause AND GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "\
     file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
     file://testcases/open_posix_testsuite/COPYING;md5=48b1c5ec633e3e30ec2cf884ae699947 \
diff --git a/meta/recipes-extended/man-db/man-db_2.13.1.bb b/meta/recipes-extended/man-db/man-db_2.13.1.bb
index f044a47f7d..7fcad2ed4b 100644
--- a/meta/recipes-extended/man-db/man-db_2.13.1.bb
+++ b/meta/recipes-extended/man-db/man-db_2.13.1.bb
@@ -1,7 +1,7 @@
 SUMMARY = "An implementation of the standard Unix documentation system accessed using the man command"
 HOMEPAGE = "http://man-db.nongnu.org/"
 DESCRIPTION = "man-db is an implementation of the standard Unix documentation system accessed using the man command. It uses a Berkeley DB database in place of the traditional flat-text whatis databases."
-LICENSE = "LGPL-2.1-or-later & GPL-2.0-or-later & GPL-3.0-or-later"
+LICENSE = "GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=1ebbd3e34237af26da5dc08a4e440464 \
                     file://docs/COPYING.GPLv2;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
                     file://docs/COPYING.LIB;md5=4fbd65380cdd255951079008b364516c \
diff --git a/meta/recipes-extended/man-pages/man-pages_6.18.bb b/meta/recipes-extended/man-pages/man-pages_6.18.bb
index 3e2eb66156..5d6504b85b 100644
--- a/meta/recipes-extended/man-pages/man-pages_6.18.bb
+++ b/meta/recipes-extended/man-pages/man-pages_6.18.bb
@@ -2,7 +2,7 @@ SUMMARY = "Linux man-pages"
 DESCRIPTION = "The Linux man-pages project documents the Linux kernel and C library interfaces that are employed by user programs"
 SECTION = "console/utils"
 HOMEPAGE = "http://www.kernel.org/pub/linux/docs/man-pages"
-LICENSE = "GPL-2.0-or-later & GPL-2.0-only & GPL-1.0-or-later & BSD-2-Clause & BSD-3-Clause & BSD-4-Clause-UC & MIT"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND MIT"
 
 LIC_FILES_CHKSUM = "file://README;md5=e4d3c4124726a2b7763489612768c03c \
                     file://LICENSES/BSD-2-Clause.txt;md5=9e16594a228301089d759b4f178db91f \
diff --git a/meta/recipes-extended/mdadm/mdadm_4.6.bb b/meta/recipes-extended/mdadm/mdadm_4.6.bb
index b1d0a27c7f..e289fb9a17 100644
--- a/meta/recipes-extended/mdadm/mdadm_4.6.bb
+++ b/meta/recipes-extended/mdadm/mdadm_4.6.bb
@@ -3,7 +3,7 @@ HOMEPAGE = "http://www.kernel.org/pub/linux/utils/raid/mdadm/"
 DESCRIPTION = "mdadm is a Linux utility used to manage and monitor software RAID devices."
 
 # Some files are GPL-2.0-only while others are GPL-2.0-or-later.
-LICENSE = "GPL-2.0-only & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-only AND GPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
                     file://mdmon.c;beginline=4;endline=18;md5=af7d8444d9c4d3e5c7caac0d9d34039d \
                     file://mdadm.h;beglinlne=4;endline=22;md5=462bc9936ac0d3da110191a3f9994161"
diff --git a/meta/recipes-extended/pam/libpam_1.7.2.bb b/meta/recipes-extended/pam/libpam_1.7.2.bb
index 6955a5f2f6..ecaee30d1a 100644
--- a/meta/recipes-extended/pam/libpam_1.7.2.bb
+++ b/meta/recipes-extended/pam/libpam_1.7.2.bb
@@ -7,7 +7,7 @@ SECTION = "base"
 # PAM is dual licensed under GPL and BSD.
 # /etc/pam.d comes from Debian libpam-runtime in 2009-11 (at that time
 # libpam-runtime-1.0.1 is GPL-2.0-or-later), by openembedded
-LICENSE = "GPL-2.0-or-later | BSD-3-Clause"
+LICENSE = "BSD-3-Clause OR GPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=7eb5c1bf854e8881005d673599ee74d3 \
                     file://libpamc/License;md5=a4da476a14c093fdc73be3c3c9ba8fb3 \
                     "
diff --git a/meta/recipes-extended/perl/libconvert-asn1-perl_0.34.bb b/meta/recipes-extended/perl/libconvert-asn1-perl_0.34.bb
index c1d83139d7..88f22fff37 100644
--- a/meta/recipes-extended/perl/libconvert-asn1-perl_0.34.bb
+++ b/meta/recipes-extended/perl/libconvert-asn1-perl_0.34.bb
@@ -2,7 +2,7 @@ SUMMARY = "Convert::ASN1 - Perl ASN.1 Encode/Decode library"
 SECTION = "libs"
 HOMEPAGE = "https://metacpan.org/dist/Convert-ASN1/"
 DESCRIPTION = "Convert::ASN1 is a perl library for encoding/decoding data using ASN.1 definitions."
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 LIC_FILES_CHKSUM = "file://README.md;beginline=91;endline=97;md5=ceff7fd286eb6d8e8e0d3d23e096a63f"
 
 SRC_URI = "${CPAN_MIRROR}/authors/id/T/TI/TIMLEGGE/Convert-ASN1-${PV}.tar.gz"
diff --git a/meta/recipes-extended/perl/libtimedate-perl_2.30.bb b/meta/recipes-extended/perl/libtimedate-perl_2.30.bb
index 590b5bd0b8..028630ba90 100644
--- a/meta/recipes-extended/perl/libtimedate-perl_2.30.bb
+++ b/meta/recipes-extended/perl/libtimedate-perl_2.30.bb
@@ -3,7 +3,7 @@ HOMEPAGE = "https://metacpan.org/release/TimeDate"
 DESCRIPTION = "This is the perl5 TimeDate distribution. It requires perl version 5.003 or later."
 SECTION = "libs"
 # You can redistribute it and/or modify it under the same terms as Perl itself.
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 LIC_FILES_CHKSUM = "file://README;beginline=21;md5=576b7cb41e5e821501a01ed66f0f9d9e"
 
 SRC_URI = "${CPAN_MIRROR}/authors/id/G/GB/GBARR/TimeDate-${PV}.tar.gz"
diff --git a/meta/recipes-extended/perl/libxml-namespacesupport-perl_1.12.bb b/meta/recipes-extended/perl/libxml-namespacesupport-perl_1.12.bb
index 9653cb427b..8306206abe 100644
--- a/meta/recipes-extended/perl/libxml-namespacesupport-perl_1.12.bb
+++ b/meta/recipes-extended/perl/libxml-namespacesupport-perl_1.12.bb
@@ -5,7 +5,7 @@ DESCRIPTION = "XML::NamespaceSupport offers a simple way to process namespace-ba
                 basic checks. "
 
 SECTION = "libs"
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 
 SRCNAME = "XML-NamespaceSupport"
 
diff --git a/meta/recipes-extended/perl/libxml-sax-base-perl_1.09.bb b/meta/recipes-extended/perl/libxml-sax-base-perl_1.09.bb
index a4b4116973..499720539c 100644
--- a/meta/recipes-extended/perl/libxml-sax-base-perl_1.09.bb
+++ b/meta/recipes-extended/perl/libxml-sax-base-perl_1.09.bb
@@ -7,7 +7,7 @@ use this module as a base class so you don't have to, for example, \
 implement the characters() callback."
 
 SECTION = "libs"
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 RDEPENDS:${PN} += "perl-module-extutils-makemaker"
 
 LIC_FILES_CHKSUM = "file://dist.ini;endline=5;md5=8f9c9a55340aefaee6e9704c88466446"
diff --git a/meta/recipes-extended/perl/libxml-sax-perl_1.02.bb b/meta/recipes-extended/perl/libxml-sax-perl_1.02.bb
index 5f982a4c4c..167591145c 100644
--- a/meta/recipes-extended/perl/libxml-sax-perl_1.02.bb
+++ b/meta/recipes-extended/perl/libxml-sax-perl_1.02.bb
@@ -9,7 +9,7 @@ come from the Java JAXP specification (SAX part), only without the \
 javaness."
 
 SECTION = "libs"
-LICENSE = "Artistic-1.0 | GPL-1.0-or-later"
+LICENSE = "Artistic-1.0 OR GPL-1.0-or-later"
 DEPENDS += "libxml-namespacesupport-perl-native"
 RDEPENDS:${PN} += "libxml-namespacesupport-perl libxml-sax-base-perl perl-module-file-temp"
 
diff --git a/meta/recipes-extended/pigz/pigz_2.8.bb b/meta/recipes-extended/pigz/pigz_2.8.bb
index fcf0c93e41..9c949097c4 100644
--- a/meta/recipes-extended/pigz/pigz_2.8.bb
+++ b/meta/recipes-extended/pigz/pigz_2.8.bb
@@ -5,7 +5,7 @@ multiple cores to the hilt when compressing data. pigz was written by Mark \
 Adler, and uses the zlib and pthread libraries."
 HOMEPAGE = "http://zlib.net/pigz/"
 SECTION = "console/utils"
-LICENSE = "Zlib & Apache-2.0"
+LICENSE = "Apache-2.0 AND Zlib"
 LIC_FILES_CHKSUM = "file://pigz.c;md5=9ae6dee8ceba9610596ed0ada493d142;beginline=7;endline=21"
 
 SRC_URI = "http://zlib.net/${BPN}/fossils/${BP}.tar.gz"
diff --git a/meta/recipes-extended/procps/procps_4.0.6.bb b/meta/recipes-extended/procps/procps_4.0.6.bb
index a9ec3f39d6..2437be1c3a 100644
--- a/meta/recipes-extended/procps/procps_4.0.6.bb
+++ b/meta/recipes-extended/procps/procps_4.0.6.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Procps contains a set of system utilities that provide system inf
 the /proc filesystem. The package includes the programs ps, top, vmstat, w, kill, and skill."
 HOMEPAGE = "https://gitlab.com/procps-ng/procps"
 SECTION = "base"
-LICENSE = "GPL-2.0-or-later & LGPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
                     file://COPYING.LIB;md5=4cf66a4984120007c9881cc871cf49db \
                     "
diff --git a/meta/recipes-extended/quota/quota_4.11.bb b/meta/recipes-extended/quota/quota_4.11.bb
index 811056f1f7..de6a7a56e5 100644
--- a/meta/recipes-extended/quota/quota_4.11.bb
+++ b/meta/recipes-extended/quota/quota_4.11.bb
@@ -3,7 +3,7 @@ SECTION = "base"
 HOMEPAGE = "http://sourceforge.net/projects/linuxquota/"
 DESCRIPTION = "Tools and patches for the Linux Diskquota system as part of the Linux kernel"
 BUGTRACKER = "http://sourceforge.net/tracker/?group_id=18136&atid=118136"
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://rquota_server.c;beginline=1;endline=20;md5=fe7e0d7e11c6f820f8fa62a5af71230f \
                     file://svc_socket.c;beginline=1;endline=17;md5=24d5a8792da45910786eeac750be8ceb"
 
diff --git a/meta/recipes-extended/shadow/shadow-sysroot_4.6.bb b/meta/recipes-extended/shadow/shadow-sysroot_4.6.bb
index d66ef1e6a4..54ef18479e 100644
--- a/meta/recipes-extended/shadow/shadow-sysroot_4.6.bb
+++ b/meta/recipes-extended/shadow/shadow-sysroot_4.6.bb
@@ -2,7 +2,7 @@ SUMMARY = "Shadow utils requirements for useradd.bbclass"
 HOMEPAGE = "http://github.com/shadow-maint/shadow"
 BUGTRACKER = "http://github.com/shadow-maint/shadow/issues"
 SECTION = "base utils"
-LICENSE = "BSD-3-Clause | Artistic-1.0"
+LICENSE = "Artistic-1.0 OR BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://login.defs_shadow-sysroot;endline=1;md5=ceddfb61608e4db87012499555184aed"
 
 DEPENDS = "base-passwd"
diff --git a/meta/recipes-extended/sudo/sudo.inc b/meta/recipes-extended/sudo/sudo.inc
index a23de1fcf7..f80a35539e 100644
--- a/meta/recipes-extended/sudo/sudo.inc
+++ b/meta/recipes-extended/sudo/sudo.inc
@@ -3,7 +3,7 @@ DESCRIPTION = "Sudo (superuser do) allows a system administrator to give certain
 HOMEPAGE = "http://www.sudo.ws"
 BUGTRACKER = "http://www.sudo.ws/bugs/"
 SECTION = "admin"
-LICENSE = "ISC & BSD-3-Clause & BSD-2-Clause & Zlib"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause AND ISC AND Zlib"
 LIC_FILES_CHKSUM = "file://LICENSE.md;md5=2841c822e587db145364ca95e9be2ffa \
                     file://plugins/sudoers/redblack.c;beginline=1;endline=46;md5=03e35317699ba00b496251e0dfe9f109 \
                     file://lib/util/reallocarray.c;beginline=3;endline=15;md5=397dd45c7683e90b9f8bf24638cf03bf \
diff --git a/meta/recipes-extended/timezone/timezone.inc b/meta/recipes-extended/timezone/timezone.inc
index 47f9ac2855..8939cd2cb5 100644
--- a/meta/recipes-extended/timezone/timezone.inc
+++ b/meta/recipes-extended/timezone/timezone.inc
@@ -3,7 +3,7 @@ DESCRIPTION = "The Time Zone Database contains code and data that represent \
 the history of local time for many representative locations around the globe."
 HOMEPAGE = "http://www.iana.org/time-zones"
 SECTION = "base"
-LICENSE = "PD & BSD-3-Clause"
+LICENSE = "BSD-3-Clause AND LicenseRef-PD"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=c679c9d6b02bc2757b3eaf8f53c43fba"
 
 PV = "2026c"
diff --git a/meta/recipes-extended/zstd/zstd_1.5.7.bb b/meta/recipes-extended/zstd/zstd_1.5.7.bb
index e5088e2d0d..4960ed5b48 100644
--- a/meta/recipes-extended/zstd/zstd_1.5.7.bb
+++ b/meta/recipes-extended/zstd/zstd_1.5.7.bb
@@ -7,7 +7,7 @@ SECTION = "console/utils"
 
 PROVIDES += "zstd-decompress"
 
-LICENSE = "BSD-3-Clause | GPL-2.0-only"
+LICENSE = "BSD-3-Clause OR GPL-2.0-only"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=0822a32f7acdbe013606746641746ee8 \
                     file://COPYING;md5=39bba7d2cf0ba1036f2a6e2be52fe3f0 \
                     "
diff --git a/meta/recipes-gnome/gi-docgen/gi-docgen_2026.1.bb b/meta/recipes-gnome/gi-docgen/gi-docgen_2026.1.bb
index 5d3fc40374..7d4e903bfa 100644
--- a/meta/recipes-gnome/gi-docgen/gi-docgen_2026.1.bb
+++ b/meta/recipes-gnome/gi-docgen/gi-docgen_2026.1.bb
@@ -5,7 +5,7 @@ introspection data generated by GObject-based libraries to generate the API \
 reference of these libraries, as well as other ancillary documentation."
 HOMEPAGE = "https://gnome.pages.gitlab.gnome.org/gi-docgen/"
 
-LICENSE = "GPL-3.0-or-later & Apache-2.0"
+LICENSE = "Apache-2.0 AND GPL-3.0-or-later"
 LIC_FILES_CHKSUM = "file://gi-docgen.py;beginline=1;endline=5;md5=2dc0f1f01202478cfe813c0e7f80b326"
 
 SRC_URI = "git://gitlab.gnome.org/GNOME/gi-docgen.git;protocol=https;branch=main;tag=${PV}"
diff --git a/meta/recipes-gnome/gnome/adwaita-icon-theme_50.0.bb b/meta/recipes-gnome/gnome/adwaita-icon-theme_50.0.bb
index 8d26aae75c..b0dc59353d 100644
--- a/meta/recipes-gnome/gnome/adwaita-icon-theme_50.0.bb
+++ b/meta/recipes-gnome/gnome/adwaita-icon-theme_50.0.bb
@@ -5,7 +5,7 @@ HOMEPAGE = "https://gitlab.gnome.org/GNOME/adwaita-icon-theme"
 BUGTRACKER = "https://gitlab.gnome.org/GNOME/adwaita-icon-theme/issues"
 SECTION = "x11/gnome"
 
-LICENSE = "LGPL-3.0-only | CC-BY-SA-3.0"
+LICENSE = "CC-BY-SA-3.0 OR LGPL-3.0-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=c84cac88e46fc07647ea07e6c24eeb7c \
                     file://COPYING_CCBYSA3;md5=96143d33de3a79321b1006c4e8ed07e7 \
                     file://COPYING_LGPL;md5=e6a600fd5e1d9cbde2d983680233ad02"
diff --git a/meta/recipes-gnome/gobject-introspection/gobject-introspection_1.86.0.bb b/meta/recipes-gnome/gobject-introspection/gobject-introspection_1.86.0.bb
index 51cae5fff6..91525f99b7 100644
--- a/meta/recipes-gnome/gobject-introspection/gobject-introspection_1.86.0.bb
+++ b/meta/recipes-gnome/gobject-introspection/gobject-introspection_1.86.0.bb
@@ -6,7 +6,7 @@ generation for bindings, API verification and documentation generation."
 HOMEPAGE = "https://gitlab.gnome.org/GNOME/gobject-introspection"
 BUGTRACKER = "https://gitlab.gnome.org/GNOME/gobject-introspection/issues"
 SECTION = "libs"
-LICENSE = "LGPL-2.0-or-later & GPL-2.0-or-later & MIT"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.0-or-later AND MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=c434e8128a68bedd59b80b2ac1eb1c4a \
                     file://tools/compiler.c;endline=20;md5=fc5007fc20022720e6c0b0cdde41fabd \
                     file://giscanner/sourcescanner.c;endline=22;md5=194d6e0c1d00662f32d030ce44de8d39 \
diff --git a/meta/recipes-gnome/gtk+/gtk+3_3.24.52.bb b/meta/recipes-gnome/gtk+/gtk+3_3.24.52.bb
index 1fcc08443d..f385901bef 100644
--- a/meta/recipes-gnome/gtk+/gtk+3_3.24.52.bb
+++ b/meta/recipes-gnome/gtk+/gtk+3_3.24.52.bb
@@ -13,7 +13,7 @@ CVE_PRODUCT = "gnome:gtk gtk:gtk+"
 
 DEPENDS = "glib-2.0 cairo pango atk jpeg libpng gdk-pixbuf gdk-pixbuf-native"
 
-LICENSE = "LGPL-2.0-only & LGPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "LGPL-2.0-only AND LGPL-2.0-or-later AND LGPL-2.1-or-later"
 
 GNOMEBN = "gtk"
 
diff --git a/meta/recipes-gnome/gtk+/gtk4_4.22.4.bb b/meta/recipes-gnome/gtk+/gtk4_4.22.4.bb
index bb2e041595..1d2e4bf9b8 100644
--- a/meta/recipes-gnome/gtk+/gtk4_4.22.4.bb
+++ b/meta/recipes-gnome/gtk+/gtk4_4.22.4.bb
@@ -25,7 +25,7 @@ DEPENDS = " \
     tiff \
 "
 
-LICENSE = "LGPL-2.0-only & LGPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "LGPL-2.0-only AND LGPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = " \
     file://COPYING;md5=5f30f0716dfdd0d91eb439ebec522ec2 \
     file://gtk/gtk.h;endline=25;md5=61900d77e8d5bc67cf15ad93de9a3490 \
diff --git a/meta/recipes-graphics/cairo/cairo_1.18.4.bb b/meta/recipes-graphics/cairo/cairo_1.18.4.bb
index 0ed81166b5..ae448101d9 100644
--- a/meta/recipes-graphics/cairo/cairo_1.18.4.bb
+++ b/meta/recipes-graphics/cairo/cairo_1.18.4.bb
@@ -10,12 +10,12 @@ HOMEPAGE = "http://cairographics.org"
 BUGTRACKER = "https://gitlab.freedesktop.org/cairo/cairo/-/issues"
 SECTION = "libs"
 
-LICENSE = "(MPL-1.1 | LGPL-2.1-only) & GPL-3.0-or-later"
-LICENSE:${PN} = "MPL-1.1 | LGPL-2.1-only"
-LICENSE:${PN}-dev = "MPL-1.1 | LGPL-2.1-only"
-LICENSE:${PN}-doc = "MPL-1.1 | LGPL-2.1-only"
-LICENSE:${PN}-gobject = "MPL-1.1 | LGPL-2.1-only"
-LICENSE:${PN}-script-interpreter = "MPL-1.1 | LGPL-2.1-only"
+LICENSE = "GPL-3.0-or-later AND (LGPL-2.1-only OR MPL-1.1)"
+LICENSE:${PN} = "LGPL-2.1-only OR MPL-1.1"
+LICENSE:${PN}-dev = "LGPL-2.1-only OR MPL-1.1"
+LICENSE:${PN}-doc = "LGPL-2.1-only OR MPL-1.1"
+LICENSE:${PN}-gobject = "LGPL-2.1-only OR MPL-1.1"
+LICENSE:${PN}-script-interpreter = "LGPL-2.1-only OR MPL-1.1"
 LICENSE:${PN}-perf-utils = "GPL-3.0-or-later"
 # Adapt the licenses for cairo-dbg and cairo-src depending on whether
 # cairo-trace is being built.
diff --git a/meta/recipes-graphics/cantarell-fonts/cantarell-fonts_0.303.1.bb b/meta/recipes-graphics/cantarell-fonts/cantarell-fonts_0.303.1.bb
index 6e32d1b861..be961f4d33 100644
--- a/meta/recipes-graphics/cantarell-fonts/cantarell-fonts_0.303.1.bb
+++ b/meta/recipes-graphics/cantarell-fonts/cantarell-fonts_0.303.1.bb
@@ -7,7 +7,7 @@ DESCRIPTION = "The Cantarell font typeface is designed as a \
 
 HOMEPAGE = "https://gitlab.gnome.org/GNOME/cantarell-fonts/"
 SECTION = "fonts"
-LICENSE = "OFL-1.1 & Apache-2.0"
+LICENSE = "Apache-2.0 AND OFL-1.1"
 LIC_FILES_CHKSUM = "file://COPYING;md5=fb1ef92b6909969a472a6ea3c4e99cb7"
 
 inherit gnomebase allarch fontcache
diff --git a/meta/recipes-graphics/fontconfig/fontconfig_2.18.2.bb b/meta/recipes-graphics/fontconfig/fontconfig_2.18.2.bb
index d2b6050081..792d44b7f0 100644
--- a/meta/recipes-graphics/fontconfig/fontconfig_2.18.2.bb
+++ b/meta/recipes-graphics/fontconfig/fontconfig_2.18.2.bb
@@ -11,7 +11,7 @@ rasterize fonts."
 HOMEPAGE = "http://www.fontconfig.org"
 BUGTRACKER = "https://bugs.freedesktop.org/enter_bug.cgi?product=fontconfig"
 
-LICENSE = "MIT & PD"
+LICENSE = "MIT AND LicenseRef-PD"
 LIC_FILES_CHKSUM = "file://COPYING;md5=00252fd272bf2e722925613ad74cb6c7 \
                     file://src/fcfreetype.c;endline=23;md5=f7c0140c1b0387cf4cf45420b059847c \
                     "
diff --git a/meta/recipes-graphics/freetype/freetype_2.14.3.bb b/meta/recipes-graphics/freetype/freetype_2.14.3.bb
index a7a8585b15..924bcbfc4f 100644
--- a/meta/recipes-graphics/freetype/freetype_2.14.3.bb
+++ b/meta/recipes-graphics/freetype/freetype_2.14.3.bb
@@ -7,7 +7,7 @@ HOMEPAGE = "https://freetype.org/"
 BUGTRACKER = "https://gitlab.freedesktop.org/groups/freetype/-/issues"
 SECTION = "libs"
 
-LICENSE = "(FTL | GPL-2.0-or-later) & MIT"
+LICENSE = "MIT AND (FTL OR GPL-2.0-or-later)"
 LIC_FILES_CHKSUM = "file://LICENSE.TXT;md5=eeb073d5fb86d23c52bb9b84aa256307 \
                     file://docs/FTL.TXT;md5=72d844cd2f3bcaf6a85244b508032be7 \
                     file://docs/GPLv2.TXT;md5=8ef380476f642c20ebf40fecb0add2ec \
diff --git a/meta/recipes-graphics/glslang/glslang_1.4.350.1.bb b/meta/recipes-graphics/glslang/glslang_1.4.350.1.bb
index bc33931b3c..4d31a19e76 100644
--- a/meta/recipes-graphics/glslang/glslang_1.4.350.1.bb
+++ b/meta/recipes-graphics/glslang/glslang_1.4.350.1.bb
@@ -5,7 +5,7 @@ of the specifications for these languages. It is open and free for anyone to use
 either from a command line or programmatically."
 SECTION = "graphics"
 HOMEPAGE = "https://www.khronos.org/opengles/sdk/tools/Reference-Compiler"
-LICENSE = "BSD-3-Clause & BSD-2-Clause & MIT & Apache-2.0 & GPL-3-with-bison-exception"
+LICENSE = "Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND MIT AND GPL-3.0-or-later WITH Bison-exception-2.2"
 LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=50ff9d0fcde2d5b953ebe431c48e34e3"
 
 SRCREV = "275822a6261ee689aadb1da5f09a0ec2f058685c"
diff --git a/meta/recipes-graphics/jpeg/libjpeg-turbo_3.2.0.bb b/meta/recipes-graphics/jpeg/libjpeg-turbo_3.2.0.bb
index 98e2f00a57..8950441976 100644
--- a/meta/recipes-graphics/jpeg/libjpeg-turbo_3.2.0.bb
+++ b/meta/recipes-graphics/jpeg/libjpeg-turbo_3.2.0.bb
@@ -2,7 +2,7 @@ SUMMARY = "Hardware accelerated JPEG compression/decompression library"
 DESCRIPTION = "libjpeg-turbo is a derivative of libjpeg that uses SIMD instructions (MMX, SSE2, NEON) to accelerate baseline JPEG compression and decompression"
 HOMEPAGE = "http://libjpeg-turbo.org/"
 
-LICENSE = "IJG & BSD-3-Clause & Zlib"
+LICENSE = "BSD-3-Clause AND IJG AND Zlib"
 LIC_FILES_CHKSUM = "file://LICENSE.md;md5=d21daef3b4b318f77062055059c72934"
 
 DEPENDS:append:x86-64:class-target = " nasm-native"
diff --git a/meta/recipes-graphics/libmatchbox/libmatchbox_1.14.bb b/meta/recipes-graphics/libmatchbox/libmatchbox_1.14.bb
index 9de44d4c95..0712e9ecac 100644
--- a/meta/recipes-graphics/libmatchbox/libmatchbox_1.14.bb
+++ b/meta/recipes-graphics/libmatchbox/libmatchbox_1.14.bb
@@ -7,7 +7,7 @@ SECTION = "x11/libs"
 HOMEPAGE = "http://matchbox-project.org/"
 BUGTRACKER = "http://bugzilla.yoctoproject.com/"
 
-LICENSE = "LGPL-2.0-or-later & HPND"
+LICENSE = "HPND AND LGPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=87712c91ca9a2c2d475a0604c00f8f54 \
                     file://COPYING.HPND;md5=508defeea3622831e69c4827a31d6db0"
 
diff --git a/meta/recipes-graphics/libsdl2/libsdl2_2.32.10.bb b/meta/recipes-graphics/libsdl2/libsdl2_2.32.10.bb
index 091ce8ed8b..6038d3eb1d 100644
--- a/meta/recipes-graphics/libsdl2/libsdl2_2.32.10.bb
+++ b/meta/recipes-graphics/libsdl2/libsdl2_2.32.10.bb
@@ -7,7 +7,7 @@ BUGTRACKER = "http://bugzilla.libsdl.org/"
 
 SECTION = "libs"
 
-LICENSE = "Zlib & BSD-2-Clause"
+LICENSE = "BSD-2-Clause AND Zlib"
 LIC_FILES_CHKSUM = "\
     file://LICENSE.txt;md5=cbf0e3161523f9a9315b6b915c5c4457 \
     file://src/hidapi/LICENSE.txt;md5=7c3949a631240cb6c31c50f3eb696077 \
diff --git a/meta/recipes-graphics/mesa/mesa-demos_9.0.0.bb b/meta/recipes-graphics/mesa/mesa-demos_9.0.0.bb
index e7fb297448..ad17f7632b 100644
--- a/meta/recipes-graphics/mesa/mesa-demos_9.0.0.bb
+++ b/meta/recipes-graphics/mesa/mesa-demos_9.0.0.bb
@@ -5,7 +5,7 @@ HOMEPAGE = "http://mesa3d.org"
 BUGTRACKER = "https://bugs.freedesktop.org"
 SECTION = "x11"
 
-LICENSE = "MIT & PD"
+LICENSE = "MIT AND LicenseRef-PD"
 LIC_FILES_CHKSUM = "file://src/xdemos/glxgears.c;beginline=1;endline=5;md5=2c456e2fe0a0a05d31a72e076d404528 \
                     file://src/xdemos/glxdemo.c;beginline=1;endline=8;md5=b01d5ab1aee94d35b7efaa2ef48e1a06"
 
diff --git a/meta/recipes-graphics/piglit/piglit_git.bb b/meta/recipes-graphics/piglit/piglit_git.bb
index a020d67bbf..a3203464d1 100644
--- a/meta/recipes-graphics/piglit/piglit_git.bb
+++ b/meta/recipes-graphics/piglit/piglit_git.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Piglit is an open-source test suite for OpenGL and OpenCL \
 implementations."
 HOMEPAGE = "https://gitlab.freedesktop.org/mesa/piglit"
 BUGTRACKER = "https://gitlab.freedesktop.org/mesa/piglit/-/issues"
-LICENSE = "MIT & LGPL-2.0-or-later & GPL-3.0-only & GPL-2.0-or-later & BSD-3-Clause"
+LICENSE = "BSD-3-Clause AND GPL-2.0-or-later AND GPL-3.0-only AND LGPL-2.0-or-later AND MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=b2beded7103a3d8a442a2a0391d607b0"
 
 SRC_URI = "git://gitlab.freedesktop.org/mesa/piglit.git;protocol=https;branch=main \
diff --git a/meta/recipes-graphics/spir/spirv-headers_1.4.350.1.bb b/meta/recipes-graphics/spir/spirv-headers_1.4.350.1.bb
index c4a7be4045..c4af29652d 100644
--- a/meta/recipes-graphics/spir/spirv-headers_1.4.350.1.bb
+++ b/meta/recipes-graphics/spir/spirv-headers_1.4.350.1.bb
@@ -1,7 +1,7 @@
 SUMMARY = "Machine-readable files for the SPIR-V Registry"
 SECTION = "graphics"
 HOMEPAGE = "https://www.khronos.org/registry/spir-v"
-LICENSE = "MIT & CC-BY-4.0"
+LICENSE = "CC-BY-4.0 AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=a0dcaa512cc2dee95fe0fd791ee83a18"
 
 SRCREV = "ad9184e76a66b1001c29db9b0a3e87f646c64de0"
diff --git a/meta/recipes-graphics/vulkan/vulkan-headers_1.4.350.1.bb b/meta/recipes-graphics/vulkan/vulkan-headers_1.4.350.1.bb
index ff5108e013..f6d797cae7 100644
--- a/meta/recipes-graphics/vulkan/vulkan-headers_1.4.350.1.bb
+++ b/meta/recipes-graphics/vulkan/vulkan-headers_1.4.350.1.bb
@@ -7,7 +7,7 @@ HOMEPAGE = "https://www.khronos.org/vulkan/"
 BUGTRACKER = "https://github.com/KhronosGroup/Vulkan-Headers"
 SECTION = "libs"
 
-LICENSE = "Apache-2.0 & MIT"
+LICENSE = "Apache-2.0 AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE.md;md5=1bc355d8c4196f774c8b87ed1a8dd625"
 SRC_URI = "git://github.com/KhronosGroup/Vulkan-Headers.git;branch=main;protocol=https;tag=vulkan-sdk-${PV}"
 
diff --git a/meta/recipes-graphics/vulkan/vulkan-validation-layers_1.4.350.1.bb b/meta/recipes-graphics/vulkan/vulkan-validation-layers_1.4.350.1.bb
index 367438e1e1..163fe0beea 100644
--- a/meta/recipes-graphics/vulkan/vulkan-validation-layers_1.4.350.1.bb
+++ b/meta/recipes-graphics/vulkan/vulkan-validation-layers_1.4.350.1.bb
@@ -5,7 +5,7 @@ HOMEPAGE = "https://www.khronos.org/vulkan/"
 BUGTRACKER = "https://github.com/KhronosGroup/Vulkan-ValidationLayers"
 SECTION = "libs"
 
-LICENSE = "Apache-2.0 & MIT & BSL-1.0 "
+LICENSE = "Apache-2.0 AND BSL-1.0 AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=b1a17d548e004bfbbfaa0c40988b6b31"
 
 SRC_URI = "git://github.com/KhronosGroup/Vulkan-ValidationLayers.git;branch=vulkan-sdk-1.4.350;protocol=https;tag=vulkan-sdk-${PV}"
diff --git a/meta/recipes-graphics/xorg-font/encodings_1.1.0.bb b/meta/recipes-graphics/xorg-font/encodings_1.1.0.bb
index 7432c08ec0..4f240d17a6 100644
--- a/meta/recipes-graphics/xorg-font/encodings_1.1.0.bb
+++ b/meta/recipes-graphics/xorg-font/encodings_1.1.0.bb
@@ -4,7 +4,7 @@ DESCRIPTION = "The encodings that map to specific characters for a \
 number of Xorg and common fonts."
 
 require xorg-font-common.inc
-LICENSE = "PD"
+LICENSE = "LicenseRef-PD"
 LIC_FILES_CHKSUM = "file://COPYING;md5=9da93f2daf2d5572faa2bfaf0dbd9e76"
 PE = "1"
 
diff --git a/meta/recipes-graphics/xorg-font/font-util_1.4.2.bb b/meta/recipes-graphics/xorg-font/font-util_1.4.2.bb
index 2b38c10ad3..05f246bf20 100644
--- a/meta/recipes-graphics/xorg-font/font-util_1.4.2.bb
+++ b/meta/recipes-graphics/xorg-font/font-util_1.4.2.bb
@@ -2,7 +2,7 @@ SUMMARY = "X.Org font package creation/installation utilities"
 
 require xorg-font-common.inc
 
-LICENSE = "Unicode-TOU & MIT & X11 & BSD-2-Clause"
+LICENSE = "BSD-2-Clause AND MIT AND Unicode-TOU AND X11"
 LIC_FILES_CHKSUM = "file://COPYING;md5=756e7412ee04c80f5833cd2f35242f7a \
                     file://ucs2any.c;endline=28;md5=8357dc567fc628bd12696f15b2a33bcb \
                     file://bdftruncate.c;endline=26;md5=4f82ffc101a1b165eae9c6998abff937 \
diff --git a/meta/recipes-graphics/xorg-font/xorg-minimal-fonts.bb b/meta/recipes-graphics/xorg-font/xorg-minimal-fonts.bb
index 97c8be0a07..4e48b92fb2 100644
--- a/meta/recipes-graphics/xorg-font/xorg-minimal-fonts.bb
+++ b/meta/recipes-graphics/xorg-font/xorg-minimal-fonts.bb
@@ -5,7 +5,7 @@ HOMEPAGE = "http://www.x.org"
 SECTION = "x11/fonts"
 
 # Compiled fonts from https://gitlab.freedesktop.org/xorg/font/misc-misc/
-LICENSE = "PD"
+LICENSE = "LicenseRef-PD"
 LIC_FILES_CHKSUM = "file://../misc/fonts.dir;md5=82a143d94d6a974aafe97132d2d519ab \
                     file://../misc/cursor.pcf.gz;md5=40bc81001fef4c21ca08df4305014a2a"
 
diff --git a/meta/recipes-graphics/xorg-lib/libx11-compose-data_1.8.12.bb b/meta/recipes-graphics/xorg-lib/libx11-compose-data_1.8.12.bb
index 4bf9f07aba..fc0c602b96 100644
--- a/meta/recipes-graphics/xorg-lib/libx11-compose-data_1.8.12.bb
+++ b/meta/recipes-graphics/xorg-lib/libx11-compose-data_1.8.12.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "This package provides the compose data files for libx11."
 
 require xorg-lib-common.inc
 
-LICENSE = "MIT & BSD-1-Clause & HPND & HPND-sell-variant & ISC"
+LICENSE = "BSD-1-Clause AND HPND AND HPND-sell-variant AND ISC AND MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=1d49cdd2b386c5db11ec636d680b7116"
 
 XORG_PN = "libX11"
diff --git a/meta/recipes-graphics/xorg-lib/libx11_1.8.13.bb b/meta/recipes-graphics/xorg-lib/libx11_1.8.13.bb
index f5c27e0102..c06832e35e 100644
--- a/meta/recipes-graphics/xorg-lib/libx11_1.8.13.bb
+++ b/meta/recipes-graphics/xorg-lib/libx11_1.8.13.bb
@@ -6,7 +6,7 @@ basic functions of the window system."
 
 require xorg-lib-common.inc
 
-LICENSE = "MIT & BSD-1-Clause & HPND & HPND-sell-variant & ISC"
+LICENSE = "BSD-1-Clause AND HPND AND HPND-sell-variant AND ISC AND MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=8f2a1d92c4a50eedcf7c12672b908851"
 
 DEPENDS += "xorgproto \
diff --git a/meta/recipes-graphics/xorg-lib/libxfont2_2.0.8.bb b/meta/recipes-graphics/xorg-lib/libxfont2_2.0.8.bb
index 192c41d41c..33cf5816e0 100644
--- a/meta/recipes-graphics/xorg-lib/libxfont2_2.0.8.bb
+++ b/meta/recipes-graphics/xorg-lib/libxfont2_2.0.8.bb
@@ -6,7 +6,7 @@ such as freetype)."
 
 require xorg-lib-common.inc
 
-LICENSE = "MIT & MIT & BSD-4-Clause-UC & BSD-2-Clause"
+LICENSE = "BSD-2-Clause AND BSD-4-Clause-UC AND MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=a5d1388c9d40be70dbad35fa440443f7"
 
 DEPENDS += "freetype xtrans xorgproto libfontenc zlib"
diff --git a/meta/recipes-graphics/xorg-lib/libxfont_1.5.4.bb b/meta/recipes-graphics/xorg-lib/libxfont_1.5.4.bb
index 9ec7cc30f5..f70b4e2ad3 100644
--- a/meta/recipes-graphics/xorg-lib/libxfont_1.5.4.bb
+++ b/meta/recipes-graphics/xorg-lib/libxfont_1.5.4.bb
@@ -6,7 +6,7 @@ such as freetype)."
 
 require xorg-lib-common.inc
 
-LICENSE = "MIT & MIT & BSD-3-Clause"
+LICENSE = "BSD-3-Clause AND MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=a46c8040f2f737bcd0c435feb2ab1c2c"
 
 DEPENDS += "freetype xtrans xorgproto libfontenc zlib"
diff --git a/meta/recipes-graphics/xorg-lib/libxi_1.8.3.bb b/meta/recipes-graphics/xorg-lib/libxi_1.8.3.bb
index d7e778610e..240215379f 100644
--- a/meta/recipes-graphics/xorg-lib/libxi_1.8.3.bb
+++ b/meta/recipes-graphics/xorg-lib/libxi_1.8.3.bb
@@ -7,7 +7,7 @@ input devices other than the core X keyboard and pointer.  It allows \
 client programs to select input from these devices independently from \
 each other and independently from the core devices."
 
-LICENSE = "MIT & MIT"
+LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=17b064789fab936a1c58c4e13d965b0f \
                     file://src/XIGetDevFocus.c;endline=23;md5=cdfb0d435a33ec57ea0d1e8e395b729f"
 
diff --git a/meta/recipes-graphics/xorg-lib/libxkbcommon_1.13.2.bb b/meta/recipes-graphics/xorg-lib/libxkbcommon_1.13.2.bb
index ac02ad87c8..45e1352761 100644
--- a/meta/recipes-graphics/xorg-lib/libxkbcommon_1.13.2.bb
+++ b/meta/recipes-graphics/xorg-lib/libxkbcommon_1.13.2.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "libxkbcommon is a keymap compiler and support library which \
 processes a reduced subset of keymaps as defined by the XKB specification."
 HOMEPAGE = "http://www.xkbcommon.org"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=70eff33050c59f900f5b83275dcf1211"
-LICENSE = "MIT & MIT-open-group & HPND & HPND-sell-variant & X11"
+LICENSE = "HPND AND HPND-sell-variant AND MIT AND MIT-open-group AND X11"
 
 DEPENDS = "flex-native bison-native"
 
diff --git a/meta/recipes-graphics/xorg-lib/libxmu_1.3.1.bb b/meta/recipes-graphics/xorg-lib/libxmu_1.3.1.bb
index 9f0c65ee94..bd29691826 100644
--- a/meta/recipes-graphics/xorg-lib/libxmu_1.3.1.bb
+++ b/meta/recipes-graphics/xorg-lib/libxmu_1.3.1.bb
@@ -9,7 +9,7 @@ second library, libXmuu."
 
 require xorg-lib-common.inc
 
-LICENSE = "MIT & MIT"
+LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=e79ad4fcc53b9bfe0fc38507a56446b9"
 
 DEPENDS += "libxt libxext"
diff --git a/meta/recipes-graphics/xorg-lib/libxt_1.3.1.bb b/meta/recipes-graphics/xorg-lib/libxt_1.3.1.bb
index 97323ad282..5503605e7e 100644
--- a/meta/recipes-graphics/xorg-lib/libxt_1.3.1.bb
+++ b/meta/recipes-graphics/xorg-lib/libxt_1.3.1.bb
@@ -12,7 +12,7 @@ independent of any particular user interface policy or style."
 
 require xorg-lib-common.inc
 
-LICENSE = "MIT & MIT"
+LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=d6e9ca2c4b2276625afe025b0a2a4d8c"
 
 DEPENDS += "util-linux libxcb libsm virtual/libx11 xorgproto libxdmcp"
diff --git a/meta/recipes-graphics/xorg-lib/pixman_0.46.4.bb b/meta/recipes-graphics/xorg-lib/pixman_0.46.4.bb
index 468871f114..d86aa78b9a 100644
--- a/meta/recipes-graphics/xorg-lib/pixman_0.46.4.bb
+++ b/meta/recipes-graphics/xorg-lib/pixman_0.46.4.bb
@@ -15,7 +15,7 @@ UPSTREAM_CHECK_REGEX = "pixman-(?P<pver>\d+\.(\d*[02468])+(\.\d+)+)"
 
 PE = "1"
 
-LICENSE = "MIT & HPND-sell-variant"
+LICENSE = "HPND-sell-variant AND MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=14096c769ae0cbb5fcb94ec468be11b3 \
                     file://pixman/pixman-matrix.c;endline=21;md5=4a018dff3e4e25302724c88ff95c2456 \
                     file://pixman/pixman-arm-neon-asm.h;endline=24;md5=9a9cc1e51abbf1da58f4d9528ec9d49b \
diff --git a/meta/recipes-graphics/xorg-lib/xkeyboard-config_2.48.bb b/meta/recipes-graphics/xorg-lib/xkeyboard-config_2.48.bb
index dc0d1e1677..ef3579464d 100644
--- a/meta/recipes-graphics/xorg-lib/xkeyboard-config_2.48.bb
+++ b/meta/recipes-graphics/xorg-lib/xkeyboard-config_2.48.bb
@@ -9,7 +9,7 @@ systems."
 HOMEPAGE = "http://freedesktop.org/wiki/Software/XKeyboardConfig"
 BUGTRACKER = "https://bugs.freedesktop.org/enter_bug.cgi?product=xkeyboard-config"
 
-LICENSE = "MIT & MIT"
+LICENSE = "MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=faa756e04053029ddc602caf99e5ef1d"
 
 SRC_URI = "${XORG_MIRROR}/individual/data/xkeyboard-config/${BPN}-${PV}.tar.xz"
diff --git a/meta/recipes-graphics/xorg-xserver/xserver-xorg.inc b/meta/recipes-graphics/xorg-xserver/xserver-xorg.inc
index 782c1f76ca..7c0a24e58b 100644
--- a/meta/recipes-graphics/xorg-xserver/xserver-xorg.inc
+++ b/meta/recipes-graphics/xorg-xserver/xserver-xorg.inc
@@ -1,7 +1,7 @@
 SUMMARY = "The X.Org X server"
 HOMEPAGE = "http://www.x.org"
 SECTION = "x11/base"
-LICENSE = "MIT & Adobe-Display-PostScript & BSD-3-Clause & DEC-3-Clause & HPND & HPND-Netrek & HPND-sell-MIT-disclaimer-xserver & HPND-sell-variant & HPND-UC & ICU & ISC & MIT-open-group & NTP & SGI-B-2.0 & SMLNJ & X11 & X11-no-permit-persons"
+LICENSE = "Adobe-Display-PostScript AND BSD-3-Clause AND DEC-3-Clause AND HPND AND HPND-Netrek AND HPND-UC AND HPND-sell-MIT-disclaimer-xserver AND HPND-sell-variant AND ICU AND ISC AND MIT AND MIT-open-group AND NTP AND SGI-B-2.0 AND SMLNJ AND X11 AND X11-no-permit-persons"
 LIC_FILES_CHKSUM = "file://COPYING;md5=f8778cfcd90ece0e4b225f30182227ca"
 
 # xf86-*-* packages depend on an X server built with the xfree86 DDX
diff --git a/meta/recipes-graphics/xwayland/xwayland_24.1.13.bb b/meta/recipes-graphics/xwayland/xwayland_24.1.13.bb
index 41bf1687a2..1f32177ec5 100644
--- a/meta/recipes-graphics/xwayland/xwayland_24.1.13.bb
+++ b/meta/recipes-graphics/xwayland/xwayland_24.1.13.bb
@@ -6,7 +6,7 @@ the transition from X Window System to Wayland environments, providing \
 a way to run unported applications in the meantime."
 HOMEPAGE = "https://fedoraproject.org/wiki/Changes/XwaylandStandalone"
 
-LICENSE = "MIT & Adobe-Display-PostScript & BSD-3-Clause & DEC-3-Clause & HPND & HPND-Netrek & HPND-sell-MIT-disclaimer-xserver & HPND-sell-variant & HPND-UC & ICU & ISC & MIT-open-group & NTP & SGI-B-2.0 & SMLNJ & X11 & X11-no-permit-persons"
+LICENSE = "Adobe-Display-PostScript AND BSD-3-Clause AND DEC-3-Clause AND HPND AND HPND-Netrek AND HPND-UC AND HPND-sell-MIT-disclaimer-xserver AND HPND-sell-variant AND ICU AND ISC AND MIT AND MIT-open-group AND NTP AND SGI-B-2.0 AND SMLNJ AND X11 AND X11-no-permit-persons"
 LIC_FILES_CHKSUM = "file://COPYING;md5=f8778cfcd90ece0e4b225f30182227ca"
 
 SRC_URI = "https://www.x.org/archive/individual/xserver/xwayland-${PV}.tar.xz"
diff --git a/meta/recipes-kernel/dtc/dtc_1.8.1.bb b/meta/recipes-kernel/dtc/dtc_1.8.1.bb
index 5c3b1d7a6d..e2c7edcc46 100644
--- a/meta/recipes-kernel/dtc/dtc_1.8.1.bb
+++ b/meta/recipes-kernel/dtc/dtc_1.8.1.bb
@@ -2,7 +2,7 @@ SUMMARY = "Device Tree Compiler"
 HOMEPAGE = "https://devicetree.org/"
 DESCRIPTION = "The Device Tree Compiler is a toolchain for working with device tree source and binary files."
 SECTION = "bootloader"
-LICENSE = "GPL-2.0-only | BSD-2-Clause"
+LICENSE = "BSD-2-Clause OR GPL-2.0-only"
 
 LIC_FILES_CHKSUM = "file://GPL;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
                     file://BSD-2-Clause;md5=5d6306d1b08f8df623178dfd81880927 \
diff --git a/meta/recipes-kernel/kern-tools/kern-tools-native_git.bb b/meta/recipes-kernel/kern-tools/kern-tools-native_git.bb
index 2e13e4ca31..cb09800535 100644
--- a/meta/recipes-kernel/kern-tools/kern-tools-native_git.bb
+++ b/meta/recipes-kernel/kern-tools/kern-tools-native_git.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Powerful set of tools or managing Yocto Linux kernel sources \
 and configuration data. You can use these tools to make a single configuration \
 change, apply multiple patches, or work with your own kernel sources."
 HOMEPAGE = "https://www.yoctoproject.org/"
-LICENSE = "GPL-2.0-only & MIT"
+LICENSE = "GPL-2.0-only AND MIT"
 LIC_FILES_CHKSUM = "\
 	file://tools/kgit;beginline=5;endline=9;md5=9c30e971d435e249624278c3e343e501 \
 	file://Kconfiglib/LICENSE.txt;md5=712177a72a3937909543eda3ad1bfb7c \
diff --git a/meta/recipes-kernel/kmod/kmod_34.2.bb b/meta/recipes-kernel/kmod/kmod_34.2.bb
index e5923a64cf..892468a87e 100644
--- a/meta/recipes-kernel/kmod/kmod_34.2.bb
+++ b/meta/recipes-kernel/kmod/kmod_34.2.bb
@@ -5,7 +5,7 @@ SUMMARY = "Tools for managing Linux kernel modules"
 DESCRIPTION = "kmod is a set of tools to handle common tasks with Linux kernel modules like \
                insert, remove, list, check properties, resolve dependencies and aliases."
 HOMEPAGE = "http://kernel.org/pub/linux/utils/kernel/kmod/"
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LICENSE:libkmod = "LGPL-2.1-or-later"
 SECTION = "base"
 
diff --git a/meta/recipes-kernel/libtraceevent/libtraceevent_1.9.0.bb b/meta/recipes-kernel/libtraceevent/libtraceevent_1.9.0.bb
index 0dee0ebcc2..a44253a567 100644
--- a/meta/recipes-kernel/libtraceevent/libtraceevent_1.9.0.bb
+++ b/meta/recipes-kernel/libtraceevent/libtraceevent_1.9.0.bb
@@ -3,7 +3,7 @@
 
 SUMMARY = "API to access the kernel tracefs directory"
 HOMEPAGE = "https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/"
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://LICENSES/GPL-2.0;md5=e6a75371ba4d16749254a51215d13f97 \
                     file://LICENSES/LGPL-2.1;md5=b370887980db5dd40659b50909238dbd"
 SECTION = "libs"
diff --git a/meta/recipes-kernel/linux/linux-yocto-fitimage.bb b/meta/recipes-kernel/linux/linux-yocto-fitimage.bb
index 6ce1960a87..4dcffb6209 100644
--- a/meta/recipes-kernel/linux/linux-yocto-fitimage.bb
+++ b/meta/recipes-kernel/linux/linux-yocto-fitimage.bb
@@ -3,7 +3,7 @@ SECTION = "kernel"
 
 # If an initramfs is included in the FIT image more licenses apply.
 # But also the kernel uses more than one license (see Documentation/process/license-rules.rst)
-LICENSE = "GPL-2.0-with-Linux-syscall-note"
+LICENSE = "GPL-2.0-only WITH Linux-syscall-note"
 LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/GPL-2.0-with-Linux-syscall-note;md5=0bad96c422c41c3a94009dcfe1bff992"
 
 inherit linux-kernel-base kernel-fit-image
diff --git a/meta/recipes-kernel/linux/linux-yocto.inc b/meta/recipes-kernel/linux/linux-yocto.inc
index 4e230d405a..477eecb0ee 100644
--- a/meta/recipes-kernel/linux/linux-yocto.inc
+++ b/meta/recipes-kernel/linux/linux-yocto.inc
@@ -1,6 +1,6 @@
 SUMMARY = "Linux kernel"
 SECTION = "kernel"
-LICENSE = "GPL-2.0-with-Linux-syscall-note"
+LICENSE = "GPL-2.0-only WITH Linux-syscall-note"
 HOMEPAGE = "https://www.yoctoproject.org/"
 
 LIC_FILES_CHKSUM ?= "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7"
diff --git a/meta/recipes-kernel/lttng/babeltrace2_2.1.2.bb b/meta/recipes-kernel/lttng/babeltrace2_2.1.2.bb
index b0cd6efde1..7c151bf729 100644
--- a/meta/recipes-kernel/lttng/babeltrace2_2.1.2.bb
+++ b/meta/recipes-kernel/lttng/babeltrace2_2.1.2.bb
@@ -2,7 +2,7 @@ SUMMARY = "Babeltrace2 - Trace Format Babel Tower"
 DESCRIPTION = "Babeltrace provides trace read and write libraries in host side, as well as a trace converter, which used to convert LTTng 2.0 traces into human-readable log."
 HOMEPAGE = "http://babeltrace.org/"
 BUGTRACKER = "https://bugs.lttng.org/projects/babeltrace"
-LICENSE = "MIT & GPL-2.0-only & LGPL-2.1-only & BSD-2-Clause & BSD-4-Clause & GPL-3.0-or-later & CC-BY-SA-4.0 & PSF-2.0"
+LICENSE = "BSD-2-Clause AND BSD-4-Clause AND CC-BY-SA-4.0 AND GPL-2.0-only AND GPL-3.0-or-later AND LGPL-2.1-only AND MIT AND PSF-2.0"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=f6b015e4f388d6e78adb1b1f9a887d06"
 
 DEPENDS = "glib-2.0 util-linux popt bison-native flex-native virtual/libiconv swig-native"
diff --git a/meta/recipes-kernel/lttng/lttng-modules_2.15.2.bb b/meta/recipes-kernel/lttng/lttng-modules_2.15.2.bb
index e281ed2fd8..49f2bc8eb2 100644
--- a/meta/recipes-kernel/lttng/lttng-modules_2.15.2.bb
+++ b/meta/recipes-kernel/lttng/lttng-modules_2.15.2.bb
@@ -2,7 +2,7 @@ SECTION = "devel"
 SUMMARY = "Linux Trace Toolkit KERNEL MODULE"
 DESCRIPTION = "The lttng-modules 2.0 package contains the kernel tracer modules"
 HOMEPAGE = "https://lttng.org/"
-LICENSE = "LGPL-2.1-only & GPL-2.0-only & MIT"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-only AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=018e002dbdda3306682e394ddd65fa32"
 
 inherit module
diff --git a/meta/recipes-kernel/lttng/lttng-tools_2.15.1.bb b/meta/recipes-kernel/lttng/lttng-tools_2.15.1.bb
index 9fdb0ede72..9a56d1711b 100644
--- a/meta/recipes-kernel/lttng/lttng-tools_2.15.1.bb
+++ b/meta/recipes-kernel/lttng/lttng-tools_2.15.1.bb
@@ -5,7 +5,7 @@ to extract program execution details from the Linux operating system \
 and interpret them."
 HOMEPAGE = "https://github.com/lttng/lttng-tools"
 
-LICENSE = "GPL-2.0-only & LGPL-2.1-only"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=40ef17463fbd6f377db3c47b1cbaded8 \
                     file://LICENSES/GPL-2.0;md5=e68f69a54b44ba526ad7cb963e18fbce \
                     file://LICENSES/LGPL-2.1;md5=9920968d0f2ff585ce61fae30344dd95"
diff --git a/meta/recipes-kernel/lttng/lttng-ust_2.15.1.bb b/meta/recipes-kernel/lttng/lttng-ust_2.15.1.bb
index d731aa2eb0..9f1d0961a1 100644
--- a/meta/recipes-kernel/lttng/lttng-ust_2.15.1.bb
+++ b/meta/recipes-kernel/lttng/lttng-ust_2.15.1.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "The LTTng UST 2.x package contains the userspace tracer library t
 HOMEPAGE = "http://lttng.org/ust"
 BUGTRACKER = "https://bugs.lttng.org/projects/lttng-ust"
 
-LICENSE = "LGPL-2.1-or-later & MIT & GPL-2.0-only"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-or-later AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=3b04e8f34dbcf08198c6618d05e8fe7b"
 
 PYTHON_OPTION = "am_cv_python_pyexecdir='${PYTHON_SITEPACKAGES_DIR}' \
diff --git a/meta/recipes-multimedia/alsa/alsa-lib_1.2.16.1.bb b/meta/recipes-multimedia/alsa/alsa-lib_1.2.16.1.bb
index 0c81e3cb3b..1033250204 100644
--- a/meta/recipes-multimedia/alsa/alsa-lib_1.2.16.1.bb
+++ b/meta/recipes-multimedia/alsa/alsa-lib_1.2.16.1.bb
@@ -4,7 +4,7 @@ provides a level of abstraction over the /dev interfaces provided by the kernel
 HOMEPAGE = "http://www.alsa-project.org"
 BUGTRACKER = "http://alsa-project.org/main/index.php/Bug_Tracking"
 SECTION = "libs/multimedia"
-LICENSE = "LGPL-2.1-only & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=a916467b91076e631dd8edb7424769c7 \
                     file://src/socket.c;md5=285675b45e83f571c6a957fe4ab79c93;beginline=9;endline=24 \
                     "
diff --git a/meta/recipes-multimedia/alsa/alsa-plugins_1.2.12.bb b/meta/recipes-multimedia/alsa/alsa-plugins_1.2.12.bb
index 7db0c4d677..793f6a7eba 100644
--- a/meta/recipes-multimedia/alsa/alsa-plugins_1.2.12.bb
+++ b/meta/recipes-multimedia/alsa/alsa-plugins_1.2.12.bb
@@ -16,7 +16,7 @@ CVE_PRODUCT = "alsa"
 # consistent with the libsamplerate license. However, if the licensee has a
 # commercial license for libsamplerate, the samplerate plugin may be used under
 # the terms of LGPL-2.1-only like the rest of the plugins.
-LICENSE = "LGPL-2.1-only & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=a916467b91076e631dd8edb7424769c7 \
                     file://COPYING.GPL;md5=59530bdf33659b29e73d4adb9f9f6552 \
                     file://m4/attributes.m4;endline=33;md5=bb8c6b2a67ac15156961e242fec33e50 \
diff --git a/meta/recipes-multimedia/alsa/alsa-tools_1.2.15.bb b/meta/recipes-multimedia/alsa/alsa-tools_1.2.15.bb
index 1228176fb9..b58f106cec 100644
--- a/meta/recipes-multimedia/alsa/alsa-tools_1.2.15.bb
+++ b/meta/recipes-multimedia/alsa/alsa-tools_1.2.15.bb
@@ -5,7 +5,7 @@ firmware loaders for pcmcia, USB and the hdsp devices."
 HOMEPAGE = "http://www.alsa-project.org"
 BUGTRACKER = "http://alsa-project.org/main/index.php/Bug_Tracking"
 SECTION = "console/utils"
-LICENSE = "GPL-2.0-only & LGPL-2.0-or-later"
+LICENSE = "GPL-2.0-only AND LGPL-2.0-or-later"
 DEPENDS = "alsa-lib"
 
 LIC_FILES_CHKSUM = "file://hdsploader/COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
diff --git a/meta/recipes-multimedia/ffmpeg/ffmpeg_8.1.2.bb b/meta/recipes-multimedia/ffmpeg/ffmpeg_8.1.2.bb
index 38eccbf2ad..26614762e5 100644
--- a/meta/recipes-multimedia/ffmpeg/ffmpeg_8.1.2.bb
+++ b/meta/recipes-multimedia/ffmpeg/ffmpeg_8.1.2.bb
@@ -5,7 +5,7 @@ DESCRIPTION = "FFmpeg is the leading multimedia framework, able to decode, encod
 HOMEPAGE = "https://www.ffmpeg.org/"
 SECTION = "libs"
 
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later & ISC & MIT & BSD-2-Clause & BSD-3-Clause & IJG"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause AND GPL-2.0-or-later AND IJG AND ISC AND LGPL-2.1-or-later AND MIT"
 LICENSE:${PN} = "GPL-2.0-or-later"
 LICENSE:libavcodec = "${@bb.utils.contains('PACKAGECONFIG', 'gpl', 'GPL-2.0-or-later', 'LGPL-2.1-or-later', d)}"
 LICENSE:libavdevice = "${@bb.utils.contains('PACKAGECONFIG', 'gpl', 'GPL-2.0-or-later', 'LGPL-2.1-or-later', d)}"
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.28.4.bb b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.28.4.bb
index a406f4783f..4051bcf7f2 100644
--- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.28.4.bb
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.28.4.bb
@@ -15,7 +15,7 @@ SRC_URI[sha256sum] = "332b7320f30c60f2d5941446d03b9d05e3781f2c2561befbe88718bd77
 
 S = "${UNPACKDIR}/gst-plugins-bad-${PV}"
 
-LICENSE = "LGPL-2.1-or-later & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=4fbd65380cdd255951079008b364516c"
 
 DEPENDS += "gstreamer1.0-plugins-base"
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-ugly_1.28.4.bb b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-ugly_1.28.4.bb
index 4c0811a056..04df81f6d8 100644
--- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-ugly_1.28.4.bb
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-ugly_1.28.4.bb
@@ -8,7 +8,7 @@ BUGTRACKER = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-ugly/-/issues
 LIC_FILES_CHKSUM = "file://COPYING;md5=a6f89e2100d9b6cdffcea4f398e37343 \
                    "
 
-LICENSE = "LGPL-2.1-or-later & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LICENSE_FLAGS = "commercial"
 
 SRC_URI = " \
diff --git a/meta/recipes-multimedia/libtiff/tiff_4.7.2.bb b/meta/recipes-multimedia/libtiff/tiff_4.7.2.bb
index 3462803cb2..47f1b3f4dc 100644
--- a/meta/recipes-multimedia/libtiff/tiff_4.7.2.bb
+++ b/meta/recipes-multimedia/libtiff/tiff_4.7.2.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Library provides support for the Tag Image File Format \
 (TIFF), a widely used format for storing image data.  This library \
 provide means to easily access and create TIFF image files."
 HOMEPAGE = "http://www.libtiff.org/"
-LICENSE = "libtiff & BSD-4.3TAHOE"
+LICENSE = "BSD-4.3TAHOE AND libtiff"
 LIC_FILES_CHKSUM = "file://LICENSE.md;md5=4ab490c3088a0acff254eb2f8c577547"
 
 CVE_PRODUCT = "libtiff"
diff --git a/meta/recipes-multimedia/pulseaudio/pulseaudio.inc b/meta/recipes-multimedia/pulseaudio/pulseaudio.inc
index 30305fa44a..975929918f 100644
--- a/meta/recipes-multimedia/pulseaudio/pulseaudio.inc
+++ b/meta/recipes-multimedia/pulseaudio/pulseaudio.inc
@@ -45,7 +45,7 @@ SECTION = "libs/multimedia"
 # libdbus is a system library that is covered by the "special exception" in
 # GPLv2's section 3, and therefore libdbus's GPL license doesn't affect
 # PulseAudio.
-LICENSE = "LGPL-2.1-or-later & MIT & BSD-3-Clause"
+LICENSE = "BSD-3-Clause AND LGPL-2.1-or-later AND MIT"
 
 LIC_FILES_CHKSUM = "file://LICENSE;md5=0e5cd938de1a7a53ea5adac38cc10c39 \
                     file://GPL;md5=4325afd396febcb659c36b49533135d4 \
diff --git a/meta/recipes-multimedia/sbc/sbc_2.2.bb b/meta/recipes-multimedia/sbc/sbc_2.2.bb
index ace764d5d3..0050144c21 100644
--- a/meta/recipes-multimedia/sbc/sbc_2.2.bb
+++ b/meta/recipes-multimedia/sbc/sbc_2.2.bb
@@ -2,7 +2,7 @@ SUMMARY = "SBC Audio Codec"
 DESCRIPTION = "Bluetooth low-complexity, subband codec (SBC) library."
 HOMEPAGE = "https://www.bluez.org"
 SECTION = "libs"
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LICENSE:${PN} = "LGPL-2.1-or-later"
 LICENSE:${PN}-examples = "GPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=12f884d2ae1ff87c09e5b7ccc2c4ca7e \
diff --git a/meta/recipes-rt/rt-tests/rt-tests_git.bb b/meta/recipes-rt/rt-tests/rt-tests_git.bb
index 1f48e143d4..aea3d82e20 100644
--- a/meta/recipes-rt/rt-tests/rt-tests_git.bb
+++ b/meta/recipes-rt/rt-tests/rt-tests_git.bb
@@ -3,7 +3,7 @@ HOMEPAGE = "https://wiki.linuxfoundation.org/realtime/documentation/start"
 DESCRIPTION = "The main aim of the PREEMPT_RT patch is to minimize the amount of kernel code that is non-preemptible Therefore several substitution mechanisms and new mechanisms are implemented."
 SECTION = "tests"
 DEPENDS = "linux-libc-headers virtual/libc numactl"
-LICENSE = "GPL-2.0-only & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-only AND GPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=751419260aa954499f7abaabaa882bbe"
 
 require rt-tests.inc
diff --git a/meta/recipes-sato/matchbox-desktop/matchbox-desktop_2.3.bb b/meta/recipes-sato/matchbox-desktop/matchbox-desktop_2.3.bb
index 85e5300520..69a8c7472f 100644
--- a/meta/recipes-sato/matchbox-desktop/matchbox-desktop_2.3.bb
+++ b/meta/recipes-sato/matchbox-desktop/matchbox-desktop_2.3.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "A lightweight windows manager for embedded systems. It uses the d
 HOMEPAGE = "http://matchbox-project.org/"
 BUGTRACKER = "http://bugzilla.yoctoproject.org/"
 
-LICENSE = "GPL-2.0-or-later & LGPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=94d55d512a9ba36caa9b7df079bae19f \
                     file://src/desktop.c;endline=20;md5=2e488557570c7dee53bfd0567e4273a9 \
                     file://src/main.c;endline=19;md5=5d2234b35efa927ab3ae36ebac52ba59"
diff --git a/meta/recipes-sato/pcmanfm/pcmanfm_1.3.2.bb b/meta/recipes-sato/pcmanfm/pcmanfm_1.3.2.bb
index 2e463cd7b3..844589d43f 100644
--- a/meta/recipes-sato/pcmanfm/pcmanfm_1.3.2.bb
+++ b/meta/recipes-sato/pcmanfm/pcmanfm_1.3.2.bb
@@ -2,7 +2,7 @@ SUMMARY = "Fast lightweight tabbed filemanager"
 DESCRIPTION = "A free file manager application and the standard file manager of LXDE."
 HOMEPAGE = "http://pcmanfm.sourceforge.net/"
 
-LICENSE = "GPL-2.0-only & GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
                     file://src/pcmanfm.h;endline=22;md5=417b3855771a3a87f8ad753d994491f0 \
                     file://src/gseal-gtk-compat.h;endline=21;md5=46922c8691f58d124f9420fe16149ce2"
diff --git a/meta/recipes-sato/sato-screenshot/sato-screenshot_0.3.bb b/meta/recipes-sato/sato-screenshot/sato-screenshot_0.3.bb
index a2af4faed3..27850a8b98 100644
--- a/meta/recipes-sato/sato-screenshot/sato-screenshot_0.3.bb
+++ b/meta/recipes-sato/sato-screenshot/sato-screenshot_0.3.bb
@@ -2,7 +2,7 @@ SUMMARY = "Ultra-simple screen capture utility, aimed at handheld devices"
 HOMEPAGE = "http://www.o-hand.com"
 BUGTRACKER = "http://bugzilla.yoctoproject.org/"
 
-LICENSE = "GPL-2.0-only & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-only AND GPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=94d55d512a9ba36caa9b7df079bae19f \
                     file://main.c;endline=9;md5=023e14d6404d0a961eb97cbd011fc141 \
                     file://screenshot-ui.h;endline=9;md5=638d9ffa83e9325a36df224166ed6ad0"
diff --git a/meta/recipes-sato/webkit/webkitgtk_2.52.5.bb b/meta/recipes-sato/webkit/webkitgtk_2.52.5.bb
index 1a834733ce..945d7b77cb 100644
--- a/meta/recipes-sato/webkit/webkitgtk_2.52.5.bb
+++ b/meta/recipes-sato/webkit/webkitgtk_2.52.5.bb
@@ -2,7 +2,7 @@ SUMMARY = "WebKit web rendering engine for the GTK+ platform"
 HOMEPAGE = "https://www.webkitgtk.org/"
 BUGTRACKER = "https://bugs.webkit.org/"
 
-LICENSE = "BSD-2-Clause & LGPL-2.0-or-later"
+LICENSE = "BSD-2-Clause AND LGPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://Source/JavaScriptCore/COPYING.LIB;md5=d0c6d6397a5d84286dda758da57bd691 \
                     file://Source/WebCore/LICENSE-APPLE;md5=4646f90082c40bcf298c285f8bab0b12 \
                     file://Source/WebCore/LICENSE-LGPL-2;md5=36357ffde2b64ae177b2494445b79d21 \
diff --git a/meta/recipes-support/aspell/aspell_0.60.8.2.bb b/meta/recipes-support/aspell/aspell_0.60.8.2.bb
index 5b4fab7c35..60d3376678 100644
--- a/meta/recipes-support/aspell/aspell_0.60.8.2.bb
+++ b/meta/recipes-support/aspell/aspell_0.60.8.2.bb
@@ -10,7 +10,7 @@ SECTION = "console/utils"
 
 HOMEPAGE = "http://aspell.net/"
 
-LICENSE = "LGPL-2.0-only | LGPL-2.1-only"
+LICENSE = "LGPL-2.0-only OR LGPL-2.1-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=7fbc338309ac38fefcd64b04bb903e34"
 
 SRC_URI = "${GNU_MIRROR}/aspell/aspell-${PV}.tar.gz"
diff --git a/meta/recipes-support/attr/acl_2.4.0.bb b/meta/recipes-support/attr/acl_2.4.0.bb
index ef9ee492a0..d470989acc 100644
--- a/meta/recipes-support/attr/acl_2.4.0.bb
+++ b/meta/recipes-support/attr/acl_2.4.0.bb
@@ -7,7 +7,7 @@ BUGTRACKER = "http://savannah.nongnu.org/bugs/?group=acl"
 
 SECTION = "libs"
 
-LICENSE = "LGPL-2.1-or-later & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LICENSE:${PN} = "GPL-2.0-or-later"
 LICENSE:lib${BPN} = "LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://doc/COPYING;md5=c781d70ed2b4d48995b790403217a249 \
diff --git a/meta/recipes-support/attr/attr_2.6.0.bb b/meta/recipes-support/attr/attr_2.6.0.bb
index aa5e7eb98f..4af6c4fac2 100644
--- a/meta/recipes-support/attr/attr_2.6.0.bb
+++ b/meta/recipes-support/attr/attr_2.6.0.bb
@@ -6,7 +6,7 @@ SECTION = "libs"
 
 DEPENDS = "virtual/libintl"
 
-LICENSE = "LGPL-2.1-or-later & GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LICENSE:${PN} = "GPL-2.0-or-later"
 LICENSE:lib${BPN} = "LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://doc/COPYING;md5=2d0aa14b3fce4694e4f615e30186335f \
diff --git a/meta/recipes-support/boost/boost-1.91.0.inc b/meta/recipes-support/boost/boost-1.91.0.inc
index ba3f6062f3..dc68d7a336 100644
--- a/meta/recipes-support/boost/boost-1.91.0.inc
+++ b/meta/recipes-support/boost/boost-1.91.0.inc
@@ -4,7 +4,7 @@
 # intended to be widely useful, and are in regular use by
 # thousands of programmers across a broad spectrum of applications.
 HOMEPAGE = "http://www.boost.org/"
-LICENSE = "BSL-1.0 & MIT & Python-2.0"
+LICENSE = "BSL-1.0 AND MIT AND Python-2.0"
 LIC_FILES_CHKSUM = "file://LICENSE_1_0.txt;md5=e4224ccaecb14d942c71d31bef20d78c"
 
 BOOST_VER = "${@"_".join(d.getVar("PV").split("."))}"
diff --git a/meta/recipes-support/ca-certificates/ca-certificates_20260601.bb b/meta/recipes-support/ca-certificates/ca-certificates_20260601.bb
index 1bc64fe34a..90a8568947 100644
--- a/meta/recipes-support/ca-certificates/ca-certificates_20260601.bb
+++ b/meta/recipes-support/ca-certificates/ca-certificates_20260601.bb
@@ -4,7 +4,7 @@ SSL-based applications to check for the authenticity of SSL connections. \
 This derived from Debian's CA Certificates."
 HOMEPAGE = "http://packages.debian.org/sid/ca-certificates"
 SECTION = "misc"
-LICENSE = "GPL-2.0-or-later & MPL-2.0"
+LICENSE = "GPL-2.0-or-later AND MPL-2.0"
 LIC_FILES_CHKSUM = "file://debian/copyright;md5=dab7c7cea776d1a1648deb0052c72647"
 
 # This is needed to ensure we can run the postinst at image creation time
diff --git a/meta/recipes-support/debianutils/debianutils_5.23.2.bb b/meta/recipes-support/debianutils/debianutils_5.23.2.bb
index 29581c2b95..06bc4060c9 100644
--- a/meta/recipes-support/debianutils/debianutils_5.23.2.bb
+++ b/meta/recipes-support/debianutils/debianutils_5.23.2.bb
@@ -5,7 +5,7 @@ you may use them directly. "
 HOMEPAGE = "https://packages.debian.org/sid/debianutils"
 BUGTRACKER = "https://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=debianutils;dist=unstable"
 SECTION = "base"
-LICENSE = "GPL-2.0-only & SMAIL-GPL"
+LICENSE = "GPL-2.0-only AND SMAIL-GPL"
 LIC_FILES_CHKSUM = "file://debian/copyright;md5=4b667f30411d21bc8fd7db85d502a8e9"
 
 SRC_URI = "git://salsa.debian.org/debian/debianutils.git;protocol=https;branch=master;tag=debian/${PV} \
diff --git a/meta/recipes-support/gmp/gmp_6.3.0.bb b/meta/recipes-support/gmp/gmp_6.3.0.bb
index 8f18bdca1b..579e112fc2 100644
--- a/meta/recipes-support/gmp/gmp_6.3.0.bb
+++ b/meta/recipes-support/gmp/gmp_6.3.0.bb
@@ -1,6 +1,6 @@
 require gmp.inc
 
-LICENSE = "GPL-2.0-or-later | LGPL-3.0-or-later"
+LICENSE = "GPL-2.0-or-later OR LGPL-3.0-or-later"
 
 LIC_FILES_CHKSUM = "\
         file://COPYING;md5=d32239bcb673463ab874e80d47fae504 \
diff --git a/meta/recipes-support/gnupg/gnupg_2.5.20.bb b/meta/recipes-support/gnupg/gnupg_2.5.20.bb
index 4146b12824..fc594793cc 100644
--- a/meta/recipes-support/gnupg/gnupg_2.5.20.bb
+++ b/meta/recipes-support/gnupg/gnupg_2.5.20.bb
@@ -5,7 +5,7 @@ and sign your data and communications; it features a versatile key \
 management system, along with access modules for all kinds of public \
 key directories."
 HOMEPAGE = "http://www.gnupg.org/"
-LICENSE = "GPL-3.0-only & LGPL-3.0-only"
+LICENSE = "GPL-3.0-only AND LGPL-3.0-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=189af8afca6d6075ba6c9e0aa8077626 \
                     file://COPYING.LGPL3;md5=a2b6bf2cb38ee52619e60f30a1fc7257"
 
diff --git a/meta/recipes-support/gnutls/gnutls_3.8.13.bb b/meta/recipes-support/gnutls/gnutls_3.8.13.bb
index 943864d4ba..e360db6fff 100644
--- a/meta/recipes-support/gnutls/gnutls_3.8.13.bb
+++ b/meta/recipes-support/gnutls/gnutls_3.8.13.bb
@@ -4,7 +4,7 @@ TLS and DTLS protocols and technologies around them."
 HOMEPAGE = "https://gnutls.org/"
 BUGTRACKER = "https://savannah.gnu.org/support/?group=gnutls"
 
-LICENSE = "GPL-3.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-3.0-or-later AND LGPL-2.1-or-later"
 LICENSE:${PN} = "LGPL-2.1-or-later"
 LICENSE:${PN}-xx = "LGPL-2.1-or-later"
 LICENSE:${PN}-bin = "GPL-3.0-or-later"
diff --git a/meta/recipes-support/gnutls/libtasn1_4.21.0.bb b/meta/recipes-support/gnutls/libtasn1_4.21.0.bb
index 4570488c4c..236948a861 100644
--- a/meta/recipes-support/gnutls/libtasn1_4.21.0.bb
+++ b/meta/recipes-support/gnutls/libtasn1_4.21.0.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "A highly portable C library that encodes and decodes \
 DER/BER data following an ASN.1 schema. "
 HOMEPAGE = "http://www.gnu.org/software/libtasn1/"
 
-LICENSE = "GPL-3.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-3.0-or-later AND LGPL-2.1-or-later"
 LICENSE:${PN}-bin = "GPL-3.0-or-later"
 LICENSE:${PN} = "LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=1ebbd3e34237af26da5dc08a4e440464 \
diff --git a/meta/recipes-support/gpgme/gpgme_2.1.2.bb b/meta/recipes-support/gpgme/gpgme_2.1.2.bb
index 328b544212..32db75fdfd 100644
--- a/meta/recipes-support/gpgme/gpgme_2.1.2.bb
+++ b/meta/recipes-support/gpgme/gpgme_2.1.2.bb
@@ -3,8 +3,8 @@ DESCRIPTION = "GnuPG Made Easy (GPGME) is a library designed to make access to G
 HOMEPAGE = "http://www.gnupg.org/gpgme.html"
 BUGTRACKER = "https://bugs.g10code.com/gnupg/index"
 
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later & GPL-3.0-or-later"
-LICENSE:${PN} = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-2.1-or-later"
+LICENSE:${PN} = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LICENSE:${PN}-tool = "GPL-3.0-or-later"
 
 LIC_FILES_CHKSUM = "file://COPYING;md5=94d55d512a9ba36caa9b7df079bae19f \
diff --git a/meta/recipes-support/hwdata/hwdata_0.409.bb b/meta/recipes-support/hwdata/hwdata_0.409.bb
index 543d24dc4e..7117c0857c 100644
--- a/meta/recipes-support/hwdata/hwdata_0.409.bb
+++ b/meta/recipes-support/hwdata/hwdata_0.409.bb
@@ -4,7 +4,7 @@ configuration data, such as the pci.ids and usb.ids databases."
 HOMEPAGE = "https://github.com/vcrhonek/hwdata"
 SECTION = "System/Base"
 
-LICENSE = "GPL-2.0-or-later | X11"
+LICENSE = "GPL-2.0-or-later OR X11"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=1556547711e8246992b999edd9445a57"
 
 SRC_URI = "git://github.com/vcrhonek/${BPN}.git;branch=master;protocol=https;tag=v${PV}"
diff --git a/meta/recipes-support/icu/icu_78.3.bb b/meta/recipes-support/icu/icu_78.3.bb
index ad920f3ef4..c057505e3c 100644
--- a/meta/recipes-support/icu/icu_78.3.bb
+++ b/meta/recipes-support/icu/icu_78.3.bb
@@ -5,7 +5,7 @@ internationalization (I18N) and globalization (G11N), giving applications the \
 same results on all platforms."
 HOMEPAGE = "https://icu.unicode.org/"
 
-LICENSE = "ICU & MIT"
+LICENSE = "ICU AND MIT"
 DEPENDS = "icu-native"
 
 CVE_PRODUCT = "international_components_for_unicode"
diff --git a/meta/recipes-support/libassuan/libassuan_3.0.2.bb b/meta/recipes-support/libassuan/libassuan_3.0.2.bb
index 2ae2fa77cb..3c4ce4f1a3 100644
--- a/meta/recipes-support/libassuan/libassuan_3.0.2.bb
+++ b/meta/recipes-support/libassuan/libassuan_3.0.2.bb
@@ -5,7 +5,7 @@ Both, server and client side functions are provided. "
 HOMEPAGE = "http://www.gnupg.org/related_software/libassuan/"
 BUGTRACKER = "https://bugs.g10code.com/gnupg/index"
 
-LICENSE = "GPL-3.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-3.0-or-later AND LGPL-2.1-or-later"
 LICENSE:${PN} = "LGPL-2.1-or-later"
 LICENSE:${PN}-doc = "GPL-3.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=f27defe1e96c2e1ecd4e0c9be8967949 \
diff --git a/meta/recipes-support/libatomic-ops/libatomic-ops_7.10.0.bb b/meta/recipes-support/libatomic-ops/libatomic-ops_7.10.0.bb
index 82adf417a3..6bb25fcec5 100644
--- a/meta/recipes-support/libatomic-ops/libatomic-ops_7.10.0.bb
+++ b/meta/recipes-support/libatomic-ops/libatomic-ops_7.10.0.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Package provides semi-portable access to hardware-provided atomic
 HOMEPAGE = "https://github.com/bdwgc/libatomic_ops/"
 SECTION = "optional"
 PROVIDES += "libatomics-ops"
-LICENSE = "GPL-2.0-only & MIT"
+LICENSE = "GPL-2.0-only AND MIT"
 LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
                     file://LICENSE;md5=5700d28353dfa2f191ca9b1bd707865e \
                     "
diff --git a/meta/recipes-support/libbsd/libbsd_0.12.2.bb b/meta/recipes-support/libbsd/libbsd_0.12.2.bb
index 39ecda26af..2ebc3e1003 100644
--- a/meta/recipes-support/libbsd/libbsd_0.12.2.bb
+++ b/meta/recipes-support/libbsd/libbsd_0.12.2.bb
@@ -21,7 +21,7 @@ HOMEPAGE = "https://libbsd.freedesktop.org/wiki/"
 # License: ISC
 # License: ISC-Original
 # License: public-domain
-LICENSE = "BSD-3-Clause & ISC & PD"
+LICENSE = "BSD-3-Clause AND ISC AND LicenseRef-PD"
 LIC_FILES_CHKSUM = "file://COPYING;md5=9b087a0981a1fcad42efbba6d4925a0f"
 
 SECTION = "libs"
diff --git a/meta/recipes-support/libcap-ng/libcap-ng.inc b/meta/recipes-support/libcap-ng/libcap-ng.inc
index 32f37987d9..5c1a7fdfea 100644
--- a/meta/recipes-support/libcap-ng/libcap-ng.inc
+++ b/meta/recipes-support/libcap-ng/libcap-ng.inc
@@ -3,7 +3,7 @@ DESCRIPTION = "The libcap-ng library is intended to make programming \
 with POSIX capabilities much easier than the traditional libcap library."
 HOMEPAGE = "https://github.com/stevegrubb/libcap-ng"
 SECTION = "base"
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=94d55d512a9ba36caa9b7df079bae19f \
 		    file://COPYING.LIB;md5=e3eda01d9815f8d24aae2dbd89b68b06"
 
diff --git a/meta/recipes-support/libevent/libevent_2.1.13.bb b/meta/recipes-support/libevent/libevent_2.1.13.bb
index 431018f0f3..6566e73bbd 100644
--- a/meta/recipes-support/libevent/libevent_2.1.13.bb
+++ b/meta/recipes-support/libevent/libevent_2.1.13.bb
@@ -8,7 +8,7 @@ HOMEPAGE = "http://libevent.org/"
 BUGTRACKER = "https://github.com/libevent/libevent/issues"
 SECTION = "libs"
 
-LICENSE = "BSD-3-Clause & MIT"
+LICENSE = "BSD-3-Clause AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=17f20574c0b154d12236d5fbe964f549"
 
 SRC_URI = "${GITHUB_BASE_URI}/download/release-${PV}-stable/${BP}-stable.tar.gz \
diff --git a/meta/recipes-support/libfm/libfm_1.3.2.bb b/meta/recipes-support/libfm/libfm_1.3.2.bb
index ab29ce4b40..95f821eee7 100644
--- a/meta/recipes-support/libfm/libfm_1.3.2.bb
+++ b/meta/recipes-support/libfm/libfm_1.3.2.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "LibFM provides file management functions built on top of Glib/GIO
 giving a convenient higher-level API."
 HOMEPAGE = "http://pcmanfm.sourceforge.net/"
 
-LICENSE = "GPL-2.0-or-later & LGPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=4641e94ec96f98fabc56ff9cc48be14b \
                     file://src/fm.h;beginline=8;endline=21;md5=ef1f84da64b3c01cca447212f7ef6007 \
                     file://src/base/fm-config.h;beginline=10;endline=23;md5=ef1f84da64b3c01cca447212f7ef6007 \
diff --git a/meta/recipes-support/libgcrypt/libgcrypt_1.12.2.bb b/meta/recipes-support/libgcrypt/libgcrypt_1.12.2.bb
index 1eb6c472a3..697deed607 100644
--- a/meta/recipes-support/libgcrypt/libgcrypt_1.12.2.bb
+++ b/meta/recipes-support/libgcrypt/libgcrypt_1.12.2.bb
@@ -6,9 +6,9 @@ HOMEPAGE = "http://directory.fsf.org/project/libgcrypt/"
 BUGTRACKER = "https://bugs.g10code.com/gnupg/index"
 SECTION = "libs"
 
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later & BSD-3-Clause"
-LICENSE:${PN} = "LGPL-2.1-or-later & BSD-3-Clause"
-LICENSE:${PN}-dev = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "BSD-3-Clause AND GPL-2.0-or-later AND LGPL-2.1-or-later"
+LICENSE:${PN} = "BSD-3-Clause AND LGPL-2.1-or-later"
+LICENSE:${PN}-dev = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 
 LIC_FILES_CHKSUM = "file://COPYING;md5=570a9b3749dd0463a1778803b12a6dce \
                     file://COPYING.LIB;md5=4bf661c1e3793e55c8d1051bc5e0ae21 \
diff --git a/meta/recipes-support/libgpg-error/libgpg-error_1.61.bb b/meta/recipes-support/libgpg-error/libgpg-error_1.61.bb
index de3918a998..982f6edc63 100644
--- a/meta/recipes-support/libgpg-error/libgpg-error_1.61.bb
+++ b/meta/recipes-support/libgpg-error/libgpg-error_1.61.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "Contains common error codes and error handling functions used by
 HOMEPAGE = "http://www.gnupg.org/related_software/libgpg-error/"
 BUGTRACKER = "https://bugs.g10code.com/gnupg/index"
 
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-or-later"
+LICENSE = "GPL-2.0-or-later AND LGPL-2.1-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
                     file://COPYING.LIB;md5=2d5025d4aa3495befef8f17206a5b0a1 \
                     file://src/gpg-error.h.in;beginline=2;endline=18;md5=f146974b5d59380f15c9f0eaaac4cbec \
diff --git a/meta/recipes-support/libical/libical_4.0.3.bb b/meta/recipes-support/libical/libical_4.0.3.bb
index d7001d4a8c..dff79bcc4f 100644
--- a/meta/recipes-support/libical/libical_4.0.3.bb
+++ b/meta/recipes-support/libical/libical_4.0.3.bb
@@ -5,7 +5,7 @@ calendar clients can communicate with calendar servers so users can store \
 their calendar data and arrange meetings with other users. "
 HOMEPAGE = "https://github.com/libical/libical"
 BUGTRACKER = "https://github.com/libical/libical/issues"
-LICENSE = "LGPL-2.1-only | MPL-2.0"
+LICENSE = "LGPL-2.1-only OR MPL-2.0"
 LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=6d9294493d031c817783b0400a126c89 \
                     "
 SECTION = "libs"
diff --git a/meta/recipes-support/libjitterentropy/libjitterentropy_3.6.3.bb b/meta/recipes-support/libjitterentropy/libjitterentropy_3.6.3.bb
index 36721d201c..776cfe9785 100644
--- a/meta/recipes-support/libjitterentropy/libjitterentropy_3.6.3.bb
+++ b/meta/recipes-support/libjitterentropy/libjitterentropy_3.6.3.bb
@@ -4,7 +4,7 @@ It does not depend on any system resource other than a high-resolution time \
 stamp. It is a small-scale, yet fast entropy source that is viable in almost \
 all environments and on a lot of CPU architectures."
 HOMEPAGE = "http://www.chronox.de/jent.html"
-LICENSE = "BSD-3-Clause | GPL-2.0-only"
+LICENSE = "BSD-3-Clause OR GPL-2.0-only"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=e01027c4ad1fe5a4768f8488c945d491 \
                     file://LICENSE.gplv2;md5=eb723b61539feef013de476e68b5c50a \
                     file://LICENSE.bsd;md5=66a5cedaf62c4b2637025f049f9b826f \
diff --git a/meta/recipes-support/libksba/libksba_1.8.0.bb b/meta/recipes-support/libksba/libksba_1.8.0.bb
index 938bda67f5..553fd336cc 100644
--- a/meta/recipes-support/libksba/libksba_1.8.0.bb
+++ b/meta/recipes-support/libksba/libksba_1.8.0.bb
@@ -5,8 +5,8 @@ the implemented protocols and presents the data in a consistent way. The \
 library does not rely on another cryptographic library but provides \
 hooks for easy integration with Libgcrypt. "
 HOMEPAGE = "http://www.gnupg.org/related_software/libksba/"
-LICENSE = "GPL-3.0-or-later & (GPL-2.0-or-later | LGPL-3.0-or-later)"
-LICENSE:${PN} = "GPL-2.0-or-later | LGPL-3.0-or-later"
+LICENSE = "GPL-3.0-or-later AND (GPL-2.0-or-later OR LGPL-3.0-or-later)"
+LICENSE:${PN} = "GPL-2.0-or-later OR LGPL-3.0-or-later"
 LICENSE:${PN}-doc = "GPL-3.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING;md5=fd541d83f75d038c4e0617b672ed8bda \
                     file://COPYING.GPLv2;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
diff --git a/meta/recipes-support/libmd/libmd_1.2.0.bb b/meta/recipes-support/libmd/libmd_1.2.0.bb
index 1aee94a054..b630708961 100644
--- a/meta/recipes-support/libmd/libmd_1.2.0.bb
+++ b/meta/recipes-support/libmd/libmd_1.2.0.bb
@@ -5,7 +5,7 @@ libmd (FreeBSD, DragonflyBSD, macOS, Solaris) libraries and \
 lacking on others like GNU systems."
 HOMEPAGE = "https://www.hadrons.org/software/libmd/"
 
-LICENSE = "BSD-3-Clause & BSD-2-Clause"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://COPYING;md5=261bf22602270e2b29c53930d409a3ca"
 
 SRC_URI = "https://archive.hadrons.org/software/libmd/libmd-${PV}.tar.xz \
diff --git a/meta/recipes-support/libpcre/libpcre2_10.47.bb b/meta/recipes-support/libpcre/libpcre2_10.47.bb
index 70079e0b65..35330845d1 100644
--- a/meta/recipes-support/libpcre/libpcre2_10.47.bb
+++ b/meta/recipes-support/libpcre/libpcre2_10.47.bb
@@ -7,7 +7,7 @@ not the original PCRE 8.x series."
 SUMMARY = "Perl Compatible Regular Expressions version 2"
 HOMEPAGE = "http://www.pcre.org"
 SECTION = "devel"
-LICENSE = "BSD-3-Clause & BSD-2-Clause & MIT"
+LICENSE = "BSD-2-Clause AND BSD-3-Clause AND MIT"
 LIC_FILES_CHKSUM = "file://LICENCE.md;md5=6720bf3bcff57543b915c2b22e526df0 \
                     file://deps/sljit/LICENSE;md5=97268427d235c41c0be238ce8e5fda17 \
                     "
diff --git a/meta/recipes-support/libunistring/libunistring_1.4.2.bb b/meta/recipes-support/libunistring/libunistring_1.4.2.bb
index 8f6cc27193..d3bfe976c9 100644
--- a/meta/recipes-support/libunistring/libunistring_1.4.2.bb
+++ b/meta/recipes-support/libunistring/libunistring_1.4.2.bb
@@ -13,7 +13,7 @@ DESCRIPTION = "Text files are nowadays usually encoded in Unicode, and may\
 
 HOMEPAGE = "http://www.gnu.org/software/libunistring/"
 SECTION = "devel"
-LICENSE = "LGPL-3.0-or-later | GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later OR LGPL-3.0-or-later"
 LIC_FILES_CHKSUM = "file://COPYING.LIB;md5=6a6a8e020838b23406c81b19c1d46df6 \
                     file://README;beginline=45;endline=65;md5=3a896a943b4da2c551e6be1af27eff8d \
                     file://doc/libunistring.texi;md5=55cc91e1fe09c7aec78b6dc932202300 \
diff --git a/meta/recipes-support/liburcu/liburcu_0.15.6.bb b/meta/recipes-support/liburcu/liburcu_0.15.6.bb
index 1cb349f55d..140488eaa3 100644
--- a/meta/recipes-support/liburcu/liburcu_0.15.6.bb
+++ b/meta/recipes-support/liburcu/liburcu_0.15.6.bb
@@ -5,7 +5,7 @@ with the number of cores. "
 HOMEPAGE = "http://lttng.org/urcu"
 BUGTRACKER = "http://lttng.org/project/issues"
 
-LICENSE = "LGPL-2.1-or-later & MIT"
+LICENSE = "LGPL-2.1-or-later AND MIT"
 LIC_FILES_CHKSUM = "file://LICENSE.md;md5=c2a92498b6e88e276f986877995425b8 \
                     file://include/urcu/urcu.h;beginline=1;endline=18;md5=d35fe8cc2613ca70e0a624ed8bf6fef9 \
                     file://include/urcu/uatomic/x86.h;beginline=1;endline=6;md5=358d69272ba7b5f85e29e342430d440c \
diff --git a/meta/recipes-support/lz4/lz4_1.10.0.bb b/meta/recipes-support/lz4/lz4_1.10.0.bb
index fae5796c2b..61a7237f83 100644
--- a/meta/recipes-support/lz4/lz4_1.10.0.bb
+++ b/meta/recipes-support/lz4/lz4_1.10.0.bb
@@ -2,7 +2,7 @@ SUMMARY = "Extremely Fast Compression algorithm"
 DESCRIPTION = "LZ4 is a very fast lossless compression algorithm, providing compression speed at 400 MB/s per core, scalable with multi-cores CPU. It also features an extremely fast decoder, with speed in multiple GB/s per core, typically reaching RAM speed limits on multi-core systems."
 HOMEPAGE = "https://github.com/lz4/lz4"
 
-LICENSE = "BSD-2-Clause | GPL-2.0-or-later"
+LICENSE = "BSD-2-Clause OR GPL-2.0-or-later"
 LIC_FILES_CHKSUM = "file://lib/LICENSE;md5=5cd5f851b52ec832b10eedb3f01f885a \
                     file://programs/COPYING;md5=492daf447d6db0e5eb344a7922e7ec25 \
                     file://LICENSE;md5=c111c47e301c2ffe8776729b40b44477 \
diff --git a/meta/recipes-support/nettle/nettle_4.0.bb b/meta/recipes-support/nettle/nettle_4.0.bb
index c66677c08a..0e05804057 100644
--- a/meta/recipes-support/nettle/nettle_4.0.bb
+++ b/meta/recipes-support/nettle/nettle_4.0.bb
@@ -5,7 +5,7 @@ DESCRIPTION = "It tries to solve a problem of providing a common set of \
 cryptographic algorithms for higher-level applications by implementing a \
 context-independent set of cryptographic algorithms"
 SECTION = "libs"
-LICENSE = "LGPL-3.0-or-later | GPL-2.0-or-later"
+LICENSE = "GPL-2.0-or-later OR LGPL-3.0-or-later"
 
 LIC_FILES_CHKSUM = "file://COPYING.LESSERv3;md5=3000208d539ec061b899bce1d9ce9404 \
                     file://COPYINGv2;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
diff --git a/meta/recipes-support/numactl/numactl_2.0.19.bb b/meta/recipes-support/numactl/numactl_2.0.19.bb
index 38c09199c3..5fd35f1770 100644
--- a/meta/recipes-support/numactl/numactl_2.0.19.bb
+++ b/meta/recipes-support/numactl/numactl_2.0.19.bb
@@ -3,7 +3,7 @@ HOMEPAGE = "http://oss.sgi.com/projects/libnuma/"
 DESCRIPTION = "Simple NUMA policy support. It consists of a numactl program \
 to run other programs with a specific NUMA policy and a libnuma to do \
 allocations with NUMA policy in applications."
-LICENSE = "GPL-2.0-only & LGPL-2.1-only"
+LICENSE = "GPL-2.0-only AND LGPL-2.1-only"
 SECTION = "apps"
 
 inherit autotools-brokensep ptest
diff --git a/meta/recipes-support/re2c/re2c_4.5.1.bb b/meta/recipes-support/re2c/re2c_4.5.1.bb
index ee3774017f..ad33ef6a0b 100644
--- a/meta/recipes-support/re2c/re2c_4.5.1.bb
+++ b/meta/recipes-support/re2c/re2c_4.5.1.bb
@@ -3,7 +3,7 @@ DESCRIPTION = "A free and open-source lexer generator for C, C++ and Go. It comp
 HOMEPAGE = "http://re2c.org/"
 BUGTRACKER = "https://github.com/skvadrik/re2c/issues"
 SECTION = "devel"
-LICENSE = "PD"
+LICENSE = "LicenseRef-PD"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=64eca4d8a3b67f9dc7656094731a2c8d"
 
 SRC_URI = "${GITHUB_BASE_URI}/download/${PV}/${BPN}-${PV}.tar.xz"
diff --git a/meta/recipes-support/taglib/taglib_2.3.bb b/meta/recipes-support/taglib/taglib_2.3.bb
index b29f28702d..26839cdbdb 100644
--- a/meta/recipes-support/taglib/taglib_2.3.bb
+++ b/meta/recipes-support/taglib/taglib_2.3.bb
@@ -2,7 +2,7 @@ SUMMARY = "Library for reading and editing the meta-data of popular audio format
 DESCRIPTION = "Platform-independent library (tested on Windows/Linux) for reading and writing metadata in media files, including video, audio, and photo formats. This is a convenient one-stop-shop to present or tag all your media collection, regardless of which format/container these might use. You can read/write the standard or more common tags/properties of a media, or you can also create and retrieve your own custom tags."
 SECTION = "libs/multimedia"
 HOMEPAGE = "http://taglib.github.io/"
-LICENSE = "LGPL-2.1-only | MPL-1.1"
+LICENSE = "LGPL-2.1-only OR MPL-1.1"
 LIC_FILES_CHKSUM = "file://COPYING.LGPL;md5=4fbd65380cdd255951079008b364516c \
                     file://COPYING.MPL;md5=bfe1f75d606912a4111c90743d6c7325 \
                     file://taglib/audioproperties.h;beginline=1;endline=24;md5=9df2c7399519b7310568a7c55042ecee"
diff --git a/meta/recipes-support/utfcpp/utfcpp_4.1.1.bb b/meta/recipes-support/utfcpp/utfcpp_4.1.1.bb
index 80da59bf90..c2ad0939a1 100644
--- a/meta/recipes-support/utfcpp/utfcpp_4.1.1.bb
+++ b/meta/recipes-support/utfcpp/utfcpp_4.1.1.bb
@@ -1,9 +1,9 @@
 SUMMARY = " UTF-8 with C++ in a Portable Way"
 HOMEPAGE = "https://github.com/nemtrif/utfcpp"
 
-LICENSE = "BSL-1.0 & MIT"
+LICENSE = "BSL-1.0 AND MIT"
 LICENSE:${PN} = "BSL-1.0"
-LICENSE:${PN}-ptest = "BSL-1.0 & MIT"
+LICENSE:${PN}-ptest = "BSL-1.0 AND MIT"
 
 LIC_FILES_CHKSUM = "file://LICENSE;md5=e4224ccaecb14d942c71d31bef20d78c \
                     file://tests/ftest.h;endline=25;md5=d33c6488d3b003723a5f17ac984db030"
diff --git a/meta/recipes-support/vte/vte_0.84.0.bb b/meta/recipes-support/vte/vte_0.84.0.bb
index 70cc6b3c99..43aa280c56 100644
--- a/meta/recipes-support/vte/vte_0.84.0.bb
+++ b/meta/recipes-support/vte/vte_0.84.0.bb
@@ -2,7 +2,7 @@ SUMMARY = "Virtual terminal emulator GTK+ widget library"
 DESCRIPTION = "VTE provides a virtual terminal widget for GTK applications."
 HOMEPAGE = "https://wiki.gnome.org/Apps/Terminal/VTE"
 BUGTRACKER = "https://bugzilla.gnome.org/buglist.cgi?product=vte"
-LICENSE = "GPL-3.0-only & LGPL-3.0-or-later & MIT"
+LICENSE = "GPL-3.0-only AND LGPL-3.0-or-later AND MIT"
 LICENSE:libvte = "LGPL-3.0-or-later"
 
 LIC_FILES_CHKSUM = " \
diff --git a/meta/recipes-support/xxhash/xxhash_0.8.3.bb b/meta/recipes-support/xxhash/xxhash_0.8.3.bb
index 15436113b1..75b34bb0a2 100644
--- a/meta/recipes-support/xxhash/xxhash_0.8.3.bb
+++ b/meta/recipes-support/xxhash/xxhash_0.8.3.bb
@@ -2,7 +2,7 @@ SUMMARY = "Extremely fast non-cryptographic hash algorithm"
 DESCRIPTION = "xxHash is an extremely fast non-cryptographic hash algorithm, \
 working at speeds close to RAM limits."
 HOMEPAGE = "http://www.xxhash.com/"
-LICENSE = "BSD-2-Clause & GPL-2.0-only"
+LICENSE = "BSD-2-Clause AND GPL-2.0-only"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=13be6b481ff5616f77dda971191bb29b \
                     file://cli/COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \
                     "
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [OE-core][PATCH 22/22] meta-selftest: libxpm: Fix license
  2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
                   ` (20 preceding siblings ...)
  2026-07-14 18:31 ` [OE-core][PATCH 21/22] Convert licenses to SPDX expressions Joshua Watt
@ 2026-07-14 18:31 ` Joshua Watt
  21 siblings, 0 replies; 23+ messages in thread
From: Joshua Watt @ 2026-07-14 18:31 UTC (permalink / raw)
  To: openembedded-core; +Cc: Joshua Watt

The license for this software is X11 and MIT (verified using the SPDX
license matcher website), so fix it up to be the correct SPDX
expression.

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 meta-skeleton/recipes-skeleton/libxpm/libxpm_3.5.6.bb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/meta-skeleton/recipes-skeleton/libxpm/libxpm_3.5.6.bb b/meta-skeleton/recipes-skeleton/libxpm/libxpm_3.5.6.bb
index 1fcbbdd65e..bcfa65ab17 100644
--- a/meta-skeleton/recipes-skeleton/libxpm/libxpm_3.5.6.bb
+++ b/meta-skeleton/recipes-skeleton/libxpm/libxpm_3.5.6.bb
@@ -1,7 +1,7 @@
 require recipes-graphics/xorg-lib/xorg-lib-common.inc
 
 DESCRIPTION = "X11 Pixmap library"
-LICENSE = "X-BSD"
+LICENSE = "MIT AND X11"
 LIC_FILES_CHKSUM = "file://COPYING;md5=3e07763d16963c3af12db271a31abaa5"
 DEPENDS += "libxext"
 PE = "1"
-- 
2.54.0



^ permalink raw reply related	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2026-07-14 19:04 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14 18:31 [OE-core][PATCH 00/22] Rework LICENSE to be SPDX License Expressions Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 01/22] scripts/pull-spdx-licenses.py: Add exceptions Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 02/22] Add SPDX License Exceptions Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 03/22] Add SPDX license library Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 04/22] Parse LICENSE as SPDX Expression Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 05/22] linux-firmware: Convert to SPDX license strings Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 06/22] meta-selftest: Add NO_GENERIC_LICENSE Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 07/22] convert-spdx-licenses: Convert to valid SPDX expressions Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 08/22] gcc-common.inc: Remove LICENSE Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 09/22] gcc: Update license Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 10/22] xz: Replace deprecated SPDX identifier Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 11/22] autoconf-archive: " Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 12/22] gnu-config: " Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 13/22] libglvnd: " Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 14/22] flac: " Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 15/22] libgit2: " Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 16/22] Fix up licenses Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 17/22] lib: oe: license: Rework package licenses matching Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 18/22] classes/go-mod-update-modules: Switch to SPDX license Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 19/22] license: Remove tidy_licenses() Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 20/22] meta-selftest: Change license on test recipes Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 21/22] Convert licenses to SPDX expressions Joshua Watt
2026-07-14 18:31 ` [OE-core][PATCH 22/22] meta-selftest: libxpm: Fix license Joshua Watt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).