Openembedded Core Discussions
 help / color / mirror / Atom feed
From: Stefano Tondo <stondo@gmail.com>
To: openembedded-core@lists.openembedded.org
Cc: stefano.tondo.ext@siemens.com,
	bitbake-devel@lists.openembedded.org,
	Joshua Watt <JPEWhacker@gmail.com>,
	Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>,
	Alexander Kanavin <alex.kanavin@gmail.com>,
	Peter Marko <peter.marko@siemens.com>,
	Adrian Freihofer <adrian.freihofer@siemens.com>,
	Patrick Wicki <patrick.wicki@siemens.com>
Subject: [RFC] spdx30: name, version and purl for dependency downloads
Date: Thu,  5 Nov 2026 13:21:45 +0100	[thread overview]
Message-ID: <20261105122145.543282-1-stondo@gmail.com> (raw)

Hi all,

I would like your opinion on a direction for the SPDX output of
recipes with language dependencies. I have working patches for it,
described below, but I would rather agree on the approach before
sending them.

Yocto already knows each language dependency at fetch time for the
recipes that list them in SRC_URI (crate://, gomod://, gomodgit://, and
npmsw:// through its shrinkwrap file). The SPDX output loses most of
that: the downloads are recorded, but without a name, version or
package URL that a scanner can use, and dependencies fetched
implicitly (git submodules, shrinkwrap dependencies) are not recorded
at all.

Measured on current master (oe-core 3a3eef7afb, bitbake 0f33b68cb,
meta-openembedded 33f74f5dc5), source downloads in the build SPDX of
each recipe, today and with the patches:

                  today                   with the patches
  python3-bcrypt  42 crates, none with    all 42 with name,
                  version or purl         version and purl
  crucible        36 Go modules, none     all 36 with name,
                  with version or purl    version and purl
  p11-kit         gitsm, submodule        submodule recorded with
                  pkcs11-json missing     its own revision
  webserver-oob   2 downloads, the 70     72 downloads, 71 with
                  shrinkwrap packages     a purl
                  missing

webserver-oob is from TI's meta-tisdk, built on qemux86-64 without its
am335x and meta-ti runtime dependencies and without one git.ti.com
source that failed to clone, since neither oe-core nor
meta-openembedded has an npmsw recipe. crucible also fetches 67
go.mod-only entries (;mod=1), which are not compiled in and stay
without an identity.

Today a crate shows up as name "cipher-0.4.4.crate" with download
location https://static.crates.io/crates/cipher/0.4.4/download, and a
Go module as gomod://github.com/felixge/httpsnoop, with the version
only in the file name "github.com.felixge.httpsnoop@v1.0.4.zip".
Consumers end up parsing URLs and file names per ecosystem to recover
what the fetcher already knew.

I am aware of two earlier threads and would like to build on them, not
reopen them:

- Joshua's "lib: spdx30_tasks: Use Fetch.expanded_urldata()" (March
  2025), which stalled on an intermittent edk2-firmware gitsm failure
  on the autobuilder. I think I found the cause: the patch passes each
  expanded URL to oe.patch.patch_path(), which calls
  Fetch.localpath(url). For a URL that is not in SRC_URI, that creates
  a new FetchData with the recipe datastore, where the
  SRCREV_<submodule> that the gitsm fetcher sets in its own datastore
  copy does not exist. A recipe with only named SRCREVs, like
  edk2-firmware, then fails with "Please set a valid SRCREV". It
  reproduces every time with meta-selftest's git-submodule-test given
  a named SRCREV. My guess for the intermittency is that gitsm only
  lists the submodules when the clone is in DL_DIR.
- Stefan's "Concept for tightly coupled package manager" RFC (December
  2024). My reading of that thread is that explicit SRC_URI lists
  generated in layers (go-mod-update-modules,
  cargo-update-recipe-crates) are the preferred model and that
  fetchers should stay thin. This proposal assumes that model and does
  not add any dependency resolution to bitbake.

The patches have two parts.

1. Record implicit downloads

   add_download_files() also records what implicit_urldata() returns
   for each SRC_URI entry, but keeps the patch check on the SRC_URI
   entries, so implicit downloads are never set up again with the
   recipe datastore. The npmsw fetcher gets an implicit_urldata(),
   since it already builds the list of URLs internally (ud.proxy). The
   gitsm fetcher warns when the repository is not in DL_DIR, instead
   of silently returning no submodules.

