Buildroot Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Devoogdt <thomas@devoogdt.com>
To: buildroot@buildroot.org
Cc: eric.le.bihan.dev@free.fr, fontaine.fabrice@gmail.com,
	guillaume.chaye@zeetim.com, ju.o@free.fr, romain.naour@smile.fr,
	thomas.petazzoni@bootlin.com, thomas@devoogdt.com
Subject: [Buildroot] [PATCH v7 1/2] package/pkg-cargo: add support for prevendored Cargo.lock
Date: Wed,  4 Feb 2026 15:10:00 +0100	[thread overview]
Message-ID: <20260204141001.3962397-1-thomas@devoogdt.com> (raw)
In-Reply-To: <20260101173630.10079d1b@windsurf>

Add support for using pre-vendored Cargo.lock files in Buildroot
packages. This allows package maintainers to provide a Cargo.lock file
directly in the package directory, which is useful when:

- The upstream package doesn't provide a Cargo.lock file
- Specific dependency versions need to be pinned

The implementation automatically detects if a Cargo.lock file exists in
the package directory (next to the .mk file) and uses it during the
vendoring process. The download helper searches upwards from the
manifest to find the top-most Cargo.toml and places the lockfile there.

To handle updates to the Cargo.lock file without bumping the package
version, a FOO_CARGO_LOCK_VERSION variable is introduced. This defaults
to 1 and should be incremented (to 2, 3, etc.) each time the Cargo.lock
is updated independently. When set to values greater than 1, it adds a
"-lockN" suffix to the tarball name to force re-downloading. When the
package version is bumped, this variable should be removed to reset to
the default.

This work is based on ideas from:
- Yann E. Morin's cargo-unchained branch:
  https://gitlab.com/ymorin/buildroot/-/tree/yem/cargo-unchained
- Thomas Devoogdt's patch series:
  https://patchwork.ozlabs.org/project/buildroot/patch/20251019064503.2583945-1-thomas@devoogdt.com/

Signed-off-by: Thomas Devoogdt <thomas@devoogdt.com>
---
v7: reworked based on talks at DeveloperDaysFOSDEM2026
    https://mensuel.framapad.org/p/buildroot-fosdem-2026-ajdk?lang=en
---
 docs/manual/adding-packages-cargo.adoc | 35 ++++++++++++++++++++++----
 package/pkg-cargo.mk                   | 14 +++++++++++
 package/pkg-utils.mk                   |  3 ++-
 support/download/cargo-post-process    | 19 +++++++++++++-
 4 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/docs/manual/adding-packages-cargo.adoc b/docs/manual/adding-packages-cargo.adoc
index 4df758537b4..3170406fa2f 100644
--- a/docs/manual/adding-packages-cargo.adoc
+++ b/docs/manual/adding-packages-cargo.adoc
@@ -77,6 +77,13 @@ typical packages will therefore only use a few of them.
   is not at the root of the tree extracted by the tarball. If
   +HOST_FOO_SUBDIR+ is not specified, it defaults to +FOO_SUBDIR+.
 
+* +FOO_CARGO_LOCK_VERSION+ defaults to +1+ when a +Cargo.lock+ file is
+  provided in the Buildroot package directory (next to the +.mk+ file).
+  Only set this explicitly if you need to increment it (to +2+, +3+,
+  etc.) when updating the +Cargo.lock+ without bumping +FOO_VERSION+.
+  When +FOO_VERSION+ is bumped, remove this variable to let it default
+  back to +1+.
+
 * +FOO_CARGO_ENV+ can be used to pass additional variables in the
   environment of +cargo+ invocations. It used at both build and
   installation time
@@ -94,8 +101,26 @@ step of packages that use the +cargo-package+ infrastructure. Such
 dependencies are then kept together with the package source code in
 the tarball cached in Buildroot's +DL_DIR+, and therefore the hash of
 the package's tarball doesn't only cover the source of the package
-itself, but also covers the sources of the dependencies. Thus, a change
-injected into one of the dependencies will also be discovered by the
-hash check. In addition,  this mechanism allows the build to be
-performed completely offline since cargo will not do any downloads
-during the build. This mechanism is called vendoring the dependencies.
+itself, but also covers the sources of the dependencies. In addition,
+this mechanism allows the build to be performed completely offline
+since cargo will not do any downloads during the build. This mechanism
+is called vendoring the dependencies.
+
+==== Pre-vendoring with +Cargo.lock+
+
+In some cases, you may need to provide a custom +Cargo.lock+ file in
+Buildroot (e.g., when the upstream package doesn't provide one, or you
+need to pin specific dependency versions). To do this, place a
++Cargo.lock+ file in the package directory (next to the +.mk+ file).
+Buildroot will automatically detect and use it during vendoring.
+
+When you update the +Cargo.lock+ without bumping +FOO_VERSION+, you must
+increment +FOO_CARGO_LOCK_VERSION+:
+
+----
+FOO_CARGO_LOCK_VERSION = 2
+----
+
+Increment it for each subsequent +Cargo.lock+ change (+3+, +4+, etc.).
+When +FOO_VERSION+ is bumped, remove this variable to let it default
+back to +1+.
diff --git a/package/pkg-cargo.mk b/package/pkg-cargo.mk
index 47a6353f259..78f1561476c 100644
--- a/package/pkg-cargo.mk
+++ b/package/pkg-cargo.mk
@@ -195,6 +195,20 @@ ifneq ($$($(2)_SUBDIR),)
 $(2)_DOWNLOAD_POST_PROCESS_OPTS += -m$$($(2)_SUBDIR)/Cargo.toml
 endif
 
