Skip to content

Conversation

@polarathene
Copy link
Contributor

@polarathene polarathene commented Jun 28, 2025

TL;DR:

  • Rust 1.82 (Oct 2024) is required to build the crate, encode that information into Cargo.toml. This benefits users and the cargo resolver going forward.
  • Consider bumping edition to 2021 given the minimum version of rust is well beyond 1.56?

UPDATE: As later discussed, prior to this PR bindings were generated for the latest Rust toolchain, whereas this PR has been adjusted to lower that to permit building on Rust prior to 1.82.


Required for bindings change to unsafe extern:

  • This PR from Dec 2024 bumped bindgen version, and committed a change to use unsafe extern (introduced with Rust 1.82 in Oct 2024).
  • Unfortunately this change was part of the 1.5.1 release of libbpf-sys (May 2025), so anyone using the Nov 2024 1.5.0 release (without explicitly pinning it) has had their minimum required Rust also bumped.
  • Not only is rust-version helpful at communicating this information to the resolver, users will not need to troubleshoot the build failure to identify the minimum Rust toolchain required.

On Rust toolchains prior to 1.82, builds for [email protected] would fail with the following:

error: extern block cannot be declared unsafe
    --> /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libbpf-sys-1.5.1+v1.5.1/src/bindings.rs:9168:1
     |
9168 | unsafe extern "C" {
     | ^^^^^^
     |
     = note: see issue #123743 <https://github.com/rust-lang/rust/issues/123743> for more information

NOTE: Feb 2025 released Rust 1.85 which introduced the Rust 2024 edition. There's technically no need to raise the version of rust required to 1.85, but bumping the rust edition to 2024 this may be required AFAIK (and may require some additional work). Given Rust 2021 edition was from Oct 2021 with Rust 1.56.0 and the required rust-version to build this crate, you might as well consider bumping that though?


I have not contributed a CI update, but ideally you would run tests for your minimum supported rust version to catch these sort of implicit bumps.

  • Technically bindgen crate should probably have this themselves, as once rust-version is configured for a crate, the resolver should be able to fallback to earlier releases (when semver constraint is compatible).
  • Since this is the first time rust-version is added to Cargo.toml here, falling back to 1.5.1 as the prior release will of course still expect Rust 1.82, but if it had been configured for that release instead, the fallback to 1.5.0 would have worked.

@alexforster
Copy link
Member

Good catch! I'm leaning toward making bindgen generate pre-2024 compatible code instead; there's no good reason for us to require 2024 imo. I assume that's possible? I'll look into it.

@polarathene
Copy link
Contributor Author

polarathene commented Jun 28, 2025

there's no good reason for us to require 2024 imo. I assume that's possible? I'll look into it.

Actually, I think this is because I am not familiar with using bindgen myself, it seems that you can have it configured to generate bindings for a given MSRV?: rust-lang/rust-bindgen#3049

In that thread they later discuss using rust-version in Cargo.toml and how it is provided as a Cargo ENV that you can use to influence the generated bindings. I assume lowering that below 1.82 would allow you to bring down that requirement, removing the unsafe extern generation.

Some earlier discussion in that thread describes avoiding newer versions of Rust for the bindgen target due to issues, and then later bumping it once fixes landed for their usage. I'm not familiar enough with bindgen to know of the merits of a higher target for this project, I assume so far it's just been using whatever version of rust toolchain was used at the time.

@alexforster
Copy link
Member

alexforster commented Jun 28, 2025

Yeah I'm definitely not a bindgen expert but I figured there must be a way. If you feel like figuring out how I'm happy to merge! Otherwise I'll research it.

@alexforster
Copy link
Member

alexforster commented Jun 28, 2025

This looks fine, the build failure looks like some buggy CI. I don't mind debugging that, you've already done enough :)

@polarathene
Copy link
Contributor Author

polarathene commented Jun 28, 2025

Ok I've followed this advice to leverage the Cargo ENV CARGO_PKG_RUST_VERSION with bindgen builder method rust_target:

CARGO_PKG_RUST_VERSION — The Rust version from the manifest of your package. Note that this is the minimum Rust version supported by the package, not the current Rust version.

Which should parse a string value into the expected RustTarget struct for rust_target() to use 🤔

I went with rust-version=1.70 (June 2023) to match the bindgen MSRV required to build that crate. If you want to target lower than that, you'd need to be explicit and not rely on using rust-version from Cargo.toml.

I'm not sure what the actual MSRV is for libbpf-sys or it's consumers of the bindings generated, so if you'd rather avoid rust-version and generate for a lower version that's understandable.

That said, the unsafe extern is required for Rust 2024 (Feb 2025 / Rust 1.85) onwards I think, so I'm not sure if you'll have a compatibility issue there between newer and older toolchains with the bindings?

@polarathene
Copy link
Contributor Author

polarathene commented Jun 28, 2025

I don't mind debugging that, you've already done enough :)

