From d7b1c272cc29b427b88c642cd4e57b06c45967cf Mon Sep 17 00:00:00 2001 From: Roumen Petrov Date: Sat, 23 Feb 2013 21:06:38 +0200 Subject: [PATCH 12/15] MINGW: default sys.path calculations for windows platforms also create PC subdir for out of source tree builds --- Makefile.pre.in | 10 +++++- PC/getpathp.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- configure.ac | 13 +++++++ 3 files changed, 129 insertions(+), 2 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in index 03875ef..97464eb 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -237,7 +237,7 @@ COVERAGE_REPORT_OPTIONS=--no-branch-coverage --title "CPython lcov report" # Modules MODULE_OBJS= \ Modules/config.o \ - Modules/getpath.o \ + @MODULE_GETPATH@ \ Modules/main.o \ Modules/gcmodule.o @@ -696,6 +696,7 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \ -DHGBRANCH="\"`LC_ALL=C $(HGBRANCH)`\"" \ -o $@ $(srcdir)/Modules/getbuildinfo.c +# default sys.path calculations for posix platforms Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile $(CC) -c $(PY_CORE_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \ -DPREFIX='"$(prefix)"' \ @@ -704,6 +705,13 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile -DVPATH='"$(VPATH)"' \ -o $@ $(srcdir)/Modules/getpath.c +# default sys.path calculations for windows platforms +PC/getpathp.o: $(srcdir)/PC/getpathp.c Makefile + $(CC) -c $(PY_CORE_CFLAGS) \ + -DVERSION='"$(VERSION)"' \ + -DSRCDIR='"$(srcdir)"' \ + -o $@ $(srcdir)/PC/getpathp.c + Programs/python.o: $(srcdir)/Programs/python.c $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/python.c diff --git a/PC/getpathp.c b/PC/getpathp.c index deb40e7..074b5ad 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -87,10 +87,26 @@ * with a semicolon separated path prior to calling Py_Initialize. */ +#ifndef PYTHONPATH +# define PYTHONPATH L".\\DLLs;.\\lib" +#endif + #ifndef LANDMARK #define LANDMARK L"lib\\os.py" #endif +#ifdef __MINGW32__ + +static wchar_t *lib_python = L"lib\\python" VERSION; + +# undef LANDMARK +# define LANDMARK L"os.py" + +# define USE_POSIX_PREFIX + +#endif + + static wchar_t prefix[MAXPATHLEN+1]; static wchar_t progpath[MAXPATHLEN+1]; static wchar_t dllpath[MAXPATHLEN+1]; @@ -173,6 +189,69 @@ join(wchar_t *buffer, wchar_t *stuff) buffer[n+k] = '\0'; } +#ifdef USE_POSIX_PREFIX + +/* based on getpath.c but with paths relative to executable */ +/* search_for_prefix requires that path be no more than MAXPATHLEN + bytes long. + return: 1 if found; -1 if found build directory +*/ +static int +search_for_posix_prefix(wchar_t *argv0_path, wchar_t *home, wchar_t *_prefix) +{ + size_t n; + + /* If PYTHONHOME is set, we believe it unconditionally */ + if (home) { + wchar_t *delim; + wcsncpy(prefix, home, MAXPATHLEN); + delim = wcschr(prefix, DELIM); + if (delim) + *delim = L'\0'; + join(prefix, lib_python); + join(prefix, LANDMARK); + return 1; + } + + /* Check to see if argv[0] is in the build directory */ + wcscpy(prefix, argv0_path); + join(prefix, L"Modules\\Setup"); + if (exists(prefix)) { + wchar_t *vpath; + /* Check source directory if argv0_path is in the build directory. */ + vpath = Py_DecodeLocale(SRCDIR, NULL); + if (vpath != NULL) { + wcscpy(prefix, argv0_path); + join(prefix, vpath); + PyMem_Free(vpath); + join(prefix, L"Lib"); + join(prefix, LANDMARK); + if (ismodule(prefix)) + return -1; + } + } + + /* Search from argv0_path, until root is found */ + wcscpy(prefix, argv0_path); + do { + n = wcslen(prefix); + join(prefix, lib_python); + join(prefix, LANDMARK); + if (ismodule(prefix)) + return 1; + prefix[n] = L'\0'; + reduce(prefix); + } while (prefix[0]); + + /* Configure prefix is unused */ + (void)_prefix; + + /* Fail */ + return 0; +} + +#endif /*def USE_POSIX_PREFIX */ + /* gotlandmark only called by search_for_prefix, which ensures 'prefix' is null terminated in bounds. join() ensures 'landmark' can not overflow prefix if too long. @@ -477,6 +556,9 @@ calculate_path(void) size_t bufsz; wchar_t *pythonhome = Py_GetPythonHome(); wchar_t *envpath = NULL; +#ifdef USE_POSIX_PREFIX + int pfound; +#endif #ifdef MS_WINDOWS int skiphome, skipdefault; @@ -537,6 +619,16 @@ calculate_path(void) } } +#ifdef USE_POSIX_PREFIX + pfound = search_for_posix_prefix(argv0_path, pythonhome, NULL); + if (!pfound) { + wcsncpy(prefix, argv0_path, MAXPATHLEN); + reduce(prefix); + join(prefix, lib_python); + } + else + reduce(prefix); +#else if (pythonhome == NULL || *pythonhome == '\0') { if (search_for_prefix(argv0_path, LANDMARK)) pythonhome = prefix; @@ -545,11 +637,11 @@ calculate_path(void) } else wcsncpy(prefix, pythonhome, MAXPATHLEN); +#endif if (envpath && *envpath == '\0') envpath = NULL; - #ifdef MS_WINDOWS /* Calculate zip archive path */ if (dllpath[0]) /* use name of python DLL */ @@ -603,6 +695,9 @@ calculate_path(void) } else bufsz = 0; +#ifdef USE_POSIX_PREFIX + bufsz += wcslen(prefix) + 1; +#endif bufsz += wcslen(PYTHONPATH) + 1; bufsz += wcslen(argv0_path) + 1; #ifdef MS_WINDOWS @@ -645,6 +740,11 @@ calculate_path(void) buf = wcschr(buf, L'\0'); *buf++ = DELIM; } +#ifdef USE_POSIX_PREFIX + wcscpy(buf, prefix); + buf = wcschr(buf, L'\0'); + *buf++ = DELIM; +#endif if (userpath) { wcscpy(buf, userpath); buf = wcschr(buf, L'\0'); @@ -707,6 +807,12 @@ calculate_path(void) on the path, and that our 'prefix' directory is the parent of that. */ +#ifdef USE_POSIX_PREFIX + if (pfound > 0) { + reduce(prefix); + reduce(prefix); + } +#endif if (*prefix==L'\0') { wchar_t lookBuf[MAXPATHLEN+1]; wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */ diff --git a/configure.ac b/configure.ac index fdc9125..677474d 100644 --- a/configure.ac +++ b/configure.ac @@ -4967,8 +4967,21 @@ case $host in ;; esac +dnl getpath module - default sys.path calculations +AC_SUBST(MODULE_GETPATH) +MODULE_GETPATH=Modules/getpath.o +case $host in + *-*-mingw*) + dnl default sys.path calculations for windows platforms + MODULE_GETPATH=PC/getpathp.o + ;; +esac + AC_SUBST(SRCDIRS) SRCDIRS="Parser Grammar Objects Python Modules Mac Programs" +case $host in + *-*-mingw*) SRCDIRS="$SRCDIRS PC";; +esac AC_MSG_CHECKING(for build directories) for dir in $SRCDIRS; do if test ! -d $dir; then -- 1.8.4