diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh index 6505b629..39d810e3 100755 --- a/cpython-unix/build-cpython.sh +++ b/cpython-unix/build-cpython.sh @@ -455,12 +455,21 @@ if [ -n "${CPYTHON_OPTIMIZED}" ]; then # Allow users to enable the experimental JIT on 3.13+ if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]]; then - # The JIT build is failing on macOS due to compiler errors - # Only enable on Linux / 3.13 until that's fixed upstream - if [[ "${PYBUILD_PLATFORM}" != "macos" ]]; then + # Do not enable on x86-64 macOS because the JIT requires macOS 11+ and we are currently + # using 10.15 as a miniumum version. + if [ "${TARGET_TRIPLE}" != "x86_64-apple-darwin" ]; then CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --enable-experimental-jit=yes-off" fi + # Respect CFLAGS during JIT compilation. + # Backports https://github.com/python/cpython/pull/134276 + if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]; then + patch -p1 -i ${ROOT}/patch-jit-cflags-314.patch + elif [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then + patch -p1 -i ${ROOT}/patch-jit-cflags-313.patch + fi + + if [[ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_13}" ]]; then # On 3.13, LLVM 18 is hard-coded into the configure script. Override it to our toolchain # version. diff --git a/cpython-unix/patch-jit-cflags-313.patch b/cpython-unix/patch-jit-cflags-313.patch new file mode 100644 index 00000000..d82d1eed --- /dev/null +++ b/cpython-unix/patch-jit-cflags-313.patch @@ -0,0 +1,80 @@ +diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py +index 50b5d923a35..4a71476026f 100644 +--- a/Tools/jit/_targets.py ++++ b/Tools/jit/_targets.py +@@ -10,6 +10,7 @@ + import sys + import tempfile + import typing ++import shlex + + import _llvm + import _schema +@@ -44,6 +45,17 @@ class _Target(typing.Generic[_S, _R]): + stable: bool = False + debug: bool = False + verbose: bool = False ++ cflags: str = "" ++ known_symbols: dict[str, int] = dataclasses.field(default_factory=dict) ++ ++ def _get_nop(self) -> bytes: ++ if re.fullmatch(r"aarch64-.*", self.triple): ++ nop = b"\x1f\x20\x03\xD5" ++ elif re.fullmatch(r"x86_64-.*|i686.*", self.triple): ++ nop = b"\x90" ++ else: ++ raise ValueError(f"NOP not defined for {self.triple}") ++ return nop + + def _compute_digest(self, out: pathlib.Path) -> str: + hasher = hashlib.sha256() +@@ -114,6 +126,7 @@ async def _compile( + return _stencils.StencilGroup() + o = tempdir / f"{opname}.o" + args = [ ++ *shlex.split(self.cflags), + f"--target={self.triple}", + "-DPy_BUILD_CORE_MODULE", + "-D_DEBUG" if self.debug else "-DNDEBUG", +diff --git a/Tools/jit/build.py b/Tools/jit/build.py +index 4a23c6f0afa..618b53804db 100644 +--- a/Tools/jit/build.py ++++ b/Tools/jit/build.py +@@ -22,7 +22,11 @@ + parser.add_argument( + "-v", "--verbose", action="store_true", help="echo commands as they are run" + ) ++ parser.add_argument( ++ "--with-cflags", help="additional flags to pass to the compiler", default="" ++ ) + args = parser.parse_args() + args.target.debug = args.debug + args.target.verbose = args.verbose ++ args.target.cflags = args.with_cflags + args.target.build(pathlib.Path.cwd(), comment=comment, force=args.force) +diff --git a/configure b/configure +index 1cd1f690f7b..7fb6c4adfea 100755 +--- a/configure ++++ b/configure +@@ -8326,7 +8326,7 @@ then : + + else $as_nop + as_fn_append CFLAGS_NODIST " $jit_flags" +- REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host" ++ REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host --with-cflags=\"\$(CONFIGURE_CFLAGS)\"" + JIT_STENCILS_H="jit_stencils.h" + if test "x$Py_DEBUG" = xtrue + then : +diff --git a/configure.ac b/configure.ac +index 3fcb18922c5..616999a96b2 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1846,7 +1846,7 @@ AS_VAR_IF([jit_flags], + [], + [AS_VAR_APPEND([CFLAGS_NODIST], [" $jit_flags"]) + AS_VAR_SET([REGEN_JIT_COMMAND], +- ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host"]) ++ ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host --with-cflags=\"\$(CONFIGURE_CFLAGS)\""]) + AS_VAR_SET([JIT_STENCILS_H], ["jit_stencils.h"]) + AS_VAR_IF([Py_DEBUG], + [true], diff --git a/cpython-unix/patch-jit-cflags-314.patch b/cpython-unix/patch-jit-cflags-314.patch new file mode 100644 index 00000000..81f6fd02 --- /dev/null +++ b/cpython-unix/patch-jit-cflags-314.patch @@ -0,0 +1,70 @@ +diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py +index b3b065652e0..d361f57382e 100644 +--- a/Tools/jit/_targets.py ++++ b/Tools/jit/_targets.py +@@ -10,6 +10,7 @@ + import sys + import tempfile + import typing ++import shlex + + import _llvm + import _schema +@@ -42,6 +43,7 @@ class _Target(typing.Generic[_S, _R]): + stable: bool = False + debug: bool = False + verbose: bool = False ++ cflags: str = "" + known_symbols: dict[str, int] = dataclasses.field(default_factory=dict) + + def _get_nop(self) -> bytes: +@@ -115,6 +117,7 @@ async def _compile( + ) -> _stencils.StencilGroup: + o = tempdir / f"{opname}.o" + args = [ ++ *shlex.split(self.cflags), + f"--target={self.triple}", + "-DPy_BUILD_CORE_MODULE", + "-D_DEBUG" if self.debug else "-DNDEBUG", +diff --git a/Tools/jit/build.py b/Tools/jit/build.py +index a8cb0f67c36..663874ad439 100644 +--- a/Tools/jit/build.py ++++ b/Tools/jit/build.py +@@ -22,7 +22,11 @@ + parser.add_argument( + "-v", "--verbose", action="store_true", help="echo commands as they are run" + ) ++ parser.add_argument( ++ "--with-cflags", help="additional flags to pass to the compiler", default="" ++ ) + args = parser.parse_args() + args.target.debug = args.debug + args.target.verbose = args.verbose ++ args.target.cflags = args.with_cflags + args.target.build(pathlib.Path.cwd(), comment=comment, force=args.force) +diff --git a/configure b/configure +index 1b75ddfa26d..3c9e550b5d3 100755 +--- a/configure ++++ b/configure +@@ -8399,7 +8399,7 @@ then : + + else case e in #( + e) as_fn_append CFLAGS_NODIST " $jit_flags" +- REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host" ++ REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host --with-cflags=\"\$(CONFIGURE_CFLAGS)\"" + JIT_STENCILS_H="jit_stencils.h" + if test "x$Py_DEBUG" = xtrue + then : +diff --git a/configure.ac b/configure.ac +index c449bb5ebb3..5f9d08a4ee7 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1827,7 +1827,7 @@ AS_VAR_IF([jit_flags], + [], + [AS_VAR_APPEND([CFLAGS_NODIST], [" $jit_flags"]) + AS_VAR_SET([REGEN_JIT_COMMAND], +- ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host"]) ++ ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host --with-cflags=\"\$(CONFIGURE_CFLAGS)\""]) + AS_VAR_SET([JIT_STENCILS_H], ["jit_stencils.h"]) + AS_VAR_IF([Py_DEBUG], + [true],