diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 47b6446..00f953c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -17,7 +17,8 @@ jobs: strategy: fail-fast: true matrix: - python-version: [3.9.21, 3.10.16, 3.11.11, 3.12.8] + #python-version: [3.9.21, 3.10.16, 3.11.11, 3.12.8, 3.13.0] + python-version: [3.13.0] os: [ubuntu] include: - os: ubuntu diff --git a/CMakeLists.txt b/CMakeLists.txt index bf04642..4337edb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,6 +162,9 @@ if(UNIX) else() set(WITH_STATIC_DEPENDENCIES 0) endif() +if(PY_VERSION VERSION_GREATER_EQUAL "3.13") + option(WITH_FREE_THREADING "Enable experimental free-threaded build and disables the GIL" OFF) +endif() # Detect source directory set(_landmark "pyconfig.h.in") # CMake will look for this file. @@ -335,6 +338,8 @@ set(_download_3.12.5_md5 "d23d56b51d36a9d51b2b13d30c849d00") set(_download_3.12.6_md5 "c2f1dd5c8807ee50b778684b7958ee28") set(_download_3.12.7_md5 "5d0c0e4c6a022a87165a9addcd869109") set(_download_3.12.8_md5 "304473cf367fa65e450edf4b06b55fcc") +# 3.13.x +set(_download_3.13.0_md5 "c29f37220520ec6075fc37d4c62e178b") set(_extracted_dir "Python-${PY_VERSION}") @@ -586,6 +591,14 @@ if(UNIX) configure_file(cmake/config-unix/pyconfig.h.in ${PYCONFIG_BUILD_DIR}/pyconfig.h) elseif(WIN32) + if(PY_VERSION VERSION_GREATER_EQUAL "3.13") + file(READ ${SRC_DIR}/PC/pyconfig.h.in PYCONFIG_H_CONTENTS) + if(WITH_FREE_THREADING) + string(REPLACE "/* #define Py_GIL_DISABLED 1 */" "#define Py_GIL_DISABLED 1" PYCONFIG_H_CONTENTS "${PYCONFIG_H_CONTENTS}") + endif() + file(WRITE ${SRC_DIR}/PC/pyconfig.h "${PYCONFIG_H_CONTENTS}") + endif() + set(PYCONFIG_BUILD_DIR ${SRC_DIR}/PC) # In a windows build tree, 'pyconfig.h' is NOT required to # live along side the python executable. # See function '_init_posix()' and '_init_non_posix()' diff --git a/cmake/ConfigureChecks.cmake b/cmake/ConfigureChecks.cmake index 05d99a6..7a1540c 100644 --- a/cmake/ConfigureChecks.cmake +++ b/cmake/ConfigureChecks.cmake @@ -207,6 +207,9 @@ endif() if(WITH_PYMALLOC AND PY_VERSION VERSION_LESS "3.8") set(ABIFLAGS "${ABIFLAGS}m") endif() +if(WITH_FREE_THREADING AND PY_VERSION VERSION_GREATER_EQUAL "3.13") + set(ABIFLAGS "${ABIFLAGS}t") +endif() message(STATUS "${_msg} - ${ABIFLAGS}") set(_msg "Checking PLATFORM_TRIPLET") @@ -326,6 +329,7 @@ check_include_files(memory.h HAVE_MEMORY_H) # libffi and cpython check_include_files(minix/config.h HAVE_MINIX_CONFIG_H) check_include_files(ncurses.h HAVE_NCURSES_H) check_include_files(ncurses/panel.h HAVE_NCURSES_PANEL_H) +check_include_files(ncursesw/panel.h HAVE_NCURSESW_PANEL_H) check_include_files(netdb.h HAVE_NETDB_H) check_include_files(netinet/in.h HAVE_NETINET_IN_H) check_include_files(netpacket/packet.h HAVE_NETPACKET_PACKET_H) diff --git a/cmake/config-unix/pyconfig.h.in b/cmake/config-unix/pyconfig.h.in index 8102789..813dc52 100644 --- a/cmake/config-unix/pyconfig.h.in +++ b/cmake/config-unix/pyconfig.h.in @@ -813,6 +813,15 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_NCURSES_H 1 +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NCURSES_PANEL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NCURSESW_PANEL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_PANEL_H 1 + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_NETDB_H 1 diff --git a/cmake/extensions/CMakeLists.txt b/cmake/extensions/CMakeLists.txt index 0b33dbc..8d80d13 100644 --- a/cmake/extensions/CMakeLists.txt +++ b/cmake/extensions/CMakeLists.txt @@ -15,8 +15,14 @@ if(Cosmopolitan) set(NOT_COSMOPOLITAN 0) endif() +if(WITH_FREE_THREADING) + add_definitions(-DPy_GIL_DISABLED) +endif() + add_python_extension(array ${WIN32_BUILTIN} SOURCES arraymodule.c) -add_python_extension(audioop ${WIN32_BUILTIN} REQUIRES HAVE_LIBM SOURCES audioop.c LIBRARIES ${M_LIBRARIES}) +if(PY_VERSION VERSION_LESS "3.13") + add_python_extension(audioop ${WIN32_BUILTIN} REQUIRES HAVE_LIBM SOURCES audioop.c LIBRARIES ${M_LIBRARIES}) +endif() add_python_extension(_bisect ${WIN32_BUILTIN} SOURCES _bisectmodule.c) add_python_extension(cmath REQUIRES HAVE_LIBM ${WIN32_BUILTIN} SOURCES $<$:_math.c> cmathmodule.c LIBRARIES ${M_LIBRARIES}) add_python_extension(_codecs_cn ${WIN32_BUILTIN} SOURCES cjkcodecs/_codecs_cn.c) @@ -27,11 +33,13 @@ add_python_extension(_codecs_kr ${WIN32_BUILTIN} SOURCES cjkcodecs/_codecs_kr.c) add_python_extension(_codecs_tw ${WIN32_BUILTIN} SOURCES cjkcodecs/_codecs_tw.c) add_python_extension(_collections ${WIN32_BUILTIN} ${PY3_BUILTIN} SOURCES _collectionsmodule.c) # Container types add_python_extension(cPickle ${WIN32_BUILTIN} REQUIRES IS_PY2 SOURCES cPickle.c) -set(crypt2_NAME crypt) -set(crypt2_SOURCES cryptmodule.c) -set(crypt3_NAME _crypt) -set(crypt3_SOURCES _cryptmodule.c) -add_python_extension(${crypt${PY_VERSION_MAJOR}_NAME} REQUIRES HAVE_LIBCRYPT SOURCES ${crypt${PY_VERSION_MAJOR}_SOURCES} LIBRARIES ${HAVE_LIBCRYPT}) +if(PY_VERSION VERSION_LESS "3.13") + set(crypt2_NAME crypt) + set(crypt2_SOURCES cryptmodule.c) + set(crypt3_NAME _crypt) + set(crypt3_SOURCES _cryptmodule.c) + add_python_extension(${crypt${PY_VERSION_MAJOR}_NAME} REQUIRES HAVE_LIBCRYPT SOURCES ${crypt${PY_VERSION_MAJOR}_SOURCES} LIBRARIES ${HAVE_LIBCRYPT}) +endif() add_python_extension(cStringIO ${WIN32_BUILTIN} REQUIRES IS_PY2 SOURCES cStringIO.c) add_python_extension(_csv ${WIN32_BUILTIN} SOURCES _csv.c) add_python_extension(_ctypes_test NEVER_BUILTIN REQUIRES HAVE_LIBM SOURCES _ctypes/_ctypes_test.c LIBRARIES ${M_LIBRARIES}) @@ -85,40 +93,51 @@ add_python_extension(strop ${WIN32_BUILTIN} REQUIRES IS_PY2 SOURCES stropmodule. add_python_extension(_struct ${WIN32_BUILTIN} SOURCES _struct.c) set(testcapi_SOURCES _testcapimodule.c) if(PY_VERSION VERSION_GREATER_EQUAL "3.12") - list(APPEND testcapi_SOURCES - _testcapi/abstract.c - _testcapi/buffer.c - _testcapi/bytearray.c - _testcapi/bytes.c - _testcapi/code.c - _testcapi/codec.c - _testcapi/complex.c - _testcapi/datetime.c - _testcapi/dict.c - _testcapi/docstring.c - _testcapi/exceptions.c - _testcapi/file.c - _testcapi/float.c - _testcapi/gc.c - _testcapi/getargs.c - _testcapi/heaptype.c - _testcapi/heaptype_relative.c - _testcapi/immortal.c - _testcapi/list.c - _testcapi/long.c - _testcapi/mem.c - _testcapi/numbers.c - _testcapi/pyos.c - _testcapi/pytime.c - _testcapi/set.c - _testcapi/structmember.c - _testcapi/sys.c - _testcapi/tuple.c - _testcapi/unicode.c - _testcapi/vectorcall.c - _testcapi/vectorcall_limited.c - _testcapi/watchers.c - ) + if(PY_VERSION VERSION_LESS "3.13") + list(APPEND testcapi_SOURCES + _testcapi/bytearray.c + _testcapi/heaptype_relative.c + _testcapi/pyos.c + _testcapi/pytime.c + _testcapi/sys.c + _testcapi/vectorcall_limited.c + ) + else() + list(APPEND testcapi_SOURCES + _testcapi/hash.c + _testcapi/pyatomic.c + _testcapi/run.c + _testcapi/time.c + ) + endif() + list(APPEND testcapi_SOURCES + _testcapi/abstract.c + _testcapi/buffer.c + _testcapi/bytes.c + _testcapi/code.c + _testcapi/codec.c + _testcapi/complex.c + _testcapi/datetime.c + _testcapi/dict.c + _testcapi/docstring.c + _testcapi/exceptions.c + _testcapi/file.c + _testcapi/float.c + _testcapi/gc.c + _testcapi/getargs.c + _testcapi/heaptype.c + _testcapi/immortal.c + _testcapi/list.c + _testcapi/long.c + _testcapi/mem.c + _testcapi/numbers.c + _testcapi/set.c + _testcapi/structmember.c + _testcapi/tuple.c + _testcapi/unicode.c + _testcapi/vectorcall.c + _testcapi/watchers.c + ) endif() if(PY_VERSION VERSION_LESS "3.12" OR UNIX) # This module seems to build incorrectly for Python 3.12 Windows @@ -208,7 +227,16 @@ endif() # Python 3.8 if(PY_VERSION VERSION_GREATER_EQUAL "3.8") - add_python_extension(_testinternalcapi SOURCES _testinternalcapi.c DEFINITIONS "PY3_DLLNAME=\"python3$<$:_d>\"") + set(_testinternalcapi_SOURCES _testinternalcapi.c) + if(PY_VERSION VERSION_GREATER_EQUAL "3.13") + list(APPEND _testinternalcapi_SOURCES + _testinternalcapi/pytime.c + _testinternalcapi/set.c + _testinternalcapi/test_lock.c + _testinternalcapi/test_critical_sections.c + ) + endif() + add_python_extension(_testinternalcapi SOURCES ${_testinternalcapi_SOURCES} DEFINITIONS "PY3_DLLNAME=\"python3$<$:_d>\"") endif() # Python 3.9 @@ -237,17 +265,21 @@ if(TIRPC_LIBRARY AND TIRPC_RPC_INCLUDE_PATH) list(APPEND nis_LIBRARIES ${TIRPC_STATIC_LIBRARIES}) endif() endif() -add_python_extension(nis - REQUIRES ${nis_REQUIRES} - SOURCES nismodule.c - LIBRARIES ${nis_LIBRARIES} - INCLUDEDIRS ${nis_INCLUDEDIRS} -) +if(PY_VERSION VERSION_LESS "3.13") + add_python_extension(nis + REQUIRES ${nis_REQUIRES} + SOURCES nismodule.c + LIBRARIES ${nis_LIBRARIES} + INCLUDEDIRS ${nis_INCLUDEDIRS} + ) +endif() add_python_extension(posix REQUIRES UNIX ALWAYS_BUILTIN SOURCES posixmodule.c DEFINITIONS Py_BUILD_CORE) add_python_extension(pwd REQUIRES UNIX BUILTIN SOURCES pwdmodule.c) # this is needed to find out the user's home dir if $HOME is not set add_python_extension(resource REQUIRES UNIX SOURCES resource.c) -add_python_extension(spwd REQUIRES UNIX HAVE_GETSPNAM HAVE_GETSPENT SOURCES spwdmodule.c) +if(PY_VERSION VERSION_LESS "3.13") + add_python_extension(spwd REQUIRES UNIX HAVE_GETSPNAM HAVE_GETSPENT SOURCES spwdmodule.c) +endif() add_python_extension(syslog REQUIRES UNIX SOURCES syslogmodule.c) add_python_extension(termios REQUIRES UNIX SOURCES termios.c) @@ -266,7 +298,9 @@ add_python_extension(_scproxy # Linux-only extensions add_python_extension(linuxaudiodev REQUIRES LINUX IS_PY2 NOT_COSMOPOLITAN SOURCES linuxaudiodev.c) -add_python_extension(ossaudiodev REQUIRES LINUX NOT_COSMOPOLITAN SOURCES ossaudiodev.c) +if(PY_VERSION VERSION_LESS "3.13") + add_python_extension(ossaudiodev REQUIRES LINUX NOT_COSMOPOLITAN SOURCES ossaudiodev.c) +endif() # Python 3.8: UNIX-only extensions if(PY_VERSION VERSION_GREATER_EQUAL "3.8") @@ -278,11 +312,13 @@ if(PY_VERSION VERSION_GREATER_EQUAL "3.8") endif() # Windows-only extensions -add_python_extension(_msi - REQUIRES WIN32 - SOURCES ${SRC_DIR}/PC/_msi.c - LIBRARIES cabinet.lib msi.lib rpcrt4.lib -) +if(PY_VERSION VERSION_LESS "3.13") + add_python_extension(_msi + REQUIRES WIN32 + SOURCES ${SRC_DIR}/PC/_msi.c + LIBRARIES cabinet.lib msi.lib rpcrt4.lib + ) +endif() add_python_extension(msvcrt REQUIRES MSVC BUILTIN SOURCES ${SRC_DIR}/PC/msvcrtmodule.c) add_python_extension(nt REQUIRES WIN32 ALWAYS_BUILTIN SOURCES posixmodule.c) add_python_extension(_subprocess REQUIRES WIN32 IS_PY2 BUILTIN SOURCES ${SRC_DIR}/PC/_subprocess.c) diff --git a/cmake/libpython/CMakeLists.txt b/cmake/libpython/CMakeLists.txt index fc6b22b..b4a523e 100644 --- a/cmake/libpython/CMakeLists.txt +++ b/cmake/libpython/CMakeLists.txt @@ -2,6 +2,10 @@ add_definitions(-DPy_BUILD_CORE) add_definitions(-DPy_BUILD_CORE_BUILTIN) add_definitions(-DNDEBUG) +if(WITH_FREE_THREADING) + add_definitions(-DPy_GIL_DISABLED) +endif() + set(MODULE_SOURCES # Equivalent to MODULE_OBJS in Makefile.pre ${SRC_DIR}/Modules/gcmodule.c ${SRC_DIR}/Modules/main.c @@ -85,8 +89,23 @@ if(PY_VERSION VERSION_GREATER_EQUAL "3.10") ${SRC_DIR}/Parser/pegen.c ${SRC_DIR}/Parser/string_parser.c ${SRC_DIR}/Parser/token.c - ${SRC_DIR}/Parser/tokenizer.c ) + if(PY_VERSION VERSION_GREATER_EQUAL "3.13") + list(APPEND PARSER_COMMON_SOURCES + ${SRC_DIR}/Parser/lexer/buffer.c + ${SRC_DIR}/Parser/lexer/lexer.c + ${SRC_DIR}/Parser/lexer/state.c + ${SRC_DIR}/Parser/tokenizer/string_tokenizer.c + ${SRC_DIR}/Parser/tokenizer/readline_tokenizer.c + ${SRC_DIR}/Parser/tokenizer/utf8_tokenizer.c + ${SRC_DIR}/Parser/tokenizer/file_tokenizer.c + ${SRC_DIR}/Parser/tokenizer/helpers.c + ) + else() + list(APPEND PARSER_COMMON_SOURCES + ${SRC_DIR}/Parser/tokenizer.c + ) + endif() if(PY_VERSION VERSION_GREATER_EQUAL "3.11") list(APPEND PARSER_COMMON_SOURCES ${SRC_DIR}/Parser/action_helpers.c @@ -206,8 +225,12 @@ set(OBJECT_COMMON_SOURCES # Equivalent to OBJECT_OBJS in Makefile.pre ${SRC_DIR}/Objects/weakrefobject.c ) if(PY_VERSION VERSION_GREATER_EQUAL "3.8") + if(PY_VERSION VERSION_LESS "3.13") + list(APPEND OBJECT_COMMON_SOURCES + ${SRC_DIR}/Objects/interpreteridobject.c + ) + endif() list(APPEND OBJECT_COMMON_SOURCES - ${SRC_DIR}/Objects/interpreteridobject.c ${SRC_DIR}/Objects/picklebufobject.c ) endif() @@ -221,6 +244,13 @@ if(PY_VERSION VERSION_GREATER_EQUAL "3.10") ${SRC_DIR}/Objects/unionobject.c ) endif() +if(PY_VERSION VERSION_GREATER_EQUAL "3.13") + if(WIN32) + # mimalloc is enabled for Windows + # TODO: enable this for other platforms via switches + include_directories(${SRC_DIR}/Include/internal/mimalloc) + endif() +endif() if(CMAKE_C_COMPILER_ID MATCHES GNU) foreach(filename class complex float int method string type unicode weakref) @@ -381,6 +411,21 @@ if(PY_VERSION VERSION_GREATER_EQUAL "3.12") ${SRC_DIR}/Python/tracemalloc.c ) endif() +if(PY_VERSION VERSION_GREATER_EQUAL "3.13") + list(APPEND PYTHON_COMMON_SOURCES + ${SRC_DIR}/Python/critical_section.c + ${SRC_DIR}/Python/crossinterp.c + ${SRC_DIR}/Python/gc.c + ${SRC_DIR}/Python/gc_free_threading.c + ${SRC_DIR}/Python/gc_gil.c + ${SRC_DIR}/Python/instruction_sequence.c + ${SRC_DIR}/Python/interpconfig.c + ${SRC_DIR}/Python/lock.c + ${SRC_DIR}/Python/object_stack.c + ${SRC_DIR}/Python/parking_lot.c + ${SRC_DIR}/Python/qsbr.c + ) +endif() if(UNIX) list(APPEND PYTHON_COMMON_SOURCES @@ -544,10 +589,10 @@ endif() set(LIBPYTHON_FROZEN_SOURCES ) set(LIBPYTHON_DEEPFREEZE_SOURCES ) -if(PY_VERSION VERSION_GREATER_EQUAL "3.11") - set(LIBPYTHON_DEEPFREEZE_SOURCES - ${SRC_DIR}/Python/deepfreeze/deepfreeze.c - ) +if(PY_VERSION VERSION_GREATER_EQUAL "3.11" AND PY_VERSION VERSION_LESS "3.13") + set(LIBPYTHON_DEEPFREEZE_SOURCES + ${SRC_DIR}/Python/deepfreeze/deepfreeze.c + ) endif() if(IS_PY3) @@ -631,218 +676,220 @@ if(PY_VERSION VERSION_LESS "3.11") endif() else() set(LIBPYTHON_FROZEN_SOURCES - ${SRC_DIR}/Python/frozen_modules/importlib._bootstrap.h - ${SRC_DIR}/Python/frozen_modules/importlib._bootstrap_external.h - ${SRC_DIR}/Python/frozen_modules/zipimport.h - ${SRC_DIR}/Python/frozen_modules/abc.h - ${SRC_DIR}/Python/frozen_modules/codecs.h - ${SRC_DIR}/Python/frozen_modules/io.h - ${SRC_DIR}/Python/frozen_modules/_collections_abc.h - ${SRC_DIR}/Python/frozen_modules/_sitebuiltins.h - ${SRC_DIR}/Python/frozen_modules/genericpath.h - ${SRC_DIR}/Python/frozen_modules/ntpath.h - ${SRC_DIR}/Python/frozen_modules/posixpath.h - ${SRC_DIR}/Python/frozen_modules/os.h - ${SRC_DIR}/Python/frozen_modules/site.h - ${SRC_DIR}/Python/frozen_modules/stat.h - ${SRC_DIR}/Python/frozen_modules/importlib.util.h - ${SRC_DIR}/Python/frozen_modules/importlib.machinery.h - ${SRC_DIR}/Python/frozen_modules/runpy.h - ${SRC_DIR}/Python/frozen_modules/__hello__.h - ${SRC_DIR}/Python/frozen_modules/__phello__.h - ${SRC_DIR}/Python/frozen_modules/__phello__.ham.h - ${SRC_DIR}/Python/frozen_modules/__phello__.ham.eggs.h - ${SRC_DIR}/Python/frozen_modules/__phello__.spam.h - ${SRC_DIR}/Python/frozen_modules/frozen_only.h - ${SRC_DIR}/Python/frozen_modules/getpath.h - ) - add_custom_command( - OUTPUT ${LIBPYTHON_FROZEN_SOURCES} - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - importlib._bootstrap - ${SRC_DIR}/Lib/importlib/_bootstrap.py ${SRC_DIR}/Python/frozen_modules/importlib._bootstrap.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - importlib._bootstrap_external - ${SRC_DIR}/Lib/importlib/_bootstrap_external.py ${SRC_DIR}/Python/frozen_modules/importlib._bootstrap_external.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - zipimport - ${SRC_DIR}/Lib/zipimport.py ${SRC_DIR}/Python/frozen_modules/zipimport.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - abc - ${SRC_DIR}/Lib/abc.py ${SRC_DIR}/Python/frozen_modules/abc.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - codecs - ${SRC_DIR}/Lib/codecs.py ${SRC_DIR}/Python/frozen_modules/codecs.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - io - ${SRC_DIR}/Lib/io.py ${SRC_DIR}/Python/frozen_modules/io.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - _collections_abc - ${SRC_DIR}/Lib/_collections_abc.py ${SRC_DIR}/Python/frozen_modules/_collections_abc.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - _sitebuiltins - ${SRC_DIR}/Lib/_sitebuiltins.py ${SRC_DIR}/Python/frozen_modules/_sitebuiltins.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - genericpath - ${SRC_DIR}/Lib/genericpath.py ${SRC_DIR}/Python/frozen_modules/genericpath.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - ntpath - ${SRC_DIR}/Lib/ntpath.py ${SRC_DIR}/Python/frozen_modules/ntpath.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - posixpath - ${SRC_DIR}/Lib/posixpath.py ${SRC_DIR}/Python/frozen_modules/posixpath.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - os - ${SRC_DIR}/Lib/os.py ${SRC_DIR}/Python/frozen_modules/os.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - site - ${SRC_DIR}/Lib/site.py ${SRC_DIR}/Python/frozen_modules/site.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - stat - ${SRC_DIR}/Lib/stat.py ${SRC_DIR}/Python/frozen_modules/stat.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - importlib.util - ${SRC_DIR}/Lib/importlib/util.py ${SRC_DIR}/Python/frozen_modules/importlib.util.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - importlib.machinery - ${SRC_DIR}/Lib/importlib/machinery.py ${SRC_DIR}/Python/frozen_modules/importlib.machinery.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - runpy - ${SRC_DIR}/Lib/runpy.py ${SRC_DIR}/Python/frozen_modules/runpy.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - __hello__ - ${SRC_DIR}/Lib/__hello__.py ${SRC_DIR}/Python/frozen_modules/__hello__.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - __phello__ - ${SRC_DIR}/Lib/__phello__/__init__.py ${SRC_DIR}/Python/frozen_modules/__phello__.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - __phello__.ham - ${SRC_DIR}/Lib/__phello__/ham/__init__.py ${SRC_DIR}/Python/frozen_modules/__phello__.ham.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - __phello__.ham.eggs - ${SRC_DIR}/Lib/__phello__/ham/eggs.py ${SRC_DIR}/Python/frozen_modules/__phello__.ham.eggs.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - __phello__.spam - ${SRC_DIR}/Lib/__phello__/spam.py ${SRC_DIR}/Python/frozen_modules/__phello__.spam.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - frozen_only - ${SRC_DIR}/Tools/freeze/flag.py ${SRC_DIR}/Python/frozen_modules/frozen_only.h - COMMAND - ${CMAKE_CROSSCOMPILING_EMULATOR} $ - getpath - ${SRC_DIR}/Modules/getpath.py ${SRC_DIR}/Python/frozen_modules/getpath.h - DEPENDS - _freeze_importlib - ${SRC_DIR}/Lib/importlib/_bootstrap.py - ${SRC_DIR}/Lib/importlib/_bootstrap_external.py - ${SRC_DIR}/Lib/zipimport.py - ${SRC_DIR}/Lib/abc.py - ${SRC_DIR}/Lib/codecs.py - ${SRC_DIR}/Lib/io.py - ${SRC_DIR}/Lib/_collections_abc.py - ${SRC_DIR}/Lib/_sitebuiltins.py - ${SRC_DIR}/Lib/genericpath.py - ${SRC_DIR}/Lib/ntpath.py - ${SRC_DIR}/Lib/posixpath.py - ${SRC_DIR}/Lib/os.py - ${SRC_DIR}/Lib/site.py - ${SRC_DIR}/Lib/stat.py - ${SRC_DIR}/Lib/importlib/util.py - ${SRC_DIR}/Lib/importlib/machinery.py - ${SRC_DIR}/Lib/runpy.py - ${SRC_DIR}/Lib/__hello__.py - ${SRC_DIR}/Lib/__phello__/__init__.py - ${SRC_DIR}/Lib/__phello__/ham/__init__.py - ${SRC_DIR}/Lib/__phello__/ham/eggs.py - ${SRC_DIR}/Lib/__phello__/spam.py - ${SRC_DIR}/Tools/freeze/flag.py - ${SRC_DIR}/Modules/getpath.py + ) + add_custom_command( + OUTPUT ${LIBPYTHON_FROZEN_SOURCES} + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + importlib._bootstrap + ${SRC_DIR}/Lib/importlib/_bootstrap.py + ${SRC_DIR}/Python/frozen_modules/importlib._bootstrap.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + importlib._bootstrap_external + ${SRC_DIR}/Lib/importlib/_bootstrap_external.py + ${SRC_DIR}/Python/frozen_modules/importlib._bootstrap_external.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + zipimport + ${SRC_DIR}/Lib/zipimport.py + ${SRC_DIR}/Python/frozen_modules/zipimport.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + abc + ${SRC_DIR}/Lib/abc.py + ${SRC_DIR}/Python/frozen_modules/abc.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + codecs + ${SRC_DIR}/Lib/codecs.py + ${SRC_DIR}/Python/frozen_modules/codecs.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + io + ${SRC_DIR}/Lib/io.py + ${SRC_DIR}/Python/frozen_modules/io.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + _collections_abc + ${SRC_DIR}/Lib/_collections_abc.py + ${SRC_DIR}/Python/frozen_modules/_collections_abc.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + _sitebuiltins + ${SRC_DIR}/Lib/_sitebuiltins.py + ${SRC_DIR}/Python/frozen_modules/_sitebuiltins.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + genericpath + ${SRC_DIR}/Lib/genericpath.py + ${SRC_DIR}/Python/frozen_modules/genericpath.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + ntpath + ${SRC_DIR}/Lib/ntpath.py + ${SRC_DIR}/Python/frozen_modules/ntpath.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + posixpath + ${SRC_DIR}/Lib/posixpath.py + ${SRC_DIR}/Python/frozen_modules/posixpath.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + os + ${SRC_DIR}/Lib/os.py + ${SRC_DIR}/Python/frozen_modules/os.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + site + ${SRC_DIR}/Lib/site.py + ${SRC_DIR}/Python/frozen_modules/site.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + stat + ${SRC_DIR}/Lib/stat.py + ${SRC_DIR}/Python/frozen_modules/stat.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + importlib.util + ${SRC_DIR}/Lib/importlib/util.py + ${SRC_DIR}/Python/frozen_modules/importlib.util.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + importlib.machinery + ${SRC_DIR}/Lib/importlib/machinery.py + ${SRC_DIR}/Python/frozen_modules/importlib.machinery.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + runpy + ${SRC_DIR}/Lib/runpy.py + ${SRC_DIR}/Python/frozen_modules/runpy.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + __hello__ + ${SRC_DIR}/Lib/__hello__.py + ${SRC_DIR}/Python/frozen_modules/__hello__.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + __phello__ + ${SRC_DIR}/Lib/__phello__/__init__.py + ${SRC_DIR}/Python/frozen_modules/__phello__.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + __phello__.ham + ${SRC_DIR}/Lib/__phello__/ham/__init__.py + ${SRC_DIR}/Python/frozen_modules/__phello__.ham.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + __phello__.ham.eggs + ${SRC_DIR}/Lib/__phello__/ham/eggs.py + ${SRC_DIR}/Python/frozen_modules/__phello__.ham.eggs.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + __phello__.spam + ${SRC_DIR}/Lib/__phello__/spam.py + ${SRC_DIR}/Python/frozen_modules/__phello__.spam.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + frozen_only + ${SRC_DIR}/Tools/freeze/flag.py + ${SRC_DIR}/Python/frozen_modules/frozen_only.h + COMMAND + ${CMAKE_CROSSCOMPILING_EMULATOR} $ + getpath + ${SRC_DIR}/Modules/getpath.py + ${SRC_DIR}/Python/frozen_modules/getpath.h + DEPENDS + _freeze_importlib + ${SRC_DIR}/Lib/importlib/_bootstrap.py + ${SRC_DIR}/Lib/importlib/_bootstrap_external.py + ${SRC_DIR}/Lib/zipimport.py + ${SRC_DIR}/Lib/abc.py + ${SRC_DIR}/Lib/codecs.py + ${SRC_DIR}/Lib/io.py + ${SRC_DIR}/Lib/_collections_abc.py + ${SRC_DIR}/Lib/_sitebuiltins.py + ${SRC_DIR}/Lib/genericpath.py + ${SRC_DIR}/Lib/ntpath.py + ${SRC_DIR}/Lib/posixpath.py + ${SRC_DIR}/Lib/os.py + ${SRC_DIR}/Lib/site.py + ${SRC_DIR}/Lib/stat.py + ${SRC_DIR}/Lib/importlib/util.py + ${SRC_DIR}/Lib/importlib/machinery.py + ${SRC_DIR}/Lib/runpy.py + ${SRC_DIR}/Lib/__hello__.py + ${SRC_DIR}/Lib/__phello__/__init__.py + ${SRC_DIR}/Lib/__phello__/ham/__init__.py + ${SRC_DIR}/Lib/__phello__/ham/eggs.py + ${SRC_DIR}/Lib/__phello__/spam.py + ${SRC_DIR}/Tools/freeze/flag.py + ${SRC_DIR}/Modules/getpath.py ) - if(PY_VERSION VERSION_GREATER_EQUAL "3.12") - set(DEEPFREEZE_PY ${SRC_DIR}/Tools/build/deepfreeze.py) - else() - set(DEEPFREEZE_PY ${SRC_DIR}/Tools/scripts/deepfreeze.py) - endif() - add_custom_command( - OUTPUT ${LIBPYTHON_DEEPFREEZE_SOURCES} - COMMAND - ${Python3_EXECUTABLE} ${DEEPFREEZE_PY} - "${SRC_DIR}/Python/frozen_modules/importlib._bootstrap.h:importlib._bootstrap" - "${SRC_DIR}/Python/frozen_modules/importlib._bootstrap_external.h:importlib._bootstrap_external" - "${SRC_DIR}/Python/frozen_modules/zipimport.h:zipimport" - "${SRC_DIR}/Python/frozen_modules/abc.h:abc" - "${SRC_DIR}/Python/frozen_modules/codecs.h:codecs" - "${SRC_DIR}/Python/frozen_modules/io.h:io" - "${SRC_DIR}/Python/frozen_modules/_collections_abc.h:_collections_abc" - "${SRC_DIR}/Python/frozen_modules/_sitebuiltins.h:_sitebuiltins" - "${SRC_DIR}/Python/frozen_modules/genericpath.h:genericpath" - "${SRC_DIR}/Python/frozen_modules/ntpath.h:ntpath" - "${SRC_DIR}/Python/frozen_modules/posixpath.h:posixpath" - "${SRC_DIR}/Python/frozen_modules/os.h:os" - "${SRC_DIR}/Python/frozen_modules/site.h:site" - "${SRC_DIR}/Python/frozen_modules/stat.h:stat" - "${SRC_DIR}/Python/frozen_modules/importlib.util.h:importlib.util" - "${SRC_DIR}/Python/frozen_modules/importlib.machinery.h:importlib.machinery" - "${SRC_DIR}/Python/frozen_modules/runpy.h:runpy" - "${SRC_DIR}/Python/frozen_modules/__hello__.h:__hello__" - "${SRC_DIR}/Python/frozen_modules/__phello__.h:__phello__" - "${SRC_DIR}/Python/frozen_modules/__phello__.ham.h:__phello__.ham" - "${SRC_DIR}/Python/frozen_modules/__phello__.ham.eggs.h:__phello__.ham.eggs" - "${SRC_DIR}/Python/frozen_modules/__phello__.spam.h:__phello__.spam" - "${SRC_DIR}/Python/frozen_modules/frozen_only.h:frozen_only" - "-o" "${LIBPYTHON_DEEPFREEZE_SOURCES}" - DEPENDS - ${DEEPFREEZE_PY} - ${LIBPYTHON_FROZEN_SOURCES} - ) + if(PY_VERSION VERSION_LESS "3.13") + if(PY_VERSION VERSION_EQUAL "3.12") + set(DEEPFREEZE_PY ${SRC_DIR}/Tools/build/deepfreeze.py) + else() + set(DEEPFREEZE_PY ${SRC_DIR}/Tools/scripts/deepfreeze.py) + endif() + add_custom_command( + OUTPUT ${LIBPYTHON_DEEPFREEZE_SOURCES} + COMMAND + ${Python3_EXECUTABLE} ${DEEPFREEZE_PY} + "${SRC_DIR}/Python/frozen_modules/importlib._bootstrap.h:importlib._bootstrap" + "${SRC_DIR}/Python/frozen_modules/importlib._bootstrap_external.h:importlib._bootstrap_external" + "${SRC_DIR}/Python/frozen_modules/zipimport.h:zipimport" + "${SRC_DIR}/Python/frozen_modules/abc.h:abc" + "${SRC_DIR}/Python/frozen_modules/codecs.h:codecs" + "${SRC_DIR}/Python/frozen_modules/io.h:io" + "${SRC_DIR}/Python/frozen_modules/_collections_abc.h:_collections_abc" + "${SRC_DIR}/Python/frozen_modules/_sitebuiltins.h:_sitebuiltins" + "${SRC_DIR}/Python/frozen_modules/genericpath.h:genericpath" + "${SRC_DIR}/Python/frozen_modules/ntpath.h:ntpath" + "${SRC_DIR}/Python/frozen_modules/posixpath.h:posixpath" + "${SRC_DIR}/Python/frozen_modules/os.h:os" + "${SRC_DIR}/Python/frozen_modules/site.h:site" + "${SRC_DIR}/Python/frozen_modules/stat.h:stat" + "${SRC_DIR}/Python/frozen_modules/importlib.util.h:importlib.util" + "${SRC_DIR}/Python/frozen_modules/importlib.machinery.h:importlib.machinery" + "${SRC_DIR}/Python/frozen_modules/runpy.h:runpy" + "${SRC_DIR}/Python/frozen_modules/__hello__.h:__hello__" + "${SRC_DIR}/Python/frozen_modules/__phello__.h:__phello__" + "${SRC_DIR}/Python/frozen_modules/__phello__.ham.h:__phello__.ham" + "${SRC_DIR}/Python/frozen_modules/__phello__.ham.eggs.h:__phello__.ham.eggs" + "${SRC_DIR}/Python/frozen_modules/__phello__.spam.h:__phello__.spam" + "${SRC_DIR}/Python/frozen_modules/frozen_only.h:frozen_only" + "-o" "${LIBPYTHON_DEEPFREEZE_SOURCES}" + DEPENDS + ${DEEPFREEZE_PY} + ${LIBPYTHON_FROZEN_SOURCES} + ) + endif() endif() # This is a convenience target allowing to regenerate @@ -938,12 +985,20 @@ elseif(UNIX) ) endif() if(PY_VERSION VERSION_GREATER_EQUAL "3.12") + if(PY_VERSION VERSION_LESS "3.13") + list(APPEND LIBPYTHON_SOURCES + ${SRC_DIR}/Modules/_xxinterpchannelsmodule.c + ) + else() + list(APPEND LIBPYTHON_SOURCES + ${SRC_DIR}/Modules/_interpretersmodule.c + ) + endif() list(APPEND LIBPYTHON_SOURCES ${SRC_DIR}/Modules/_hacl/Hacl_Hash_MD5.c ${SRC_DIR}/Modules/_hacl/Hacl_Hash_SHA1.c ${SRC_DIR}/Modules/_hacl/Hacl_Hash_SHA2.c ${SRC_DIR}/Modules/_hacl/Hacl_Hash_SHA3.c - ${SRC_DIR}/Modules/_xxinterpchannelsmodule.c ${SRC_DIR}/Modules/md5module.c ${SRC_DIR}/Modules/sha1module.c ${SRC_DIR}/Modules/sha2module.c diff --git a/cmake/python/CMakeLists.txt b/cmake/python/CMakeLists.txt index 903390f..63ae3ac 100644 --- a/cmake/python/CMakeLists.txt +++ b/cmake/python/CMakeLists.txt @@ -12,6 +12,9 @@ set_property( ) target_compile_definitions(python PRIVATE Py_BUILD_CORE) add_definitions(-DPy_BUILD_CORE) +if(WITH_FREE_THREADING) + add_definitions(-DPy_GIL_DISABLED) +endif() # Link against the shared libpython if it was built, otherwise use the static # version. diff --git a/cmake/tools/CMakeLists.txt b/cmake/tools/CMakeLists.txt index f0b0350..81cfe54 100644 --- a/cmake/tools/CMakeLists.txt +++ b/cmake/tools/CMakeLists.txt @@ -1,6 +1,6 @@ set(files) -if(PY_VERSION VERSION_GREATER_EQUAL "3.6") +if(PY_VERSION VERSION_GREATER_EQUAL "3.6" AND PY_VERSION VERSION_LESS "3.13") list(APPEND files Tools/scripts/run_tests.py ) diff --git a/patches/3.12/06-solaris-fcntlmodule.patch b/patches/3.12/06-solaris-fcntlmodule.patch index f0c2cff..269a636 100644 --- a/patches/3.12/06-solaris-fcntlmodule.patch +++ b/patches/3.12/06-solaris-fcntlmodule.patch @@ -1,20 +1,20 @@ -diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c -index 2bca40213c6..59dab31bc40 100644 ---- a/Modules/fcntlmodule.c -+++ b/Modules/fcntlmodule.c -@@ -628,6 +628,15 @@ all_ins(PyObject* m) - #endif - - #ifdef HAVE_STROPTS_H -+ -+#if defined(sun) || defined(__sun) -+ #ifndef STR -+ /* for some reason, the preprocessor does not resolve this symbol */ -+ /* from /usr/include/sys/stropts.h on Solaris 11 */ -+ #define STR ('S'<<8) -+ #endif -+#endif -+ - /* Unix 98 guarantees that these are in stropts.h. */ - if (PyModule_AddIntMacro(m, I_PUSH)) return -1; - if (PyModule_AddIntMacro(m, I_POP)) return -1; +diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c +index 2bca40213c6..59dab31bc40 100644 +--- a/Modules/fcntlmodule.c ++++ b/Modules/fcntlmodule.c +@@ -628,6 +628,15 @@ all_ins(PyObject* m) + #endif + + #ifdef HAVE_STROPTS_H ++ ++#if defined(sun) || defined(__sun) ++ #ifndef STR ++ /* for some reason, the preprocessor does not resolve this symbol */ ++ /* from /usr/include/sys/stropts.h on Solaris 11 */ ++ #define STR ('S'<<8) ++ #endif ++#endif ++ + /* Unix 98 guarantees that these are in stropts.h. */ + if (PyModule_AddIntMacro(m, I_PUSH)) return -1; + if (PyModule_AddIntMacro(m, I_POP)) return -1; diff --git a/patches/3.13/01-PC-config_minimal.patch b/patches/3.13/01-PC-config_minimal.patch new file mode 100644 index 0000000..11f3272 --- /dev/null +++ b/patches/3.13/01-PC-config_minimal.patch @@ -0,0 +1,17 @@ +diff --git a/PC/config_minimal.c b/PC/config_minimal.c +index 928a4efd32..e541204c79 100644 +--- a/PC/config_minimal.c ++++ b/PC/config_minimal.c +@@ -8,6 +8,12 @@ + /* Define extern variables omitted from minimal builds */ + void *PyWin_DLLhModule = NULL; + ++#if !defined(MS_DLL_ID) ++# error MS_DLL_ID must be defined ++#endif ++ ++const char *PyWin_DLLVersionString = MS_DLL_ID; ++ + + extern PyObject* PyInit_faulthandler(void); + extern PyObject* PyInit__tracemalloc(void); diff --git a/patches/3.13/02-freebsd-errno.patch b/patches/3.13/02-freebsd-errno.patch new file mode 100644 index 0000000..a40dda1 --- /dev/null +++ b/patches/3.13/02-freebsd-errno.patch @@ -0,0 +1,43 @@ +diff --git a/Include/Python.h b/Include/Python.h +index fb2d32d7110..4b8bf901bdf 100644 +--- a/Include/Python.h ++++ b/Include/Python.h +@@ -33,7 +33,15 @@ + // The and headers are not included by limited C API + // version 3.13 and newer. + #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 ++# if defined(__FreeBSD__) && defined(_POSIX_SOURCE) ++# define _WANT_POSIX_SOURCE ++# undef _POSIX_SOURCE ++# endif + # include // errno ++# if defined(_WANT_POSIX_SOURCE) ++# define _POSIX_SOURCE ++# undef _WANT_POSIX_SOURCE ++# endif + # include // FILE* + # include // getenv() + # include // memcpy() +diff --git a/Modules/errnomodule.c b/Modules/errnomodule.c +index 3f96f2f846d..db1a2d23a74 100644 +--- a/Modules/errnomodule.c ++++ b/Modules/errnomodule.c +@@ -6,6 +6,18 @@ + # define Py_LIMITED_API 0x030d0000 + #endif + ++#if defined(__FreeBSD__) ++# if defined(_POSIX_SOURCE) ++# define _WANT_POSIX_SOURCE ++# undef _POSIX_SOURCE ++# endif ++# include ++# if defined(_WANT_POSIX_SOURCE) ++# define _POSIX_SOURCE ++# undef _WANT_POSIX_SOURCE ++# endif ++#endif ++ + #include "Python.h" + #include // EPIPE + diff --git a/patches/3.13/03-cosmo-sys-random.patch b/patches/3.13/03-cosmo-sys-random.patch new file mode 100644 index 0000000..9c2c02c --- /dev/null +++ b/patches/3.13/03-cosmo-sys-random.patch @@ -0,0 +1,14 @@ +diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c +index bd2a7fbf53..ed39ee6615 100644 +--- a/Modules/posixmodule.c ++++ b/Modules/posixmodule.c +@@ -321,6 +321,9 @@ corresponding Unix manual entries for more information on calls."); + #ifdef HAVE_LINUX_RANDOM_H + # include + #endif ++#if defined(HAVE_SYS_RANDOM_H) && defined(__COSMOPOLITAN__) ++# include ++#endif + #ifdef HAVE_GETRANDOM_SYSCALL + # include + #endif diff --git a/patches/3.13/04-getpath_noop-missing-stub.patch b/patches/3.13/04-getpath_noop-missing-stub.patch new file mode 100644 index 0000000..3a0f101 --- /dev/null +++ b/patches/3.13/04-getpath_noop-missing-stub.patch @@ -0,0 +1,14 @@ +diff --git a/Modules/getpath_noop.c b/Modules/getpath_noop.c +index c10e41d07f..16d75834c3 100644 +--- a/Modules/getpath_noop.c ++++ b/Modules/getpath_noop.c +@@ -8,3 +8,9 @@ _PyConfig_InitPathConfig(PyConfig *config, int compute_path_config) + { + return PyStatus_Error("path configuration is unsupported"); + } ++ ++PyObject * ++_Py_Get_Getpath_CodeObject(void) ++{ ++ return NULL; ++} diff --git a/patches/3.13/05-solaris-fcntlmodule.patch b/patches/3.13/05-solaris-fcntlmodule.patch new file mode 100644 index 0000000..269a636 --- /dev/null +++ b/patches/3.13/05-solaris-fcntlmodule.patch @@ -0,0 +1,20 @@ +diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c +index 2bca40213c6..59dab31bc40 100644 +--- a/Modules/fcntlmodule.c ++++ b/Modules/fcntlmodule.c +@@ -628,6 +628,15 @@ all_ins(PyObject* m) + #endif + + #ifdef HAVE_STROPTS_H ++ ++#if defined(sun) || defined(__sun) ++ #ifndef STR ++ /* for some reason, the preprocessor does not resolve this symbol */ ++ /* from /usr/include/sys/stropts.h on Solaris 11 */ ++ #define STR ('S'<<8) ++ #endif ++#endif ++ + /* Unix 98 guarantees that these are in stropts.h. */ + if (PyModule_AddIntMacro(m, I_PUSH)) return -1; + if (PyModule_AddIntMacro(m, I_POP)) return -1; diff --git a/patches/3.13/06-relative-getpath-h.patch b/patches/3.13/06-relative-getpath-h.patch new file mode 100644 index 0000000..69fe3eb --- /dev/null +++ b/patches/3.13/06-relative-getpath-h.patch @@ -0,0 +1,13 @@ +diff --git a/Modules/getpath.c b/Modules/getpath.c +index d0128b20fae..13a7df16199 100644 +--- a/Modules/getpath.c ++++ b/Modules/getpath.c +@@ -22,7 +22,7 @@ + #endif + + /* Reference the precompiled getpath.py */ +-#include "Python/frozen_modules/getpath.h" ++#include "../Python/frozen_modules/getpath.h" + + #if (!defined(PREFIX) || !defined(EXEC_PREFIX) \ + || !defined(VERSION) || !defined(VPATH) \ diff --git a/patches/3.13/07-testcapimodule-gettimeofday.patch b/patches/3.13/07-testcapimodule-gettimeofday.patch new file mode 100644 index 0000000..a6bdf71 --- /dev/null +++ b/patches/3.13/07-testcapimodule-gettimeofday.patch @@ -0,0 +1,15 @@ +diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c +index 01b6bd89d13..a5a97a1d618 100644 +--- a/Modules/_testcapimodule.c ++++ b/Modules/_testcapimodule.c +@@ -23,6 +23,10 @@ + # include // W_STOPCODE + #endif + ++#ifdef HAVE_SYS_TIME_H ++# include ++#endif ++ + #ifdef bool + # error "The public headers should not include , see gh-48924" + #endif diff --git a/patches/3.13/portable/01-getpath-portable-prefix.patch b/patches/3.13/portable/01-getpath-portable-prefix.patch new file mode 100644 index 0000000..fa5af29 --- /dev/null +++ b/patches/3.13/portable/01-getpath-portable-prefix.patch @@ -0,0 +1,125 @@ +diff --git a/Modules/getpath.c b/Modules/getpath.c +index 5dbe57c950..47b67e4ccb 100644 +--- a/Modules/getpath.c ++++ b/Modules/getpath.c +@@ -9,6 +9,120 @@ + #include + #include + ++ ++#if defined(__linux__) || defined(__APPLE__) ++char _portable_python_path_sep = '/'; ++#else ++char _portable_python_path_sep = '\\'; ++#endif ++ ++static void _portable_python_trim_to_parent_directory(char* path) { ++ char* last_slash = strrchr(path, _portable_python_path_sep); ++ if (last_slash == NULL) { ++ fprintf(stderr, "Invalid path: No parent directory found\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ // Calculate the length of the parent directory excluding the trailing slash ++ size_t parent_dir_length = last_slash - path; ++ path[parent_dir_length] = '\0'; ++} ++ ++#ifdef __linux__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++pthread_mutex_t portable_python_prefix_mutex = PTHREAD_MUTEX_INITIALIZER; ++char portable_python_prefix[PATH_MAX] = {0}; ++ ++static char* portable_python_get_install_prefix() { ++ pthread_mutex_lock(&portable_python_prefix_mutex); ++ ++ if (portable_python_prefix[0] != '\0') { ++ pthread_mutex_unlock(&portable_python_prefix_mutex); ++ return portable_python_prefix; ++ } ++ ++ // First, get the path of the running executable ++ ssize_t len = readlink("/proc/self/exe", portable_python_prefix, PATH_MAX); ++ if (len == -1) { ++ perror("Error getting executable path"); ++ exit(EXIT_FAILURE); ++ } ++ portable_python_prefix[len] = '\0'; // Null-terminate the string ++ ++ _portable_python_trim_to_parent_directory(portable_python_prefix); // bin directory ++ _portable_python_trim_to_parent_directory(portable_python_prefix); // root directory ++ ++ pthread_mutex_unlock(&portable_python_prefix_mutex); ++ return portable_python_prefix; ++} ++ ++#endif ++ ++#ifdef __APPLE__ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++pthread_mutex_t portable_python_prefix_mutex = PTHREAD_MUTEX_INITIALIZER; ++char portable_python_prefix[PATH_MAX] = {0}; ++ ++static char* portable_python_get_install_prefix() { ++ pthread_mutex_lock(&portable_python_prefix_mutex); ++ ++ if (portable_python_prefix[0] != '\0') { ++ pthread_mutex_unlock(&portable_python_prefix_mutex); ++ return portable_python_prefix; ++ } ++ ++ char path[PATH_MAX]; ++ uint32_t bufsize = PATH_MAX; ++ if (_NSGetExecutablePath(path, &bufsize) != 0) { ++ fprintf(stderr, "Error getting executable path\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ // Resolve symlink if necessary ++ if (realpath(path, portable_python_prefix) == NULL) { ++ perror("Error resolving symlink"); ++ exit(EXIT_FAILURE); ++ } ++ ++ _portable_python_trim_to_parent_directory(portable_python_prefix); // bin directory ++ _portable_python_trim_to_parent_directory(portable_python_prefix); // root directory ++ ++ pthread_mutex_unlock(&portable_python_prefix_mutex); ++ return portable_python_prefix; ++} ++ ++#endif ++ ++#if defined(__linux__) || defined(__APPLE__) ++ ++#ifdef PREFIX ++# undef PREFIX ++#endif ++ ++#ifdef EXEC_PREFIX ++# undef EXEC_PREFIX ++#endif ++ ++#define PREFIX (portable_python_get_install_prefix()) ++#define EXEC_PREFIX (portable_python_get_install_prefix()) ++ ++#endif ++ + #ifdef __APPLE__ + # include + #endif diff --git a/patches/3.13/portable/02-portable-sysconfig.patch b/patches/3.13/portable/02-portable-sysconfig.patch new file mode 100644 index 0000000..d81a6ed --- /dev/null +++ b/patches/3.13/portable/02-portable-sysconfig.patch @@ -0,0 +1,82 @@ +diff --git a/Lib/sysconfig/__init__.py b/Lib/sysconfig/__init__.py +index 80aef344711..628c8b05270 100644 +--- a/Lib/sysconfig/__init__.py ++++ b/Lib/sysconfig/__init__.py +@@ -686,3 +686,52 @@ def expand_makefile_vars(s, vars): + else: + break + return s ++ ++ ++# Patch the included pkgconfig files to use the prefix computed during ++# runtime. This is a hack for mesonbuild, which looks for Python using ++# pkgconfig. Since a portable Python installation can be moved around, ++# we have to fix the pkgconfig files to use the correct prefix. ++def portable_python_fixup_pkgconfig(): ++ vars = get_config_vars() ++ ++ pkgcfgdir = vars.get('LIBPC') ++ prefix = vars.get('prefix') ++ if pkgcfgdir and os.path.isdir(pkgcfgdir): ++ import tempfile ++ import hashlib ++ tempdir_root = tempfile.gettempdir() ++ suffix = hashlib.md5(sys.version.encode('utf-8')).hexdigest() ++ portable_python_tempdir = os.path.join(tempdir_root, f'.portable-python-{suffix}') ++ portable_python_pkgconfig = os.path.join(portable_python_tempdir, 'lib/pkgconfig') ++ ++ if pkgcfgdir == portable_python_pkgconfig: ++ return ++ ++ os.makedirs(portable_python_pkgconfig, exist_ok=True) ++ ++ for root, dirs, files in os.walk(pkgcfgdir): ++ for file in files: ++ if file.endswith('.pc'): ++ with open(os.path.join(root, file), 'r', encoding='utf8') as f: ++ data = f.read() ++ for line in data.split('\n'): ++ if line.startswith('prefix=') and line != f'prefix={prefix}': ++ data = data.replace(line, f'prefix={prefix}') ++ break ++ if not os.path.exists(os.path.join(portable_python_pkgconfig, file)): ++ with open(os.path.join(portable_python_pkgconfig, file), 'w+', encoding='utf8') as f: ++ f.write(data) ++ else: ++ with open(os.path.join(portable_python_pkgconfig, file), 'r', encoding='utf8') as f: ++ tempdata = f.read() ++ if tempdata != data: ++ with open(os.path.join(portable_python_pkgconfig, file), 'w', encoding='utf8') as f: ++ f.write(data) ++ ++ _CONFIG_VARS['LIBPC'] = portable_python_pkgconfig ++ ++try: ++ portable_python_fixup_pkgconfig() ++except: ++ pass +\ No newline at end of file +diff --git a/Lib/sysconfig/__main__.py b/Lib/sysconfig/__main__.py +index d7257b9d2d0..9ddfff692bc 100644 +--- a/Lib/sysconfig/__main__.py ++++ b/Lib/sysconfig/__main__.py +@@ -215,6 +215,19 @@ def _generate_posix_vars(): + f.write('build_time_vars = ') + _print_config_dict(vars, stream=f) + ++ # fixup sysconfig to use dynamic paths for portable python ++ with open(destfile, 'r', encoding='utf8') as f: ++ varsfile = f.read() ++ if '# patched for portable python' not in varsfile: ++ varsfile = varsfile.replace(" '"+vars['prefix'], " f'{root}") ++ varsfile = varsfile.replace(" '-I"+vars['prefix'], " f'-I{root}") ++ varsfile = varsfile.replace(" \"'"+vars['prefix'], " f\"'{root}") ++ with open(destfile, 'w', encoding='utf8') as f: ++ f.write('# patched for portable python\n') ++ f.write('import sys\nimport os\n') ++ f.write('root = os.path.dirname(os.path.dirname(sys.executable))\n') ++ f.write(varsfile) ++ + # Create file used for sys.path fixup -- see Modules/getpath.c + with open('pybuilddir.txt', 'w', encoding='utf8') as f: + f.write(pybuilddir) diff --git a/patches/3.13/portable/03-ssl.patch b/patches/3.13/portable/03-ssl.patch new file mode 100644 index 0000000..c772c94 --- /dev/null +++ b/patches/3.13/portable/03-ssl.patch @@ -0,0 +1,26 @@ +diff --git a/Lib/ssl.py b/Lib/ssl.py +index cb5ec51681..43ae9889e6 100644 +--- a/Lib/ssl.py ++++ b/Lib/ssl.py +@@ -119,6 +119,10 @@ from _ssl import ( + ) + from _ssl import _DEFAULT_CIPHERS, _OPENSSL_API_VERSION + ++if os.name == "nt": ++ _portable_python_certifi_path = os.path.join(sys.prefix, "Lib", "site-packages", "certifi", "cacert.pem") ++else: ++ _portable_python_certifi_path = os.path.join(sys.prefix, "lib", f"python{sys.version_info.major}.{sys.version_info.minor}", "site-packages", "certifi", "cacert.pem") + + _IntEnum._convert_( + '_SSLMethod', __name__, +@@ -742,6 +746,10 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None, + context.verify_mode = CERT_REQUIRED + context.check_hostname = True + ++ if cafile is None: ++ if os.path.exists(_portable_python_certifi_path): ++ cafile = _portable_python_certifi_path ++ + if cafile or capath or cadata: + context.load_verify_locations(cafile, capath, cadata) + elif context.verify_mode != CERT_NONE: