From 5f51c19502709228d5f6520412fb35167f078030 Mon Sep 17 00:00:00 2001 From: Roumen Petrov Date: Tue, 26 Feb 2013 23:56:16 +0200 Subject: [PATCH 06/24] MINGW: implement exec prefix use content of pybuilddir.txt to find just build extentions --- PC/getpathp.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/PC/getpathp.c b/PC/getpathp.c index af77a2d..5ee058d 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -104,10 +104,17 @@ static wchar_t *lib_python = L"lib\\python" VERSION; # 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; @@ -290,6 +297,82 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *landmark) /* 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. @@ -559,6 +642,9 @@ calculate_path(void) #ifdef USE_POSIX_PREFIX int pfound; #endif +#ifdef USE_EXEC_PREFIX + int efound; +#endif #ifdef MS_WINDOWS int skiphome, skipdefault; @@ -642,6 +728,16 @@ calculate_path(void) 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 */ if (dllpath[0]) /* use name of python DLL */ @@ -698,6 +794,9 @@ calculate_path(void) #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 @@ -745,6 +844,11 @@ calculate_path(void) 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) { wcscpy(buf, userpath); buf = wcschr(buf, L'\0'); @@ -812,6 +916,17 @@ calculate_path(void) 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]; @@ -881,7 +996,13 @@ Py_GetPrefix(void) 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 * -- 1.7.12.1