You've already forked macports-ports
mirror of
https://github.com/macports/macports-ports.git
synced 2026-07-12 18:20:25 -07:00
83 lines
3.2 KiB
Diff
83 lines
3.2 KiB
Diff
|
|
As of macOS 12, dladdr, NSLibraryNameForModule, and similar functions
|
||
|
|
will resolve symlinks, which breaks virtualenv. This works around that
|
||
|
|
issue by not using those functions if at all possible.
|
||
|
|
|
||
|
|
Adapted from https://github.com/apple-oss-distributions/python/blob/python-136.120.2/2.7/fix/getpath.c.ed
|
||
|
|
--- Modules/getpath.c.orig 2022-01-08 05:08:48.000000000 +1100
|
||
|
|
+++ Modules/getpath.c 2022-01-08 05:13:34.000000000 +1100
|
||
|
|
@@ -7,7 +7,7 @@
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
#ifdef __APPLE__
|
||
|
|
-#include <mach-o/dyld.h>
|
||
|
|
+#include <dlfcn.h>
|
||
|
|
#include <AvailabilityMacros.h>
|
||
|
|
#endif
|
||
|
|
|
||
|
|
@@ -380,9 +380,10 @@ calculate_path(void)
|
||
|
|
size_t prefixsz;
|
||
|
|
char *defpath = pythonpath;
|
||
|
|
#ifdef WITH_NEXT_FRAMEWORK
|
||
|
|
- NSModule pythonModule;
|
||
|
|
+ Dl_info addrinfo;
|
||
|
|
+ int first_pass = 1;
|
||
|
|
#endif
|
||
|
|
-#ifdef __APPLE__
|
||
|
|
+#if 0
|
||
|
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||
|
|
uint32_t nsexeclength = MAXPATHLEN;
|
||
|
|
#else
|
||
|
|
@@ -397,7 +398,7 @@ calculate_path(void)
|
||
|
|
*/
|
||
|
|
if (strchr(prog, SEP))
|
||
|
|
strncpy(progpath, prog, MAXPATHLEN);
|
||
|
|
-#ifdef __APPLE__
|
||
|
|
+#if 0
|
||
|
|
/* On Mac OS X, if a script uses an interpreter of the form
|
||
|
|
* "#!/opt/python2.3/bin/python", the kernel only passes "python"
|
||
|
|
* as argv[0], which falls through to the $PATH search below.
|
||
|
|
@@ -410,7 +411,7 @@ calculate_path(void)
|
||
|
|
*/
|
||
|
|
else if(0 == _NSGetExecutablePath(progpath, &nsexeclength) && progpath[0] == SEP)
|
||
|
|
;
|
||
|
|
-#endif /* __APPLE__ */
|
||
|
|
+#endif /* notdef */
|
||
|
|
else if (path) {
|
||
|
|
while (1) {
|
||
|
|
char *delim = strchr(path, DELIM);
|
||
|
|
@@ -449,9 +450,18 @@ calculate_path(void)
|
||
|
|
** which is in the framework, not relative to the executable, which ma
|
||
|
|
** be outside of the framework. Except when we're in the build directory...
|
||
|
|
*/
|
||
|
|
- pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
|
||
|
|
- /* Use dylib functions to find out where the framework was loaded from */
|
||
|
|
- buf = (char *)NSLibraryNameForModule(pythonModule);
|
||
|
|
+ /* dladdr() now returns the real path of the dylib, instead of the
|
||
|
|
+ ** path of the symlink. This breaks virtualenv. To fix this, we
|
||
|
|
+ ** skip using dladdr() during a first pass, and if that fails, then
|
||
|
|
+ ** we go back and do the dladdr(). It turns out that since we moved
|
||
|
|
+ ** Python.app to inside the Python.framework bundle, the call to
|
||
|
|
+ ** search_for_prefix() will now succeed without needing dladdr().
|
||
|
|
+ ** However, virtualenv copies the wrong binary when the prefix is
|
||
|
|
+ ** /usr, so if progpath begins with /usr/bin/, we skip the first pass.
|
||
|
|
+ */
|
||
|
|
+ if (strncmp(progpath, "/usr/bin/", 9) == 0) first_pass = 0;
|
||
|
|
+return_here_for_second_pass:
|
||
|
|
+ buf = first_pass ? NULL : (dladdr("_Py_Initialize", &addrinfo) ? (char *)addrinfo.dli_fname : NULL);
|
||
|
|
if (buf != NULL) {
|
||
|
|
/* We're in a framework. */
|
||
|
|
/* See if we might be in the build directory. The framework in the
|
||
|
|
@@ -504,6 +514,12 @@ calculate_path(void)
|
||
|
|
*/
|
||
|
|
|
||
|
|
if (!(pfound = search_for_prefix(argv0_path, home))) {
|
||
|
|
+#ifdef WITH_NEXT_FRAMEWORK
|
||
|
|
+ if (first_pass) {
|
||
|
|
+ first_pass = 0;
|
||
|
|
+ goto return_here_for_second_pass;
|
||
|
|
+ }
|
||
|
|
+#endif
|
||
|
|
if (!Py_FrozenFlag)
|
||
|
|
fprintf(stderr,
|
||
|
|
"Could not find platform independent libraries <prefix>\n");
|