From 4988ea4f4ce6af0b567e6a2dc2c23aaf7cc5f12d Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Mon, 31 Jul 2017 10:59:47 -0400 Subject: [PATCH 1/3] VS2010 Support: Backport "Fix #13210. Port the Windows build from VS2008 to VS2010." This commit is a partial backport of python/cpython@401f9f3. It was originally designed to work with python-cmake-buildsystem. The following modules have NOT been backported: * Tools/msi * Tools/buildbot * PCBuild --- Lib/distutils/command/build_ext.py | 2 +- Lib/distutils/msvc9compiler.py | 11 ++++++----- PC/dl_nt.c | 11 ++++++++++- PC/msvcrtmodule.c | 15 ++++++++++++++- PC/pyconfig.h | 9 +++++++-- Python/dynload_win.c | 8 ++++++++ 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index 2c68be3..f1d184b 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -193,7 +193,7 @@ class build_ext (Command): # Append the source distribution include and library directories, # this allows distutils on windows to work in the source tree self.include_dirs.append(os.path.join(sys.exec_prefix, 'PC')) - if MSVC_VERSION == 9: + if MSVC_VERSION >= 9: # Use the .lib files for the correct architecture if self.plat_name == 'win32': suffix = '' diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py index 33d3e51..f6de11c 100644 --- a/Lib/distutils/msvc9compiler.py +++ b/Lib/distutils/msvc9compiler.py @@ -662,11 +662,12 @@ class MSVCCompiler(CCompiler) : if mfinfo is not None: mffilename, mfid = mfinfo out_arg = '-outputresource:%s;%s' % (output_filename, mfid) - try: - self.spawn(['mt.exe', '-nologo', '-manifest', - mffilename, out_arg]) - except DistutilsExecError, msg: - raise LinkError(msg) + if self.__version < 10: + try: + self.spawn(['mt.exe', '-nologo', '-manifest', + temp_manifest, out_arg]) + except PackagingExecError as msg: + raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename) diff --git a/PC/dl_nt.c b/PC/dl_nt.c index ef1ce09..5ff07fd 100644 --- a/PC/dl_nt.c +++ b/PC/dl_nt.c @@ -18,7 +18,8 @@ char dllVersionBuffer[16] = ""; // a private buffer HMODULE PyWin_DLLhModule = NULL; const char *PyWin_DLLVersionString = dllVersionBuffer; -// Windows "Activation Context" work: +#if HAVE_SXS +// Windows "Activation Context" work. // Our .pyd extension modules are generally built without a manifest (ie, // those included with Python and those built with a default distutils. // This requires we perform some "activation context" magic when loading our @@ -29,6 +30,8 @@ const char *PyWin_DLLVersionString = dllVersionBuffer; // As an added complication, this magic only works on XP or later - we simply // use the existence (or not) of the relevant function pointers from kernel32. // See bug 4566 (http://python.org/sf/4566) for more details. +// In Visual Studio 2010, side by side assemblies are no longer used by +// default. typedef BOOL (WINAPI * PFN_GETCURRENTACTCTX)(HANDLE *); typedef BOOL (WINAPI * PFN_ACTIVATEACTCTX)(HANDLE, ULONG_PTR *); @@ -76,6 +79,8 @@ void _Py_DeactivateActCtx(ULONG_PTR cookie) OutputDebugString("Python failed to de-activate the activation context\n"); } +#endif /* HAVE_SXS */ + BOOL WINAPI DllMain (HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) @@ -87,17 +92,21 @@ BOOL WINAPI DllMain (HANDLE hInst, // 1000 is a magic number I picked out of the air. Could do with a #define, I spose... LoadString(hInst, 1000, dllVersionBuffer, sizeof(dllVersionBuffer)); +#if HAVE_SXS // and capture our activation context for use when loading extensions. _LoadActCtxPointers(); if (pfnGetCurrentActCtx && pfnAddRefActCtx) if ((*pfnGetCurrentActCtx)(&PyWin_DLLhActivationContext)) if (!(*pfnAddRefActCtx)(PyWin_DLLhActivationContext)) OutputDebugString("Python failed to load the default activation context\n"); +#endif break; case DLL_PROCESS_DETACH: +#if HAVE_SXS if (pfnReleaseActCtx) (*pfnReleaseActCtx)(PyWin_DLLhActivationContext); +#endif break; } return TRUE; diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c index 44c82e4..68928dd 100644 --- a/PC/msvcrtmodule.c +++ b/PC/msvcrtmodule.c @@ -25,6 +25,8 @@ #ifdef _MSC_VER #if _MSC_VER >= 1500 && _MSC_VER < 1600 #include +#elif _MSC_VER >= 1600 +#include #endif #endif @@ -398,7 +400,7 @@ PyMODINIT_FUNC initmsvcrt(void) { int st; - PyObject *d; + PyObject *d, *version; PyObject *m = Py_InitModule("msvcrt", msvcrt_functions); if (m == NULL) return; @@ -412,6 +414,7 @@ initmsvcrt(void) insertint(d, "LK_UNLCK", _LK_UNLCK); /* constants for the crt versions */ + (void)st; #ifdef _VC_ASSEMBLY_PUBLICKEYTOKEN st = PyModule_AddStringConstant(m, "VC_ASSEMBLY_PUBLICKEYTOKEN", _VC_ASSEMBLY_PUBLICKEYTOKEN); @@ -427,4 +430,14 @@ initmsvcrt(void) __LIBRARIES_ASSEMBLY_NAME_PREFIX); if (st < 0)return; #endif + +/* constants for the 2010 crt versions */ +#if defined(_VC_CRT_MAJOR_VERSION) && defined (_VC_CRT_MINOR_VERSION) && defined(_VC_CRT_BUILD_VERSION) && defined(_VC_CRT_RBUILD_VERSION) + version = PyUnicode_FromFormat("%d.%d.%d.%d", _VC_CRT_MAJOR_VERSION, + _VC_CRT_MINOR_VERSION, + _VC_CRT_BUILD_VERSION, + _VC_CRT_RBUILD_VERSION); + st = PyModule_AddObject(m, "CRT_ASSEMBLY_VERSION", version); + if (st < 0) return NULL; +#endif } diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 5d1c90a..b60af1e 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -231,14 +231,19 @@ typedef int pid_t; #define hypot _hypot #endif -#endif /* _MSC_VER */ +/* Side by Side assemblies supported in VS 2005 and VS 2008 but not 2010*/ +#if _MSC_VER >= 1400 && _MSC_VER < 1600 +#define HAVE_SXS 1 +#endif /* define some ANSI types that are not defined in earlier Win headers */ -#if defined(_MSC_VER) && _MSC_VER >= 1200 +#if _MSC_VER >= 1200 /* This file only exists in VC 6.0 or higher */ #include #endif +#endif /* _MSC_VER */ + /* ------------------------------------------------------------------------*/ /* The Borland compiler defines __BORLANDC__ */ /* XXX These defines are likely incomplete, but should be easy to fix. */ diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 4e5555e..8626642 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -12,8 +12,10 @@ #include // "activation context" magic - see dl_nt.c... +#if HAVE_SXS extern ULONG_PTR _Py_ActivateActCtx(); void _Py_DeactivateActCtx(ULONG_PTR cookie); +#endif const struct filedescr _PyImport_DynLoadFiletab[] = { #ifdef _DEBUG @@ -176,7 +178,9 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, char pathbuf[260]; LPTSTR dummy; unsigned int old_mode; +#if HAVE_SXS ULONG_PTR cookie = 0; +#endif /* We use LoadLibraryEx so Windows looks for dependent DLLs in directory of pathname first. However, Windows95 can sometimes not work correctly unless the absolute @@ -190,11 +194,15 @@ dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, sizeof(pathbuf), pathbuf, &dummy)) { +#if HAVE_SXS ULONG_PTR cookie = _Py_ActivateActCtx(); +#endif /* XXX This call doesn't exist in Windows CE */ hDLL = LoadLibraryEx(pathname, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); +#if HAVE_SXS _Py_DeactivateActCtx(cookie); +#endif } /* restore old error mode settings */ -- 2.5.0