+# Automatically detect if a Cargo.lock file exists in the package directory
+# and use it for vendoring if present
+ifneq ($$(wildcard $(pkgdir)/Cargo.lock),)
+# Set the lock version if not already set, defaulting to 1
+ifndef $(3)_CARGO_LOCK_VERSION
+ $(3)_CARGO_LOCK_VERSION = 1
+endif
+# Only set EXTRA_FMT_VERSION if lock version is greater than 1
+ifneq ($$($(3)_CARGO_LOCK_VERSION),1)
+$(2)_EXTRA_FMT_VERSION = -lock$$($(3)_CARGO_LOCK_VERSION)
+endif
+$(2)_DOWNLOAD_POST_PROCESS_OPTS += -l $$(abspath $(pkgdir)/Cargo.lock)
+endif
+
 # Because we append vendored info, we can't rely on the values being empty
 # once we eventually get into the generic-package infra. So, we duplicate
 # the heuristics here
diff --git a/package/pkg-utils.mk b/package/pkg-utils.mk
index 211e681e8f5..5b2334b5f61 100644
--- a/package/pkg-utils.mk
+++ b/package/pkg-utils.mk
@@ -47,8 +47,9 @@ pkgname = $(lastword $(subst /, ,$(pkgdir)))
 
 # Helper to build the extension for a package archive, based on various
 # conditions.
+# NOTE! _EXTRA_FMT_VERSION should only be set by the infra, not individual packages!
 # $(1): upper-case package name
-pkg_source_ext = $(BR_FMT_VERSION_$($(1)_SITE_METHOD))$(BR_FMT_VERSION_$($(1)_DOWNLOAD_POST_PROCESS)).tar.gz
+pkg_source_ext = $(BR_FMT_VERSION_$($(1)_SITE_METHOD))$(BR_FMT_VERSION_$($(1)_DOWNLOAD_POST_PROCESS))$($(1)_EXTRA_FMT_VERSION).tar.gz
 
 # Define extractors for different archive suffixes
 INFLATE.bz2  = $(BZCAT)
diff --git a/support/download/cargo-post-process b/support/download/cargo-post-process
index b0e59ad74d8..c328002530f 100755
--- a/support/download/cargo-post-process
+++ b/support/download/cargo-post-process
@@ -11,11 +11,12 @@ if [ "${BR_CARGO_MANIFEST_PATH}" ]; then
 fi
 
 manifest=Cargo.toml
-while getopts "n:o:m:" OPT; do
+while getopts "n:o:m:l:" OPT; do
     case "${OPT}" in
     o)  output="${OPTARG}";;
     n)  base_name="${OPTARG}";;
     m)  manifest="${OPTARG}";;
+    l)  lockfile="${OPTARG}";;
     :)  error "option '%s' expects a mandatory argument\n" "${OPTARG}";;
     \?) error "unknown option '%s'\n" "${OPTARG}";;
     esac
@@ -31,6 +32,22 @@ post_process_unpack "${base_name}" "${output}"
 # Do the Cargo vendoring
 pushd "${base_name}" > /dev/null
 
+# If a lockfile was explicitly provided via -l option, use it
+if [ -n "${lockfile}" ]; then
+    # Search upwards from the manifest to find the top-most Cargo.toml
+    dir="${manifest}"
+    lock_dir="$(dirname "${manifest}")"
+    while [ "${dir}" != "." ]; do
+        dir="$(dirname "${dir}")"
+        if [ -e "${dir}/Cargo.toml" ]; then
+            lock_dir="${dir}"
+        fi
+    done
+
+    cp "${lockfile}" "${lock_dir}/Cargo.lock"
+    printf 'Using provided Cargo.lock from %s\n' "${lockfile}"
+fi
+
 # Create the local .cargo/config.toml with vendor info
 mkdir -p .cargo/
 mkdir -p "${CARGO_HOME}"
-- 
2.43.0

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

  reply	other threads:[~2026-02-04 14:10 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-30  8:07 [Buildroot] [PATCH v5 1/3] package/pkg-cargo: add support to bundle a custom Cargo.lock file Thomas Devoogdt
2025-09-30  8:07 ` [Buildroot] [PATCH v5 2/3] package/cargo-c: add new package Thomas Devoogdt
2025-09-30  8:07 ` [Buildroot] [PATCH v5 3/3] package/librsvg: bump version to 2.61.1 Thomas Devoogdt
2025-10-11  8:56 ` [Buildroot] [PATCH v5 1/3] package/pkg-cargo: add support to bundle a custom Cargo.lock file Thomas Devoogdt
2025-10-19  6:45   ` [Buildroot] [PATCH v6 " Thomas Devoogdt
2025-10-19  6:45     ` [Buildroot] [PATCH v6 2/3] package/cargo-c: add new package Thomas Devoogdt
2025-10-19  6:45     ` [Buildroot] [PATCH v6] package/librsvg: bump version to 2.61.1 Thomas Devoogdt
2026-01-01 17:00       ` Thomas Petazzoni via buildroot
2026-01-03 11:20         ` Thomas Devoogdt
2026-01-01 16:36     ` [Buildroot] [PATCH v6 1/3] package/pkg-cargo: add support to bundle a custom Cargo.lock file Thomas Petazzoni via buildroot
2026-02-04 14:10       ` Thomas Devoogdt [this message]
2026-02-04 14:10         ` [Buildroot] [PATCH v7 2/2] package/cargo-c: add new package Thomas Devoogdt

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=20260204141001.3962397-1-thomas@devoogdt.com \
    --to=thomas@devoogdt.com \
    --cc=buildroot@buildroot.org \
    --cc=eric.le.bihan.dev@free.fr \
    --cc=fontaine.fabrice@gmail.com \
    --cc=guillaume.chaye@zeetim.com \
    --cc=ju.o@free.fr \
    --cc=romain.naour@smile.fr \
    --cc=thomas.petazzoni@bootlin.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