{"thread":{"id":"64372","subject":"[PATCH 0/3] rust: generate bindings via cbindgen","startedAt":"2025-10-23T07:17:45Z","lastAt":"2025-10-31T23:37:09Z","messageCount":38,"participants":["Patrick Steinhardt","Junio C Hamano","Ezekiel Newren","Toon Claes","brian m. carlson"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"529483","messageId":"20251023-b4-pks-rust-cbindgen-v1-0-c19b61b03127@pks.im","threadId":"64372","inReplyTo":null,"subject":"[PATCH 0/3] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-23T07:17:37Z","receivedAt":"2025-10-23T07:17:45Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Hi,\n\nthis small patch series introduces support for cbindgen(1). This tool is\nused to generate C headers from `extern \"C\"` blocks so that Rust code\ncan easily be called from C code.\n\nFor now, the only use case is to verify that our varint reimplementation\nmatches the C implementation. But later on this can and will be used to\ncall Rust-specific features from C, as well.\n\nThe topic is built on top of c54a18ef67 (The twenty-second batch,\n2025-10-22) with ps/ci-rust at e509b5b8be (rust: support for Windows,\n2025-10-15) merged into it.\n\nThanks!\n\nPatrick\n\n---\nPatrick Steinhardt (3):\n      ci: use Debian instead of deprecated i386/ubuntu\n      meson: rename Rust library target\n      rust: generate bindings via cbindgen\n\n .github/workflows/main.yml |  3 +--\n .gitignore                 |  1 +\n .gitlab-ci.yml             |  2 +-\n Makefile                   | 14 +++++++++++---\n cbindgen.toml              |  7 +++++++\n ci/install-dependencies.sh | 10 +++++-----\n ci/lib.sh                  |  2 +-\n meson.build                | 25 ++++++++++++++++++++-----\n shared.mak                 |  1 +\n src/meson.build            |  2 +-\n varint.c                   |  9 +++++++++\n 11 files changed, 58 insertions(+), 18 deletions(-)\n\n\n---\nbase-commit: 8654b230d9afe1326340989dd7082997c672472e\nchange-id: 20251009-b4-pks-rust-cbindgen-d80779ed2269\n\n"},{"id":"529484","messageId":"20251023-b4-pks-rust-cbindgen-v1-1-c19b61b03127@pks.im","threadId":"64372","inReplyTo":"20251023-b4-pks-rust-cbindgen-v1-0-c19b61b03127@pks.im","subject":"[PATCH 1/3] ci: use Debian instead of deprecated i386/ubuntu","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-23T07:17:38Z","receivedAt":"2025-10-23T07:17:48Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Ubuntu has ended support for 32 bit platforms and is not maintaining any\nrelease anymore that has 32 bit support. But we still use i386/ubuntu in\nour CI pipeline to test for compatibility with 32 bit systems, even\nthough that specific image does not receive updates anymore.\n\nBesides being end-of-life, this image also doesn't have all packages\navailable to it anymore. This creates problems with a subsequent patch,\nwhere we're about to pull in cbindgen for generating Rust to C bindings.\n\nDrop the Ubuntu image and use Debian instead, which continues to\nmaintain its 32 bit port.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .github/workflows/main.yml | 3 +--\n .gitlab-ci.yml             | 2 +-\n ci/install-dependencies.sh | 6 +++---\n ci/lib.sh                  | 2 +-\n 4 files changed, 6 insertions(+), 7 deletions(-)\n\ndiff --git a/.github/workflows/main.yml b/.github/workflows/main.yml\nindex cc54824c388..0b16970cd7e 100644\n--- a/.github/workflows/main.yml\n+++ b/.github/workflows/main.yml\n@@ -395,9 +395,8 @@ jobs:\n           cc: gcc\n         - jobname: linux-musl-meson\n           image: alpine:latest\n-        # Supported until 2025-04-02.\n         - jobname: linux32\n-          image: i386/ubuntu:focal\n+          image: i386/debian:latest\n         # A RHEL 8 compatible distro.  Supported until 2029-05-31.\n         - jobname: almalinux-8\n           image: almalinux:8\ndiff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\nindex b419a84e2cc..85feebf72d6 100644\n--- a/.gitlab-ci.yml\n+++ b/.gitlab-ci.yml\n@@ -63,7 +63,7 @@ test:linux:\n       - jobname: linux-musl-meson\n         image: alpine:latest\n       - jobname: linux32\n-        image: i386/ubuntu:20.04\n+        image: i386/debian:latest\n       - jobname: linux-meson\n         image: ubuntu:rolling\n         CC: gcc\ndiff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\nindex 50628ee2dd6..b7b3cf35edf 100755\n--- a/ci/install-dependencies.sh\n+++ b/ci/install-dependencies.sh\n@@ -39,7 +39,7 @@ fedora-*|almalinux-*)\n \tdnf -yq update >/dev/null &&\n \tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo >/dev/null\n \t;;\n-ubuntu-*|i386/ubuntu-*|debian-*)\n+ubuntu-*|i386/debian-*|debian-*)\n \t# Required so that apt doesn't wait for user input on certain packages.\n \texport DEBIAN_FRONTEND=noninteractive\n \n@@ -48,9 +48,9 @@ ubuntu-*|i386/ubuntu-*|debian-*)\n \t\tSVN='libsvn-perl subversion'\n \t\tLANGUAGES='language-pack-is'\n \t\t;;\n-\ti386/ubuntu-*)\n+\ti386/debian-*)\n \t\tSVN=\n-\t\tLANGUAGES='language-pack-is'\n+\t\tLANGUAGES='locales-all'\n \t\t;;\n \t*)\n \t\tSVN='libsvn-perl subversion'\ndiff --git a/ci/lib.sh b/ci/lib.sh\nindex f561884d401..865a0675371 100755\n--- a/ci/lib.sh\n+++ b/ci/lib.sh\n@@ -250,7 +250,7 @@ then\n \t\tCI_OS_NAME=osx\n \t\tJOBS=$(nproc)\n \t\t;;\n-\t*,alpine:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*)\n+\t*,alpine:*|*,fedora:*|*,ubuntu:*|*,i386/debian:*)\n \t\tCI_OS_NAME=linux\n \t\tJOBS=$(nproc)\n \t\t;;\n\n-- \n2.51.1.930.gacf6e81ea2.dirty\n\n"},{"id":"529485","messageId":"20251023-b4-pks-rust-cbindgen-v1-2-c19b61b03127@pks.im","threadId":"64372","inReplyTo":"20251023-b4-pks-rust-cbindgen-v1-0-c19b61b03127@pks.im","subject":"[PATCH 2/3] meson: rename Rust library target","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-23T07:17:39Z","receivedAt":"2025-10-23T07:17:51Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Rename the Rust library target from `git_rs` to `rust`. The latter is\nway easier to remember if one wants to compile only that target via\n`meson compile rust`. Furthermore, this name matches the test target\nthat we have for Rust that can be invoked via `meson test rust`.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n src/meson.build | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/src/meson.build b/src/meson.build\nindex 25b9ad5a147..1c73549696c 100644\n--- a/src/meson.build\n+++ b/src/meson.build\n@@ -17,7 +17,7 @@ if get_option('buildtype') == 'release'\n   cargo_command += '--release'\n endif\n \n-libgit_rs = custom_target('git_rs',\n+libgit_rs = custom_target('rust',\n   input: libgit_rs_sources + [\n     meson.project_source_root() / 'Cargo.toml',\n   ],\n\n-- \n2.51.1.930.gacf6e81ea2.dirty\n\n"},{"id":"529486","messageId":"20251023-b4-pks-rust-cbindgen-v1-3-c19b61b03127@pks.im","threadId":"64372","inReplyTo":"20251023-b4-pks-rust-cbindgen-v1-0-c19b61b03127@pks.im","subject":"[PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-23T07:17:40Z","receivedAt":"2025-10-23T07:17:54Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"When compiling Git with Rust enabled we replace our C implementation of\nthe varint encoding with a Rust implementation. A prerequisite for doing\nso is of course that the interfaces for both implementations are exactly\nthe same. If they aren't, then we risk subtle runtime errors.\n\nWe don't really have a way to detect such interface mismatches though:\nthe code will happily compile if we change either of the implementations\nwithout adjusting the other implementation in the same spirit. The risk\nof divergence is low right now as we only replace a single subsystem.\nBut it is expected that we'll grow more reimplementations over time, so\nit is bound to increase.\n\nA related issue is that we don't have an easy way to implement features\nexclusively in Rust and make them available to our C library. Again, we\ndon't have such features yet, but there are work-in-progress patch\nseries that will eventually add them.\n\nBoth of these issues can be addressed by generating C bindings via the\ncbindgen(1) tool: given a Rust crate, it extracts all functions marked\nwith `extern \"C\"` and creates a C declaration for them. These are then\nwritten into a header file that we can include.\n\nSet up this infrastructure in both our Makefile and in Meson. To\ndemonstrate its use, the generated \"c-bindings.h\" header is included in\n\"varint.c\". If we now adapt \"varint.rs\" to have a different function\nsignature than the C code we'll now get a compiler error:\n\n    In file included from ../varint.c:10:\n    ./c-bindings.h:10:10: error: conflicting types for 'decode_varint'\n       10 | uint32_t decode_varint(const uint8_t **bufp);\n          |          ^\n    ../varint.h:5:10: note: previous declaration is here\n        5 | uint64_t decode_varint(const unsigned char **);\n\nAn initial version instead included the bindings in \"varint.h\". But that\nwould cause us to recompile all dependents of \"varint.h\" every time the\nsignatures of exported Rust functions change. So instead, we now include\nit in \"varint.c\" and compile that file unconditionally again.\n\nAdapt our CI to install cbindgen(1) accordingly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .gitignore                 |  1 +\n Makefile                   | 14 +++++++++++---\n cbindgen.toml              |  7 +++++++\n ci/install-dependencies.sh |  4 ++--\n meson.build                | 25 ++++++++++++++++++++-----\n shared.mak                 |  1 +\n varint.c                   |  9 +++++++++\n 7 files changed, 51 insertions(+), 10 deletions(-)\n\ndiff --git a/.gitignore b/.gitignore\nindex 78a45cb5bec..20558c9dc8a 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -197,6 +197,7 @@\n /gitweb/gitweb.cgi\n /gitweb/static/gitweb.js\n /gitweb/static/gitweb.min.*\n+/c-bindings.h\n /config-list.h\n /command-list.h\n /hook-list.h\ndiff --git a/Makefile b/Makefile\nindex 0bf5f17a90c..1213a0fc960 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1326,9 +1326,7 @@ LIB_OBJS += urlmatch.o\n LIB_OBJS += usage.o\n LIB_OBJS += userdiff.o\n LIB_OBJS += utf8.o\n-ifndef WITH_RUST\n LIB_OBJS += varint.o\n-endif\n LIB_OBJS += version.o\n LIB_OBJS += versioncmp.o\n LIB_OBJS += walker.o\n@@ -1562,6 +1560,14 @@ ALL_LDFLAGS = $(LDFLAGS) $(LDFLAGS_APPEND)\n ifdef WITH_RUST\n BASIC_CFLAGS += -DWITH_RUST\n GITLIBS += $(RUST_LIB)\n+\n+C_BINDINGS = c-bindings.h\n+\n+GENERATED_H += $(C_BINDINGS)\n+\n+$(C_BINDINGS): cbindgen.toml $(RUST_SOURCES)\n+\t$(QUIET_CBINDGEN)cbindgen --output $@\n+\n ifeq ($(uname_S),Windows)\n EXTLIBS += -luserenv\n endif\n@@ -2619,6 +2625,8 @@ PAGER_ENV_CQ_SQ = $(subst ','\\'',$(PAGER_ENV_CQ))\n pager.sp pager.s pager.o: EXTRA_CPPFLAGS = \\\n \t-DPAGER_ENV='$(PAGER_ENV_CQ_SQ)'\n \n+varint.sp varint.s varint.o: $(C_BINDINGS)\n+\n version-def.h: version-def.h.in GIT-VERSION-GEN GIT-VERSION-FILE GIT-USER-AGENT\n \t$(QUIET_GEN)$(call version_gen,\"$(shell pwd)\",$<,$@)\n \n@@ -3806,7 +3814,7 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) $(FUZZ_PROGRAMS)\n \t$(RM) $(SP_OBJ)\n \t$(RM) $(HCC)\n-\t$(RM) -r Cargo.lock target/\n+\t$(RM) -r Cargo.lock target/ $(C_BINDINGS)\n \t$(RM) version-def.h\n \t$(RM) -r $(dep_dirs) $(compdb_dir) compile_commands.json\n \t$(RM) $(test_bindir_programs)\ndiff --git a/cbindgen.toml b/cbindgen.toml\nnew file mode 100644\nindex 00000000000..ba4b2d63672\n--- /dev/null\n+++ b/cbindgen.toml\n@@ -0,0 +1,7 @@\n+language = \"C\"\n+\n+# Don't include standard C headers. These are managed by \"git-compat-util.h\".\n+no_includes = true\n+\n+# Use plain structs instead of using typedefs.\n+style = \"tag\"\ndiff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\nindex b7b3cf35edf..3bce6f47f87 100755\n--- a/ci/install-dependencies.sh\n+++ b/ci/install-dependencies.sh\n@@ -37,7 +37,7 @@ fedora-*|almalinux-*)\n \t\tMESON_DEPS=\"meson ninja\";;\n \tesac\n \tdnf -yq update >/dev/null &&\n-\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo >/dev/null\n+\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo cbindgen >/dev/null\n \t;;\n ubuntu-*|i386/debian-*|debian-*)\n \t# Required so that apt doesn't wait for user input on certain packages.\n@@ -64,7 +64,7 @@ ubuntu-*|i386/debian-*|debian-*)\n \t\tmake libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \\\n \t\ttcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \\\n \t\tlibemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \\\n-\t\tlibsecret-1-dev libpcre2-dev meson ninja-build pkg-config cargo \\\n+\t\tlibsecret-1-dev libpcre2-dev meson ninja-build pkg-config cargo cbindgen \\\n \t\t${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE\n \n \t# Starting with Ubuntu 25.10, sudo can now be provided via either\ndiff --git a/meson.build b/meson.build\nindex 308798e861b..b4acc417ad4 100644\n--- a/meson.build\n+++ b/meson.build\n@@ -523,6 +523,7 @@ libgit_sources = [\n   'usage.c',\n   'userdiff.c',\n   'utf8.c',\n+  'varint.c',\n   'version.c',\n   'versioncmp.c',\n   'walker.c',\n@@ -1704,7 +1705,9 @@ version_def_h = custom_target(\n libgit_sources += version_def_h\n \n cargo = find_program('cargo', dirs: program_path, native: true, required: get_option('rust'))\n-rust_option = get_option('rust').disable_auto_if(not cargo.found())\n+cbindgen = find_program('cbindgen', dirs: program_path, native: true, required: get_option('rust'))\n+\n+rust_option = get_option('rust').disable_auto_if(not cargo.found() or not cbindgen.found())\n if rust_option.allowed()\n   subdir('src')\n   libgit_c_args += '-DWITH_RUST'\n@@ -1712,10 +1715,22 @@ if rust_option.allowed()\n   if host_machine.system() == 'windows'\n     libgit_dependencies += compiler.find_library('userenv')\n   endif\n-else\n-  libgit_sources += [\n-    'varint.c',\n-  ]\n+\n+  cbindgen_input = [ 'cbindgen.toml' ]\n+  foreach source : libgit_rs_sources\n+    cbindgen_input += 'src' / source\n+  endforeach\n+\n+  libgit_sources += custom_target('c-bindings.h',\n+    input: cbindgen_input,\n+    output: 'c-bindings.h',\n+    command: [\n+      cbindgen,\n+      '--output',\n+      '@OUTPUT@',\n+      meson.current_source_dir(),\n+    ],\n+  )\n endif\n \n libgit = declare_dependency(\ndiff --git a/shared.mak b/shared.mak\nindex 0e7492076eb..598e58e069c 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -57,6 +57,7 @@ ifndef V\n \n ## Used in \"Makefile\"\n \tQUIET_CARGO    = @echo '   ' CARGO $@;\n+\tQUIET_CBINDGEN = @echo '   ' CBINDGEN $@;\n \tQUIET_CC       = @echo '   ' CC $@;\n \tQUIET_AR       = @echo '   ' AR $@;\n \tQUIET_LINK     = @echo '   ' LINK $@;\ndiff --git a/varint.c b/varint.c\nindex 03cd54416b6..1ed738a756c 100644\n--- a/varint.c\n+++ b/varint.c\n@@ -1,6 +1,14 @@\n #include \"git-compat-util.h\"\n #include \"varint.h\"\n \n+/*\n+ * When building with Rust we don't compile the C code, but we only verify\n+ * whether the function signatures of our C bindings match the ones we have\n+ * declared in \"varint.h\".\n+ */\n+#ifdef WITH_RUST\n+# include \"c-bindings.h\"\n+#else\n uint64_t decode_varint(const unsigned char **bufp)\n {\n \tconst unsigned char *buf = *bufp;\n@@ -28,3 +36,4 @@ uint8_t encode_varint(uint64_t value, unsigned char *buf)\n \t\tmemcpy(buf, varint + pos, sizeof(varint) - pos);\n \treturn sizeof(varint) - pos;\n }\n+#endif\n\n-- \n2.51.1.930.gacf6e81ea2.dirty\n\n"},{"id":"529513","messageId":"xmqqbjlxv6xa.fsf@gitster.g","threadId":"64372","inReplyTo":"20251023-b4-pks-rust-cbindgen-v1-1-c19b61b03127@pks.im","subject":"Re: [PATCH 1/3] ci: use Debian instead of deprecated i386/ubuntu","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-10-23T17:56:01Z","receivedAt":"2025-10-23T17:56:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Ubuntu has ended support for 32 bit platforms and is not maintaining any\n> release anymore that has 32 bit support. But we still use i386/ubuntu in\n> our CI pipeline to test for compatibility with 32 bit systems, even\n> though that specific image does not receive updates anymore.\n>\n> Besides being end-of-life, this image also doesn't have all packages\n> available to it anymore. This creates problems with a subsequent patch,\n> where we're about to pull in cbindgen for generating Rust to C bindings.\n>\n> Drop the Ubuntu image and use Debian instead, which continues to\n> maintain its 32 bit port.\n\nThanks, this is long overdue.\n\nWould this have nagative interactions with our recent tweak for\nsudo-rust vs sudo-C, which I thought was only releavant for Ubuntu?\n\nI guess as long as i386/debian does not have /etc/alternatives/sudo\nwe should be safe, and we also handle debian-* (presumably 64-bit)\nin the same case arm, so this should not be a new problem.  Just\ndouble checking.\n\n> -        # Supported until 2025-04-02.\n>          - jobname: linux32\n> -          image: i386/ubuntu:focal\n> +          image: i386/debian:latest\n\nWill queue.  Thanks.\n"},{"id":"529514","messageId":"CAH=ZcbADTLvTioBf+LYQej1G0biZM8s3-iJG+BZjnpxj+8NjsA@mail.gmail.com","threadId":"64372","inReplyTo":"20251023-b4-pks-rust-cbindgen-v1-3-c19b61b03127@pks.im","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Ezekiel Newren","fromEmail":"ezekielnewren@gmail.com","sentAt":"2025-10-23T18:00:21Z","receivedAt":"2025-10-23T18:00:35Z","isPatch":true,"sender":{"key":"ezekielnewren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/18313324?v=4"},"body":"On Thu, Oct 23, 2025 at 1:17 AM Patrick Steinhardt <ps@pks.im> wrote:\n> +C_BINDINGS = c-bindings.h\n> +\n> +GENERATED_H += $(C_BINDINGS)\n> +\n> +$(C_BINDINGS): cbindgen.toml $(RUST_SOURCES)\n> +       $(QUIET_CBINDGEN)cbindgen --output $@\n> +\n\nMy preference is to store all generated header files from cbindgen\nunder interop/ that way we don't pollute the root of Git. It also\nmakes ignoring generated header files easier (if we choose to) since\nwe'd only need to specify `/interop/` in .gitignore. For platforms\nthat can't compile Rust how are they going to build C if they depend\non those generated headers?\n\n> diff --git a/cbindgen.toml b/cbindgen.toml\n> new file mode 100644\n> index 00000000000..ba4b2d63672\n> --- /dev/null\n> +++ b/cbindgen.toml\n> @@ -0,0 +1,7 @@\n> +language = \"C\"\n> +\n> +# Don't include standard C headers. These are managed by \"git-compat-util.h\".\n> +no_includes = true\n> +\n> +# Use plain structs instead of using typedefs.\n> +style = \"tag\"\n\nThis is what my cbindgen.toml file looked like.\n```\nsys_includes = [\"git-compat-util.h\"]\n\nautogen_warning = \"/* Warning, this file is autogenerated by cbindgen.\nDon't modify this manually. */\"\n\nlanguage = \"C\"\nno_includes = true\nusize_is_size_t = true\nstyle = \"tag\"\ntab_width = 4\n\n[parse]\nparse_deps = false\n```\ntab_width is the number of spaces, there is no option to use a tab\ncharacter in cbindgen.\n\n> diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\n> index b7b3cf35edf..3bce6f47f87 100755\n> --- a/ci/install-dependencies.sh\n> +++ b/ci/install-dependencies.sh\n> @@ -37,7 +37,7 @@ fedora-*|almalinux-*)\n>                 MESON_DEPS=\"meson ninja\";;\n>         esac\n>         dnf -yq update >/dev/null &&\n> -       dnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo >/dev/null\n> +       dnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo cbindgen >/dev/null\n>         ;;\n>  ubuntu-*|i386/debian-*|debian-*)\n>         # Required so that apt doesn't wait for user input on certain packages.\n> @@ -64,7 +64,7 @@ ubuntu-*|i386/debian-*|debian-*)\n>                 make libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \\\n>                 tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \\\n>                 libemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \\\n> -               libsecret-1-dev libpcre2-dev meson ninja-build pkg-config cargo \\\n> +               libsecret-1-dev libpcre2-dev meson ninja-build pkg-config cargo cbindgen \\\n>                 ${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE\n\ncbindgen is a Rust crate and it should be specified in the Cargo.toml\nunder [build-dependencies] block. Also I think that we should convert\nfrom using a Cargo crate to using a Cargo workspace, so that we can\ngenerate multiple header files (1 per crate) rather than a monolithic\ngenerated header. This is because cbindgen operates at the granularity\nof a crate.\n"},{"id":"529531","messageId":"xmqqjz0ls3ak.fsf@gitster.g","threadId":"64372","inReplyTo":"20251023-b4-pks-rust-cbindgen-v1-3-c19b61b03127@pks.im","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-10-23T21:42:43Z","receivedAt":"2025-10-23T21:42:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Set up this infrastructure in both our Makefile and in Meson. To\n> demonstrate its use, the generated \"c-bindings.h\" header is included in\n> \"varint.c\". If we now adapt \"varint.rs\" to have a different function\n> signature than the C code we'll now get a compiler error:\n>\n>     In file included from ../varint.c:10:\n>     ./c-bindings.h:10:10: error: conflicting types for 'decode_varint'\n>        10 | uint32_t decode_varint(const uint8_t **bufp);\n>           |          ^\n>     ../varint.h:5:10: note: previous declaration is here\n>         5 | uint64_t decode_varint(const unsigned char **);\n>\n> An initial version instead included the bindings in \"varint.h\". But that\n> would cause us to recompile all dependents of \"varint.h\" every time the\n> signatures of exported Rust functions change. So instead, we now include\n> it in \"varint.c\" and compile that file unconditionally again.\n>\n> Adapt our CI to install cbindgen(1) accordingly.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n\nOK.  I am getting this out of \"make c-bindings.h\", which looks\nquite reasonable.\n\n/**\n * Decode the variable-length integer stored in `bufp` and return the decoded value.\n *\n * Returns 0 in case the decoded integer would overflow u64::MAX.\n *\n * # Safety\n *\n * The buffer must be NUL-terminated to ensure safety.\n */\nuint64_t decode_varint(const uint8_t **bufp);\n\n/**\n * Encode `value` into `buf` as a variable-length integer unless `buf` is null.\n *\n * Returns the number of bytes written, or, if `buf` is null, the number of bytes that would be\n * written to encode the integer.\n *\n * # Safety\n *\n * `buf` must either be null or point to at least 16 bytes of memory.\n */\nuint8_t encode_varint(uint64_t value, uint8_t *buf);\n"},{"id":"529534","messageId":"xmqqbjlxs2f7.fsf@gitster.g","threadId":"64372","inReplyTo":"20251023-b4-pks-rust-cbindgen-v1-3-c19b61b03127@pks.im","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-10-23T22:01:32Z","receivedAt":"2025-10-23T22:01:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> An initial version instead included the bindings in \"varint.h\". But that\n> would cause us to recompile all dependents of \"varint.h\" every time the\n> signatures of exported Rust functions change. So instead, we now include\n> it in \"varint.c\" and compile that file unconditionally again.\n>\n> Adapt our CI to install cbindgen(1) accordingly.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n\nI am debating myself if we want a patch like this.  I tend to prefer\n\"make clean\" not to be too specific to the build options used to\nleave crufts.\n\n\n Makefile | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git i/Makefile w/Makefile\nindex 59e5a2c61c..9b673865e5 100644\n--- i/Makefile\n+++ w/Makefile\n@@ -1558,12 +1558,13 @@ endif\n ALL_CFLAGS = $(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_APPEND)\n ALL_LDFLAGS = $(LDFLAGS) $(LDFLAGS_APPEND)\n \n+# allow \"make WITH_RUST=Yes && make clean\" to discard it\n+C_BINDINGS = c-bindings.h\n+\n ifdef WITH_RUST\n BASIC_CFLAGS += -DWITH_RUST\n GITLIBS += $(RUST_LIB)\n \n-C_BINDINGS = c-bindings.h\n-\n GENERATED_H += $(C_BINDINGS)\n \n $(C_BINDINGS): cbindgen.toml $(RUST_SOURCES)\n"},{"id":"529536","messageId":"xmqq7bwls0qh.fsf@gitster.g","threadId":"64372","inReplyTo":"20251023-b4-pks-rust-cbindgen-v1-3-c19b61b03127@pks.im","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-10-23T22:37:58Z","receivedAt":"2025-10-23T22:38:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\n> index b7b3cf35edf..3bce6f47f87 100755\n> --- a/ci/install-dependencies.sh\n> +++ b/ci/install-dependencies.sh\n> @@ -37,7 +37,7 @@ fedora-*|almalinux-*)\n>  \t\tMESON_DEPS=\"meson ninja\";;\n>  \tesac\n>  \tdnf -yq update >/dev/null &&\n> -\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo >/dev/null\n> +\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo cbindgen >/dev/null\n>  \t;;\n\nA single ~120 columns wide should be line-wrapped.  This seems to\nfail with almalinux-8 CI job due to lack of the package.\n\n"},{"id":"529558","messageId":"aPseaeIPq29R1TZz@pks.im","threadId":"64372","inReplyTo":"xmqqbjlxv6xa.fsf@gitster.g","subject":"Re: [PATCH 1/3] ci: use Debian instead of deprecated i386/ubuntu","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-24T06:36:25Z","receivedAt":"2025-10-24T06:36:37Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Oct 23, 2025 at 10:56:01AM -0700, Junio C Hamano wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > Ubuntu has ended support for 32 bit platforms and is not maintaining any\n> > release anymore that has 32 bit support. But we still use i386/ubuntu in\n> > our CI pipeline to test for compatibility with 32 bit systems, even\n> > though that specific image does not receive updates anymore.\n> >\n> > Besides being end-of-life, this image also doesn't have all packages\n> > available to it anymore. This creates problems with a subsequent patch,\n> > where we're about to pull in cbindgen for generating Rust to C bindings.\n> >\n> > Drop the Ubuntu image and use Debian instead, which continues to\n> > maintain its 32 bit port.\n> \n> Thanks, this is long overdue.\n> \n> Would this have nagative interactions with our recent tweak for\n> sudo-rust vs sudo-C, which I thought was only releavant for Ubuntu?\n> \n> I guess as long as i386/debian does not have /etc/alternatives/sudo\n> we should be safe, and we also handle debian-* (presumably 64-bit)\n> in the same case arm, so this should not be a new problem.  Just\n> double checking.\n\nYup, exactly. Debian continues to use the old sudo implementation, and\nit doesn't have /etc/alternatives/sudo at the current point in time.\n\nPatrick\n"},{"id":"529559","messageId":"aPseeELtGzHvn2IS@pks.im","threadId":"64372","inReplyTo":"xmqq7bwls0qh.fsf@gitster.g","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-24T06:36:40Z","receivedAt":"2025-10-24T06:36:45Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Oct 23, 2025 at 03:37:58PM -0700, Junio C Hamano wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\n> > index b7b3cf35edf..3bce6f47f87 100755\n> > --- a/ci/install-dependencies.sh\n> > +++ b/ci/install-dependencies.sh\n> > @@ -37,7 +37,7 @@ fedora-*|almalinux-*)\n> >  \t\tMESON_DEPS=\"meson ninja\";;\n> >  \tesac\n> >  \tdnf -yq update >/dev/null &&\n> > -\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo >/dev/null\n> > +\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo cbindgen >/dev/null\n> >  \t;;\n> \n> A single ~120 columns wide should be line-wrapped.  This seems to\n> fail with almalinux-8 CI job due to lack of the package.\n\nThanks, that's a test gap in GitLab CI then. Will fix the issue and the\ngap.\n\nPatrick\n"},{"id":"529560","messageId":"aPsepOtUf92fqDL-@pks.im","threadId":"64372","inReplyTo":"CAH=ZcbADTLvTioBf+LYQej1G0biZM8s3-iJG+BZjnpxj+8NjsA@mail.gmail.com","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-24T06:37:24Z","receivedAt":"2025-10-24T06:37:30Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Oct 23, 2025 at 12:00:21PM -0600, Ezekiel Newren wrote:\n> On Thu, Oct 23, 2025 at 1:17 AM Patrick Steinhardt <ps@pks.im> wrote:\n> > +C_BINDINGS = c-bindings.h\n> > +\n> > +GENERATED_H += $(C_BINDINGS)\n> > +\n> > +$(C_BINDINGS): cbindgen.toml $(RUST_SOURCES)\n> > +       $(QUIET_CBINDGEN)cbindgen --output $@\n> > +\n> \n> My preference is to store all generated header files from cbindgen\n> under interop/ that way we don't pollute the root of Git. It also\n> makes ignoring generated header files easier (if we choose to) since\n> we'd only need to specify `/interop/` in .gitignore.\n\nIt's (unfortunately) common practice to generate headers all over the\nplace in Git. So I'd propose that until we grow a second interop header\nwe keep it in the root hierarchy.\n\nThe proper fix for this in my opinion is out-of-tree builds. In Meson\nfor example we don't have to worry about this issue at all. If we wanted\nto fix this more broadly for our Makefile, as well, I'd propose to\ninstead introduce a \"generated/\" directory and move all of our generated\nheaders into it.\n\n> For platforms that can't compile Rust how are they going to build C if\n> they depend on those generated headers?\n\nFor now they don't have to care about this, as the interop header is\nonly included in case we build with Rust support enabled.\n\n> > diff --git a/cbindgen.toml b/cbindgen.toml\n> > new file mode 100644\n> > index 00000000000..ba4b2d63672\n> > --- /dev/null\n> > +++ b/cbindgen.toml\n> > @@ -0,0 +1,7 @@\n> > +language = \"C\"\n> > +\n> > +# Don't include standard C headers. These are managed by \"git-compat-util.h\".\n> > +no_includes = true\n> > +\n> > +# Use plain structs instead of using typedefs.\n> > +style = \"tag\"\n> \n> This is what my cbindgen.toml file looked like.\n>\n> ```\n> sys_includes = [\"git-compat-util.h\"]\n\nOur headers generally don't include \"git-compat-util.h\". The rule is\nthat it should always be included first by our code files. So I think we\nshould stick to that rule for this generated file, as well.\n\n> autogen_warning = \"/* Warning, this file is autogenerated by cbindgen.\n> Don't modify this manually. */\"\n\nMakes sense.\n\n> language = \"C\"\n> no_includes = true\n> style = \"tag\"\n\nYup, also got these.\n\n> usize_is_size_t = true\n\nAh, this feels like the right thing to do, agreed.\n\n> tab_width = 4\n> \n> tab_width is the number of spaces, there is no option to use a tab\n> character in cbindgen.\n\nShouldn't this rather use 8 then to match our coding style better, even\nif it's not a perfect match?\n\n> [parse]\n> parse_deps = false\n\nThis is the default according to cbindgen's documentation, so I'll not\ninclude this line.\n\n> > diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\n> > index b7b3cf35edf..3bce6f47f87 100755\n> > --- a/ci/install-dependencies.sh\n> > +++ b/ci/install-dependencies.sh\n> > @@ -37,7 +37,7 @@ fedora-*|almalinux-*)\n> >                 MESON_DEPS=\"meson ninja\";;\n> >         esac\n> >         dnf -yq update >/dev/null &&\n> > -       dnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo >/dev/null\n> > +       dnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo cbindgen >/dev/null\n> >         ;;\n> >  ubuntu-*|i386/debian-*|debian-*)\n> >         # Required so that apt doesn't wait for user input on certain packages.\n> > @@ -64,7 +64,7 @@ ubuntu-*|i386/debian-*|debian-*)\n> >                 make libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \\\n> >                 tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \\\n> >                 libemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \\\n> > -               libsecret-1-dev libpcre2-dev meson ninja-build pkg-config cargo \\\n> > +               libsecret-1-dev libpcre2-dev meson ninja-build pkg-config cargo cbindgen \\\n> >                 ${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE\n> \n> cbindgen is a Rust crate and it should be specified in the Cargo.toml\n> under [build-dependencies] block.\n\nWhat is the benefit for us? The generated code is not a dependency of\nthe Rust code, and neither do we use it via \"build.rs\". And if we use\ncbindgen via \"Cargo.toml\" we'd be forced to build it first, which slows\ndown our CI jobs.\n\nPlease let me know in case I miss any reasons to have it in our build\ndependencies instead.\n\n> Also I think that we should convert from using a Cargo crate to using\n> a Cargo workspace, so that we can generate multiple header files (1\n> per crate) rather than a monolithic generated header. This is because\n> cbindgen operates at the granularity of a crate.\n\nI'm basically still punting this into the future. There is no good\nreason yet to have workspaces, so I'd rather introduce them once we have\na better way to sell them and demonstrate their immediate benefits.\n\nPatrick\n"},{"id":"529577","messageId":"20251024-b4-pks-rust-cbindgen-v2-0-4b4bd4f18490@pks.im","threadId":"64372","inReplyTo":"20251023-b4-pks-rust-cbindgen-v1-0-c19b61b03127@pks.im","subject":"[PATCH v2 0/5] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-24T09:51:32Z","receivedAt":"2025-10-24T09:51:50Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Hi,\n\nthis small patch series introduces support for cbindgen(1). This tool is\nused to generate C headers from `extern \"C\"` blocks so that Rust code\ncan easily be called from C code.\n\nFor now, the only use case is to verify that our varint reimplementation\nmatches the C implementation. But later on this can and will be used to\ncall Rust-specific features from C, as well.\n\nThe topic is built on top of c54a18ef67 (The twenty-second batch,\n2025-10-22) with ps/ci-rust at e509b5b8be (rust: support for Windows,\n2025-10-15) merged into it.\n\nChanges in v2:\n  - Take some of the pieces from Ezekiel's \"cbindgen.toml\" file. I have\n    not yet taken `usize_is_size_t`, as that option requires cbindgen\n    v0.16.0, which is not available on Ubuntu 20.04.\n  - Backfill missing jobs for GitLab CI.\n  - Fix CI failures on Alma Linux 8 because cbindgen isn't available\n    there.\n  - Link to v1: https://lore.kernel.org/r/20251023-b4-pks-rust-cbindgen-v1-0-c19b61b03127@pks.im\n\nThanks!\n\nPatrick\n\n---\nPatrick Steinhardt (5):\n      gitlab-ci: reorder Linux job matrix to match GitHub's order\n      gitlab-ci: backfill missing Linux jobs\n      ci: use Debian instead of deprecated i386/ubuntu\n      meson: rename Rust library target\n      rust: generate bindings via cbindgen\n\n .github/workflows/main.yml |  3 +--\n .gitignore                 |  1 +\n .gitlab-ci.yml             | 22 ++++++++++++++--------\n Makefile                   | 14 +++++++++++---\n cbindgen.toml              | 13 +++++++++++++\n ci/install-dependencies.sh | 16 +++++++++++-----\n ci/lib.sh                  |  2 +-\n meson.build                | 25 ++++++++++++++++++++-----\n shared.mak                 |  1 +\n src/meson.build            |  2 +-\n varint.c                   |  9 +++++++++\n 11 files changed, 83 insertions(+), 25 deletions(-)\n\nRange-diff versus v1:\n\n-:  ---------- > 1:  81e7677f3a gitlab-ci: reorder Linux job matrix to match GitHub's order\n-:  ---------- > 2:  c367154007 gitlab-ci: backfill missing Linux jobs\n1:  740702529c ! 3:  a1d7260326 ci: use Debian instead of deprecated i386/ubuntu\n    @@ .gitlab-ci.yml: test:linux:\n            - jobname: linux32\n     -        image: i386/ubuntu:20.04\n     +        image: i386/debian:latest\n    -       - jobname: linux-meson\n    -         image: ubuntu:rolling\n    -         CC: gcc\n    +       # A RHEL 8 compatible distro.  Supported until 2029-05-31.\n    +       - jobname: almalinux-8\n    +         image: almalinux:8\n     \n      ## ci/install-dependencies.sh ##\n     @@ ci/install-dependencies.sh: fedora-*|almalinux-*)\n    @@ ci/lib.sh: then\n      \t\tCI_OS_NAME=osx\n      \t\tJOBS=$(nproc)\n      \t\t;;\n    --\t*,alpine:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*)\n    -+\t*,alpine:*|*,fedora:*|*,ubuntu:*|*,i386/debian:*)\n    +-\t*,almalinux:*|*,alpine:*|*,debian:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*)\n    ++\t*,almalinux:*|*,alpine:*|*,debian:*|*,fedora:*|*,ubuntu:*|*,i386/debian:*)\n      \t\tCI_OS_NAME=linux\n      \t\tJOBS=$(nproc)\n      \t\t;;\n2:  ff696cfb2e = 4:  490c8a4d45 meson: rename Rust library target\n3:  67a9f353df ! 5:  8b7a2469b2 rust: generate bindings via cbindgen\n    @@ cbindgen.toml (new)\n     @@\n     +language = \"C\"\n     +\n    ++# Write a warning into the generated file.\n    ++autogen_warning = \"/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */\"\n    ++\n     +# Don't include standard C headers. These are managed by \"git-compat-util.h\".\n     +no_includes = true\n     +\n     +# Use plain structs instead of using typedefs.\n     +style = \"tag\"\n    ++\n    ++# Match our coding style more closely.\n    ++tab_width = 8\n     \n      ## ci/install-dependencies.sh ##\n    -@@ ci/install-dependencies.sh: fedora-*|almalinux-*)\n    +@@ ci/install-dependencies.sh: alpine-*)\n    + \t\tbash cvs gnupg perl-cgi perl-dbd-sqlite perl-io-tty >/dev/null\n    + \t;;\n    + fedora-*|almalinux-*)\n    ++\tRUST_DEPS=\"cargo cbindgen\"\n    + \tcase \"$jobname\" in\n    ++\talmalinux-8)\n    ++\t\t# AlmaLinux 8 does not have cbindgen, it was only added in version 9.\n    ++\t\tRUST_DEPS=;;\n    + \t*-meson)\n      \t\tMESON_DEPS=\"meson ninja\";;\n      \tesac\n    ++\n      \tdnf -yq update >/dev/null &&\n     -\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo >/dev/null\n    -+\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo cbindgen >/dev/null\n    ++\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext \\\n    ++\t\tzlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS $RUST_DEPS >/dev/null\n      \t;;\n      ubuntu-*|i386/debian-*|debian-*)\n      \t# Required so that apt doesn't wait for user input on certain packages.\n\n---\nbase-commit: 8654b230d9afe1326340989dd7082997c672472e\nchange-id: 20251009-b4-pks-rust-cbindgen-d80779ed2269\n\n"},{"id":"529578","messageId":"20251024-b4-pks-rust-cbindgen-v2-1-4b4bd4f18490@pks.im","threadId":"64372","inReplyTo":"20251024-b4-pks-rust-cbindgen-v2-0-4b4bd4f18490@pks.im","subject":"[PATCH v2 1/5] gitlab-ci: reorder Linux job matrix to match GitHub's order","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-24T09:51:33Z","receivedAt":"2025-10-24T09:51:53Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"We have mostly the exact same CI configuration as GitHub has for our\nLinux jobs. It's harder than necessary though to compare them with one\nanother as the ordering is different between both.\n\nReorder the job matrix in GitLab CI to match GitHub's order.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .gitlab-ci.yml | 14 +++++++-------\n 1 file changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\nindex b419a84e2c..1dbf236b2c 100644\n--- a/.gitlab-ci.yml\n+++ b/.gitlab-ci.yml\n@@ -42,15 +42,15 @@ test:linux:\n       - jobname: linux-reftable\n         image: ubuntu:rolling\n         CC: clang\n+      - jobname: linux-TEST-vars\n+        image: ubuntu:20.04\n+        CC: gcc\n+        CC_PACKAGE: gcc-8\n       - jobname: linux-breaking-changes\n         image: ubuntu:20.04\n         CC: gcc\n       - jobname: fedora-breaking-changes-meson\n         image: fedora:latest\n-      - jobname: linux-TEST-vars\n-        image: ubuntu:20.04\n-        CC: gcc\n-        CC_PACKAGE: gcc-8\n       - jobname: linux-leaks\n         image: ubuntu:rolling\n         CC: gcc\n@@ -60,13 +60,13 @@ test:linux:\n       - jobname: linux-asan-ubsan\n         image: ubuntu:rolling\n         CC: clang\n+      - jobname: linux-meson\n+        image: ubuntu:rolling\n+        CC: gcc\n       - jobname: linux-musl-meson\n         image: alpine:latest\n       - jobname: linux32\n         image: i386/ubuntu:20.04\n-      - jobname: linux-meson\n-        image: ubuntu:rolling\n-        CC: gcc\n   artifacts:\n     paths:\n       - t/failed-test-artifacts\n\n-- \n2.51.1.930.gacf6e81ea2.dirty\n\n"},{"id":"529579","messageId":"20251024-b4-pks-rust-cbindgen-v2-2-4b4bd4f18490@pks.im","threadId":"64372","inReplyTo":"20251024-b4-pks-rust-cbindgen-v2-0-4b4bd4f18490@pks.im","subject":"[PATCH v2 2/5] gitlab-ci: backfill missing Linux jobs","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-24T09:51:34Z","receivedAt":"2025-10-24T09:51:56Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"We're missing two Linux CI jobs in GitLab's CI that are present in\nGitHub's CI. Backfill them to ensure that GitLab has the same test\ncoverage.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .gitlab-ci.yml | 6 ++++++\n ci/lib.sh      | 2 +-\n 2 files changed, 7 insertions(+), 1 deletion(-)\n\ndiff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\nindex 1dbf236b2cd..f61ec2b6989 100644\n--- a/.gitlab-ci.yml\n+++ b/.gitlab-ci.yml\n@@ -67,6 +67,12 @@ test:linux:\n         image: alpine:latest\n       - jobname: linux32\n         image: i386/ubuntu:20.04\n+      # A RHEL 8 compatible distro.  Supported until 2029-05-31.\n+      - jobname: almalinux-8\n+        image: almalinux:8\n+      # Supported until 2026-08-31.\n+      - jobname: debian-11\n+        image: debian:11\n   artifacts:\n     paths:\n       - t/failed-test-artifacts\ndiff --git a/ci/lib.sh b/ci/lib.sh\nindex f561884d401..a5c4eb40bea 100755\n--- a/ci/lib.sh\n+++ b/ci/lib.sh\n@@ -250,7 +250,7 @@ then\n \t\tCI_OS_NAME=osx\n \t\tJOBS=$(nproc)\n \t\t;;\n-\t*,alpine:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*)\n+\t*,almalinux:*|*,alpine:*|*,debian:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*)\n \t\tCI_OS_NAME=linux\n \t\tJOBS=$(nproc)\n \t\t;;\n\n-- \n2.51.1.930.gacf6e81ea2.dirty\n\n"},{"id":"529580","messageId":"20251024-b4-pks-rust-cbindgen-v2-3-4b4bd4f18490@pks.im","threadId":"64372","inReplyTo":"20251024-b4-pks-rust-cbindgen-v2-0-4b4bd4f18490@pks.im","subject":"[PATCH v2 3/5] ci: use Debian instead of deprecated i386/ubuntu","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-24T09:51:35Z","receivedAt":"2025-10-24T09:51:59Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Ubuntu has ended support for 32 bit platforms and is not maintaining any\nrelease anymore that has 32 bit support. But we still use i386/ubuntu in\nour CI pipeline to test for compatibility with 32 bit systems, even\nthough that specific image does not receive updates anymore.\n\nBesides being end-of-life, this image also doesn't have all packages\navailable to it anymore. This creates problems with a subsequent patch,\nwhere we're about to pull in cbindgen for generating Rust to C bindings.\n\nDrop the Ubuntu image and use Debian instead, which continues to\nmaintain its 32 bit port.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .github/workflows/main.yml | 3 +--\n .gitlab-ci.yml             | 2 +-\n ci/install-dependencies.sh | 6 +++---\n ci/lib.sh                  | 2 +-\n 4 files changed, 6 insertions(+), 7 deletions(-)\n\ndiff --git a/.github/workflows/main.yml b/.github/workflows/main.yml\nindex cc54824c388..0b16970cd7e 100644\n--- a/.github/workflows/main.yml\n+++ b/.github/workflows/main.yml\n@@ -395,9 +395,8 @@ jobs:\n           cc: gcc\n         - jobname: linux-musl-meson\n           image: alpine:latest\n-        # Supported until 2025-04-02.\n         - jobname: linux32\n-          image: i386/ubuntu:focal\n+          image: i386/debian:latest\n         # A RHEL 8 compatible distro.  Supported until 2029-05-31.\n         - jobname: almalinux-8\n           image: almalinux:8\ndiff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\nindex f61ec2b6989..31d5e5a3e0d 100644\n--- a/.gitlab-ci.yml\n+++ b/.gitlab-ci.yml\n@@ -66,7 +66,7 @@ test:linux:\n       - jobname: linux-musl-meson\n         image: alpine:latest\n       - jobname: linux32\n-        image: i386/ubuntu:20.04\n+        image: i386/debian:latest\n       # A RHEL 8 compatible distro.  Supported until 2029-05-31.\n       - jobname: almalinux-8\n         image: almalinux:8\ndiff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\nindex 50628ee2dd6..b7b3cf35edf 100755\n--- a/ci/install-dependencies.sh\n+++ b/ci/install-dependencies.sh\n@@ -39,7 +39,7 @@ fedora-*|almalinux-*)\n \tdnf -yq update >/dev/null &&\n \tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo >/dev/null\n \t;;\n-ubuntu-*|i386/ubuntu-*|debian-*)\n+ubuntu-*|i386/debian-*|debian-*)\n \t# Required so that apt doesn't wait for user input on certain packages.\n \texport DEBIAN_FRONTEND=noninteractive\n \n@@ -48,9 +48,9 @@ ubuntu-*|i386/ubuntu-*|debian-*)\n \t\tSVN='libsvn-perl subversion'\n \t\tLANGUAGES='language-pack-is'\n \t\t;;\n-\ti386/ubuntu-*)\n+\ti386/debian-*)\n \t\tSVN=\n-\t\tLANGUAGES='language-pack-is'\n+\t\tLANGUAGES='locales-all'\n \t\t;;\n \t*)\n \t\tSVN='libsvn-perl subversion'\ndiff --git a/ci/lib.sh b/ci/lib.sh\nindex a5c4eb40bea..fdfde612339 100755\n--- a/ci/lib.sh\n+++ b/ci/lib.sh\n@@ -250,7 +250,7 @@ then\n \t\tCI_OS_NAME=osx\n \t\tJOBS=$(nproc)\n \t\t;;\n-\t*,almalinux:*|*,alpine:*|*,debian:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*)\n+\t*,almalinux:*|*,alpine:*|*,debian:*|*,fedora:*|*,ubuntu:*|*,i386/debian:*)\n \t\tCI_OS_NAME=linux\n \t\tJOBS=$(nproc)\n \t\t;;\n\n-- \n2.51.1.930.gacf6e81ea2.dirty\n\n"},{"id":"529581","messageId":"20251024-b4-pks-rust-cbindgen-v2-4-4b4bd4f18490@pks.im","threadId":"64372","inReplyTo":"20251024-b4-pks-rust-cbindgen-v2-0-4b4bd4f18490@pks.im","subject":"[PATCH v2 4/5] meson: rename Rust library target","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-24T09:51:36Z","receivedAt":"2025-10-24T09:52:02Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Rename the Rust library target from `git_rs` to `rust`. The latter is\nway easier to remember if one wants to compile only that target via\n`meson compile rust`. Furthermore, this name matches the test target\nthat we have for Rust that can be invoked via `meson test rust`.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n src/meson.build | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/src/meson.build b/src/meson.build\nindex 25b9ad5a14..1c73549696 100644\n--- a/src/meson.build\n+++ b/src/meson.build\n@@ -17,7 +17,7 @@ if get_option('buildtype') == 'release'\n   cargo_command += '--release'\n endif\n \n-libgit_rs = custom_target('git_rs',\n+libgit_rs = custom_target('rust',\n   input: libgit_rs_sources + [\n     meson.project_source_root() / 'Cargo.toml',\n   ],\n\n-- \n2.51.1.930.gacf6e81ea2.dirty\n\n"},{"id":"529582","messageId":"20251024-b4-pks-rust-cbindgen-v2-5-4b4bd4f18490@pks.im","threadId":"64372","inReplyTo":"20251024-b4-pks-rust-cbindgen-v2-0-4b4bd4f18490@pks.im","subject":"[PATCH v2 5/5] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-24T09:51:37Z","receivedAt":"2025-10-24T09:52:05Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"When compiling Git with Rust enabled we replace our C implementation of\nthe varint encoding with a Rust implementation. A prerequisite for doing\nso is of course that the interfaces for both implementations are exactly\nthe same. If they aren't, then we risk subtle runtime errors.\n\nWe don't really have a way to detect such interface mismatches though:\nthe code will happily compile if we change either of the implementations\nwithout adjusting the other implementation in the same spirit. The risk\nof divergence is low right now as we only replace a single subsystem.\nBut it is expected that we'll grow more reimplementations over time, so\nit is bound to increase.\n\nA related issue is that we don't have an easy way to implement features\nexclusively in Rust and make them available to our C library. Again, we\ndon't have such features yet, but there are work-in-progress patch\nseries that will eventually add them.\n\nBoth of these issues can be addressed by generating C bindings via the\ncbindgen(1) tool: given a Rust crate, it extracts all functions marked\nwith `extern \"C\"` and creates a C declaration for them. These are then\nwritten into a header file that we can include.\n\nSet up this infrastructure in both our Makefile and in Meson. To\ndemonstrate its use, the generated \"c-bindings.h\" header is included in\n\"varint.c\". If we now adapt \"varint.rs\" to have a different function\nsignature than the C code we'll now get a compiler error:\n\n    In file included from ../varint.c:10:\n    ./c-bindings.h:10:10: error: conflicting types for 'decode_varint'\n       10 | uint32_t decode_varint(const uint8_t **bufp);\n          |          ^\n    ../varint.h:5:10: note: previous declaration is here\n        5 | uint64_t decode_varint(const unsigned char **);\n\nAn initial version instead included the bindings in \"varint.h\". But that\nwould cause us to recompile all dependents of \"varint.h\" every time the\nsignatures of exported Rust functions change. So instead, we now include\nit in \"varint.c\" and compile that file unconditionally again.\n\nAdapt our CI to install cbindgen(1) accordingly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .gitignore                 |  1 +\n Makefile                   | 14 +++++++++++---\n cbindgen.toml              | 13 +++++++++++++\n ci/install-dependencies.sh | 10 ++++++++--\n meson.build                | 25 ++++++++++++++++++++-----\n shared.mak                 |  1 +\n varint.c                   |  9 +++++++++\n 7 files changed, 63 insertions(+), 10 deletions(-)\n\ndiff --git a/.gitignore b/.gitignore\nindex 78a45cb5be..20558c9dc8 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -197,6 +197,7 @@\n /gitweb/gitweb.cgi\n /gitweb/static/gitweb.js\n /gitweb/static/gitweb.min.*\n+/c-bindings.h\n /config-list.h\n /command-list.h\n /hook-list.h\ndiff --git a/Makefile b/Makefile\nindex 0bf5f17a90..1213a0fc96 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1326,9 +1326,7 @@ LIB_OBJS += urlmatch.o\n LIB_OBJS += usage.o\n LIB_OBJS += userdiff.o\n LIB_OBJS += utf8.o\n-ifndef WITH_RUST\n LIB_OBJS += varint.o\n-endif\n LIB_OBJS += version.o\n LIB_OBJS += versioncmp.o\n LIB_OBJS += walker.o\n@@ -1562,6 +1560,14 @@ ALL_LDFLAGS = $(LDFLAGS) $(LDFLAGS_APPEND)\n ifdef WITH_RUST\n BASIC_CFLAGS += -DWITH_RUST\n GITLIBS += $(RUST_LIB)\n+\n+C_BINDINGS = c-bindings.h\n+\n+GENERATED_H += $(C_BINDINGS)\n+\n+$(C_BINDINGS): cbindgen.toml $(RUST_SOURCES)\n+\t$(QUIET_CBINDGEN)cbindgen --output $@\n+\n ifeq ($(uname_S),Windows)\n EXTLIBS += -luserenv\n endif\n@@ -2619,6 +2625,8 @@ PAGER_ENV_CQ_SQ = $(subst ','\\'',$(PAGER_ENV_CQ))\n pager.sp pager.s pager.o: EXTRA_CPPFLAGS = \\\n \t-DPAGER_ENV='$(PAGER_ENV_CQ_SQ)'\n \n+varint.sp varint.s varint.o: $(C_BINDINGS)\n+\n version-def.h: version-def.h.in GIT-VERSION-GEN GIT-VERSION-FILE GIT-USER-AGENT\n \t$(QUIET_GEN)$(call version_gen,\"$(shell pwd)\",$<,$@)\n \n@@ -3806,7 +3814,7 @@ clean: profile-clean coverage-clean cocciclean\n \t$(RM) $(FUZZ_PROGRAMS)\n \t$(RM) $(SP_OBJ)\n \t$(RM) $(HCC)\n-\t$(RM) -r Cargo.lock target/\n+\t$(RM) -r Cargo.lock target/ $(C_BINDINGS)\n \t$(RM) version-def.h\n \t$(RM) -r $(dep_dirs) $(compdb_dir) compile_commands.json\n \t$(RM) $(test_bindir_programs)\ndiff --git a/cbindgen.toml b/cbindgen.toml\nnew file mode 100644\nindex 0000000000..7f8cdfa4b2\n--- /dev/null\n+++ b/cbindgen.toml\n@@ -0,0 +1,13 @@\n+language = \"C\"\n+\n+# Write a warning into the generated file.\n+autogen_warning = \"/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */\"\n+\n+# Don't include standard C headers. These are managed by \"git-compat-util.h\".\n+no_includes = true\n+\n+# Use plain structs instead of using typedefs.\n+style = \"tag\"\n+\n+# Match our coding style more closely.\n+tab_width = 8\ndiff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\nindex b7b3cf35ed..d42c705391 100755\n--- a/ci/install-dependencies.sh\n+++ b/ci/install-dependencies.sh\n@@ -32,12 +32,18 @@ alpine-*)\n \t\tbash cvs gnupg perl-cgi perl-dbd-sqlite perl-io-tty >/dev/null\n \t;;\n fedora-*|almalinux-*)\n+\tRUST_DEPS=\"cargo cbindgen\"\n \tcase \"$jobname\" in\n+\talmalinux-8)\n+\t\t# AlmaLinux 8 does not have cbindgen, it was only added in version 9.\n+\t\tRUST_DEPS=;;\n \t*-meson)\n \t\tMESON_DEPS=\"meson ninja\";;\n \tesac\n+\n \tdnf -yq update >/dev/null &&\n-\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo >/dev/null\n+\tdnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext \\\n+\t\tzlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS $RUST_DEPS >/dev/null\n \t;;\n ubuntu-*|i386/debian-*|debian-*)\n \t# Required so that apt doesn't wait for user input on certain packages.\n@@ -64,7 +70,7 @@ ubuntu-*|i386/debian-*|debian-*)\n \t\tmake libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \\\n \t\ttcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \\\n \t\tlibemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \\\n-\t\tlibsecret-1-dev libpcre2-dev meson ninja-build pkg-config cargo \\\n+\t\tlibsecret-1-dev libpcre2-dev meson ninja-build pkg-config cargo cbindgen \\\n \t\t${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE\n \n \t# Starting with Ubuntu 25.10, sudo can now be provided via either\ndiff --git a/meson.build b/meson.build\nindex 308798e861..b4acc417ad 100644\n--- a/meson.build\n+++ b/meson.build\n@@ -523,6 +523,7 @@ libgit_sources = [\n   'usage.c',\n   'userdiff.c',\n   'utf8.c',\n+  'varint.c',\n   'version.c',\n   'versioncmp.c',\n   'walker.c',\n@@ -1704,7 +1705,9 @@ version_def_h = custom_target(\n libgit_sources += version_def_h\n \n cargo = find_program('cargo', dirs: program_path, native: true, required: get_option('rust'))\n-rust_option = get_option('rust').disable_auto_if(not cargo.found())\n+cbindgen = find_program('cbindgen', dirs: program_path, native: true, required: get_option('rust'))\n+\n+rust_option = get_option('rust').disable_auto_if(not cargo.found() or not cbindgen.found())\n if rust_option.allowed()\n   subdir('src')\n   libgit_c_args += '-DWITH_RUST'\n@@ -1712,10 +1715,22 @@ if rust_option.allowed()\n   if host_machine.system() == 'windows'\n     libgit_dependencies += compiler.find_library('userenv')\n   endif\n-else\n-  libgit_sources += [\n-    'varint.c',\n-  ]\n+\n+  cbindgen_input = [ 'cbindgen.toml' ]\n+  foreach source : libgit_rs_sources\n+    cbindgen_input += 'src' / source\n+  endforeach\n+\n+  libgit_sources += custom_target('c-bindings.h',\n+    input: cbindgen_input,\n+    output: 'c-bindings.h',\n+    command: [\n+      cbindgen,\n+      '--output',\n+      '@OUTPUT@',\n+      meson.current_source_dir(),\n+    ],\n+  )\n endif\n \n libgit = declare_dependency(\ndiff --git a/shared.mak b/shared.mak\nindex 0e7492076e..598e58e069 100644\n--- a/shared.mak\n+++ b/shared.mak\n@@ -57,6 +57,7 @@ ifndef V\n \n ## Used in \"Makefile\"\n \tQUIET_CARGO    = @echo '   ' CARGO $@;\n+\tQUIET_CBINDGEN = @echo '   ' CBINDGEN $@;\n \tQUIET_CC       = @echo '   ' CC $@;\n \tQUIET_AR       = @echo '   ' AR $@;\n \tQUIET_LINK     = @echo '   ' LINK $@;\ndiff --git a/varint.c b/varint.c\nindex 03cd54416b..1ed738a756 100644\n--- a/varint.c\n+++ b/varint.c\n@@ -1,6 +1,14 @@\n #include \"git-compat-util.h\"\n #include \"varint.h\"\n \n+/*\n+ * When building with Rust we don't compile the C code, but we only verify\n+ * whether the function signatures of our C bindings match the ones we have\n+ * declared in \"varint.h\".\n+ */\n+#ifdef WITH_RUST\n+# include \"c-bindings.h\"\n+#else\n uint64_t decode_varint(const unsigned char **bufp)\n {\n \tconst unsigned char *buf = *bufp;\n@@ -28,3 +36,4 @@ uint8_t encode_varint(uint64_t value, unsigned char *buf)\n \t\tmemcpy(buf, varint + pos, sizeof(varint) - pos);\n \treturn sizeof(varint) - pos;\n }\n+#endif\n\n-- \n2.51.1.930.gacf6e81ea2.dirty\n\n"},{"id":"529605","messageId":"87v7k4pffg.fsf@iotcl.com","threadId":"64372","inReplyTo":"20251024-b4-pks-rust-cbindgen-v2-5-4b4bd4f18490@pks.im","subject":"Re: [PATCH v2 5/5] rust: generate bindings via cbindgen","fromName":"Toon Claes","fromEmail":"toon@iotcl.com","sentAt":"2025-10-24T14:01:07Z","receivedAt":"2025-10-24T14:01:22Z","isPatch":true,"sender":{"key":"toon@iotcl.com","avatar":"https://avatars.githubusercontent.com/u/121621?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> [snip]\n>\n> diff --git a/meson.build b/meson.build\n> index 308798e861..b4acc417ad 100644\n> --- a/meson.build\n> +++ b/meson.build\n> @@ -523,6 +523,7 @@ libgit_sources = [\n>    'usage.c',\n>    'userdiff.c',\n>    'utf8.c',\n> +  'varint.c',\n>    'version.c',\n>    'versioncmp.c',\n>    'walker.c',\n> @@ -1704,7 +1705,9 @@ version_def_h = custom_target(\n>  libgit_sources += version_def_h\n>  \n>  cargo = find_program('cargo', dirs: program_path, native: true, required: get_option('rust'))\n> -rust_option = get_option('rust').disable_auto_if(not cargo.found())\n> +cbindgen = find_program('cbindgen', dirs: program_path, native: true, required: get_option('rust'))\n> +\n> +rust_option = get_option('rust').disable_auto_if(not cargo.found() or not cbindgen.found())\n\nThis means to compile with Rust we not only need cargo, but also\ncbindgen. As we ideally want to have a broad platform support, would\nadding another dependency (i.e. `cbindgen`) narrow the platforms we'd\neventually support? Or can we consider platforms supporting Rust also\nhave cbindgen?\n\n> [snip]\n>\n> diff --git a/varint.c b/varint.c\n> index 03cd54416b..1ed738a756 100644\n> --- a/varint.c\n> +++ b/varint.c\n> @@ -1,6 +1,14 @@\n>  #include \"git-compat-util.h\"\n>  #include \"varint.h\"\n>  \n> +/*\n> + * When building with Rust we don't compile the C code, but we only verify\n> + * whether the function signatures of our C bindings match the ones we have\n> + * declared in \"varint.h\".\n> + */\n> +#ifdef WITH_RUST\n> +# include \"c-bindings.h\"\n\nSo when we rewrite more subsystems into Rust, this will include\ndefinitions from all those subsystems into this compilation unit.\nIf one subsystem with a Rust alternative implementation includes the\nheader from another subsystem with a Rust-alternative implementation,\nthe function signatures are checked twice, and errors are surfaced\ntwice. I guess this is a tradeoff we can accept for now, because:\n\n* We only have one subsystem in Rust now.\n* The approach in this patch simplifies the build setup.\n\nWe might revisit that at some point, but I can agree this is the most\nsensical approach for now.\n\n-- \nCheers,\nToon\n"},{"id":"529756","messageId":"CAH=ZcbBWuS6QVQT4LsxSP-X4GupZwr+NwzXNH2+qZGoufUWDrQ@mail.gmail.com","threadId":"64372","inReplyTo":"aPsepOtUf92fqDL-@pks.im","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Ezekiel Newren","fromEmail":"ezekielnewren@gmail.com","sentAt":"2025-10-27T20:35:59Z","receivedAt":"2025-10-27T20:36:12Z","isPatch":true,"sender":{"key":"ezekielnewren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/18313324?v=4"},"body":"On Fri, Oct 24, 2025 at 12:37 AM Patrick Steinhardt <ps@pks.im> wrote:\n> > cbindgen is a Rust crate and it should be specified in the Cargo.toml\n> > under [build-dependencies] block.\n>\n> What is the benefit for us? The generated code is not a dependency of\n> the Rust code, and neither do we use it via \"build.rs\". And if we use\n> cbindgen via \"Cargo.toml\" we'd be forced to build it first, which slows\n> down our CI jobs.\n>\n> Please let me know in case I miss any reasons to have it in our build\n> dependencies instead.\n\nYou're targeting a very old version of Rust (1.49). I'm not even sure\nthat cbindgen will work with a version that old, but if it does then\nwe should use it in build.rs to make sure we're not using any features\nof cbindgen that aren't available until later versions. If we use\ncbindgen that is packaged with the platform then we can't precisely\ncontrol which version of cbindgen is being used. This is a matter of\nreproducibility. There may be platforms that can compile Rust, but\ncan't generate C header files via cbindgen because cbindgen hard codes\nthat a certain minimum Rust version is required in its own Cargo.toml\nfile.\n\n> > Also I think that we should convert from using a Cargo crate to using\n> > a Cargo workspace, so that we can generate multiple header files (1\n> > per crate) rather than a monolithic generated header. This is because\n> > cbindgen operates at the granularity of a crate.\n>\n> I'm basically still punting this into the future. There is no good\n> reason yet to have workspaces, so I'd rather introduce them once we have\n> a better way to sell them and demonstrate their immediate benefits.\n\nI'd like to avoid creating a gordian knot in Rust like how the\nexisting C code is a gordian knot. Creating multiple crates will\nencourage better api design so that our code can be more modular and\neasier to maintain. The reason why I don't want to put this off is\nbecause the more we add to Rust the harder it'll be to refactor the\ncode to use Cargo workspaces. Let's do it now while it's still really\neasy. As there is only 1 crate conceptually the code changes required\nto convert it to a workspace will be very minimal.\n"},{"id":"529759","messageId":"aP_gy-Rj8MI7zAWd@fruit.crustytoothpaste.net","threadId":"64372","inReplyTo":"CAH=ZcbBWuS6QVQT4LsxSP-X4GupZwr+NwzXNH2+qZGoufUWDrQ@mail.gmail.com","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2025-10-27T21:14:51Z","receivedAt":"2025-10-27T21:14:53Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2025-10-27 at 20:35:59, Ezekiel Newren wrote:\n> On Fri, Oct 24, 2025 at 12:37 AM Patrick Steinhardt <ps@pks.im> wrote:\n> > > cbindgen is a Rust crate and it should be specified in the Cargo.toml\n> > > under [build-dependencies] block.\n> >\n> > What is the benefit for us? The generated code is not a dependency of\n> > the Rust code, and neither do we use it via \"build.rs\". And if we use\n> > cbindgen via \"Cargo.toml\" we'd be forced to build it first, which slows\n> > down our CI jobs.\n> >\n> > Please let me know in case I miss any reasons to have it in our build\n> > dependencies instead.\n> \n> You're targeting a very old version of Rust (1.49). I'm not even sure\n> that cbindgen will work with a version that old, but if it does then\n> we should use it in build.rs to make sure we're not using any features\n> of cbindgen that aren't available until later versions. If we use\n> cbindgen that is packaged with the platform then we can't precisely\n> control which version of cbindgen is being used. This is a matter of\n> reproducibility. There may be platforms that can compile Rust, but\n> can't generate C header files via cbindgen because cbindgen hard codes\n> that a certain minimum Rust version is required in its own Cargo.toml\n> file.\n\nYes, I agree with this.  Not all systems have cbindgen and it's not\nguaranteed that the system's cbindgen will work with the version of Rust\nthat you want to target or that's being used to compile.\n\nFor instance, I'm using Debian unstable with a system cbindgen 0.27.0.\nThis requires Rust 1.70 or newer. If I use rustup to test my code on\nRust 1.49, then the code won't compile for me.\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"529761","messageId":"xmqq8qgvfyq0.fsf@gitster.g","threadId":"64372","inReplyTo":"aP_gy-Rj8MI7zAWd@fruit.crustytoothpaste.net","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-10-28T04:15:51Z","receivedAt":"2025-10-28T04:15:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"brian m. carlson\" <sandals@crustytoothpaste.net> writes:\n\n> On 2025-10-27 at 20:35:59, Ezekiel Newren wrote:\n>> On Fri, Oct 24, 2025 at 12:37 AM Patrick Steinhardt <ps@pks.im> wrote:\n>> > > cbindgen is a Rust crate and it should be specified in the Cargo.toml\n>> > > under [build-dependencies] block.\n>> >\n>> > What is the benefit for us? The generated code is not a dependency of\n>> > the Rust code, and neither do we use it via \"build.rs\". And if we use\n>> > cbindgen via \"Cargo.toml\" we'd be forced to build it first, which slows\n>> > down our CI jobs.\n>> >\n>> > Please let me know in case I miss any reasons to have it in our build\n>> > dependencies instead.\n>> \n>> You're targeting a very old version of Rust (1.49). I'm not even sure\n>> that cbindgen will work with a version that old, but if it does then\n>> we should use it in build.rs to make sure we're not using any features\n>> of cbindgen that aren't available until later versions.\n> ...\n> For instance, I'm using Debian unstable with a system cbindgen 0.27.0.\n> This requires Rust 1.70 or newer. If I use rustup to test my code on\n> Rust 1.49, then the code won't compile for me.\n\nHave we even agreed on which Rust version we would aim for?  With\nBreakingChanges.adoc We have agreed to make some version of Rust\nmandatory by the time we hit Git 3.0 but IIRC, there isn't anything\nwritten down except for an old message from you\n\n  https://lore.kernel.org/git/ZZ9K1CVBKdij4tG0@tapette.crustytoothpaste.net/\n\nthat expressed your preference to support the version of Rust in the\nlatest Debian stable plus the version in Debian's oldstable until\nthe latest stable has been out for a year, which nobody responded\nto, so we cannot quite say that is the consensus of the community,\nyet.\n\nGiven that the stable/trixie was released on August 9th, 2025, we\nstill need to go by oldstable/bookworm, which has Rust 1.63, if\npeople agree that your rule to decide the floor version is sensible\n(which I would say is OK).\n\n\n\n"},{"id":"529814","messageId":"CAH=ZcbDzkACjFsT+z9WJ8MXwivWQczMRhEnV2MOpJ8r3zDc-3Q@mail.gmail.com","threadId":"64372","inReplyTo":"xmqq8qgvfyq0.fsf@gitster.g","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Ezekiel Newren","fromEmail":"ezekielnewren@gmail.com","sentAt":"2025-10-28T19:11:53Z","receivedAt":"2025-10-28T19:12:07Z","isPatch":true,"sender":{"key":"ezekielnewren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/18313324?v=4"},"body":"On Mon, Oct 27, 2025 at 10:15 PM Junio C Hamano <gitster@pobox.com> wrote:\n> Given that the stable/trixie was released on August 9th, 2025, we\n> still need to go by oldstable/bookworm, which has Rust 1.63, if\n> people agree that your rule to decide the floor version is sensible\n> (which I would say is OK).\n\nI think that 1.63 should be the minimum that Git supports. I think\n1.49 is way too old. It was a bit of a struggle to get cbindgen to\nwork with 1.63, and I don't know if it will work at all with 1.49.\n"},{"id":"529815","messageId":"CAH=ZcbAEBbDkAqp9cc908SgkM5BQOD_=52e6Y=EVd=cwyPU0Aw@mail.gmail.com","threadId":"64372","inReplyTo":"20251024-b4-pks-rust-cbindgen-v2-1-4b4bd4f18490@pks.im","subject":"Re: [PATCH v2 1/5] gitlab-ci: reorder Linux job matrix to match GitHub's order","fromName":"Ezekiel Newren","fromEmail":"ezekielnewren@gmail.com","sentAt":"2025-10-28T19:14:59Z","receivedAt":"2025-10-28T19:15:13Z","isPatch":true,"sender":{"key":"ezekielnewren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/18313324?v=4"},"body":"On Fri, Oct 24, 2025 at 3:51 AM Patrick Steinhardt <ps@pks.im> wrote:\n>\n> We have mostly the exact same CI configuration as GitHub has for our\n> Linux jobs. It's harder than necessary though to compare them with one\n> another as the ordering is different between both.\n>\n> Reorder the job matrix in GitLab CI to match GitHub's order.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  .gitlab-ci.yml | 14 +++++++-------\n>  1 file changed, 7 insertions(+), 7 deletions(-)\n>\n> diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\n> index b419a84e2c..1dbf236b2c 100644\n> --- a/.gitlab-ci.yml\n> +++ b/.gitlab-ci.yml\n> @@ -42,15 +42,15 @@ test:linux:\n>        - jobname: linux-reftable\n>          image: ubuntu:rolling\n>          CC: clang\n> +      - jobname: linux-TEST-vars\n> +        image: ubuntu:20.04\n> +        CC: gcc\n> +        CC_PACKAGE: gcc-8\n>        - jobname: linux-breaking-changes\n>          image: ubuntu:20.04\n>          CC: gcc\n>        - jobname: fedora-breaking-changes-meson\n>          image: fedora:latest\n> -      - jobname: linux-TEST-vars\n> -        image: ubuntu:20.04\n> -        CC: gcc\n> -        CC_PACKAGE: gcc-8\n>        - jobname: linux-leaks\n>          image: ubuntu:rolling\n>          CC: gcc\n> @@ -60,13 +60,13 @@ test:linux:\n>        - jobname: linux-asan-ubsan\n>          image: ubuntu:rolling\n>          CC: clang\n> +      - jobname: linux-meson\n> +        image: ubuntu:rolling\n> +        CC: gcc\n>        - jobname: linux-musl-meson\n>          image: alpine:latest\n>        - jobname: linux32\n>          image: i386/ubuntu:20.04\n> -      - jobname: linux-meson\n> -        image: ubuntu:rolling\n> -        CC: gcc\n>    artifacts:\n>      paths:\n>        - t/failed-test-artifacts\n>\n> --\n> 2.51.1.930.gacf6e81ea2.dirty\n>\n\nLooks good.\n"},{"id":"529816","messageId":"CAH=ZcbAvg0rQugxq5PF8s+-WCEQeD98YcT2sqXKcE_dx1j7OMA@mail.gmail.com","threadId":"64372","inReplyTo":"20251024-b4-pks-rust-cbindgen-v2-2-4b4bd4f18490@pks.im","subject":"Re: [PATCH v2 2/5] gitlab-ci: backfill missing Linux jobs","fromName":"Ezekiel Newren","fromEmail":"ezekielnewren@gmail.com","sentAt":"2025-10-28T19:15:58Z","receivedAt":"2025-10-28T19:16:11Z","isPatch":true,"sender":{"key":"ezekielnewren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/18313324?v=4"},"body":"On Fri, Oct 24, 2025 at 3:51 AM Patrick Steinhardt <ps@pks.im> wrote:\n>\n> We're missing two Linux CI jobs in GitLab's CI that are present in\n> GitHub's CI. Backfill them to ensure that GitLab has the same test\n> coverage.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  .gitlab-ci.yml | 6 ++++++\n>  ci/lib.sh      | 2 +-\n>  2 files changed, 7 insertions(+), 1 deletion(-)\n>\n> diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\n> index 1dbf236b2cd..f61ec2b6989 100644\n> --- a/.gitlab-ci.yml\n> +++ b/.gitlab-ci.yml\n> @@ -67,6 +67,12 @@ test:linux:\n>          image: alpine:latest\n>        - jobname: linux32\n>          image: i386/ubuntu:20.04\n> +      # A RHEL 8 compatible distro.  Supported until 2029-05-31.\n> +      - jobname: almalinux-8\n> +        image: almalinux:8\n> +      # Supported until 2026-08-31.\n> +      - jobname: debian-11\n> +        image: debian:11\n>    artifacts:\n>      paths:\n>        - t/failed-test-artifacts\n> diff --git a/ci/lib.sh b/ci/lib.sh\n> index f561884d401..a5c4eb40bea 100755\n> --- a/ci/lib.sh\n> +++ b/ci/lib.sh\n> @@ -250,7 +250,7 @@ then\n>                 CI_OS_NAME=osx\n>                 JOBS=$(nproc)\n>                 ;;\n> -       *,alpine:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*)\n> +       *,almalinux:*|*,alpine:*|*,debian:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*)\n>                 CI_OS_NAME=linux\n>                 JOBS=$(nproc)\n>                 ;;\n>\n> --\n> 2.51.1.930.gacf6e81ea2.dirty\n>\n\nLooks good.\n"},{"id":"529817","messageId":"CAH=ZcbB3J2Jt5Najc8p3z1iaig_Q0S_t5hGWRN-4fNRVGggARQ@mail.gmail.com","threadId":"64372","inReplyTo":"20251024-b4-pks-rust-cbindgen-v2-3-4b4bd4f18490@pks.im","subject":"Re: [PATCH v2 3/5] ci: use Debian instead of deprecated i386/ubuntu","fromName":"Ezekiel Newren","fromEmail":"ezekielnewren@gmail.com","sentAt":"2025-10-28T19:17:53Z","receivedAt":"2025-10-28T19:18:06Z","isPatch":true,"sender":{"key":"ezekielnewren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/18313324?v=4"},"body":"On Fri, Oct 24, 2025 at 3:51 AM Patrick Steinhardt <ps@pks.im> wrote:\n>\n> Ubuntu has ended support for 32 bit platforms and is not maintaining any\n> release anymore that has 32 bit support. But we still use i386/ubuntu in\n> our CI pipeline to test for compatibility with 32 bit systems, even\n> though that specific image does not receive updates anymore.\n>\n> Besides being end-of-life, this image also doesn't have all packages\n> available to it anymore. This creates problems with a subsequent patch,\n> where we're about to pull in cbindgen for generating Rust to C bindings.\n>\n> Drop the Ubuntu image and use Debian instead, which continues to\n> maintain its 32 bit port.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  .github/workflows/main.yml | 3 +--\n>  .gitlab-ci.yml             | 2 +-\n>  ci/install-dependencies.sh | 6 +++---\n>  ci/lib.sh                  | 2 +-\n>  4 files changed, 6 insertions(+), 7 deletions(-)\n>\n> diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml\n> index cc54824c388..0b16970cd7e 100644\n> --- a/.github/workflows/main.yml\n> +++ b/.github/workflows/main.yml\n> @@ -395,9 +395,8 @@ jobs:\n>            cc: gcc\n>          - jobname: linux-musl-meson\n>            image: alpine:latest\n> -        # Supported until 2025-04-02.\n>          - jobname: linux32\n> -          image: i386/ubuntu:focal\n> +          image: i386/debian:latest\n>          # A RHEL 8 compatible distro.  Supported until 2029-05-31.\n>          - jobname: almalinux-8\n>            image: almalinux:8\n> diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\n> index f61ec2b6989..31d5e5a3e0d 100644\n> --- a/.gitlab-ci.yml\n> +++ b/.gitlab-ci.yml\n> @@ -66,7 +66,7 @@ test:linux:\n>        - jobname: linux-musl-meson\n>          image: alpine:latest\n>        - jobname: linux32\n> -        image: i386/ubuntu:20.04\n> +        image: i386/debian:latest\n>        # A RHEL 8 compatible distro.  Supported until 2029-05-31.\n>        - jobname: almalinux-8\n>          image: almalinux:8\n> diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\n> index 50628ee2dd6..b7b3cf35edf 100755\n> --- a/ci/install-dependencies.sh\n> +++ b/ci/install-dependencies.sh\n> @@ -39,7 +39,7 @@ fedora-*|almalinux-*)\n>         dnf -yq update >/dev/null &&\n>         dnf -yq install shadow-utils sudo make pkg-config gcc findutils diffutils perl python3 gawk gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel $MESON_DEPS cargo >/dev/null\n>         ;;\n> -ubuntu-*|i386/ubuntu-*|debian-*)\n> +ubuntu-*|i386/debian-*|debian-*)\n>         # Required so that apt doesn't wait for user input on certain packages.\n>         export DEBIAN_FRONTEND=noninteractive\n>\n> @@ -48,9 +48,9 @@ ubuntu-*|i386/ubuntu-*|debian-*)\n>                 SVN='libsvn-perl subversion'\n>                 LANGUAGES='language-pack-is'\n>                 ;;\n> -       i386/ubuntu-*)\n> +       i386/debian-*)\n>                 SVN=\n> -               LANGUAGES='language-pack-is'\n> +               LANGUAGES='locales-all'\n>                 ;;\n>         *)\n>                 SVN='libsvn-perl subversion'\n> diff --git a/ci/lib.sh b/ci/lib.sh\n> index a5c4eb40bea..fdfde612339 100755\n> --- a/ci/lib.sh\n> +++ b/ci/lib.sh\n> @@ -250,7 +250,7 @@ then\n>                 CI_OS_NAME=osx\n>                 JOBS=$(nproc)\n>                 ;;\n> -       *,almalinux:*|*,alpine:*|*,debian:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*)\n> +       *,almalinux:*|*,alpine:*|*,debian:*|*,fedora:*|*,ubuntu:*|*,i386/debian:*)\n>                 CI_OS_NAME=linux\n>                 JOBS=$(nproc)\n>                 ;;\n>\n> --\n> 2.51.1.930.gacf6e81ea2.dirty\n>\n\nMakes sense to me, but I wonder if we should test with other 32 bit\nlinux distros. This isn't a critique or a suggestion, I'm just\nwondering out loud.\n"},{"id":"529820","messageId":"CAH=ZcbAC_u88_cD33bRxAuAPhJh02zNOHAVnkhxthncDFdZOOA@mail.gmail.com","threadId":"64372","inReplyTo":"20251024-b4-pks-rust-cbindgen-v2-0-4b4bd4f18490@pks.im","subject":"Re: [PATCH v2 0/5] rust: generate bindings via cbindgen","fromName":"Ezekiel Newren","fromEmail":"ezekielnewren@gmail.com","sentAt":"2025-10-28T19:37:00Z","receivedAt":"2025-10-28T19:37:13Z","isPatch":true,"sender":{"key":"ezekielnewren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/18313324?v=4"},"body":"On Fri, Oct 24, 2025 at 3:51 AM Patrick Steinhardt <ps@pks.im> wrote:\n>\n> Hi,\n>\n> this small patch series introduces support for cbindgen(1). This tool is\n> used to generate C headers from `extern \"C\"` blocks so that Rust code\n> can easily be called from C code.\n>\n> For now, the only use case is to verify that our varint reimplementation\n> matches the C implementation. But later on this can and will be used to\n> call Rust-specific features from C, as well.\n>\n> The topic is built on top of c54a18ef67 (The twenty-second batch,\n> 2025-10-22) with ps/ci-rust at e509b5b8be (rust: support for Windows,\n> 2025-10-15) merged into it.\n>\n> Changes in v2:\n>   - Take some of the pieces from Ezekiel's \"cbindgen.toml\" file. I have\n>     not yet taken `usize_is_size_t`, as that option requires cbindgen\n>     v0.16.0, which is not available on Ubuntu 20.04.\n>   - Backfill missing jobs for GitLab CI.\n>   - Fix CI failures on Alma Linux 8 because cbindgen isn't available\n>     there.\n>   - Link to v1: https://lore.kernel.org/r/20251023-b4-pks-rust-cbindgen-v1-0-c19b61b03127@pks.im\n\nI really think that this patch series should include migrating to a\nCargo Workspace. That'll mean moving /Cargo.toml and /src into\ngitcore/ and creating a new top-level /Cargo.toml with the following\ncontent:\n[workspace]\nmembers = [\n    \"gitcore\",\n]\nresolver = \"2\"\n\nAlong with the other cascading refactor changes needed to make this\nwork. Let's do this now while it's still easy.\n\nIf we don't do this now then we'll be locked into a single crate\nproject forever because there'll be too much momentum later. Having\nthe ability to define multiple crates allows us to:\n* Easier to understand the big picture of Git as each logical\ncomponent will be its own crate\n* Make Git more modular\n* Design better api interfaces between logically separate code\n* define a header file per crate via cbindgen\n* avoid gordian knot problems from making Rust a monolithic component\n* easier to reduce dependency sprawl as each crate only defines what it needs\n* Improves compile times through incremental rebuilds. Cargo caches\nbuild artifacts per crate. When only one crate changes, others don’t\nneed to recompile. This becomes a major quality-of-life improvement as\nthe Rust footprint grows.\n"},{"id":"529932","messageId":"aQM04h0H_SplfsQo@pks.im","threadId":"64372","inReplyTo":"CAH=ZcbDzkACjFsT+z9WJ8MXwivWQczMRhEnV2MOpJ8r3zDc-3Q@mail.gmail.com","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-30T09:50:26Z","receivedAt":"2025-10-30T09:50:37Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Oct 28, 2025 at 01:11:53PM -0600, Ezekiel Newren wrote:\n> On Mon, Oct 27, 2025 at 10:15 PM Junio C Hamano <gitster@pobox.com> wrote:\n> > Given that the stable/trixie was released on August 9th, 2025, we\n> > still need to go by oldstable/bookworm, which has Rust 1.63, if\n> > people agree that your rule to decide the floor version is sensible\n> > (which I would say is OK).\n> \n> I think that 1.63 should be the minimum that Git supports. I think\n> 1.49 is way too old. It was a bit of a struggle to get cbindgen to\n> work with 1.63, and I don't know if it will work at all with 1.49.\n\nI think cbindgen 0.20 should support Rust 1.49, but I'm honestly not\nsure about this. They simply didn't specify a MSRV before 0.21, and in\n0.21 they bumped to require Rust 1.57.\n\nPatrick\n"},{"id":"529933","messageId":"aQM07BQrGJocPKea@pks.im","threadId":"64372","inReplyTo":"xmqq8qgvfyq0.fsf@gitster.g","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-30T09:50:36Z","receivedAt":"2025-10-30T09:50:43Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Oct 27, 2025 at 09:15:51PM -0700, Junio C Hamano wrote:\n> \"brian m. carlson\" <sandals@crustytoothpaste.net> writes:\n> \n> > On 2025-10-27 at 20:35:59, Ezekiel Newren wrote:\n> >> On Fri, Oct 24, 2025 at 12:37 AM Patrick Steinhardt <ps@pks.im> wrote:\n> >> > > cbindgen is a Rust crate and it should be specified in the Cargo.toml\n> >> > > under [build-dependencies] block.\n> >> >\n> >> > What is the benefit for us? The generated code is not a dependency of\n> >> > the Rust code, and neither do we use it via \"build.rs\". And if we use\n> >> > cbindgen via \"Cargo.toml\" we'd be forced to build it first, which slows\n> >> > down our CI jobs.\n> >> >\n> >> > Please let me know in case I miss any reasons to have it in our build\n> >> > dependencies instead.\n> >> \n> >> You're targeting a very old version of Rust (1.49). I'm not even sure\n> >> that cbindgen will work with a version that old, but if it does then\n> >> we should use it in build.rs to make sure we're not using any features\n> >> of cbindgen that aren't available until later versions.\n> > ...\n> > For instance, I'm using Debian unstable with a system cbindgen 0.27.0.\n> > This requires Rust 1.70 or newer. If I use rustup to test my code on\n> > Rust 1.49, then the code won't compile for me.\n> \n> Have we even agreed on which Rust version we would aim for?  With\n> BreakingChanges.adoc We have agreed to make some version of Rust\n> mandatory by the time we hit Git 3.0 but IIRC, there isn't anything\n> written down except for an old message from you\n> \n>   https://lore.kernel.org/git/ZZ9K1CVBKdij4tG0@tapette.crustytoothpaste.net/\n> \n> that expressed your preference to support the version of Rust in the\n> latest Debian stable plus the version in Debian's oldstable until\n> the latest stable has been out for a year, which nobody responded\n> to, so we cannot quite say that is the consensus of the community,\n> yet.\n\nFor now that Rust version is 1.49, and that's enforced by our CI. The\nreason for this specific version is that it's the target version for the\ngcc-rs folks, so it may help currently-unsupported platforms to get\nsupport earlier.\n\nBut I made clear in past patch series that if we have strong reasons to\nuse a more recent version of Rust, then we should update. I mostly\nwanted us to do this intentionally than picking any random Rust version\nand saying that \"this is it now\".\n\nPatrick\n"},{"id":"529934","messageId":"aQM08k9iLA1cKe45@pks.im","threadId":"64372","inReplyTo":"CAH=ZcbB3J2Jt5Najc8p3z1iaig_Q0S_t5hGWRN-4fNRVGggARQ@mail.gmail.com","subject":"Re: [PATCH v2 3/5] ci: use Debian instead of deprecated i386/ubuntu","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-30T09:50:42Z","receivedAt":"2025-10-30T09:50:47Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Oct 28, 2025 at 01:17:53PM -0600, Ezekiel Newren wrote:\n> On Fri, Oct 24, 2025 at 3:51 AM Patrick Steinhardt <ps@pks.im> wrote:\n> > diff --git a/ci/lib.sh b/ci/lib.sh\n> > index a5c4eb40bea..fdfde612339 100755\n> > --- a/ci/lib.sh\n> > +++ b/ci/lib.sh\n> > @@ -250,7 +250,7 @@ then\n> >                 CI_OS_NAME=osx\n> >                 JOBS=$(nproc)\n> >                 ;;\n> > -       *,almalinux:*|*,alpine:*|*,debian:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*)\n> > +       *,almalinux:*|*,alpine:*|*,debian:*|*,fedora:*|*,ubuntu:*|*,i386/debian:*)\n> >                 CI_OS_NAME=linux\n> >                 JOBS=$(nproc)\n> >                 ;;\n> >\n> > --\n> > 2.51.1.930.gacf6e81ea2.dirty\n> >\n> \n> Makes sense to me, but I wonder if we should test with other 32 bit\n> linux distros. This isn't a critique or a suggestion, I'm just\n> wondering out loud.\n\nPotentially, I guess. I basically picked Debian because it's close to\nUbuntu and because we already support it in our CI. So it required the\nleast amount of churn.\n\nWe could eventually add additional 32 bit distros. The question of\ncourse is whether that's really worth it. The importance of 32 bit is\noverall dwindling, so it may be good enough to only test on a single\ndistro.\n\nThat being said, I don't really have a strong opinion on this.\n\nPatrick\n"},{"id":"529935","messageId":"aQM0-IwB3e4t7YKE@pks.im","threadId":"64372","inReplyTo":"CAH=ZcbAC_u88_cD33bRxAuAPhJh02zNOHAVnkhxthncDFdZOOA@mail.gmail.com","subject":"Re: [PATCH v2 0/5] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-30T09:50:48Z","receivedAt":"2025-10-30T09:50:54Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Tue, Oct 28, 2025 at 01:37:00PM -0600, Ezekiel Newren wrote:\n> On Fri, Oct 24, 2025 at 3:51 AM Patrick Steinhardt <ps@pks.im> wrote:\n> >\n> > Hi,\n> >\n> > this small patch series introduces support for cbindgen(1). This tool is\n> > used to generate C headers from `extern \"C\"` blocks so that Rust code\n> > can easily be called from C code.\n> >\n> > For now, the only use case is to verify that our varint reimplementation\n> > matches the C implementation. But later on this can and will be used to\n> > call Rust-specific features from C, as well.\n> >\n> > The topic is built on top of c54a18ef67 (The twenty-second batch,\n> > 2025-10-22) with ps/ci-rust at e509b5b8be (rust: support for Windows,\n> > 2025-10-15) merged into it.\n> >\n> > Changes in v2:\n> >   - Take some of the pieces from Ezekiel's \"cbindgen.toml\" file. I have\n> >     not yet taken `usize_is_size_t`, as that option requires cbindgen\n> >     v0.16.0, which is not available on Ubuntu 20.04.\n> >   - Backfill missing jobs for GitLab CI.\n> >   - Fix CI failures on Alma Linux 8 because cbindgen isn't available\n> >     there.\n> >   - Link to v1: https://lore.kernel.org/r/20251023-b4-pks-rust-cbindgen-v1-0-c19b61b03127@pks.im\n> \n> I really think that this patch series should include migrating to a\n> Cargo Workspace. That'll mean moving /Cargo.toml and /src into\n> gitcore/ and creating a new top-level /Cargo.toml with the following\n> content:\n> [workspace]\n> members = [\n>     \"gitcore\",\n> ]\n> resolver = \"2\"\n> \n> Along with the other cascading refactor changes needed to make this\n> work. Let's do this now while it's still easy.\n\nI simply think that cbindgen and workspaces are quite unrelated to one\nanother for now. So an alternate suggestion: once this patch series here\nlands we could introduce workspaces in the subsequent patch series. I\nthink that's still early enough, and this patch series here shouldn't\ncause significant additional churn.\n\nIn any case, I'd prefer if you wrote that patch series to introduce\nworkspaces. I don't feel like I have enough experience with them to be\nable to argue properly why we want to have them.\n\nDoes that work for you?\n\nThanks!\n\nPatrick\n"},{"id":"529936","messageId":"aQM0_6uRZcQYfO8R@pks.im","threadId":"64372","inReplyTo":"aP_gy-Rj8MI7zAWd@fruit.crustytoothpaste.net","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-30T09:50:55Z","receivedAt":"2025-10-30T09:51:00Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Oct 27, 2025 at 09:14:51PM +0000, brian m. carlson wrote:\n> On 2025-10-27 at 20:35:59, Ezekiel Newren wrote:\n> > On Fri, Oct 24, 2025 at 12:37 AM Patrick Steinhardt <ps@pks.im> wrote:\n> > > > cbindgen is a Rust crate and it should be specified in the Cargo.toml\n> > > > under [build-dependencies] block.\n> > >\n> > > What is the benefit for us? The generated code is not a dependency of\n> > > the Rust code, and neither do we use it via \"build.rs\". And if we use\n> > > cbindgen via \"Cargo.toml\" we'd be forced to build it first, which slows\n> > > down our CI jobs.\n> > >\n> > > Please let me know in case I miss any reasons to have it in our build\n> > > dependencies instead.\n> > \n> > You're targeting a very old version of Rust (1.49). I'm not even sure\n> > that cbindgen will work with a version that old, but if it does then\n> > we should use it in build.rs to make sure we're not using any features\n> > of cbindgen that aren't available until later versions. If we use\n> > cbindgen that is packaged with the platform then we can't precisely\n> > control which version of cbindgen is being used. This is a matter of\n> > reproducibility. There may be platforms that can compile Rust, but\n> > can't generate C header files via cbindgen because cbindgen hard codes\n> > that a certain minimum Rust version is required in its own Cargo.toml\n> > file.\n> \n> Yes, I agree with this.  Not all systems have cbindgen and it's not\n> guaranteed that the system's cbindgen will work with the version of Rust\n> that you want to target or that's being used to compile.\n\nOkay. In that case the question to me is how to drive cbindgen from our\nMakefile and from Meson if it's going to be invoked via \"build.rs\". It\ndoesn't make much sense from my PoV to make generation of the C headers\ndepend on building the complete Rust library. Doubly so because we'd now\nhave a chicken-and-egg problem:\n\n  1. To build libgit.a we need to have the C interop header.\n\n  2. To build the C interop header we need to build the Rust library.\n\n  3. The Rust library depends on libgit.a.\n\nSo am I missing anything obvious here for how to declare cbindgen in our\n\"Cargo.toml\" file and invoke it directly from our other build systems?\n\nThanks!\n\nPatrick\n"},{"id":"529937","messageId":"aQM1Bdwrf0tEluEM@pks.im","threadId":"64372","inReplyTo":"87v7k4pffg.fsf@iotcl.com","subject":"Re: [PATCH v2 5/5] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-30T09:51:01Z","receivedAt":"2025-10-30T09:51:06Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Oct 24, 2025 at 04:01:07PM +0200, Toon Claes wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> > diff --git a/meson.build b/meson.build\n> > index 308798e861..b4acc417ad 100644\n> > --- a/meson.build\n> > +++ b/meson.build\n> > @@ -523,6 +523,7 @@ libgit_sources = [\n> >    'usage.c',\n> >    'userdiff.c',\n> >    'utf8.c',\n> > +  'varint.c',\n> >    'version.c',\n> >    'versioncmp.c',\n> >    'walker.c',\n> > @@ -1704,7 +1705,9 @@ version_def_h = custom_target(\n> >  libgit_sources += version_def_h\n> >  \n> >  cargo = find_program('cargo', dirs: program_path, native: true, required: get_option('rust'))\n> > -rust_option = get_option('rust').disable_auto_if(not cargo.found())\n> > +cbindgen = find_program('cbindgen', dirs: program_path, native: true, required: get_option('rust'))\n> > +\n> > +rust_option = get_option('rust').disable_auto_if(not cargo.found() or not cbindgen.found())\n> \n> This means to compile with Rust we not only need cargo, but also\n> cbindgen. As we ideally want to have a broad platform support, would\n> adding another dependency (i.e. `cbindgen`) narrow the platforms we'd\n> eventually support? Or can we consider platforms supporting Rust also\n> have cbindgen?\n\ncbindgen is written in Rust, so as long as you have Rust you should also\nbe able to have cbindgen. The obvious catch though is that cbindgen also\nhas a minimum supported Rust version, so we need to ensure that the\nversion of cbindgen that we pick is supported by our MSRV.\n\n> > diff --git a/varint.c b/varint.c\n> > index 03cd54416b..1ed738a756 100644\n> > --- a/varint.c\n> > +++ b/varint.c\n> > @@ -1,6 +1,14 @@\n> >  #include \"git-compat-util.h\"\n> >  #include \"varint.h\"\n> >  \n> > +/*\n> > + * When building with Rust we don't compile the C code, but we only verify\n> > + * whether the function signatures of our C bindings match the ones we have\n> > + * declared in \"varint.h\".\n> > + */\n> > +#ifdef WITH_RUST\n> > +# include \"c-bindings.h\"\n> \n> So when we rewrite more subsystems into Rust, this will include\n> definitions from all those subsystems into this compilation unit.\n> If one subsystem with a Rust alternative implementation includes the\n> header from another subsystem with a Rust-alternative implementation,\n> the function signatures are checked twice, and errors are surfaced\n> twice. I guess this is a tradeoff we can accept for now, because:\n> \n> * We only have one subsystem in Rust now.\n> * The approach in this patch simplifies the build setup.\n> \n> We might revisit that at some point, but I can agree this is the most\n> sensical approach for now.\n\nYeah. I guess this is also something that may be helped by introducing\nRust workspaces as Ezekiel proposes. But for now it's going to be good\nenough, I think.\n\nPatrick\n"},{"id":"529989","messageId":"aQPbMZpYZJQH_Fd6@fruit.crustytoothpaste.net","threadId":"64372","inReplyTo":"aQM07BQrGJocPKea@pks.im","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2025-10-30T21:40:01Z","receivedAt":"2025-10-30T21:40:03Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2025-10-30 at 09:50:36, Patrick Steinhardt wrote:\n> For now that Rust version is 1.49, and that's enforced by our CI. The\n> reason for this specific version is that it's the target version for the\n> gcc-rs folks, so it may help currently-unsupported platforms to get\n> support earlier.\n\nAs I mentioned a couple of times, gcc-rs uses the standard library of\nRust 1.49 since that's what it's targeting, and as a result it will not\nsupport any platforms that Rust 1.49 didn't support since there isn't\nstandard library support for those platforms in that version.  It's like\ntrying to use a 2009 version of glibc and expecting it to work on\nRISC-V, which was released in 2010—it simply won't.\n\nThat's why I was very clear at the Contributor's Summit that the message\nwe must send to platforms that do not have Rust is that they need to\nport LLVM and target Rust that way, since that is the surest path to\nsuccess and to being able to get the necessary standard library changes\nfor things to work properly.  gcc-rs may be a viable solution in the\nfuture, but it is not now, and absent substantial advances and an\norder-of-magnitude faster development, it is unlikely to meet that\nstandard in time for Git 3.0.\n\nSo given that, I would propose that we target Rust 1.63 in conjunction\nwith my proposal.  I can send a patch to that effect later on.\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"529992","messageId":"xmqqldks3vqq.fsf@gitster.g","threadId":"64372","inReplyTo":"aQPbMZpYZJQH_Fd6@fruit.crustytoothpaste.net","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-10-30T21:50:05Z","receivedAt":"2025-10-30T21:50:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"brian m. carlson\" <sandals@crustytoothpaste.net> writes:\n\n> with my proposal.  I can send a patch to that effect later on.\n\nPresumably 1.63 is older than 1.77 so we would need the single-colon\nsyntax in the output from build.rs in your series?\n\n"},{"id":"529995","messageId":"aQP24hFPF5DhaQai@fruit.crustytoothpaste.net","threadId":"64372","inReplyTo":"xmqqldks3vqq.fsf@gitster.g","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2025-10-30T23:38:10Z","receivedAt":"2025-10-30T23:38:13Z","isPatch":true,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On 2025-10-30 at 21:50:05, Junio C Hamano wrote:\n> \"brian m. carlson\" <sandals@crustytoothpaste.net> writes:\n> \n> > with my proposal.  I can send a patch to that effect later on.\n> \n> Presumably 1.63 is older than 1.77 so we would need the single-colon\n> syntax in the output from build.rs in your series?\n\nYes, I will include that in v2.\n-- \nbrian m. carlson (they/them)\nToronto, Ontario, CA\n"},{"id":"529999","messageId":"aQRRrvSoZQxH2-nw@pks.im","threadId":"64372","inReplyTo":"aQPbMZpYZJQH_Fd6@fruit.crustytoothpaste.net","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-10-31T06:05:34Z","receivedAt":"2025-10-31T06:05:42Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Oct 30, 2025 at 09:40:01PM +0000, brian m. carlson wrote:\n> On 2025-10-30 at 09:50:36, Patrick Steinhardt wrote:\n> > For now that Rust version is 1.49, and that's enforced by our CI. The\n> > reason for this specific version is that it's the target version for the\n> > gcc-rs folks, so it may help currently-unsupported platforms to get\n> > support earlier.\n> \n> As I mentioned a couple of times, gcc-rs uses the standard library of\n> Rust 1.49 since that's what it's targeting, and as a result it will not\n> support any platforms that Rust 1.49 didn't support since there isn't\n> standard library support for those platforms in that version.  It's like\n> trying to use a 2009 version of glibc and expecting it to work on\n> RISC-V, which was released in 2010—it simply won't.\n> \n> That's why I was very clear at the Contributor's Summit that the message\n> we must send to platforms that do not have Rust is that they need to\n> port LLVM and target Rust that way, since that is the surest path to\n> success and to being able to get the necessary standard library changes\n> for things to work properly.  gcc-rs may be a viable solution in the\n> future, but it is not now, and absent substantial advances and an\n> order-of-magnitude faster development, it is unlikely to meet that\n> standard in time for Git 3.0.\n\nIt seems like there is good progress in gccrs, and it seems like the\nspeed is picking up a bit. They also recently said that it shouldn't be\nthat complicated to move to 1.80 once the 1.49 baseline is implemented,\nso that makes me more amenable towards picking a more recent Rust version\n[1].\n\n> So given that, I would propose that we target Rust 1.63 in conjunction\n> with my proposal.  I can send a patch to that effect later on.\n\nI might've missed it, but why 1.63 in particular? Happy to defer the\ndiscussion until you post the patch though. I mostly want to make sure\nthat we pick the version with intent.\n\nThanks!\n\nPatrick\n\n[1]: https://lwn.net/Articles/1040197/\n"},{"id":"530056","messageId":"CAH=ZcbCq98m-yBcpoQG=iVN9EgRJrpjSWMq0QESs-1xSdRQu6Q@mail.gmail.com","threadId":"64372","inReplyTo":"aQM0_6uRZcQYfO8R@pks.im","subject":"Re: [PATCH 3/3] rust: generate bindings via cbindgen","fromName":"Ezekiel Newren","fromEmail":"ezekielnewren@gmail.com","sentAt":"2025-10-31T23:36:56Z","receivedAt":"2025-10-31T23:37:09Z","isPatch":true,"sender":{"key":"ezekielnewren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/18313324?v=4"},"body":"On Thu, Oct 30, 2025 at 3:51 AM Patrick Steinhardt <ps@pks.im> wrote:\n>\n> On Mon, Oct 27, 2025 at 09:14:51PM +0000, brian m. carlson wrote:\n> > On 2025-10-27 at 20:35:59, Ezekiel Newren wrote:\n> > > On Fri, Oct 24, 2025 at 12:37 AM Patrick Steinhardt <ps@pks.im> wrote:\n> > > > > cbindgen is a Rust crate and it should be specified in the Cargo.toml\n> > > > > under [build-dependencies] block.\n> > > >\n> > > > What is the benefit for us? The generated code is not a dependency of\n> > > > the Rust code, and neither do we use it via \"build.rs\". And if we use\n> > > > cbindgen via \"Cargo.toml\" we'd be forced to build it first, which slows\n> > > > down our CI jobs.\n> > > >\n> > > > Please let me know in case I miss any reasons to have it in our build\n> > > > dependencies instead.\n> > >\n> > > You're targeting a very old version of Rust (1.49). I'm not even sure\n> > > that cbindgen will work with a version that old, but if it does then\n> > > we should use it in build.rs to make sure we're not using any features\n> > > of cbindgen that aren't available until later versions. If we use\n> > > cbindgen that is packaged with the platform then we can't precisely\n> > > control which version of cbindgen is being used. This is a matter of\n> > > reproducibility. There may be platforms that can compile Rust, but\n> > > can't generate C header files via cbindgen because cbindgen hard codes\n> > > that a certain minimum Rust version is required in its own Cargo.toml\n> > > file.\n> >\n> > Yes, I agree with this.  Not all systems have cbindgen and it's not\n> > guaranteed that the system's cbindgen will work with the version of Rust\n> > that you want to target or that's being used to compile.\n>\n> Okay. In that case the question to me is how to drive cbindgen from our\n> Makefile and from Meson if it's going to be invoked via \"build.rs\". It\n> doesn't make much sense from my PoV to make generation of the C headers\n> depend on building the complete Rust library. Doubly so because we'd now\n> have a chicken-and-egg problem:\n>\n>   1. To build libgit.a we need to have the C interop header.\n>\n>   2. To build the C interop header we need to build the Rust library.\n>\n>   3. The Rust library depends on libgit.a.\n>\n> So am I missing anything obvious here for how to declare cbindgen in our\n> \"Cargo.toml\" file and invoke it directly from our other build systems?\n\nYou would need a separate crate whose only job is to generate the\nheader files and then Makefile or Meson can be invoked. But since we\nonly have a single crate we can't do that.\n\nAs to why version 1.63.0 it's because of Debian [1]. \"Our discussed\nplan is to support the version in Debian stable, plus a\nyear.  So we'd be supporting 1.63.0 for a year after trixie's\nrelease.\" - Brian M. Carlson\n\nRust version 1.49 can't use cbindgen newer than 0.1.0 (the latest is\n0.29.2). Any cbindgen version newer than 0.1.0 requires a minimum of\nRust 1.68.0. The way that I got cbindgen to work with version 1.63.0\nis that I overrode cbindgen's dependencies in Cargo.toml. That hack\nonly works so far because the older the Rust version the less likely\nolder and older sub dependencies will work.\n\nSince you're worried about build times I think that cbindgen should be\nin its own crate whose only job is to generate the header files and\nthen have the subsequent CI jobs copy in those generated header files.\nFor local development cargo will need to be invoked first to generate\nthe header files and then Makefile or Meson can be invoked. If we put\ncbindgen into its own crate then we won't have a chicken-and-egg\nproblem. That's why we need to convert to a cargo workspace in this\npatch series or before. It cannot come after.\n\n[1]  https://lore.kernel.org/git/aHlp1joMwexLZAAb@fruit.crustytoothpaste.net/\n"}]}