Skip to content

Build CPython against modern kernel UAPI headers on *-linux-gnu targets#1163

Open
jjhelmus wants to merge 4 commits into
mainfrom
jjh/modern_kernel_uapi
Open

Build CPython against modern kernel UAPI headers on *-linux-gnu targets#1163
jjhelmus wants to merge 4 commits into
mainfrom
jjh/modern_kernel_uapi

Conversation

@jjhelmus

Copy link
Copy Markdown
Contributor

Use modern Linux kernel UAPI headers when building CPython for glibc Linux targets.

Adds a linux-uapi package to the project that contains the unpacked linux-libc-dev package from a modern Debian release, currently trixie-backports. This provides Linux UAPI headers from a modern kernel release.

Building CPython against these headers makes newer syscall definitions and macros available at build time, enabling CPython functionality such as os.pidfd_open.

This does not increase the minimum required glibc or runtime kernel version.

APIs compiled using these definitions may still fail at runtime. For example, if an API uses a direct syscall and the running kernel does not implement it, the kernel returns ENOSYS, which Python exposes as an OSError.

Consequently, functions such as os.pidfd_open will exist when running on an older kernel that does not implement the corresponding syscall. Applications should handle OSError with errno.ENOSYS when runtime kernel support is uncertain.

This should be included as a quirk of python-build-standalone and documented as such. The trade-off here is worth introducing this quirk.

Related to #193
Related to astral-sh/uv#11811, astral-sh/uv#9374

jjhelmus added 3 commits June 24, 2026 15:14
Package Debian's linux-libc-dev headers as a build dependency for
*-linux-gnu targets.

This new linux-uapi package provides userspace header from a modern
Linux kernel (currently 7.0.12).

When building CPython on *-linux-gnu targets use these headers to enable
modern kernel features, such as os.pidfp_open. At runtime if the kernel
does not support the needed syscalls ENOSYS will be returned.
Verify that no sysconfig variables contains the build-only linux-uapi path.
Verify that building against the modern Linux UAPI headers enables
os.pidfd_open on GNU/Linux targets.
@jjhelmus jjhelmus added platform:darwin Specific to the macOS platform platform:linux Specific to the Linux platform arch:all Select all architectures labels Jun 24, 2026
@jjhelmus

jjhelmus commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

The include guard in posixmodule.py for sys/syscall.h is HAVE_GETRANDOM_SYSCALL which is falsely in glibc 2.19 which is used on x86-64. A better guard would be HAVE_SYS_SYSCALL_H.

@geofft

geofft commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Oh, this is an interesting approach. I think it seems reasonable and safe!

Note that the quirk is technically already true of "normal" Python distributions if you run a newer OS image in e.g. a Docker container on a host with an older kernel. So generic code (libraries, etc.) already need to both test hasattr and catch ENOSYS, though very specific applications that are never deployed in containers may not have had to worry about this. I agree we should document it, but we should document it in a way that conveys it's a best practice anyway. (I think we also maybe should try to convince upstream CPython that, because of this, it would be nicer to have the functions be unconditionally present and fail with a synthetic ENOSYS if we don't have the right constants at compile time.)

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

Labels

arch:all Select all architectures platform:darwin Specific to the macOS platform platform:linux Specific to the Linux platform

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants