Skip to content

go-pathrs: don't derive ProcBase from the C enum - #408

Open
martinpitt wants to merge 1 commit into
cyphar:mainfrom
martinpitt:go-pathrs-c23-enum
Open

go-pathrs: don't derive ProcBase from the C enum#408
martinpitt wants to merge 1 commit into
cyphar:mainfrom
martinpitt:go-pathrs-c23-enum

Conversation

@martinpitt

Copy link
Copy Markdown

cbindgen v0.29.3 emits the C23 fixed-type enum syntax for sized enums1, so in C23 mode pathrs_proc_base_t names the enum rather than uint64_t. CGo maps a C enum to a signed Go type, so none of the open-coded ProcBase constants fit in it any more and the package stops compiling:

internal/libpathrs/libpathrs_linux.go:228:22: cannot use
0xFFFF_FFFE_7072_6F63 (untyped int constant 18446744067006164835) as
ProcBase value in constant declaration (overflows)

Our own tree does not show this, because CI is pinned to cbindgen v0.29.22, so the checked-in header and the release tarball still typedef uint64_t. Fedora (and presumably other distros) do hit it, because they build the crate with cargo-c, which generates the header with its own cbindgen. Fedora rawhide has cbindgen v0.29.4 and gcc 16, which defaults to C23, so libpathrs-devel-0.2.5-2.fc45 ships the C23 spelling and every Go consumer of it fails to build. The workaround there is to force the older language version with CGO_CFLAGS=-std=gnu17.

Declare the type as plain uint64 instead, which is what the docstring already promises. That also holds up under the direction discussed in 1, where the #if guards would be dropped in favour of an opt-out and the enum spelling would become unconditional.

Nothing else has to change: the values were already converted with C.pathrs_proc_base_t() at each call site, and init() already reads the C constants through int64 temporaries because CGo signs those too.

cbindgen v0.29.3 emits the C23 fixed-type enum syntax for sized
enums[1], so in C23 mode pathrs_proc_base_t names the enum rather than
uint64_t. CGo maps a C enum to a *signed* Go type, so none of the
open-coded ProcBase constants fit in it any more and the package stops
compiling:

> internal/libpathrs/libpathrs_linux.go:228:22: cannot use
> 0xFFFF_FFFE_7072_6F63 (untyped int constant 18446744067006164835) as
> ProcBase value in constant declaration (overflows)

Our own tree does not show this, because CI is pinned to cbindgen
v0.29.2[2], so the checked-in header and the release tarball still
typedef uint64_t. Fedora (and presumably other distros) do hit it,
because they build the crate with `cargo-c`, which generates the header
with its own cbindgen. Fedora rawhide has cbindgen v0.29.4 and gcc 16,
which defaults to C23, so libpathrs-devel-0.2.5-2.fc45 ships the C23
spelling and every Go consumer of it fails to build. The workaround
there is to force the older language version with `CGO_CFLAGS=-std=gnu17`.

Declare the type as plain uint64 instead, which is what the docstring
already promises. That also holds up under the direction discussed in
[1], where the #if guards would be dropped in favour of an opt-out and
the enum spelling would become unconditional.

Nothing else has to change: the values were already converted with
C.pathrs_proc_base_t() at each call site, and init() already reads the
C constants through int64 temporaries because CGo signs those too.

[1]: mozilla/cbindgen#1156
[2]: cyphar#383

Signed-off-by: Martin Pitt <martin@amutable.com>
@martinpitt

Copy link
Copy Markdown
Author

Related: #382 (comment)

@cyphar

cyphar commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Whoa whoa, you can't use cargo-c to build libpathrs and Fedora definitely doesn't do that (at least they didn't when I reviewed the specfile). cbindgen is only used for generating the header, which is committed into the repo so there's no need to run it at build time.

The behaviour here is quite complicated, as I outlined in #382. (There is also a separate type issue when building with clang which this will also cause issues with AFAICS.)

@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@martinpitt

Copy link
Copy Markdown
Author

The package does BuildRequires: cargo-c in the spec, and the recent rawhide build log shows cargo cbuild.

only used for generating the header, which is committed into the repo

That's only true for your upstream build/CI. That works because #383 pins the older cbindgen. But %cargo_cbuild rebuilds the header (as it should be in a distro -- build from source!), and Fedora has cbindgen 0.29.4.

If you want, I can talk you through standing up some actual Fedora CI in upstream PRs, with packit. (Or send a PR 😉 )

@cyphar

cyphar commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Hmm, I must've misremembered. I expected the LIBPATHRS_CAPI_BUILDMODE awfulness to not work with cargo-c, which is why I dropped my attempt to switch to it some time ago...

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.

2 participants