Files
MINGW-packages/mingw-w64-python3/0560-mingw-use-posix-getpath.patch
Алексей edc01d04d6 Update python to 3.7.0 (#4047)
* Initial python-3.7 port

* python3: Add setup.config.in to remove before patching

* python3: Implement setenv for mingw. Fix building with NT threads. Build
with unicode

* Fix typos

* Fix linking core modules

* Mingw build have exec_prefix

* Remove deprecated patch

* Fix building python and modules. Failing to build readline module and
install not working yet

* More getpath changes and more aggressive path separator conversion

* Fix readline module compilation and linking errors

* python3: By default building with posix threads, NT threads are broken.
Some patches optimization. First buildable commit

* Py_DecodeLocale handle char, not wchar

* Fix building multiprocessing module with posix threads
2018-07-06 09:57:52 +03:00

323 lines
10 KiB
Diff

diff -Naur Python-3.7.0-orig/Include/internal/pystate.h Python-3.7.0/Include/internal/pystate.h
--- Python-3.7.0-orig/Include/internal/pystate.h 2018-06-30 11:16:58.540296800 +0300
+++ Python-3.7.0/Include/internal/pystate.h 2018-06-30 11:17:01.363901700 +0300
@@ -43,7 +43,8 @@
wchar_t *prefix;
#ifdef MS_WINDOWS
wchar_t *dll_path;
-#else
+#endif
+#ifndef _MSC_VER
wchar_t *exec_prefix;
#endif
/* Set by Py_SetPath(), or computed by _PyPathConfig_Init() */
diff -Naur Python-3.7.0-orig/Modules/getpath.c Python-3.7.0/Modules/getpath.c
--- Python-3.7.0-orig/Modules/getpath.c 2018-06-30 11:17:01.020701100 +0300
+++ Python-3.7.0/Modules/getpath.c 2018-06-30 11:17:01.363901700 +0300
@@ -11,6 +11,11 @@
# include <mach-o/dyld.h>
#endif
+#ifdef MS_WINDOWS
+#include <windows.h>
+#include <shlwapi.h>
+#endif
+
/* Search in some common locations for the associated Python libraries.
*
* Two directories must be found, the platform independent directory
@@ -323,6 +328,7 @@
wcsncpy(prefix, calculate->argv0_path, MAXPATHLEN);
prefix[MAXPATHLEN] = L'\0';
joinpath(prefix, L"Modules/Setup");
+ Py_NormalizeSepsW(prefix);
if (isfile(prefix)) {
/* Check VPATH to see if argv0_path is in the build directory. */
vpath = Py_DecodeLocale(VPATH, NULL);
@@ -333,6 +339,7 @@
PyMem_RawFree(vpath);
joinpath(prefix, L"Lib");
joinpath(prefix, LANDMARK);
+ Py_NormalizeSepsW(prefix);
if (ismodule(prefix)) {
return -1;
}
@@ -465,6 +465,7 @@
wcsncpy(exec_prefix, calculate->argv0_path, MAXPATHLEN);
exec_prefix[MAXPATHLEN] = L'\0';
joinpath(exec_prefix, rel_builddir_path);
+ Py_NormalizeSepsW(exec_prefix);
PyMem_RawFree(rel_builddir_path );
return -1;
}
@@ -501,6 +508,7 @@
}
wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
joinpath(exec_prefix, L"lib/lib-dynload");
+ Py_NormalizeSepsW(exec_prefix);
}
/* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
}
@@ -523,6 +531,53 @@
}
+#ifdef MS_WINDOWS
+static int
+GetWindowsModulePaths(wchar_t *progpath)
+{
+ int result = 0;
+ wchar_t program_full_path[MAXPATHLEN+1];
+ memset(program_full_path, 0, sizeof(program_full_path));
+
+ if (GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) {
+ result = 1;
+ Py_NormalizeSepsW(program_full_path);
+ }
+
+ wcscpy(progpath, program_full_path);
+ return result;
+}
+
+
+static _PyInitError
+get_dll_path(_PyPathConfig *config)
+{
+ wchar_t dll_path[MAXPATHLEN+1];
+ memset(dll_path, 0, sizeof(dll_path));
+
+#ifdef Py_ENABLE_SHARED
+ extern HANDLE PyWin_DLLhModule;
+ if (PyWin_DLLhModule) {
+ if (GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) {
+ Py_NormalizeSepsW(dll_path);
+ reduce(dll_path);
+ } else {
+ dll_path[0] = 0;
+ }
+ }
+#else
+ dll_path[0] = 0;
+#endif
+
+ config->dll_path = _PyMem_RawWcsdup(dll_path);
+ if (config->dll_path == NULL) {
+ return _Py_INIT_NO_MEMORY();
+ }
+ return _Py_INIT_OK();
+}
+#endif /* MS_WINDOWS */
+
+
static _PyInitError
calculate_program_full_path(const _PyCoreConfig *core_config,
PyCalculatePath *calculate, _PyPathConfig *config)
@@ -570,6 +624,10 @@
PyMem_RawFree(path);
}
#endif /* __APPLE__ */
+#ifdef MS_WINDOWS
+ else if(GetWindowsModulePaths(program_full_path)) {
+ }
+#endif /* MS_WINDOWS */
else if (calculate->path_env) {
wchar_t *path = calculate->path_env;
while (1) {
@@ -743,6 +803,7 @@
wcsncpy(calculate->zip_path, calculate->prefix, MAXPATHLEN);
}
joinpath(calculate->zip_path, L"lib/python00.zip");
+ Py_NormalizeSepsW(calculate->zip_path);
/* Replace "00" with version */
size_t bufsz = wcslen(calculate->zip_path);
@@ -785,6 +846,19 @@
bufsz += wcslen(calculate->zip_path) + 1;
bufsz += wcslen(exec_prefix) + 1;
+#ifdef MS_WINDOWS
+ if (prefix[0] != '\0' && prefix[1] == L':') {
+ bufsz += wcslen(prefix) + 1;
+ }
+ if (calculate->argv0_path[0] != '\0' && calculate->argv0_path[1] == L':') {
+ bufsz += wcslen(calculate->argv0_path) + 1;
+ }
+ if (config->dll_path[0] != '\0' && config->dll_path[1] == L':') {
+ bufsz += wcslen(config->dll_path) + 1;
+ } else if (config->program_full_path[0] != '\0' && config->program_full_path[1] == L':'){
+ bufsz += wcslen(config->program_full_path) + 1;
+ }
+#endif
/* Allocate the buffer */
wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
@@ -828,11 +893,28 @@
}
else {
wcscat(buf, defpath);
+ wcscat(buf, delimiter);
break;
}
defpath = delim + 1;
}
- wcscat(buf, delimiter);
+#ifdef MS_WINDOWS
+ if (prefix[0] != '\0' && prefix[1] == L':') {
+ wcscat(buf, prefix);
+ wcscat(buf, delimiter);
+ }
+ if (calculate->argv0_path[0] != '\0' && calculate->argv0_path[1] == L':') {
+ wcscat(buf, calculate->argv0_path);
+ wcscat(buf, delimiter);
+ }
+ if (config->dll_path[0] != '\0' && config->dll_path[1] == L':') {
+ wcscat(buf, config->dll_path);
+ wcscat(buf, delimiter);
+ } else if (config->program_full_path[0] != '\0' && config->program_full_path[1] == L':'){
+ wcscat(buf, config->program_full_path);
+ wcscat(buf, delimiter);
+ }
+#endif
/* Finally, on goes the directory for dynamic-load modules */
wcscat(buf, exec_prefix);
@@ -855,15 +928,19 @@
if (!calculate->pythonpath) {
return DECODE_LOCALE_ERR("PYTHONPATH define", len);
}
+ Py_NormalizeSepsW(calculate->pythonpath);
calculate->prefix = Py_DecodeLocale(PREFIX, &len);
if (!calculate->prefix) {
return DECODE_LOCALE_ERR("PREFIX define", len);
}
+ Py_NormalizeSepsW(calculate->prefix);
calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
if (!calculate->prefix) {
return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
}
- calculate->lib_python = Py_DecodeLocale("lib/python" VERSION, &len);
+ Py_NormalizeSepsW(calculate->exec_prefix);
+ const char *lib_python_VERSION = (Py_GetSepA(NULL) == '/') ? "lib/python" VERSION : "lib\\python" VERSION;
+ calculate->lib_python = Py_DecodeLocale(lib_python_VERSION, &len);
if (!calculate->lib_python) {
return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
}
@@ -892,6 +970,13 @@
{
_PyInitError err;
+#ifdef MS_WINDOWS
+ err = get_dll_path(config);
+ if (_Py_INIT_FAILED(err)) {
+ return err;
+ }
+#endif
+
err = calculate_program_full_path(core_config, calculate, config);
if (_Py_INIT_FAILED(err)) {
return err;
@@ -968,6 +1078,60 @@
return err;
}
+
+#ifdef MS_WINDOWS
+/* Load python3.dll before loading any extension module that might refer
+ to it. That way, we can be sure that always the python3.dll corresponding
+ to this python DLL is loaded, not a python3.dll that might be on the path
+ by chance.
+ Return whether the DLL was found.
+*/
+static int python3_checked = 0;
+static HANDLE hPython3;
+int
+_Py_CheckPython3(void)
+{
+ /* This does not work well with mingw-w64-python. First it tries to
+ * look up \python3.dll, which it won't (or should not) find. But the
+ * real problem is when Python is freezed by cx_Freeze. sys.prefix
+ * is then /, and Python tries to load /\DLLs\python3.dll, which makes
+ * windows try to load python3.dll from a network address, causing
+ * a several seconds long delay before proceeding. Since this code does
+ * not do anything useful in the current state, we might just as
+ * well return immediately. */
+#ifdef __MINGW32__
+ return 0;
+#else
+ wchar_t py3path[MAXPATHLEN+1];
+ wchar_t *s;
+ if (python3_checked) {
+ return hPython3 != NULL;
+ }
+ python3_checked = 1;
+
+ /* If there is a python3.dll next to the python3y.dll,
+ assume this is a build tree; use that DLL */
+ wcscpy(py3path, _Py_path_config.dll_path);
+ s = wcsrchr(py3path, Py_GetSepW(py3path));
+ if (!s) {
+ s = py3path;
+ } else {
+ s += 1;
+ }
+ wcscpy(s, L"\\python3.dll");
+ hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+ if (hPython3 != NULL)
+ return 1;
+
+ /* Check sys.prefix\DLLs\python3.dll */
+ wcscpy(py3path, Py_GetPrefix());
+ wcscat(py3path, L"\\DLLs\\python3.dll");
+ hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+ return hPython3 != NULL;
+#endif
+}
+#endif
+
#ifdef __cplusplus
}
#endif
diff -Naur Python-3.7.0-orig/Modules/posixmodule.c Python-3.7.0/Modules/posixmodule.c
--- Python-3.7.0-orig/Modules/posixmodule.c 2018-06-30 11:17:01.036301200 +0300
+++ Python-3.7.0/Modules/posixmodule.c 2018-06-30 11:17:01.379501800 +0300
@@ -3524,7 +3524,7 @@
Py_END_ALLOW_THREADS
/* FindNextFile sets error to ERROR_NO_MORE_FILES if
it got to the end of the directory. */
- if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
+ if (!result && GetLastError() != 0 && GetLastError() != ERROR_NO_MORE_FILES) {
Py_DECREF(list);
list = path_error(path);
goto exit;
--- Python-3.7.0/Python/pathconfig.c.orig 2018-06-27 06:07:35.000000000 +0300
+++ Python-3.7.0/Python/pathconfig.c 2018-07-02 08:14:54.324696000 +0300
@@ -32,7 +140,8 @@
CLEAR(config->program_full_path);
#ifdef MS_WINDOWS
CLEAR(config->dll_path);
-#else
+#endif
+#ifndef _MSC_VER
CLEAR(config->exec_prefix);
#endif
CLEAR(config->module_search_path);
@@ -145,7 +254,8 @@
new_config.prefix = _PyMem_RawWcsdup(L"");
#ifdef MS_WINDOWS
new_config.dll_path = _PyMem_RawWcsdup(L"");
-#else
+#endif
+#ifndef _MSC_VER
new_config.exec_prefix = _PyMem_RawWcsdup(L"");
#endif
new_config.module_search_path = _PyMem_RawWcsdup(path);
@@ -224,7 +335,7 @@
wchar_t *
Py_GetExecPrefix(void)
{
-#ifdef MS_WINDOWS
+#ifdef _MSC_VER
return Py_GetPrefix();
#else
pathconfig_global_init();