From f7ae316b8a627719000810ba5ccdb82e007b3bbd Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Mon, 3 Aug 2026 10:16:31 +0200 Subject: [PATCH] docs(cra): add SBOM for CRA complience (#10352) --- .github/workflows/code_generation.yml | 34 +- .github/workflows/static_checks.yml | 6 +- COPYRIGHTS.md | 49 +- SECURITY.md | 35 + docs/src/introduction/meta.json | 1 + docs/src/introduction/security.mdx | 100 ++ sbom/README.md | 86 ++ sbom/lvgl.spdx.json | 1271 +++++++++++++++++++++++++ sbom/requirements.txt | 4 + sbom/third_party.json | 214 +++++ scripts/generate_copyrights.py | 94 ++ scripts/generate_sbom.py | 392 ++++++++ scripts/validate_sbom.py | 67 ++ 13 files changed, 2334 insertions(+), 19 deletions(-) create mode 100644 SECURITY.md create mode 100644 docs/src/introduction/security.mdx create mode 100644 sbom/README.md create mode 100644 sbom/lvgl.spdx.json create mode 100644 sbom/requirements.txt create mode 100644 sbom/third_party.json create mode 100755 scripts/generate_copyrights.py create mode 100755 scripts/generate_sbom.py create mode 100644 scripts/validate_sbom.py diff --git a/.github/workflows/code_generation.yml b/.github/workflows/code_generation.yml index 19cd44eb1f..cd287d8a16 100644 --- a/.github/workflows/code_generation.yml +++ b/.github/workflows/code_generation.yml @@ -29,7 +29,9 @@ jobs: python-version: 3.12 - name: Install dependencies - run: python3 -m pip install kconfiglib pytest + # sbom/requirements.txt pins the SBOM validator so an unreviewed + # upstream release cannot silently change or break the compliance gate. + run: python3 -m pip install kconfiglib pytest -r sbom/requirements.txt # ------------------------------------------------------------------ # Unit tests for the config-headers generator itself. @@ -57,6 +59,28 @@ jobs: include/lvgl/config/lv_conf_kconfig.h \ || (echo "::error::Generated config headers are out of date. Run scripts/generators/config_headers.py and commit the result."; exit 1) + # ------------------------------------------------------------------ + # COPYRIGHTS.md and the SPDX SBOM (sbom/) are generated from + # sbom/third_party.json. These fail if a committed output is stale. + # ------------------------------------------------------------------ + - name: "Check: COPYRIGHTS.md is up to date" + id: copyrights + continue-on-error: true + run: python3 scripts/generate_copyrights.py --check + + - name: "Check: SPDX SBOM is up to date" + id: sbom + continue-on-error: true + run: python3 scripts/generate_sbom.py --check + + # ------------------------------------------------------------------ + # The SBOM validates against the official SPDX 3.0.1 JSON Schema. + # ------------------------------------------------------------------ + - name: "Check: SPDX SBOM is schema-valid" + id: sbom_schema + continue-on-error: true + run: python3 scripts/validate_sbom.py + # ------------------------------------------------------------------ # Final gate – fail the job if any generator above is out of date. # This gives us full output from every generator before failing. @@ -65,7 +89,10 @@ jobs: - name: "Gate: fail if any generator check failed" if: | steps.config-headers-tests.outcome == 'failure' || - steps.config-headers.outcome == 'failure' + steps.config-headers.outcome == 'failure' || + steps.copyrights.outcome == 'failure' || + steps.sbom.outcome == 'failure' || + steps.sbom_schema.outcome == 'failure' run: | echo "Code generation results:" echo "------------------------" @@ -81,6 +108,9 @@ jobs: print_result "config-headers-tests" "${{ steps.config-headers-tests.outcome }}" print_result "config-headers" "${{ steps.config-headers.outcome }}" + print_result "copyrights" "${{ steps.copyrights.outcome }}" + print_result "sbom" "${{ steps.sbom.outcome }}" + print_result "sbom_schema" "${{ steps.sbom_schema.outcome }}" echo "------------------------" echo "A generator test failed, or a generated file is out of date. See above for details." diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index 3071414f18..629add1fd6 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -9,7 +9,7 @@ on: # https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#concurrency # Ensure that only one commit will be running tests at a time on each PR concurrency: - group: ${{ github.ref }}-${{ github.workflow }} + group: ${{ github.ref }}-${{ github.workflow }} cancel-in-progress: true jobs: @@ -42,7 +42,7 @@ jobs: # ------------------------------------------------------------------ # - All #includes inside must be valid relative paths. # - Angle-bracket includes must be in the explicit allow-list - # - see `ALLOWED_EXTERNAL_HEADERS` in `scripts/static_checks/check_headers.py` + # - see `ALLOWED_EXTERNAL_HEADERS` in `scripts/static_checks/check_headers.py` # - forbidden headers (stdint.h etc.) must use LV_*_INCLUDE macros. # ------------------------------------------------------------------ - name: "Check: include path validity + angle-bracket policy" @@ -67,7 +67,7 @@ jobs: run: python scripts/static_checks/check_headers.py deprecated # ------------------------------------------------------------------ - # Every header file inside `src` must use `lvgl_public.h` to access + # Every header file inside `src` must use `lvgl_public.h` to access # the public API # ------------------------------------------------------------------ - name: "Check: no direct public include from source files" diff --git a/COPYRIGHTS.md b/COPYRIGHTS.md index a720b7194a..9fdab33c30 100644 --- a/COPYRIGHTS.md +++ b/COPYRIGHTS.md @@ -1,67 +1,88 @@ LVGL uses the following third-party libraries. -For the licenses, see the corresponding `LICENSE.txt` file in each library’s folder. +Each entry lists its SPDX license expression below. The full license text is, for most libraries, found in the corresponding library folder (see the paths); some libraries only reference their license rather than shipping the full text. A machine-readable inventory is available in `sbom/`. **Barcode (Barcode generator)** - Path: src/libs/barcode - Source: https://github.com/fhunleth/code128 - -**Expat (XML parser)** -- Path: src/libs/expat -- Source: https://github.com/libexpat/libexpat +- License: BSD-2-Clause **FreeType (Font rendering library)** - Path: src/libs/freetype - Source: https://github.com/freetype/freetype +- License: FTL OR GPL-2.0-or-later - Note: Only the interfaces are used; FreeType itself is not part of LVGL. +**Liberation Sans (default demo font)** +- Path: src/libs/freetype/LiberationSans-Regular.ttf +- Source: https://github.com/liberationfonts/liberation-fonts +- License: OFL-1.1 +- Note: Font asset bundled alongside the FreeType interface; licensed separately from FreeType. + **LodePNG (PNG decoder)** - Path: src/libs/lodepng - Source: https://github.com/lvandeve/lodepng +- License: Zlib **LZ4 (Compression/Decompression)** - Path: src/libs/lz4 - Source: https://github.com/lz4/lz4 +- License: BSD-2-Clause **QR Code (QR code generator)** - Path: src/libs/qrcode - Source: https://github.com/nayuki/QR-Code-generator +- License: MIT **ThorVG (Vector graphics rendering)** - Path: src/libs/thorvg - Source: https://github.com/thorvg/thorvg +- License: MIT + +**RapidJSON (JSON parser/generator)** +- Path: src/libs/thorvg/rapidjson +- Source: https://github.com/Tencent/rapidjson +- License: MIT AND BSD-3-Clause +- Note: Bundled inside the ThorVG tree (used by ThorVG's Lottie parser); licensed separately from ThorVG. The bundled msinttypes helper (rapidjson/msinttypes) is BSD-3-Clause (Copyright (c) 2006-2013 Alexander Chemeris), hence the combined license expression. **TinyTTF** - Path: src/libs/tiny_ttf - Source: - - https://github.com/nothings/stb (*Only parts are integrated*) - - https://github.com/codewitch-honey-crisis/tiny_ttf (*Modified version of the original STB library*) + - https://github.com/nothings/stb (*Only parts are integrated*) + - https://github.com/codewitch-honey-crisis/tiny_ttf (*Modified version of the original STB library*) +- License: MIT OR Unlicense **TJPGD (JPEG decoder)** - Path: src/libs/tjpgd - Source: http://elm-chan.org/fsw/tjpgd/00index.html +- License: LicenseRef-TJpgDec **TLSF (Two-Level Segregate Fit memory allocator)** - Path: src/stdlib/builtin - Source: https://github.com/mattconte/tlsf +- License: BSD-3-Clause **Printf (Printf formatting library)** - Path: src/stdlib/builtin - Source: https://github.com/mpaland/printf - -**LVGL's XML format** -- Path: - - docs/src/auxiliary-modules/xml - - src/others/xml - - xmls +- License: MIT **FT800-FT813 (EVE GPU driver)** -- Path src/libs/FT800-FT813 +- Path: src/libs/FT800-FT813 - Source: https://github.com/RudolphRiedel/FT800-FT813 +- License: MIT **AnimatedGIF (GIF decoder library)** - Path: src/libs/gif - Source: https://github.com/bitbank2/AnimatedGIF +- License: Apache-2.0 + +**NanoVG (Anti-aliased vector graphics rendering)** +- Path: src/libs/nanovg +- Source: https://github.com/memononen/nanovg +- License: Zlib +- Note: Compiled when LV_USE_NANOVG (or the LV_USE_DRAW_NANOVG backend) is enabled. **FrogFS (read-only filesystem)** - Path: src/libs/frogfs - Source: https://github.com/jkent/frogfs +- License: MPL-2.0 diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..f6ffb87d63 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,35 @@ +# Security Policy + +## Reporting a vulnerability + +**Please do not open a public GitHub issue for security problems.** + +Report suspected vulnerabilities privately by email to +**security@lvgl.io**. + +Please include, as far as you can: + +- the affected version(s) and configuration (`lv_conf.h` toggles, target), +- a description of the impact, +- steps to reproduce or a proof of concept, and +- any suggested fix or mitigation. + +We support coordinated disclosure: please give us a reasonable window to +release a fix before any public disclosure. We will credit you in the advisory +unless you prefer otherwise. + +## Supported versions + +Fixes are made available for the actively supported releases. See the +[Policies page](https://docs.lvgl.io/master/introduction/policies) for the +current support table. + +## SBOM and more + +LVGL publishes a machine-readable SBOM (SPDX 3.0.1) in the [`sbom/`](sbom/) +folder and a human-readable component list in +[`COPYRIGHTS.md`](COPYRIGHTS.md). + +For our full security commitment, vulnerability handling process, and how LVGL +supports users' EU Cyber Resilience Act (CRA) obligations, see the +[Security page in the documentation](https://docs.lvgl.io/master/introduction/security). diff --git a/docs/src/introduction/meta.json b/docs/src/introduction/meta.json index b7a640c00c..00efe5cc54 100644 --- a/docs/src/introduction/meta.json +++ b/docs/src/introduction/meta.json @@ -5,6 +5,7 @@ "requirements", "license", "policies", + "security", "faq" ] } diff --git a/docs/src/introduction/security.mdx b/docs/src/introduction/security.mdx new file mode 100644 index 0000000000..f809622b54 --- /dev/null +++ b/docs/src/introduction/security.mdx @@ -0,0 +1,100 @@ +--- +title: Security +description: "LVGL's security commitment, vulnerability reporting process, SBOM, and how LVGL supports our users' EU Cyber Resilience Act (CRA) obligations" +--- + +## Our commitment + +LVGL is used in millions of devices, many of them shipped commercially and +placed on regulated markets. We take the security of the library and of the +products built on it seriously. LVGL Kft., as the legal entity stewarding the +project, maintains a cybersecurity policy that covers: + +- a documented **coordinated vulnerability disclosure** process, +- a published, machine-readable **Software Bill of Materials (SBOM)**, +- vulnerability handling with public security advisories, and +- cooperation with users, integrators, and the relevant authorities. + +This page describes those processes and how they help you meet your own +obligations under regulations such as the EU Cyber Resilience Act (CRA). + +## Reporting a vulnerability + +**Please do not open a public GitHub issue for security problems.** + +Report suspected vulnerabilities privately by email to +[security@lvgl.io](mailto:security@lvgl.io). + +Please include, as far as you can: + +- the affected version(s) and configuration (`lv_conf.h` toggles, target), +- a description of the impact, +- steps to reproduce or a proof of concept, and +- any suggested fix or mitigation. + +We support **coordinated disclosure**: we ask that you give us a reasonable +window to release a fix before any public disclosure, and we will credit you in +the advisory unless you prefer otherwise. + +## How we handle reports + +| Stage | What happens | +| --- | --- | +| Acknowledge | We confirm receipt of your report, typically within a few business days. | +| Triage | We reproduce and assess severity, and determine the affected versions. | +| Fix | We develop and review a fix on a private track when needed. | +| Advisory | We publish a [GitHub Security Advisory](https://github.com/lvgl/lvgl/security/advisories) and, where applicable, request a CVE identifier. | +| Release | The fix ships in a patch release; see [Policies](/introduction/policies) for the supported versions. | + +Fixes are made available for the actively supported releases listed on the +[Policies](/introduction/policies) page. + +## Software Bill of Materials (SBOM) + +LVGL publishes two views of its component inventory: + +- [**`sbom/lvgl.spdx.json`**](https://github.com/lvgl/lvgl/blob/master/sbom/lvgl.spdx.json): the **machine-readable** SBOM, in the + [SPDX 3.0.1](https://spdx.github.io/spdx-spec/v3.0.1/) JSON-LD format, a + commonly used standard suitable for automated tooling. +- [**`COPYRIGHTS.md`**](https://github.com/lvgl/lvgl/blob/master/COPYRIGHTS.md): the **human-readable** list of every third-party component with its license + and copyright. + +Both are generated from a single source of truth, +[`sbom/third_party.json`](https://github.com/lvgl/lvgl/blob/master/sbom/third_party.json), +and their correctness is enforced by CI, so they always track the checked-out +version. + +See the [SBOM README](https://github.com/lvgl/lvgl/blob/master/sbom/README.md) +for the file layout, how to regenerate the artifacts, and how to validate them. + +Note that some optional dependencies (for example FreeType) are **provided by +the integrator** rather than bundled with LVGL; the SBOM lists LVGL's +integration interface, but you are responsible for the SBOM entries of the +components you supply yourself. + +## LVGL and the EU Cyber Resilience Act (CRA) + +The CRA (Regulation (EU) 2024/2847) places obligations on **manufacturers** +who place *products with digital elements* on the EU market. LVGL is a free and +open-source **software component**, not a finished product placed on the market +by LVGL Kft. The CRA obligations for a shipped product therefore fall on the +**manufacturer that integrates LVGL** into that product. + +What LVGL provides is the upstream foundation that makes meeting those +obligations easier: + +- a **machine-readable SBOM** covering LVGL and its bundled third-party + components, +- a **coordinated vulnerability disclosure** process and public security + advisories, and +- clear licensing and component provenance in `COPYRIGHTS.md`. + +As the open-source steward of the project, LVGL Kft. maintains the cybersecurity +policy described on this page and cooperates with users and authorities on +vulnerability handling. + +> **Not legal advice.** This page describes LVGL's processes and artifacts. It +> is not legal advice, and it does not by itself make any product compliant. The +> precise classification of your product and of LVGL Kft. under the CRA, and the +> steps required for your conformity, should be confirmed with qualified +> counsel. For questions, contact [lvgl@lvgl.io](mailto:lvgl@lvgl.io). diff --git a/sbom/README.md b/sbom/README.md new file mode 100644 index 0000000000..4cce3ee7a6 --- /dev/null +++ b/sbom/README.md @@ -0,0 +1,86 @@ +# LVGL SBOM + +This folder contains the Software Bill of Materials (SBOM) for LVGL in +[SPDX 3.0.1](https://spdx.github.io/spdx-spec/v3.0.1/) JSON-LD format, plus the +single source of truth it is generated from. + +## Files + +| File | Description | +|------|-------------| +| `third_party.json` | **Single source of truth** — every third-party dependency, its license, supplier and source | +| `lvgl.spdx.json` | Generated SPDX 3.0.1 SBOM | +| `requirements.txt` | Pinned tooling for validation / the CI gate | +| `README.md` | This file | + +Two artifacts are **generated** from `third_party.json` — do not edit them by hand: + +- `sbom/lvgl.spdx.json` (this folder) +- `COPYRIGHTS.md` (repo root) + +## Regenerating + +When a dependency is added, removed, or relicensed, edit +`sbom/third_party.json` and regenerate both outputs: + +```sh +python3 scripts/generate_copyrights.py # -> COPYRIGHTS.md +python3 scripts/generate_sbom.py # -> sbom/lvgl.spdx.json +``` + +The LVGL version is read from `include/lvgl/lv_version.h` and recorded inside +the document, so the package version always tracks the checked-out tree. The +file name itself is unversioned — the SBOM is bundled inside a given LVGL +version anyway. + +## Validating + +The SBOM is validated against the **official SPDX 3.0.1 JSON Schema** (SPDX's +own recommended method) using +[check-jsonschema](https://github.com/python-jsonschema/check-jsonschema): + +```sh +python3 -m pip install -r sbom/requirements.txt +python3 scripts/validate_sbom.py +``` + +## CI + +The `Static Checks` workflow (`.github/workflows/static_checks.yml`) fails the +build if any generated file drifts from `sbom/third_party.json` or the SBOM is +not schema-valid: + +- `generate_copyrights.py --check` — COPYRIGHTS.md is up to date +- `generate_sbom.py --check` — SBOM is up to date (ignores the creation timestamp) +- `validate_sbom.py` — SBOM validates against the SPDX JSON Schema + +## `third_party.json` fields + +Each entry in `components`: + +| field | used by | notes | +|---------------|--------------------|-------| +| `key` | SBOM | slug for SPDX element ids | +| `name` | SBOM + COPYRIGHTS | component title | +| `paths` | SBOM + COPYRIGHTS | in-tree locations | +| `sources` | SBOM + COPYRIGHTS | `[{url, note?}]`; array because e.g. TinyTTF has two upstreams. First url is the SPDX download location | +| `note` | SBOM + COPYRIGHTS | free-form note | +| `version` | SBOM | vendored snapshot version (from an in-tree version macro/string), or `NOASSERTION` when the upstream copy carries no version | +| `license` | SBOM | SPDX license expression (or `LicenseRef-*`) | +| `license_file`| SBOM | path to embed for a custom `LicenseRef-*` license | +| `copyright` | SBOM | upstream copyright statement (from the library's LICENSE/source header) | +| `supplier` | SBOM | `{name, type}` where type is `person` or `organization` | +| `purl` | SBOM | Package URL identifier | +| `purpose` | SBOM | SPDX `software_primaryPurpose` | +| `third_party` | SBOM | `false` marks LVGL's own code — omitted from the SBOM component list (COPYRIGHTS.md renders every entry) | + +## Notes on the data + +- The inventory was curated from `COPYRIGHTS.md`, the `LV_USE_*` toggles in + `lv_conf_template.h`, and the `src/libs/**/LICENSE*` files. +- **FreeType** is listed because LVGL ships its integration interface, but + FreeType itself is not part of LVGL and must be provided by the integrator. +- In SPDX 3.0 a package has no license field; licensing is expressed as + `Relationship` elements (`from` package → `hasDeclaredLicense` / + `hasConcludedLicense` → `to` license expression). This is why the SBOM + contains `Relationship` nodes. diff --git a/sbom/lvgl.spdx.json b/sbom/lvgl.spdx.json new file mode 100644 index 0000000000..dafcde3d9b --- /dev/null +++ b/sbom/lvgl.spdx.json @@ -0,0 +1,1271 @@ +{ + "@context": "https://spdx.org/rdf/3.0.1/spdx-context.jsonld", + "@graph": [ + { + "type": "CreationInfo", + "@id": "_:creationinfo", + "specVersion": "3.0.1", + "created": "2026-07-20T16:40:55Z", + "createdBy": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-LVGL-Kft" + ], + "createdUsing": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Tool-generate_sbom.py" + ] + }, + { + "type": "Tool", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Tool-generate_sbom.py", + "creationInfo": "_:creationinfo", + "name": "scripts/generate_sbom.py" + }, + { + "type": "expandedlicensing_CustomLicense", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#CustomLicense-LicenseRef_TJpgDec", + "creationInfo": "_:creationinfo", + "name": "LicenseRef-TJpgDec", + "simplelicensing_licenseText": "/*----------------------------------------------------------------------------/\n/ TJpgDec - Tiny JPEG Decompressor R0.03 (C)ChaN, 2021\n/-----------------------------------------------------------------------------/\n/ The TJpgDec is a generic JPEG decompressor module for tiny embedded systems.\n/ This is a free software that opened for education, research and commercial\n/ developments under license policy of following terms.\n/\n/ Copyright (C) 2021, ChaN, all right reserved.\n/\n/ * The TJpgDec module is a free software and there is NO WARRANTY.\n/ * No restriction on use. You can use, modify and redistribute it for\n/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.\n/ * Redistributions of source code must retain the above copyright notice.\n/\n/-----------------------------------------------------------------------------/\n", + "expandedlicensing_isOsiApproved": false + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Apache_2.0", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "Apache-2.0" + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_2_Clause", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "BSD-2-Clause" + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_3_Clause", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "BSD-3-Clause" + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-FTL_OR_GPL_2.0_or_later", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "FTL OR GPL-2.0-or-later" + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-LicenseRef_TJpgDec", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "LicenseRef-TJpgDec", + "simplelicensing_customIdToUri": [ + { + "type": "DictionaryEntry", + "key": "LicenseRef-TJpgDec", + "value": "https://lvgl.io/spdx/lvgl-9.6.0-dev#CustomLicense-LicenseRef_TJpgDec" + } + ] + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "MIT" + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT_AND_BSD_3_Clause", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "MIT AND BSD-3-Clause" + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT_OR_Unlicense", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "MIT OR Unlicense" + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MPL_2.0", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "MPL-2.0" + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-OFL_1.1", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "OFL-1.1" + }, + { + "type": "simplelicensing_LicenseExpression", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Zlib", + "creationInfo": "_:creationinfo", + "simplelicensing_licenseExpression": "Zlib" + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "creationInfo": "_:creationinfo", + "name": "lvgl", + "summary": "Light and Versatile Graphics Library", + "software_packageVersion": "9.6.0-dev", + "software_copyrightText": "Copyright (c) 2025 LVGL Kft", + "software_downloadLocation": "https://github.com/lvgl/lvgl", + "software_homePage": "https://lvgl.io", + "software_primaryPurpose": "library", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-LVGL-Kft", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/lvgl/lvgl@9.6.0-dev" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-barcode", + "creationInfo": "_:creationinfo", + "name": "Barcode (Barcode generator)", + "software_packageVersion": "NOASSERTION", + "software_copyrightText": "Copyright (c) 2013-2015 LKC Technologies, Inc.", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/barcode", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-LKC-Technologies-Inc", + "software_downloadLocation": "https://github.com/fhunleth/code128", + "software_homePage": "https://github.com/fhunleth/code128", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/fhunleth/code128" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-freetype", + "creationInfo": "_:creationinfo", + "name": "FreeType (Font rendering library)", + "software_packageVersion": "NOASSERTION", + "software_copyrightText": "Copyright (C) 1996-2022 by David Turner, Robert Wilhelm, and Werner Lemberg (The FreeType Project)", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/freetype | Only the interfaces are used; FreeType itself is not part of LVGL.", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-The-FreeType-Project", + "software_downloadLocation": "https://github.com/freetype/freetype", + "software_homePage": "https://github.com/freetype/freetype", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/freetype/freetype" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-liberation-sans", + "creationInfo": "_:creationinfo", + "name": "Liberation Sans (default demo font)", + "software_packageVersion": "NOASSERTION", + "software_copyrightText": "Digitized data copyright (c) 2010 Google Corporation with Reserved Font Arimo, Tinos and Cousine; Copyright (c) 2012 Red Hat, Inc. with Reserved Font Name Liberation.", + "software_primaryPurpose": "file", + "comment": "In-tree path: src/libs/freetype/LiberationSans-Regular.ttf | Font asset bundled alongside the FreeType interface; licensed separately from FreeType.", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Red-Hat-Inc", + "software_downloadLocation": "https://github.com/liberationfonts/liberation-fonts", + "software_homePage": "https://github.com/liberationfonts/liberation-fonts", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/liberationfonts/liberation-fonts" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lodepng", + "creationInfo": "_:creationinfo", + "name": "LodePNG (PNG decoder)", + "software_packageVersion": "20230410", + "software_copyrightText": "Copyright (c) 2005-2023 Lode Vandevenne", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/lodepng", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Lode-Vandevenne", + "software_downloadLocation": "https://github.com/lvandeve/lodepng", + "software_homePage": "https://github.com/lvandeve/lodepng", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/lvandeve/lodepng@20230410" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lz4", + "creationInfo": "_:creationinfo", + "name": "LZ4 (Compression/Decompression)", + "software_packageVersion": "1.10.0", + "software_copyrightText": "Copyright (c) 2011-2023 Yann Collet", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/lz4", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Yann-Collet", + "software_downloadLocation": "https://github.com/lz4/lz4", + "software_homePage": "https://github.com/lz4/lz4", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/lz4/lz4@1.10.0" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-qrcode", + "creationInfo": "_:creationinfo", + "name": "QR Code (QR code generator)", + "software_packageVersion": "NOASSERTION", + "software_copyrightText": "Copyright (c) Project Nayuki. (MIT License)", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/qrcode", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Project-Nayuki", + "software_downloadLocation": "https://github.com/nayuki/QR-Code-generator", + "software_homePage": "https://github.com/nayuki/QR-Code-generator", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/nayuki/QR-Code-generator" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-thorvg", + "creationInfo": "_:creationinfo", + "name": "ThorVG (Vector graphics rendering)", + "software_packageVersion": "0.15.3", + "software_copyrightText": "Copyright (c) 2020 - 2025 notice for the ThorVG Project (see CONTRIBUTORS)", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/thorvg", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-The-ThorVG-Project", + "software_downloadLocation": "https://github.com/thorvg/thorvg", + "software_homePage": "https://github.com/thorvg/thorvg", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/thorvg/thorvg@0.15.3" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-rapidjson", + "creationInfo": "_:creationinfo", + "name": "RapidJSON (JSON parser/generator)", + "software_packageVersion": "1.1.0", + "software_copyrightText": "Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.; Copyright (c) 2006-2013 Alexander Chemeris (msinttypes)", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/thorvg/rapidjson | Bundled inside the ThorVG tree (used by ThorVG's Lottie parser); licensed separately from ThorVG. The bundled msinttypes helper (rapidjson/msinttypes) is BSD-3-Clause (Copyright (c) 2006-2013 Alexander Chemeris), hence the combined license expression.", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-THL-A29-Limited-a-Tencent-company", + "software_downloadLocation": "https://github.com/Tencent/rapidjson", + "software_homePage": "https://github.com/Tencent/rapidjson", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/Tencent/rapidjson@1.1.0" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tiny_ttf", + "creationInfo": "_:creationinfo", + "name": "TinyTTF", + "software_packageVersion": "1.26", + "software_copyrightText": "Copyright (c) 2017 Sean Barrett; Copyright (c) 2022 honey the codewitch", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/tiny_ttf | Additional source: https://github.com/codewitch-honey-crisis/tiny_ttf (Modified version of the original STB library)", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Sean-Barrett", + "software_downloadLocation": "https://github.com/nothings/stb", + "software_homePage": "https://github.com/nothings/stb", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/nothings/stb@1.26" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tjpgd", + "creationInfo": "_:creationinfo", + "name": "TJPGD (JPEG decoder)", + "software_packageVersion": "R0.03", + "software_copyrightText": "Copyright (C) 2021, ChaN, all right reserved.", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/tjpgd", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-ChaN", + "software_downloadLocation": "http://elm-chan.org/fsw/tjpgd/00index.html", + "software_homePage": "http://elm-chan.org/fsw/tjpgd/00index.html", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:generic/tjpgd?download_url=http://elm-chan.org/fsw/tjpgd/00index.html" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tlsf", + "creationInfo": "_:creationinfo", + "name": "TLSF (Two-Level Segregate Fit memory allocator)", + "software_packageVersion": "3.1", + "software_copyrightText": "Copyright (c) 2006-2016 Matthew Conte", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/stdlib/builtin", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Matthew-Conte", + "software_downloadLocation": "https://github.com/mattconte/tlsf", + "software_homePage": "https://github.com/mattconte/tlsf", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/mattconte/tlsf@3.1" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-printf", + "creationInfo": "_:creationinfo", + "name": "Printf (Printf formatting library)", + "software_packageVersion": "NOASSERTION", + "software_copyrightText": "Copyright (c) 2014 Marco Paland", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/stdlib/builtin", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Marco-Paland", + "software_downloadLocation": "https://github.com/mpaland/printf", + "software_homePage": "https://github.com/mpaland/printf", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/mpaland/printf" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-ft800-ft813", + "creationInfo": "_:creationinfo", + "name": "FT800-FT813 (EVE GPU driver)", + "software_packageVersion": "5.0", + "software_copyrightText": "Copyright (c) 2016-2024 Rudolph Riedel", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/FT800-FT813", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Rudolph-Riedel", + "software_downloadLocation": "https://github.com/RudolphRiedel/FT800-FT813", + "software_homePage": "https://github.com/RudolphRiedel/FT800-FT813", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/RudolphRiedel/FT800-FT813@5.0" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-gif", + "creationInfo": "_:creationinfo", + "name": "AnimatedGIF (GIF decoder library)", + "software_packageVersion": "NOASSERTION", + "software_copyrightText": "Copyright (c) 2020 BitBank Software, Inc. All rights reserved.", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/gif", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-BitBank-Software-Inc", + "software_downloadLocation": "https://github.com/bitbank2/AnimatedGIF", + "software_homePage": "https://github.com/bitbank2/AnimatedGIF", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/bitbank2/AnimatedGIF" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-nanovg", + "creationInfo": "_:creationinfo", + "name": "NanoVG (Anti-aliased vector graphics rendering)", + "software_packageVersion": "NOASSERTION", + "software_copyrightText": "Copyright (c) 2013 Mikko Mononen memon@inside.org", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/nanovg | Compiled when LV_USE_NANOVG (or the LV_USE_DRAW_NANOVG backend) is enabled.", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Mikko-Mononen", + "software_downloadLocation": "https://github.com/memononen/nanovg", + "software_homePage": "https://github.com/memononen/nanovg", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/memononen/nanovg" + } + ] + }, + { + "type": "software_Package", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-frogfs", + "creationInfo": "_:creationinfo", + "name": "FrogFS (read-only filesystem)", + "software_packageVersion": "1.0", + "software_copyrightText": "Copyright (c) Jeff Kent", + "software_primaryPurpose": "library", + "comment": "In-tree path: src/libs/frogfs", + "suppliedBy": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Jeff-Kent", + "software_downloadLocation": "https://github.com/jkent/frogfs", + "software_homePage": "https://github.com/jkent/frogfs", + "externalIdentifier": [ + { + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/jkent/frogfs@1.0" + } + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-barcode", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-barcode" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-barcode", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-barcode", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_2_Clause" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-barcode", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-barcode", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_2_Clause" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-freetype", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-freetype" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-freetype", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-freetype", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-FTL_OR_GPL_2.0_or_later" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-freetype", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-freetype", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-FTL_OR_GPL_2.0_or_later" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-liberation-sans", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-liberation-sans" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-liberation-sans", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-liberation-sans", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-OFL_1.1" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-liberation-sans", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-liberation-sans", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-OFL_1.1" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-lodepng", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lodepng" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-lodepng", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lodepng", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Zlib" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-lodepng", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lodepng", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Zlib" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-lz4", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lz4" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-lz4", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lz4", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_2_Clause" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-lz4", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lz4", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_2_Clause" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-qrcode", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-qrcode" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-qrcode", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-qrcode", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-qrcode", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-qrcode", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-thorvg", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-thorvg" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-thorvg", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-thorvg", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-thorvg", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-thorvg", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-rapidjson", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-rapidjson" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-rapidjson", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-rapidjson", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT_AND_BSD_3_Clause" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-rapidjson", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-rapidjson", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT_AND_BSD_3_Clause" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-tiny_ttf", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tiny_ttf" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-tiny_ttf", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tiny_ttf", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT_OR_Unlicense" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-tiny_ttf", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tiny_ttf", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT_OR_Unlicense" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-tjpgd", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tjpgd" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-tjpgd", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tjpgd", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-LicenseRef_TJpgDec" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-tjpgd", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tjpgd", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-LicenseRef_TJpgDec" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-tlsf", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tlsf" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-tlsf", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tlsf", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_3_Clause" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-tlsf", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tlsf", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_3_Clause" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-printf", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-printf" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-printf", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-printf", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-printf", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-printf", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-ft800-ft813", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-ft800-ft813" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-ft800-ft813", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-ft800-ft813", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-ft800-ft813", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-ft800-ft813", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-gif", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-gif" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-gif", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-gif", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Apache_2.0" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-gif", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-gif", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Apache_2.0" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-nanovg", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-nanovg" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-nanovg", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-nanovg", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Zlib" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-nanovg", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-nanovg", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Zlib" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-frogfs", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "contains", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-frogfs" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-frogfs", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-frogfs", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MPL_2.0" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-frogfs", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-frogfs", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MPL_2.0" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-lvgl", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "hasDeclaredLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT" + ] + }, + { + "type": "Relationship", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-lvgl", + "creationInfo": "_:creationinfo", + "from": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "relationshipType": "hasConcludedLicense", + "to": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT" + ] + }, + { + "type": "Organization", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-LVGL-Kft", + "creationInfo": "_:creationinfo", + "name": "LVGL Kft" + }, + { + "type": "Organization", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-LKC-Technologies-Inc", + "creationInfo": "_:creationinfo", + "name": "LKC Technologies, Inc." + }, + { + "type": "Organization", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-The-FreeType-Project", + "creationInfo": "_:creationinfo", + "name": "The FreeType Project" + }, + { + "type": "Organization", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Red-Hat-Inc", + "creationInfo": "_:creationinfo", + "name": "Red Hat, Inc." + }, + { + "type": "Person", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Lode-Vandevenne", + "creationInfo": "_:creationinfo", + "name": "Lode Vandevenne" + }, + { + "type": "Person", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Yann-Collet", + "creationInfo": "_:creationinfo", + "name": "Yann Collet" + }, + { + "type": "Organization", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Project-Nayuki", + "creationInfo": "_:creationinfo", + "name": "Project Nayuki" + }, + { + "type": "Organization", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-The-ThorVG-Project", + "creationInfo": "_:creationinfo", + "name": "The ThorVG Project" + }, + { + "type": "Organization", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-THL-A29-Limited-a-Tencent-company", + "creationInfo": "_:creationinfo", + "name": "THL A29 Limited, a Tencent company" + }, + { + "type": "Person", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Sean-Barrett", + "creationInfo": "_:creationinfo", + "name": "Sean Barrett" + }, + { + "type": "Person", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-ChaN", + "creationInfo": "_:creationinfo", + "name": "ChaN" + }, + { + "type": "Person", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Matthew-Conte", + "creationInfo": "_:creationinfo", + "name": "Matthew Conte" + }, + { + "type": "Person", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Marco-Paland", + "creationInfo": "_:creationinfo", + "name": "Marco Paland" + }, + { + "type": "Person", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Rudolph-Riedel", + "creationInfo": "_:creationinfo", + "name": "Rudolph Riedel" + }, + { + "type": "Organization", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-BitBank-Software-Inc", + "creationInfo": "_:creationinfo", + "name": "BitBank Software, Inc." + }, + { + "type": "Person", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Mikko-Mononen", + "creationInfo": "_:creationinfo", + "name": "Mikko Mononen" + }, + { + "type": "Person", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Jeff-Kent", + "creationInfo": "_:creationinfo", + "name": "Jeff Kent" + }, + { + "type": "software_Sbom", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#SBOM", + "creationInfo": "_:creationinfo", + "software_sbomType": [ + "source" + ], + "rootElement": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl" + ], + "element": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Tool-generate_sbom.py", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#CustomLicense-LicenseRef_TJpgDec", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Apache_2.0", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_2_Clause", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_3_Clause", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-FTL_OR_GPL_2.0_or_later", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-LicenseRef_TJpgDec", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT_AND_BSD_3_Clause", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT_OR_Unlicense", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MPL_2.0", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-OFL_1.1", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Zlib", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-barcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-freetype", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-liberation-sans", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lodepng", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lz4", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-qrcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-thorvg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-rapidjson", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tiny_ttf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tjpgd", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tlsf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-printf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-ft800-ft813", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-gif", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-nanovg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-frogfs", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-barcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-barcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-barcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-freetype", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-freetype", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-freetype", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-liberation-sans", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-liberation-sans", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-liberation-sans", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-lodepng", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-lodepng", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-lodepng", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-lz4", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-lz4", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-lz4", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-qrcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-qrcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-qrcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-thorvg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-thorvg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-thorvg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-rapidjson", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-rapidjson", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-rapidjson", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-tiny_ttf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-tiny_ttf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-tiny_ttf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-tjpgd", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-tjpgd", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-tjpgd", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-tlsf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-tlsf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-tlsf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-printf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-printf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-printf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-ft800-ft813", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-ft800-ft813", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-ft800-ft813", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-gif", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-gif", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-gif", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-nanovg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-nanovg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-nanovg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-frogfs", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-frogfs", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-frogfs", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-lvgl", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-lvgl", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-LVGL-Kft", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-LKC-Technologies-Inc", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-The-FreeType-Project", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Red-Hat-Inc", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Lode-Vandevenne", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Yann-Collet", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Project-Nayuki", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-The-ThorVG-Project", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-THL-A29-Limited-a-Tencent-company", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Sean-Barrett", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-ChaN", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Matthew-Conte", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Marco-Paland", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Rudolph-Riedel", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-BitBank-Software-Inc", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Mikko-Mononen", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Jeff-Kent" + ] + }, + { + "type": "SpdxDocument", + "spdxId": "https://lvgl.io/spdx/lvgl-9.6.0-dev#SPDXDocument", + "creationInfo": "_:creationinfo", + "name": "LVGL 9.6.0-dev SBOM", + "profileConformance": [ + "core", + "software", + "simpleLicensing", + "expandedLicensing" + ], + "rootElement": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#SBOM" + ], + "element": [ + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Tool-generate_sbom.py", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#CustomLicense-LicenseRef_TJpgDec", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Apache_2.0", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_2_Clause", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-BSD_3_Clause", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-FTL_OR_GPL_2.0_or_later", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-LicenseRef_TJpgDec", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT_AND_BSD_3_Clause", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MIT_OR_Unlicense", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-MPL_2.0", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-OFL_1.1", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#LicenseExpression-Zlib", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lvgl", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-barcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-freetype", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-liberation-sans", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lodepng", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-lz4", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-qrcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-thorvg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-rapidjson", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tiny_ttf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tjpgd", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-tlsf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-printf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-ft800-ft813", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-gif", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-nanovg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Package-frogfs", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-barcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-barcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-barcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-freetype", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-freetype", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-freetype", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-liberation-sans", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-liberation-sans", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-liberation-sans", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-lodepng", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-lodepng", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-lodepng", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-lz4", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-lz4", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-lz4", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-qrcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-qrcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-qrcode", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-thorvg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-thorvg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-thorvg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-rapidjson", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-rapidjson", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-rapidjson", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-tiny_ttf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-tiny_ttf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-tiny_ttf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-tjpgd", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-tjpgd", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-tjpgd", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-tlsf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-tlsf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-tlsf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-printf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-printf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-printf", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-ft800-ft813", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-ft800-ft813", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-ft800-ft813", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-gif", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-gif", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-gif", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-nanovg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-nanovg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-nanovg", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-contains-frogfs", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-frogfs", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-frogfs", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasDeclaredLicense-lvgl", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Relationship-hasConcludedLicense-lvgl", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-LVGL-Kft", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-LKC-Technologies-Inc", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-The-FreeType-Project", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Red-Hat-Inc", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Lode-Vandevenne", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Yann-Collet", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Project-Nayuki", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-The-ThorVG-Project", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-THL-A29-Limited-a-Tencent-company", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Sean-Barrett", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-ChaN", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Matthew-Conte", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Marco-Paland", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Rudolph-Riedel", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-BitBank-Software-Inc", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Mikko-Mononen", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#Agent-Jeff-Kent", + "https://lvgl.io/spdx/lvgl-9.6.0-dev#SBOM" + ] + } + ] +} diff --git a/sbom/requirements.txt b/sbom/requirements.txt new file mode 100644 index 0000000000..0485451b50 --- /dev/null +++ b/sbom/requirements.txt @@ -0,0 +1,4 @@ +# Tooling for the SBOM compliance gate (see .github/workflows/code_generation.yml). +# The validator version is pinned so the gate does not change or break from an +# unreviewed upstream release; bump it here deliberately when updating. +check-jsonschema==0.37.4 diff --git a/sbom/third_party.json b/sbom/third_party.json new file mode 100644 index 0000000000..8a356d0add --- /dev/null +++ b/sbom/third_party.json @@ -0,0 +1,214 @@ +{ + "$comment": "Single source of truth for LVGL's third-party dependencies. Edit this file when a dependency is added, removed, or relicensed, then run scripts/generate_copyrights.py and scripts/generate_sbom.py to regenerate COPYRIGHTS.md and the SPDX SBOM. 'supplier' names come from each library's copyright holder. 'version' is the vendored snapshot version (from an in-tree version macro/string) or NOASSERTION when the upstream copy carries no version. 'copyright' is the upstream copyright statement from the library's LICENSE/source header.", + "project": { + "name": "lvgl", + "summary": "Light and Versatile Graphics Library", + "license": "MIT", + "copyright": "Copyright (c) 2025 LVGL Kft", + "download_location": "https://github.com/lvgl/lvgl", + "homepage": "https://lvgl.io", + "supplier": {"name": "LVGL Kft", "type": "organization"} + }, + "components": [ + { + "key": "barcode", + "name": "Barcode (Barcode generator)", + "paths": ["src/libs/barcode"], + "sources": [{"url": "https://github.com/fhunleth/code128"}], + "version": "NOASSERTION", + "license": "BSD-2-Clause", + "copyright": "Copyright (c) 2013-2015 LKC Technologies, Inc.", + "purl": "pkg:github/fhunleth/code128", + "purpose": "library", + "supplier": {"name": "LKC Technologies, Inc.", "type": "organization"} + }, + { + "key": "freetype", + "name": "FreeType (Font rendering library)", + "paths": ["src/libs/freetype"], + "sources": [{"url": "https://github.com/freetype/freetype"}], + "note": "Only the interfaces are used; FreeType itself is not part of LVGL.", + "version": "NOASSERTION", + "license": "FTL OR GPL-2.0-or-later", + "copyright": "Copyright (C) 1996-2022 by David Turner, Robert Wilhelm, and Werner Lemberg (The FreeType Project)", + "purl": "pkg:github/freetype/freetype", + "purpose": "library", + "supplier": {"name": "The FreeType Project", "type": "organization"} + }, + { + "key": "liberation-sans", + "name": "Liberation Sans (default demo font)", + "paths": ["src/libs/freetype/LiberationSans-Regular.ttf"], + "sources": [{"url": "https://github.com/liberationfonts/liberation-fonts"}], + "note": "Font asset bundled alongside the FreeType interface; licensed separately from FreeType.", + "version": "NOASSERTION", + "license": "OFL-1.1", + "copyright": "Digitized data copyright (c) 2010 Google Corporation with Reserved Font Arimo, Tinos and Cousine; Copyright (c) 2012 Red Hat, Inc. with Reserved Font Name Liberation.", + "purl": "pkg:github/liberationfonts/liberation-fonts", + "purpose": "file", + "supplier": {"name": "Red Hat, Inc.", "type": "organization"} + }, + { + "key": "lodepng", + "name": "LodePNG (PNG decoder)", + "paths": ["src/libs/lodepng"], + "sources": [{"url": "https://github.com/lvandeve/lodepng"}], + "version": "20230410", + "license": "Zlib", + "copyright": "Copyright (c) 2005-2023 Lode Vandevenne", + "purl": "pkg:github/lvandeve/lodepng", + "purpose": "library", + "supplier": {"name": "Lode Vandevenne", "type": "person"} + }, + { + "key": "lz4", + "name": "LZ4 (Compression/Decompression)", + "paths": ["src/libs/lz4"], + "sources": [{"url": "https://github.com/lz4/lz4"}], + "version": "1.10.0", + "license": "BSD-2-Clause", + "copyright": "Copyright (c) 2011-2023 Yann Collet", + "purl": "pkg:github/lz4/lz4", + "purpose": "library", + "supplier": {"name": "Yann Collet", "type": "person"} + }, + { + "key": "qrcode", + "name": "QR Code (QR code generator)", + "paths": ["src/libs/qrcode"], + "sources": [{"url": "https://github.com/nayuki/QR-Code-generator"}], + "version": "NOASSERTION", + "license": "MIT", + "copyright": "Copyright (c) Project Nayuki. (MIT License)", + "purl": "pkg:github/nayuki/QR-Code-generator", + "purpose": "library", + "supplier": {"name": "Project Nayuki", "type": "organization"} + }, + { + "key": "thorvg", + "name": "ThorVG (Vector graphics rendering)", + "paths": ["src/libs/thorvg"], + "sources": [{"url": "https://github.com/thorvg/thorvg"}], + "version": "0.15.3", + "license": "MIT", + "copyright": "Copyright (c) 2020 - 2025 notice for the ThorVG Project (see CONTRIBUTORS)", + "purl": "pkg:github/thorvg/thorvg", + "purpose": "library", + "supplier": {"name": "The ThorVG Project", "type": "organization"} + }, + { + "key": "rapidjson", + "name": "RapidJSON (JSON parser/generator)", + "paths": ["src/libs/thorvg/rapidjson"], + "sources": [{"url": "https://github.com/Tencent/rapidjson"}], + "note": "Bundled inside the ThorVG tree (used by ThorVG's Lottie parser); licensed separately from ThorVG. The bundled msinttypes helper (rapidjson/msinttypes) is BSD-3-Clause (Copyright (c) 2006-2013 Alexander Chemeris), hence the combined license expression.", + "version": "1.1.0", + "license": "MIT AND BSD-3-Clause", + "copyright": "Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.; Copyright (c) 2006-2013 Alexander Chemeris (msinttypes)", + "purl": "pkg:github/Tencent/rapidjson@1.1.0", + "purpose": "library", + "supplier": {"name": "THL A29 Limited, a Tencent company", "type": "organization"} + }, + { + "key": "tiny_ttf", + "name": "TinyTTF", + "paths": ["src/libs/tiny_ttf"], + "sources": [ + {"url": "https://github.com/nothings/stb", "note": "Only parts are integrated"}, + {"url": "https://github.com/codewitch-honey-crisis/tiny_ttf", "note": "Modified version of the original STB library"} + ], + "version": "1.26", + "license": "MIT OR Unlicense", + "copyright": "Copyright (c) 2017 Sean Barrett; Copyright (c) 2022 honey the codewitch", + "purl": "pkg:github/nothings/stb", + "purpose": "library", + "supplier": {"name": "Sean Barrett", "type": "person"} + }, + { + "key": "tjpgd", + "name": "TJPGD (JPEG decoder)", + "paths": ["src/libs/tjpgd"], + "sources": [{"url": "http://elm-chan.org/fsw/tjpgd/00index.html"}], + "version": "R0.03", + "license": "LicenseRef-TJpgDec", + "license_file": "src/libs/tjpgd/LICENSE.txt", + "copyright": "Copyright (C) 2021, ChaN, all right reserved.", + "purl": "pkg:generic/tjpgd?download_url=http://elm-chan.org/fsw/tjpgd/00index.html", + "purpose": "library", + "supplier": {"name": "ChaN", "type": "person"} + }, + { + "key": "tlsf", + "name": "TLSF (Two-Level Segregate Fit memory allocator)", + "paths": ["src/stdlib/builtin"], + "sources": [{"url": "https://github.com/mattconte/tlsf"}], + "version": "3.1", + "license": "BSD-3-Clause", + "copyright": "Copyright (c) 2006-2016 Matthew Conte", + "purl": "pkg:github/mattconte/tlsf", + "purpose": "library", + "supplier": {"name": "Matthew Conte", "type": "person"} + }, + { + "key": "printf", + "name": "Printf (Printf formatting library)", + "paths": ["src/stdlib/builtin"], + "sources": [{"url": "https://github.com/mpaland/printf"}], + "version": "NOASSERTION", + "license": "MIT", + "copyright": "Copyright (c) 2014 Marco Paland", + "purl": "pkg:github/mpaland/printf", + "purpose": "library", + "supplier": {"name": "Marco Paland", "type": "person"} + }, + { + "key": "ft800-ft813", + "name": "FT800-FT813 (EVE GPU driver)", + "paths": ["src/libs/FT800-FT813"], + "sources": [{"url": "https://github.com/RudolphRiedel/FT800-FT813"}], + "version": "5.0", + "license": "MIT", + "copyright": "Copyright (c) 2016-2024 Rudolph Riedel", + "purl": "pkg:github/RudolphRiedel/FT800-FT813", + "purpose": "library", + "supplier": {"name": "Rudolph Riedel", "type": "person"} + }, + { + "key": "gif", + "name": "AnimatedGIF (GIF decoder library)", + "paths": ["src/libs/gif"], + "sources": [{"url": "https://github.com/bitbank2/AnimatedGIF"}], + "version": "NOASSERTION", + "license": "Apache-2.0", + "copyright": "Copyright (c) 2020 BitBank Software, Inc. All rights reserved.", + "purl": "pkg:github/bitbank2/AnimatedGIF", + "purpose": "library", + "supplier": {"name": "BitBank Software, Inc.", "type": "organization"} + }, + { + "key": "nanovg", + "name": "NanoVG (Anti-aliased vector graphics rendering)", + "paths": ["src/libs/nanovg"], + "sources": [{"url": "https://github.com/memononen/nanovg"}], + "note": "Compiled when LV_USE_NANOVG (or the LV_USE_DRAW_NANOVG backend) is enabled.", + "version": "NOASSERTION", + "license": "Zlib", + "copyright": "Copyright (c) 2013 Mikko Mononen memon@inside.org", + "purl": "pkg:github/memononen/nanovg", + "purpose": "library", + "supplier": {"name": "Mikko Mononen", "type": "person"} + }, + { + "key": "frogfs", + "name": "FrogFS (read-only filesystem)", + "paths": ["src/libs/frogfs"], + "sources": [{"url": "https://github.com/jkent/frogfs"}], + "version": "1.0", + "license": "MPL-2.0", + "copyright": "Copyright (c) Jeff Kent", + "purl": "pkg:github/jkent/frogfs", + "purpose": "library", + "supplier": {"name": "Jeff Kent", "type": "person"} + } + ] +} diff --git a/scripts/generate_copyrights.py b/scripts/generate_copyrights.py new file mode 100755 index 0000000000..45126711db --- /dev/null +++ b/scripts/generate_copyrights.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +"""Regenerate COPYRIGHTS.md from the single source of truth. + +Component data lives in sbom/third_party.json, which is also used to +generate the SPDX SBOM (see generate_sbom.py). Edit that JSON, then run this +script to refresh COPYRIGHTS.md. + +Usage: + python3 scripts/generate_copyrights.py [--output COPYRIGHTS.md] [--check] + + --check exit non-zero if COPYRIGHTS.md is out of date (for CI). +""" + +import argparse +import json +import os +import sys + +REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +DATA_FILE = os.path.join(REPO_ROOT, "sbom", "third_party.json") + +HEADER = ( + "LVGL uses the following third-party libraries.\n" + "Each entry lists its SPDX license expression below. The full license text " + "is, for most libraries, found in the corresponding library folder (see the " + "paths); some libraries only reference their license rather than shipping " + "the full text. A machine-readable inventory is available in `sbom/`.\n" +) + + +def render(data): + lines = [HEADER] + for comp in data["components"]: + lines.append("**%s**" % comp["name"]) + + paths = comp.get("paths", []) + if len(paths) == 1: + lines.append("- Path: %s" % paths[0]) + elif paths: + lines.append("- Path:") + for p in paths: + lines.append(" - %s" % p) + + sources = comp.get("sources", []) + if len(sources) == 1 and not sources[0].get("note"): + lines.append("- Source: %s" % sources[0]["url"]) + elif sources: + lines.append("- Source:") + for s in sources: + suffix = " (*%s*)" % s["note"] if s.get("note") else "" + lines.append(" - %s%s" % (s["url"], suffix)) + + if comp.get("license"): + lines.append("- License: %s" % comp["license"]) + + if comp.get("note"): + lines.append("- Note: %s" % comp["note"]) + + lines.append("") # blank line between entries + + return "\n".join(lines).rstrip() + "\n" + + +def main(): + parser = argparse.ArgumentParser(description="Regenerate COPYRIGHTS.md.") + parser.add_argument("--output", default=os.path.join(REPO_ROOT, "COPYRIGHTS.md"), + help="Output file (default: COPYRIGHTS.md).") + parser.add_argument("--check", action="store_true", + help="Exit non-zero if the output is out of date.") + args = parser.parse_args() + + with open(DATA_FILE, encoding="utf-8") as fh: + data = json.load(fh) + content = render(data) + + if args.check: + current = "" + if os.path.isfile(args.output): + with open(args.output, encoding="utf-8") as fh: + current = fh.read() + if current != content: + print("%s is out of date; run scripts/generate_copyrights.py" % args.output) + return 1 + print("%s is up to date" % args.output) + return 0 + + with open(args.output, "w", encoding="utf-8") as fh: + fh.write(content) + print("Wrote %s (%d components)" % (args.output, len(data["components"]))) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/generate_sbom.py b/scripts/generate_sbom.py new file mode 100755 index 0000000000..98fad39316 --- /dev/null +++ b/scripts/generate_sbom.py @@ -0,0 +1,392 @@ +#!/usr/bin/env python3 +"""Generate a Software Bill of Materials (SBOM) for LVGL in SPDX 3.0 (JSON-LD). + +The component data comes from a single source of truth: + sbom/third_party.json +which is also used to regenerate COPYRIGHTS.md (see generate_copyrights.py). + +The LVGL version is read at run time from include/lvgl/lv_version.h so the +document always matches the checked-out tree. + +Output: SPDX 3.0.1 JSON-LD written to the SBOM folder (default: ./sbom). + +Usage: + python3 scripts/generate_sbom.py [--output-dir sbom] [--date 2026-07-15] + +SPDX 3.0.1 spec: https://spdx.github.io/spdx-spec/v3.0.1/ +""" + +import argparse +import datetime +import json +import os +import re +import sys + +REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +DATA_FILE = os.path.join(REPO_ROOT, "sbom", "third_party.json") + +# Namespace used to mint SPDX element identifiers (URIs). The version is +# appended at run time so different releases produce distinct id spaces. +NS_BASE = "https://lvgl.io/spdx" + + +def read_version(): + """Return the LVGL version string, e.g. '9.6.0-dev'.""" + path = os.path.join(REPO_ROOT, "include", "lvgl", "lv_version.h") + with open(path, encoding="utf-8") as fh: + text = fh.read() + + def grab(macro): + m = re.search(r"#define\s+%s\s+\"?([^\"\n]+)\"?" % macro, text) + return m.group(1).strip() if m else None + + version = "%s.%s.%s" % (grab("LVGL_VERSION_MAJOR"), + grab("LVGL_VERSION_MINOR"), + grab("LVGL_VERSION_PATCH")) + info = grab("LVGL_VERSION_INFO") + if info: + version += "-" + info + return version + + +def read_file(rel_path): + """Return the text of a repo file, or None if it is not present.""" + path = os.path.join(REPO_ROOT, rel_path) + if not os.path.isfile(path): + return None + with open(path, encoding="utf-8", errors="replace") as fh: + return fh.read() + + +def build_document(data, version, spec_version, created): + """Build the SPDX 3.0 JSON-LD document as a Python dict.""" + project = data["project"] + # Third-party components only (LVGL's own code is part of the root package). + components = [c for c in data["components"] if c.get("third_party", True)] + + ns = "%s/lvgl-%s" % (NS_BASE, version) + + def sid(fragment): + return "%s#%s" % (ns, fragment) + + creation_info = "_:creationinfo" + tool_id = sid("Tool-generate_sbom.py") + doc_id = sid("SPDXDocument") + sbom_id = sid("SBOM") + root_id = sid("Package-%s" % project["name"]) + + graph = [] + + # --- Agent registry ---------------------------------------------------- + # Suppliers/creators (Person/Organization) are deduplicated by name and + # emitted once at the end of the graph. + agents = {} # name -> {"id": ..., "type": ...} + + def agent_ref(supplier): + """Register a supplier {name, type} and return its SPDX element id.""" + name = supplier["name"] + if name not in agents: + slug = re.sub(r"[^A-Za-z0-9]+", "-", name).strip("-") + kind = "Organization" if supplier.get("type") == "organization" else "Person" + agents[name] = {"id": sid("Agent-" + slug), "type": kind} + return agents[name]["id"] + + creator_id = agent_ref({"name": "LVGL Kft", "type": "organization"}) + + # --- CreationInfo (blank node) ----------------------------------------- + graph.append({ + "type": "CreationInfo", + "@id": creation_info, + "specVersion": spec_version, + "created": created, + "createdBy": [creator_id], + "createdUsing": [tool_id], + }) + graph.append({ + "type": "Tool", + "spdxId": tool_id, + "creationInfo": creation_info, + "name": "scripts/generate_sbom.py", + }) + + # --- Licensing elements ------------------------------------------------ + # Custom (non-SPDX-list) licenses referenced by a LicenseRef-* need an + # explicit CustomLicense element so the reference resolves in-document. + # Build these first so their URIs can be wired into the LicenseExpression + # elements below via simplelicensing_customIdToUri. + custom_license_uris = {} # "LicenseRef-*" -> CustomLicense element id + for comp in components: + ref = comp["license"] + if not ref.startswith("LicenseRef-"): + continue + if ref in custom_license_uris: + continue + license_file = comp.get("license_file") + if not license_file: + raise SystemExit( + "Custom license %r (component %r) needs a 'license_file' in " + "third_party.json so its text can be embedded." % (ref, comp["key"])) + text = read_file(license_file) + if text is None: + raise SystemExit( + "License file %r for custom license %r (component %r) is " + "missing; cannot embed its text." % (license_file, ref, comp["key"])) + cid = sid("CustomLicense-" + re.sub(r"[^A-Za-z0-9]+", "_", ref)) + custom_license_uris[ref] = cid + graph.append({ + "type": "expandedlicensing_CustomLicense", + "spdxId": cid, + "creationInfo": creation_info, + "name": ref, + # Schema requires the license text under simplelicensing_licenseText. + "simplelicensing_licenseText": text, + "expandedlicensing_isOsiApproved": False, + }) + + # One LicenseExpression element per distinct expression; reused by relationships. + all_licenses = sorted({c["license"] for c in components} | {project["license"]}) + license_expr_ids = {} + for expr in all_licenses: + frag = "LicenseExpression-" + re.sub(r"[^A-Za-z0-9.]+", "_", expr) + lid = sid(frag) + license_expr_ids[expr] = lid + element = { + "type": "simplelicensing_LicenseExpression", + "spdxId": lid, + "creationInfo": creation_info, + "simplelicensing_licenseExpression": expr, + } + # Map any LicenseRef-* tokens in this expression to their CustomLicense + # element so consumers can resolve the custom license text. + id_to_uri = [ + {"type": "DictionaryEntry", "key": ref, "value": uri} + for ref, uri in sorted(custom_license_uris.items()) + if re.search(r"\b%s\b" % re.escape(ref), expr) + ] + if id_to_uri: + element["simplelicensing_customIdToUri"] = id_to_uri + graph.append(element) + + # --- LVGL root package ------------------------------------------------- + graph.append({ + "type": "software_Package", + "spdxId": root_id, + "creationInfo": creation_info, + "name": project["name"], + "summary": project.get("summary", ""), + "software_packageVersion": version, + "software_copyrightText": project.get("copyright", "NOASSERTION"), + "software_downloadLocation": project["download_location"], + "software_homePage": project.get("homepage", project["download_location"]), + "software_primaryPurpose": "library", + "suppliedBy": agent_ref(project["supplier"]), + "externalIdentifier": [{ + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": "pkg:github/lvgl/lvgl@%s" % version, + }], + }) + + # --- Third-party component packages ------------------------------------ + component_ids = [] + relationships = [] + for comp in components: + cid = sid("Package-" + comp["key"]) + component_ids.append(cid) + + sources = comp.get("sources", []) + source_urls = [s["url"] for s in sources] + comment = "In-tree path: %s" % ", ".join(comp["paths"]) + if comp.get("note"): + comment += " | " + comp["note"] + # The first source is the SPDX download location (below); preserve any + # additional upstream sources in the comment so they are not dropped. + for extra in sources[1:]: + suffix = " (%s)" % extra["note"] if extra.get("note") else "" + comment += " | Additional source: %s%s" % (extra["url"], suffix) + + pkg = { + "type": "software_Package", + "spdxId": cid, + "creationInfo": creation_info, + "name": comp["name"], + "software_packageVersion": comp.get("version", "NOASSERTION"), + "software_copyrightText": comp.get("copyright", "NOASSERTION"), + "software_primaryPurpose": comp.get("purpose", "library"), + "comment": comment, + } + if comp.get("supplier"): + pkg["suppliedBy"] = agent_ref(comp["supplier"]) + if source_urls: + pkg["software_downloadLocation"] = source_urls[0] + pkg["software_homePage"] = source_urls[0] + if comp.get("purl"): + purl = comp["purl"] + # Note: use a distinct name here — do not reuse `version`, which + # holds the LVGL document version used further below. + comp_version = comp.get("version", "NOASSERTION") + # Qualify the purl with the vendored version when one is known and + # the purl does not already carry a version/qualifier of its own. + if comp_version and comp_version != "NOASSERTION" and "@" not in purl and "?" not in purl: + purl = "%s@%s" % (purl, comp_version) + pkg["externalIdentifier"] = [{ + "type": "ExternalIdentifier", + "externalIdentifierType": "packageUrl", + "identifier": purl, + }] + graph.append(pkg) + + # lvgl vendors (contains) the third-party copy. We deliberately do not + # emit a blanket `dependsOn` here: many of these libraries are optional + # (gated behind LV_USE_* toggles that are off by default), so claiming + # lvgl depends on all of them would overstate the dependency graph. + relationships.append({ + "type": "Relationship", + "spdxId": sid("Relationship-contains-%s" % comp["key"]), + "creationInfo": creation_info, + "from": root_id, + "relationshipType": "contains", + "to": [cid], + }) + # component license (declared == concluded for a vendored copy) + for rel_type in ("hasDeclaredLicense", "hasConcludedLicense"): + relationships.append({ + "type": "Relationship", + "spdxId": sid("Relationship-%s-%s" % (rel_type, comp["key"])), + "creationInfo": creation_info, + "from": cid, + "relationshipType": rel_type, + "to": [license_expr_ids[comp["license"]]], + }) + + # lvgl's own license + for rel_type in ("hasDeclaredLicense", "hasConcludedLicense"): + relationships.append({ + "type": "Relationship", + "spdxId": sid("Relationship-%s-%s" % (rel_type, project["name"])), + "creationInfo": creation_info, + "from": root_id, + "relationshipType": rel_type, + "to": [license_expr_ids[project["license"]]], + }) + + graph.extend(relationships) + + # --- Agent elements (creator + package suppliers) ---------------------- + for name, info in agents.items(): + graph.append({ + "type": info["type"], + "spdxId": info["id"], + "creationInfo": creation_info, + "name": name, + }) + + # --- SBOM element ------------------------------------------------------ + # Every element built so far (packages, licenses, relationships, agents, + # tool) is part of the SBOM's contents, so list them all here. Otherwise a + # consumer starting from the SBOM root cannot reach the relationships. + sbom_elements = [e["spdxId"] for e in graph if e.get("spdxId")] + graph.append({ + "type": "software_Sbom", + "spdxId": sbom_id, + "creationInfo": creation_info, + "software_sbomType": ["source"], + "rootElement": [root_id], + "element": sbom_elements, + }) + + # --- SpdxDocument (wraps everything) ----------------------------------- + doc_elements = [e.get("spdxId") for e in graph if e.get("spdxId")] + graph.append({ + "type": "SpdxDocument", + "spdxId": doc_id, + "creationInfo": creation_info, + "name": "LVGL %s SBOM" % version, + "profileConformance": ["core", "software", "simpleLicensing", "expandedLicensing"], + "rootElement": [sbom_id], + "element": doc_elements, + }) + + document = { + "@context": "https://spdx.org/rdf/%s/spdx-context.jsonld" % spec_version, + "@graph": graph, + } + return document + + +def _serialize(document): + return json.dumps(document, indent=2, ensure_ascii=False) + "\n" + + +def _normalized(document): + """Copy with the volatile creation timestamp blanked, for drift comparison.""" + doc = json.loads(json.dumps(document)) + for element in doc.get("@graph", []): + if element.get("type") == "CreationInfo": + element["created"] = "" + return _serialize(doc) + + +def main(): + parser = argparse.ArgumentParser(description="Generate an SPDX 3.0 SBOM for LVGL.") + parser.add_argument("--output-dir", default=os.path.join(REPO_ROOT, "sbom"), + help="Directory to write the SBOM into (default: ./sbom).") + parser.add_argument("--date", default=None, + help="Creation date (YYYY-MM-DD). Defaults to today (UTC).") + parser.add_argument("--spec-version", default="3.0.1", + help="SPDX specification version (default: 3.0.1).") + parser.add_argument("--check", action="store_true", + help="Exit non-zero if the committed SBOM is out of date " + "(ignores the creation timestamp).") + args = parser.parse_args() + + with open(DATA_FILE, encoding="utf-8") as fh: + data = json.load(fh) + + version = read_version() + # The file name carries no version: the SBOM is bundled inside a given LVGL + # version anyway, and the version is recorded inside the document. + out_path = os.path.join(args.output_dir, "lvgl.spdx.json") + + if args.date: + # strptime alone accepts non-zero-padded input like "2026-7-1", which + # would produce an invalid SPDX timestamp, so enforce the exact shape. + if not re.fullmatch(r"\d{4}-\d{2}-\d{2}", args.date): + parser.error("--date must be in YYYY-MM-DD format (zero-padded)") + try: + datetime.datetime.strptime(args.date, "%Y-%m-%d") + except ValueError: + parser.error("--date must be a valid date in YYYY-MM-DD format") + created = "%sT00:00:00Z" % args.date + else: + created = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") + + document = build_document(data, version, args.spec_version, created) + components = [c for c in data["components"] if c.get("third_party", True)] + + if args.check: + if not os.path.isfile(out_path): + print("%s is missing; run scripts/generate_sbom.py" % out_path) + return 1 + with open(out_path, encoding="utf-8") as fh: + current = fh.read() + if _normalized(json.loads(current)) != _normalized(document): + print("%s is out of date; run scripts/generate_sbom.py" % out_path) + return 1 + print("%s is up to date" % out_path) + return 0 + + os.makedirs(args.output_dir, exist_ok=True) + with open(out_path, "w", encoding="utf-8") as fh: + fh.write(_serialize(document)) + + print("Wrote SPDX %s SBOM for LVGL %s" % (args.spec_version, version)) + print(" %s" % out_path) + print(" %d third-party components, %d SPDX elements" + % (len(components), len(document["@graph"]))) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/validate_sbom.py b/scripts/validate_sbom.py new file mode 100644 index 0000000000..b683f92d0a --- /dev/null +++ b/scripts/validate_sbom.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +"""Validate LVGL's SPDX 3.0 SBOM against the official SPDX JSON Schema. + +This is the validation method recommended by SPDX itself: check the document +against the published JSON Schema for its spec version. It uses check-jsonschema +(https://github.com/python-jsonschema/check-jsonschema) as the engine: + + python3 -m pip install check-jsonschema + +Usage: + python3 scripts/validate_sbom.py [SBOM ...] + [--schema URL_OR_PATH] [--spec-version 3.0.1] + +With no SBOM argument sbom/lvgl.spdx.json is validated. The schema +defaults to the official SPDX schema for --spec-version; pass a local path with +--schema to validate offline. +""" + +import argparse +import glob +import importlib.util +import os +import subprocess +import sys + +REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +SBOM_DIR = os.path.join(REPO_ROOT, "sbom") +SCHEMA_URL = "https://spdx.org/schema/%s/spdx-json-schema.json" + + +def main(): + parser = argparse.ArgumentParser( + description="Validate LVGL's SPDX SBOM against the official SPDX JSON Schema.") + parser.add_argument("sboms", nargs="*", + help="SBOM file(s) to validate (default: sbom/lvgl.spdx.json).") + parser.add_argument("--spec-version", default="3.0.1", + help="SPDX spec version whose schema to use (default: 3.0.1).") + parser.add_argument("--schema", default=None, + help="Override the schema URL or local file path.") + args = parser.parse_args() + + sboms = args.sboms or sorted(glob.glob(os.path.join(SBOM_DIR, "lvgl.spdx.json"))) + if not sboms: + print("No SBOM files found in %s (run scripts/generate_sbom.py first)." % SBOM_DIR) + return 1 + missing = [p for p in sboms if not os.path.isfile(p)] + if missing: + print("SBOM file(s) not found: %s" % ", ".join(missing)) + return 1 + + # Launching `python -m check_jsonschema` when the module is absent exits + # with the interpreter's own error code (not FileNotFoundError), so detect + # the module up front to surface the documented install instructions. + if importlib.util.find_spec("check_jsonschema") is None: + print("check-jsonschema is not installed. Install it with:\n" + " python3 -m pip install check-jsonschema") + return 2 + + schema = args.schema or (SCHEMA_URL % args.spec_version) + + cmd = [sys.executable, "-m", "check_jsonschema", "--schemafile", schema] + sboms + print("Validating against SPDX %s schema:\n %s\n" % (args.spec_version, schema)) + return subprocess.run(cmd).returncode + + +if __name__ == "__main__": + sys.exit(main())