镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Doc/using/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,17 @@ General Options
otherwise one will be generated from the ``MULTIARCH`` tag with
``-free-threading`` and ``-debug``, as appropriate.

CPython's ``build-details.json`` also provides the CPython-specific
``arbitrary_data.extension_compiler_flags`` list. These are compiler
arguments recommended when building extension modules so they preserve
properties of the interpreter build, such as usable frame pointers. They
are not required for ABI compatibility.

This key is an implementation-specific extension to the standardized
format and may be superseded by a standard field in a later schema
version. Consumers should prefer such a standard field when available
and otherwise use this key as a fallback.

.. versionadded:: 3.16


Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_build_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import os
import os.path
import shlex
import sys
import sysconfig
import string
Expand Down Expand Up @@ -173,6 +174,13 @@ def test_c_api(self):
version = sysconfig.get_config_var('VERSION')
self.assertTrue(os.path.exists(os.path.join(value['pkgconfig_path'], f'python-{version}.pc')))

def test_extension_compiler_flags(self):
value = self.key('arbitrary_data.extension_compiler_flags')
expected = shlex.split(
sysconfig.get_config_var('FRAME_POINTER_CFLAGS') or ''
)
self.assertEqual(value, expected)


@unittest.skipIf(
generate_build_details is None,
Expand Down
1 change: 1 addition & 0 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ MAKESETUP= $(srcdir)/Modules/makesetup
# Compiler options
OPT= @OPT@
BASECFLAGS= @BASECFLAGS@
FRAME_POINTER_CFLAGS= @FRAME_POINTER_CFLAGS@
BASECPPFLAGS= @BASECPPFLAGS@
CONFIGURE_CFLAGS= @CFLAGS@
# CFLAGS_NODIST is used for building the interpreter and stdlib C extensions.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Expose CPython's frame-pointer flags for extension builds in
``build-details.json``.
3 changes: 3 additions & 0 deletions PC/layout/support/builddetails.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
},
"c_api": {
},
"arbitrary_data": {
"extension_compiler_flags": [],
},
Comment on lines +57 to +59

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We can just omit if it's known to be empty, surely?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

not opposed but why would that be preferable?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

File size is the most concrete reason, but it'd also help flush out any code that assumes it's going to be there "because it's always there". Users of the value will need a fallback anyway, so they may as well discover it sooner.

I also agree with @mgorny that we should probably do a proper update to add more (optional) fields to the other sections, rather than arbitrary_data. There are gaps, and the PEP is written in a way to require updates (or a new PEP?) to add the things we need (import libraries path and name, IIRC, in addition to the others).

@pablogsal pablogsal Oct 13, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks! I'm happy to omit the empty field and work through a spec update for the interface.

Just to clarify the motivation: PEP 831 already recommends enabling frame pointers in extensions and native dependencies. Backends can do that today with the appropriate flags for their toolchain, without waiting for this PR. We're trying to make their lives easier by exposing the relevant information without making them extract it from CPython's full CFLAGS. The question here is how best to represent that in build-details.json. I would prefer if this issue doesn't balloon to trying to fix a much bigger problem.

}


Expand Down
6 changes: 6 additions & 0 deletions Tools/build/generate-build-details.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import importlib.machinery
import json
import os
import shlex
import sys
import sysconfig

Expand Down Expand Up @@ -129,6 +130,11 @@ def generate_data(schema_version: str) -> collections.defaultdict[str, Any]:
if LIBPC:
data['c_api']['pkgconfig_path'] = LIBPC

frame_pointer_cflags = sysconfig.get_config_var('FRAME_POINTER_CFLAGS') or ''
data['arbitrary_data']['extension_compiler_flags'] = shlex.split(
frame_pointer_cflags
)

return data


Expand Down
6 changes: 5 additions & 1 deletion configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2627,6 +2627,8 @@ AC_ARG_WITH([frame-pointers],
[with_frame_pointers=yes])
AC_MSG_RESULT([$with_frame_pointers])

AC_SUBST([FRAME_POINTER_CFLAGS])
FRAME_POINTER_CFLAGS=
AS_VAR_IF([ac_cv_gcc_compat], [yes], [
dnl Keep frame pointers in CPython, stdlib objects, and third-party
dnl extensions built against this Python (BASECFLAGS propagates via
Expand Down Expand Up @@ -2658,7 +2660,8 @@ AS_VAR_IF([ac_cv_gcc_compat], [yes], [
])
], [], [-Werror])
if test -n "$frame_pointer_cflags" && test "x$with_frame_pointers" != xno; then
BASECFLAGS="$frame_pointer_cflags $BASECFLAGS"
FRAME_POINTER_CFLAGS="$frame_pointer_cflags"
BASECFLAGS="$FRAME_POINTER_CFLAGS $BASECFLAGS"
AC_DEFINE([_Py_WITH_FRAME_POINTERS], [1],
[Define to 1 if frame unwinding via pointers is expected
to work, 0 if not. Leave undefined if unknown.])
Expand Down
Loading