2. Let the fetcher state the identity of what it downloads

   FetchData gets a package_identity attribute, None by default and
   set in urldata_init() by the fetchers that know it:

     crate     ("cargo", "cipher", "0.4.4", {})
     gomod     ("golang", "github.com/felixge/httpsnoop", "v1.0.4", {})
     gomodgit  same as gomod
     npm       ("npm", "@scope/name", "1.2.3", {})
     npmsw     the same for each registry dependency

   The last element holds purl qualifiers, so a crate or npm package
   from another registry gets a repository_url. go.mod-only entries
   get None. create-spdx-3.0 sets the name, software_packageVersion and
   software_packageUrl from it and builds the purl in oe-core, so
   bitbake does not need to know the purl specification.

   I first had a FetchMethod method in mind, but npmsw fetches its
   dependencies through plain https URLs, so it has to attach the
   identity to each of them, and an attribute is enough for that. No
   URL syntax changes, unlike the dn=/dv= parameters in Stefan's
   series.

Both parts are small, about 35 lines in bitbake and 40 in oe-core plus
tests. I tested them on master with new bitbake fetcher unit tests and
new oe-selftest cases (submodules, including the named SRCREV case,
and crate identity), which fail without the patches, and with the
existing fetcher tests and the SPDX selftests closest to the change.
Two bugs I found in the existing Git handling while doing this (gitsm
skipped, changes not reaching the task signature) are fixed in a
separate series, which the oe-core part builds on:
https://lore.kernel.org/openembedded-core/20261104112257.866914-1-stondo@gmail.com/

Questions:

a) Is the fetcher the right place for the identity, or would you
   prefer oe-core to derive it from each fetcher's FetchData? The
   latter avoids touching bitbake, but for npmsw it means reading the
   internals of its proxy fetcher.

b) Should bitbake keep returning the parts and leave the purl to
   oe-core, as above, or return a purl directly?

c) For ecosystems without a fetcher (.NET/NuGet, Maven), would a
   fetcher plus an update class following go-mod-update-modules be
   welcome, or is that better kept in a layer?

d) Dependency scope. Identity alone does not give a correct SBOM: a
   lock file lists what may be needed on any platform. python3-bcrypt
   fetches wasi, wasip2 and wit-bindgen (WebAssembly only) and r-efi
   (UEFI), and with the patches they show up with a clean purl as if
   they were part of the product. As a follow-up I tried running
   cargo metadata --filter-platform ${RUST_HOST_SYS} in cargo.bbclass:
   of the 42 crates, 25 are runtime, 12 only run at build time (build
   scripts, proc-macros) and 5 are not used on the target. I recorded
   them as LifecycleScopedRelationship dependsOn with scope runtime or
   build, and an annotation on the unused ones. Go (go list -deps) and
   npm (dev, optional, os and cpu in the shrinkwrap) could work the
   same way. Does that split sound right: declared scope from the
   fetcher where the lock file has it, observed scope from the
   language classes? And is there a preferred SPDX representation for
   "fetched but not built"?

Thanks,
Stefano

             reply	other threads:[~2026-11-05 12:21 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 12:21 Stefano Tondo [this message]
2026-11-05 20:26 ` [RFC] spdx30: name, version and purl for dependency downloads Alexander Kanavin
2026-11-05 21:05   ` Stefano Tondo
2026-11-06 12:04     ` Alexander Kanavin
2026-11-06 12:17 ` [OE-core] " Richard Purdie
2026-11-10 21:59   ` Stefano Tondo
2026-11-10 22:53     ` Joshua Watt
2026-11-11 11:58       ` Stefano Tondo
2026-11-11 15:54         ` Joshua Watt
2026-11-11 15:48     ` Alexander Kanavin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261105122145.543282-1-stondo@gmail.com \
    --to=stondo@gmail.com \
    --cc=JPEWhacker@gmail.com \
    --cc=adrian.freihofer@siemens.com \
    --cc=alex.kanavin@gmail.com \
    --cc=bitbake-devel@lists.openembedded.org \
    --cc=openembedded-core@lists.openembedded.org \
    --cc=patrick.wicki@siemens.com \
    --cc=peter.marko@siemens.com \
    --cc=stefan.herbrechtsmeier@weidmueller.com \
    --cc=stefano.tondo.ext@siemens.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox