Files
MINGW-packages/mingw-w64-python3/0320-MINGW-implement-exec-prefix.patch
2016-07-12 14:49:26 +03:00

186 lines
5.1 KiB
Diff

diff -Naur Python-3.5.2-orig/PC/getpathp.c Python-3.5.2/PC/getpathp.c
--- Python-3.5.2-orig/PC/getpathp.c 2016-07-12 14:20:55.989800700 +0300
+++ Python-3.5.2/PC/getpathp.c 2016-07-12 14:21:11.286800700 +0300
@@ -104,10 +104,17 @@
# define USE_POSIX_PREFIX
+# ifdef Py_ENABLE_SHARED
+# define USE_EXEC_PREFIX
+# endif
+
#endif
static wchar_t prefix[MAXPATHLEN+1];
+#ifdef USE_EXEC_PREFIX
+static wchar_t exec_prefix[MAXPATHLEN+1];
+#endif
static wchar_t progpath[MAXPATHLEN+1];
static wchar_t dllpath[MAXPATHLEN+1];
static wchar_t *module_search_path = NULL;
@@ -299,6 +306,82 @@
/* a string loaded from the DLL at startup.*/
extern const char *PyWin_DLLVersionString;
+#ifdef USE_EXEC_PREFIX
+
+/* based on getpath.c but with path relative to executabe */
+/* search_for exec_prefix requires that paths be no more than
+ MAXPATHLEN bytes long.
+ return: 1 if found; -1 if found build directory
+*/
+static int
+search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_exec_prefix)
+{
+ size_t n;
+
+ /* If PYTHONHOME is set, we believe it unconditionally */
+ if (home) {
+ wchar_t *delim;
+ delim = wcschr(home, DELIM);
+ if (delim)
+ wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
+ else
+ wcsncpy(exec_prefix, home, MAXPATHLEN);
+ join(exec_prefix, lib_python);
+ join(exec_prefix, L"lib-dynload");
+ return 1;
+ }
+
+ /* Check to see if argv[0] is in the build directory. "pybuilddir.txt"
+ is written by setup.py and contains the relative path to the location
+ of shared library modules. */
+ wcscpy(exec_prefix, argv0_path);
+ join(exec_prefix, L"pybuilddir.txt");
+ if (exists(exec_prefix)) {
+ FILE *f = _Py_wfopen(exec_prefix, L"rb");
+ if (f == NULL)
+ errno = 0;
+ else {
+ char buf[MAXPATHLEN+1];
+ PyObject *decoded;
+ wchar_t rel_builddir_path[MAXPATHLEN+1];
+ n = fread(buf, 1, MAXPATHLEN, f);
+ buf[n] = '\0';
+ fclose(f);
+ decoded = PyUnicode_DecodeMBCS(buf, n, NULL);
+ if (decoded != NULL) {
+ Py_ssize_t k;
+ k = PyUnicode_AsWideChar(decoded,
+ rel_builddir_path, MAXPATHLEN);
+ Py_DECREF(decoded);
+ if (k >= 0) {
+ rel_builddir_path[k] = L'\0';
+ wcscpy(exec_prefix, argv0_path);
+ join(exec_prefix, rel_builddir_path);
+ return -1;
+ }
+ }
+ }
+ }
+
+ /* Search from argv0_path, until root is found */
+ wcscpy(exec_prefix, argv0_path);
+ do {
+ n = wcslen(exec_prefix);
+ join(exec_prefix, lib_python);
+ join(exec_prefix, L"lib-dynload");
+ if (exists(exec_prefix))
+ return 1;
+ exec_prefix[n] = L'\0';
+ reduce(exec_prefix);
+ } while (exec_prefix[0]);
+
+ /* Configure exec_prefix is unused */
+ (void)_exec_prefix;
+
+ /* Fail */
+ return 0;
+}
+#endif /*def USE_EXEC_PREFIX*/
/* Load a PYTHONPATH value from the registry.
Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
@@ -573,6 +656,9 @@
#ifdef USE_POSIX_PREFIX
int pfound;
#endif
+#ifdef USE_EXEC_PREFIX
+ int efound;
+#endif
#ifdef MS_WINDOWS
int skiphome, skipdefault;
@@ -668,6 +754,16 @@
if (envpath && *envpath == '\0')
envpath = NULL;
+#ifdef USE_EXEC_PREFIX
+ efound = search_for_exec_prefix(argv0_path, pythonhome, NULL);
+ if (!efound) {
+ wcsncpy(exec_prefix, argv0_path, MAXPATHLEN);
+ reduce(exec_prefix);
+ join(exec_prefix, lib_python);
+ join(exec_prefix, L"lib-dynload");
+ }
+#endif
+
#ifdef MS_WINDOWS
/* Calculate zip archive path from DLL or exe path */
if (wcscpy_s(zip_path, MAXPATHLEN+1, dllpath[0] ? dllpath : progpath))
@@ -722,6 +818,9 @@
#ifdef USE_POSIX_PREFIX
bufsz += wcslen(prefix) + 1;
#endif
+#ifdef USE_EXEC_PREFIX
+ bufsz += wcslen(exec_prefix) + 1;
+#endif
bufsz += wcslen(PYTHONPATH) + 1;
bufsz += wcslen(argv0_path) + 1;
#ifdef MS_WINDOWS
@@ -771,6 +870,11 @@
buf = wcschr(buf, L'\0');
*buf++ = DELIM;
#endif
+#ifdef USE_EXEC_PREFIX
+ wcscpy(buf, exec_prefix);
+ buf = wcschr(buf, L'\0');
+ *buf++ = DELIM;
+#endif
if (userpath) {
if (wcscpy_s(buf, bufsz - (buf - module_search_path), userpath))
Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
@@ -844,6 +948,17 @@
reduce(prefix);
reduce(prefix);
}
+ else
+ wcscpy(prefix, argv0_path);
+#endif
+#ifdef USE_EXEC_PREFIX
+ if (efound > 0) {
+ reduce(exec_prefix);
+ reduce(exec_prefix);
+ reduce(exec_prefix);
+ }
+ else
+ wcscpy(exec_prefix, argv0_path);
#endif
if (*prefix==L'\0') {
wchar_t lookBuf[MAXPATHLEN+1];
@@ -913,7 +1028,13 @@
wchar_t *
Py_GetExecPrefix(void)
{
+#ifdef USE_EXEC_PREFIX
+ if (!module_search_path)
+ calculate_path();
+ return exec_prefix;
+#else
return Py_GetPrefix();
+#endif
}
wchar_t *