diff --git a/cpython-unix/build-cpython.sh b/cpython-unix/build-cpython.sh index 33391336..8e9799f8 100755 --- a/cpython-unix/build-cpython.sh +++ b/cpython-unix/build-cpython.sh @@ -629,6 +629,11 @@ if [ -n "${CROSS_COMPILING}" ]; then # TODO: There are probably more of these, see #599. fi +# TODO description +if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]]; then + patch -p1 -i "${ROOT}/patch-python-getpath-3.14.patch" +fi + # We patched configure.ac above. Reflect those changes. autoconf diff --git a/cpython-unix/patch-python-getpath-3.14.patch b/cpython-unix/patch-python-getpath-3.14.patch new file mode 100644 index 00000000..185d49e1 --- /dev/null +++ b/cpython-unix/patch-python-getpath-3.14.patch @@ -0,0 +1,105 @@ +From 4c69b0e246bd1057f640f87dfa5937a032f32f83 Mon Sep 17 00:00:00 2001 +From: Geoffrey Thomas +Date: Mon, 1 Dec 2025 14:11:43 -0500 +Subject: [PATCH 1/1] getpath: Fix library detection and canonicalize paths + +TODO description +--- + Modules/getpath.c | 43 +++++++++++++++++++++++++++++++++++++------ + Modules/getpath.py | 4 ++-- + 2 files changed, 39 insertions(+), 8 deletions(-) + +diff --git a/Modules/getpath.c b/Modules/getpath.c +index 1e75993480a..f8fc1608de4 100644 +--- a/Modules/getpath.c ++++ b/Modules/getpath.c +@@ -802,14 +802,16 @@ progname_to_dict(PyObject *dict, const char *key) + } + + ++static void ++fclose_cleanup(FILE **pf) { ++ fclose(*pf); ++} ++ ++ + /* Add the runtime library's path to the dict */ + static int + library_to_dict(PyObject *dict, const char *key) + { +-/* macOS framework builds do not link against a libpython dynamic library, but +- instead link against a macOS Framework. */ +-#if defined(Py_ENABLE_SHARED) || defined(WITH_NEXT_FRAMEWORK) +- + #ifdef MS_WINDOWS + extern HMODULE PyWin_DLLhModule; + if (PyWin_DLLhModule) { +@@ -817,12 +819,41 @@ library_to_dict(PyObject *dict, const char *key) + } + #endif + ++ const void *target = (void *)Py_Initialize; ++ ++#ifdef __linux__ ++ /* Linux libcs do not reliably report the canonical path in dli_fname, but ++ * we have /proc/self/maps. (dyld seems to reliably report the canonical ++ * path, so this matches the behavior on macOS.) */ ++ ++ FILE *maps __attribute__((cleanup(fclose_cleanup))) = fopen("/proc/self/maps", "r"); ++ if (maps != NULL) { ++ /* Format is documented in proc_pid_maps(5), but you want to look at ++ * the implementation in fs/proc/task_mmu.c for spacing. The pathname ++ * is the last field and has any \n characters escaped, so we can read ++ * until \n. Note that the filename may have " (deleted)" appended; ++ * we don't bother to handle that specially as the one user of this ++ * value calls dirname() anyway. ++ * TODO(geofft): Consider using PROCMAP_QUERY if supported. ++ */ ++ uintptr_t low, high; ++ char filename[PATH_MAX]; ++ while (fscanf(maps, "%lx-%lx %*s %*s %*s %*s %[^\n]", &low, &high, filename) == 3) { ++ if (low <= (uintptr_t)target && (uintptr_t)target < high) { ++ if (filename[0] == '/') { ++ return decode_to_dict(dict, key, filename); ++ } ++ break; ++ } ++ } ++ } ++#endif ++ + #if HAVE_DLADDR + Dl_info libpython_info; +- if (dladdr(&Py_Initialize, &libpython_info) && libpython_info.dli_fname) { ++ if (dladdr(target, &libpython_info) && libpython_info.dli_fname) { + return decode_to_dict(dict, key, libpython_info.dli_fname); + } +-#endif + #endif + + return PyDict_SetItemString(dict, key, Py_None) == 0; +diff --git a/Modules/getpath.py b/Modules/getpath.py +index b89d7427e3f..8c431e53be2 100644 +--- a/Modules/getpath.py ++++ b/Modules/getpath.py +@@ -436,7 +436,7 @@ def search_up(prefix, *landmarks, test=isfile): + + if not executable_dir and os_name == 'darwin' and library: + # QUIRK: macOS checks adjacent to its library early +- library_dir = dirname(library) ++ library_dir = dirname(dirname(library)) + if any(isfile(joinpath(library_dir, p)) for p in STDLIB_LANDMARKS): + # Exceptions here should abort the whole process (to match + # previous behavior) +@@ -570,7 +570,7 @@ def search_up(prefix, *landmarks, test=isfile): + + # First try to detect prefix by looking alongside our runtime library, if known + if library and not prefix: +- library_dir = dirname(library) ++ library_dir = dirname(dirname(library)) + if ZIP_LANDMARK: + if os_name == 'nt': + # QUIRK: Windows does not search up for ZIP file +-- +2.50.1 (Apple Git-155) +