Skip to content

Commit

Permalink
GH-127970: find the runtime library when dladdr is available (#127972)
Browse files Browse the repository at this point in the history
  • Loading branch information
FFY00 authored Jan 8, 2025
1 parent eb26e17 commit 95cd9c6
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
We now use the location of the ``libpython`` runtime library used in the current
proccess to determine :data:`sys.base_prefix` on all platforms implementing the
`dladdr <https://pubs.opengroup.org/onlinepubs/9799919799/functions/dladdr.html>`_
function defined by the UNIX standard — this includes Linux, Android, macOS,
iOS, FreeBSD, etc. This was already the case on Windows and macOS Framework
builds.
38 changes: 15 additions & 23 deletions Modules/getpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
#endif

#ifdef __APPLE__
# include <dlfcn.h>
# include <mach-o/dyld.h>
#endif

#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif

/* Reference the precompiled getpath.py */
#include "Python/frozen_modules/getpath.h"

Expand Down Expand Up @@ -803,36 +806,25 @@ progname_to_dict(PyObject *dict, const char *key)
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
#ifdef Py_ENABLE_SHARED
extern HMODULE PyWin_DLLhModule;
if (PyWin_DLLhModule) {
return winmodule_to_dict(dict, key, PyWin_DLLhModule);
}
#endif
#elif defined(WITH_NEXT_FRAMEWORK)
static char modPath[MAXPATHLEN + 1];
static int modPathInitialized = -1;
if (modPathInitialized < 0) {
modPathInitialized = 0;

/* On Mac OS X we have a special case if we're running from a framework.
This is because the python home should be set relative to the library,
which is in the framework, not relative to the executable, which may
be outside of the framework. Except when we're in the build
directory... */
Dl_info pythonInfo;
if (dladdr(&Py_Initialize, &pythonInfo)) {
if (pythonInfo.dli_fname) {
strncpy(modPath, pythonInfo.dli_fname, MAXPATHLEN);
modPathInitialized = 1;
}
}
}
if (modPathInitialized > 0) {
return decode_to_dict(dict, key, modPath);

#if HAVE_DLADDR
Dl_info libpython_info;
if (dladdr(&Py_Initialize, &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;
}

Expand Down
6 changes: 6 additions & 0 deletions configure

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

2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -5128,7 +5128,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock closefrom close_range confstr \
copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
copy_file_range ctermid dladdr dup dup3 execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid geteuid getgid getgrent getgrgid getgrgid_r \
Expand Down
3 changes: 3 additions & 0 deletions pyconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@
/* Define if you have the 'dirfd' function or macro. */
#undef HAVE_DIRFD

/* Define to 1 if you have the 'dladdr' function. */
#undef HAVE_DLADDR

/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H

Expand Down

0 comments on commit 95cd9c6

Please sign in to comment.