Thanks, I have no clue about the CI failure cause sorry 😓

Maybe it's related to my last comment about newer Rust possibly not being happy? (I think this would only be when a project uses edition="2024" but I'm not experienced enough with how compatibility works there across crates, I think each crate is compiled for it's own edition, so it may be a non-issue)

@polarathene polarathene changed the title chore: Add rust-version to Cargo.toml chore: Generate bindings based upon rust-version Jun 28, 2025
@danielocfb
Copy link
Collaborator

danielocfb commented Jun 30, 2025

This looks fine, the build failure looks like some buggy CI. I don't mind debugging that, you've already done enough :)

If you are referring to this CI failure: https://github.com/libbpf/libbpf-sys/actions/runs/15938909087/job/44963986439?pr=124#step:6:2159

Then it's because the generated Rust binding file is outdated. The new version will have to be commited.

@alexforster alexforster force-pushed the patch-1 branch 2 times, most recently from 83fa8ec to 3db71b5 Compare July 1, 2025 20:13
@alexforster
Copy link
Member

alexforster commented Jul 1, 2025

That said, the unsafe extern is required for Rust 2024 (Feb 2025 / Rust 1.85) onwards I think, so I'm not sure if you'll have a compatibility issue there between newer and older toolchains with the bindings?

unsafe extern was stabilized in 1.82 based on this comment so I'm going to set our MSRV to that. We never had an MSRV policy before, but supporting 6 versions back still seems generous, I think?

@danielocfb
Copy link
Collaborator

unsafe extern was stabilized in 1.82 based on this comment so I'm going to set our MSRV to that. We never had an MSRV policy before, but supporting 6 versions back still seems generous, I think?

Sounds fine to me. For what it's worth, libbpf-rs's MSRV is currently 1.78, but 1.82 would be in line with our policy.

@alexforster
Copy link
Member

Sorry for the noise. I'm currently stuck on the fact that, on my machine, running rebuild.sh to regenerate bindings isn't producing the same output that the binding check CI job is. Specifically, the difference is:

diff --git a/src/bindings.rs b/src/bindings.rs
index dea2158..504e5ac 100644
--- a/src/bindings.rs
+++ b/src/bindings.rs
@@ -7112,8 +7112,8 @@ unsafe extern "C" {
         opts: *mut bpf_token_create_opts,
     ) -> ::std::os::raw::c_int;
 }
-pub type va_list = __builtin_va_list;
 pub type __gnuc_va_list = __builtin_va_list;
+pub type va_list = __builtin_va_list;
 #[repr(C)]
 #[derive(Debug, Default, Copy, Clone)]
 pub struct btf_header {

Which is... confusing. I'll keep researching

@danielocfb
Copy link
Collaborator

Sorry for the noise. I'm currently stuck on the fact that, on my machine, running rebuild.sh to regenerate bindings isn't producing the same output that the binding check CI job is. Specifically, the difference is:

diff --git a/src/bindings.rs b/src/bindings.rs
index dea2158..504e5ac 100644
--- a/src/bindings.rs
+++ b/src/bindings.rs
@@ -7112,8 +7112,8 @@ unsafe extern "C" {
         opts: *mut bpf_token_create_opts,
     ) -> ::std::os::raw::c_int;
 }
-pub type va_list = __builtin_va_list;
 pub type __gnuc_va_list = __builtin_va_list;
+pub type va_list = __builtin_va_list;
 #[repr(C)]
 #[derive(Debug, Default, Copy, Clone)]
 pub struct btf_header {

Which is... confusing. I'll keep researching

I've hit that once or twice on PRs where I actively modified bindings.rs, but have never seen issues on subsequent requests. That may have been luck, though. Not sure. It's possible that there is some non-deterministic ordering in bindgen, which would be unfortunate (but we can disable the job if need be).

index % 8
};
let mask = 1 << bit_index;
if val { byte | mask } else { byte & !mask }
Copy link
Member

@alexforster alexforster Jul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bindgen also can't seem to decide if it wants this on one line or split across multiple. It flattened this a few commits ago, only to again explode it in this commit. Not a blocker to merge this, but odd.

@alexforster
Copy link
Member

Ah, got it. Bindgen intends to have deterministic output, but only for the same input, and that includes system C headers: rust-lang/rust-bindgen#1605

So the fix is to just make sure rebuild.sh and CI use the same distro, version, and architecture.

@alexforster alexforster merged commit 3935381 into libbpf:master Jul 1, 2025
11 checks passed
@alexforster
Copy link
Member

I'll cut a release shortly – does CI work reliably now? I suppose we'll find out, but I could never seem to convince it to publish in the past.

@danielocfb
Copy link
Collaborator

danielocfb commented Jul 1, 2025

I'll cut a release shortly – does CI work reliably now? I suppose we'll find out, but I could never seem to convince it to publish in the past.

My last five publish runs were successful. Let me know if you hit problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants