# HG changeset patch # User Steve Dower # Date 1418014903 28800 # Sun Dec 07 21:01:43 2014 -0800 # Branch Projects # Node ID 82346d5966a791ebbb3fe83d2a1d68defc34cfda # Parent 9d48bd7e04ae4fb4f2dd7a2cac6b3eb742cdffa5 #22980 Adds platform tags to .pyd files diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -691,10 +691,7 @@ """ from distutils.sysconfig import get_config_var ext_path = ext_name.split('.') - # extensions in debug_mode are named 'module_d.pyd' under windows ext_suffix = get_config_var('EXT_SUFFIX') - if os.name == 'nt' and self.debug: - return os.path.join(*ext_path) + '_d' + ext_suffix return os.path.join(*ext_path) + ext_suffix def get_export_symbols(self, ext): diff --git a/Lib/test/test_importlib/test_windows.py b/Lib/test/test_importlib/test_windows.py --- a/Lib/test/test_importlib/test_windows.py +++ b/Lib/test/test_importlib/test_windows.py @@ -2,9 +2,11 @@ machinery = test_util.import_importlib('importlib.machinery') import os +import re import sys import unittest from test import support +from distutils.util import get_platform from contextlib import contextmanager from .util import temp_module @@ -83,3 +85,31 @@ (Frozen_WindowsRegistryFinderTests, Source_WindowsRegistryFinderTests ) = test_util.test_both(WindowsRegistryFinderTests, machinery=machinery) + +@unittest.skipUnless(sys.platform.startswith('win'), 'requires Windows') +class WindowsExtensionSuffixTests: + def test_tagged_suffix(self): + suffixes = self.machinery.EXTENSION_SUFFIXES + expected_tag_1 = ".cp{0.major}{0.minor}-{1}.pyd".format(sys.version_info, + re.sub('[^a-zA-Z0-9]', '_', get_platform())) + expected_tag_2 = ".cp{0.major}-{1}.pyd".format(sys.version_info, + re.sub('[^a-zA-Z0-9]', '_', get_platform())) + try: + untagged_i = suffixes.index(".pyd") + except ValueError: + untagged_i = suffixes.index("_d.pyd") + expected_tag_1 = "_d" + expected_tag_1 + expected_tag_2 = "_d" + expected_tag_2 + + self.assertIn(expected_tag_1, suffixes) + self.assertIn(expected_tag_2, suffixes) + + # Ensure the tags are in the correct order + tagged_1_i = suffixes.index(expected_tag_1) + tagged_2_i = suffixes.index(expected_tag_2) + self.assertLess(tagged_1_i, tagged_2_i) + self.assertLess(tagged_2_i, untagged_i) + +(Frozen_WindowsExtensionSuffixTests, + Source_WindowsExtensionSuffixTests + ) = test_util.test_both(WindowsExtensionSuffixTests, machinery=machinery) diff --git a/PC/pyconfig.h b/PC/pyconfig.h --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -145,9 +145,11 @@ #if defined(_M_IA64) #define COMPILER _Py_PASTE_VERSION("64 bit (Itanium)") #define MS_WINI64 +#define PYD_PLATFORM_TAG "win_ia64" #elif defined(_M_X64) || defined(_M_AMD64) #define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") #define MS_WINX64 +#define PYD_PLATFORM_TAG "win_amd64" #else #define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") #endif @@ -193,8 +195,10 @@ #if defined(MS_WIN32) && !defined(MS_WIN64) #if defined(_M_IX86) #define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") +#define PYD_PLATFORM_TAG "win32" #elif defined(_M_ARM) #define COMPILER _Py_PASTE_VERSION("32 bit (ARM)") +#define PYD_PLATFORM_TAG "win_arm" #else #define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)") #endif diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -8,6 +8,7 @@ $(SolutionDir)obj\$(ArchName)\$(ProjectName)\ $(ProjectName) $(TargetName)$(PyDebugExt) + $(TargetName)$(PydTag) false false true diff --git a/PCbuild/python.props b/PCbuild/python.props --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -96,6 +96,10 @@ python$(MajorVersionNumber)$(MinorVersionNumber)$(PyDebugExt) + + + .cp$(MajorVersionNumber)$(MinorVersionNumber)-win32 + .cp$(MajorVersionNumber)$(MinorVersionNumber)-win_amd64 diff --git a/Python/dynload_win.c b/Python/dynload_win.c --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -9,6 +9,7 @@ #include #include "importdl.h" +#include "patchlevel.h" #include // "activation context" magic - see dl_nt.c... @@ -17,16 +18,30 @@ void _Py_DeactivateActCtx(ULONG_PTR cookie); #endif +#ifdef _DEBUG +#define PYD_DEBUG_SUFFIX "_d" +#else +#define PYD_DEBUG_SUFFIX "" +#endif + +#define STRINGIZE(x) #x +#ifdef PYD_PLATFORM_TAG +#define PYD_TAGGED_SUFFIX(x, y) PYD_DEBUG_SUFFIX ".cp" STRINGIZE(x) STRINGIZE(y) "-" PYD_PLATFORM_TAG ".pyd" +#define PYD_STABLE_TAGGED_SUFFIX(x) PYD_DEBUG_SUFFIX ".cp" STRINGIZE(x) "-" PYD_PLATFORM_TAG ".pyd" +#else +#define PYD_TAGGED_SUFFIX(x, y) PYD_DEBUG_SUFFIX ".cp" STRINGIZE(x) STRINGIZE(y) ".pyd" +#define PYD_STABLE_TAGGED_SUFFIX(x) PYD_DEBUG_SUFFIX ".cp" STRINGIZE(x) ".pyd" +#endif + +#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd" + const char *_PyImport_DynLoadFiletab[] = { -#ifdef _DEBUG - "_d.pyd", -#else - ".pyd", -#endif + PYD_TAGGED_SUFFIX(PY_MAJOR_VERSION, PY_MINOR_VERSION), + PYD_STABLE_TAGGED_SUFFIX(PY_MAJOR_VERSION), + PYD_UNTAGGED_SUFFIX, NULL }; - /* Case insensitive string compare, to avoid any dependencies on particular C RTL implementations */