From 222a379e73e70a0f3c33f48cf8826a2a8c8ad7a2 Mon Sep 17 00:00:00 2001 From: rjamuar Date: Wed, 4 May 2016 10:44:41 -0500 Subject: [PATCH] distutils patch to make MSVCCompiler class respect env vars For Py3.5+ --- Lib/distutils/_msvccompiler.py | 37 +++++++++++++++++++++++++++---------- Lib/distutils/msvc9compiler.py | 26 +++++++++++++++++--------- Lib/distutils/msvccompiler.py | 25 ++++++++++++++++--------- 3 files changed, 60 insertions(+), 28 deletions(-) diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py index d0ba7d6..19ed60c 100644 --- a/Lib/distutils/_msvccompiler.py +++ b/Lib/distutils/_msvccompiler.py @@ -108,7 +108,7 @@ def _get_vc_env(plat_spec): return env def _find_exe(exe, paths=None): - """Return path to an MSVC executable program. + """Return path to an executable program. Tries to find the program in several places: first, one of the MSVC program search paths from the registry; next, the directories @@ -120,8 +120,9 @@ def _find_exe(exe, paths=None): paths = os.getenv('path').split(os.pathsep) for p in paths: fn = os.path.join(os.path.abspath(p), exe) - if os.path.isfile(fn): - return fn + for abs_path in [fn, fn+'.exe']: + if os.path.isfile(abs_path): + return abs_path return exe # A map keyed by get_platform() return values to values accepted by @@ -202,15 +203,26 @@ class MSVCCompiler(CCompiler) : "Visual Studio installation.") self._paths = vc_env.get('path', '') - paths = self._paths.split(os.pathsep) - self.cc = _find_exe("cl.exe", paths) - self.linker = _find_exe("link.exe", paths) - self.lib = _find_exe("lib.exe", paths) - self.rc = _find_exe("rc.exe", paths) # resource compiler - self.mc = _find_exe("mc.exe", paths) # message compiler - self.mt = _find_exe("mt.exe", paths) # message compiler self._vcruntime_redist = vc_env.get('py_vcruntime_redist', '') + if 'DISTUTILS_USE_SDK' in os.environ: + # If 'DISTUTILS_USE_SDK' is set to env, assume that following + # executables have already been added to PATH + self.cc = os.environ.get('CC', 'cl.exe').strip() + self.linker = os.environ.get('LD', 'link.exe').strip() + self.lib = os.environ.get('AR', 'lib.exe').strip() + self.rc = os.environ.get('RC', 'rc.exe').strip() + self.mc = os.environ.get('MC', 'mc.exe').strip() + self.mt = os.environ.get('MT', 'mt.exe').strip() + else: + paths = self._paths.split(os.pathsep) + self.cc = _find_exe("cl.exe", paths) + self.linker = _find_exe("link.exe", paths) + self.lib = _find_exe("lib.exe", paths) + self.rc = _find_exe("rc.exe", paths) # resource compiler + self.mc = _find_exe("mc.exe", paths) # message compiler + self.mt = _find_exe("mt.exe", paths) # message compiler + for dir in vc_env.get('include', '').split(os.pathsep): if dir: self.add_include_dir(dir) @@ -249,6 +261,11 @@ class MSVCCompiler(CCompiler) : self.ldflags_static = [*ldflags] self.ldflags_static_debug = [*ldflags_debug] + self.compile_options.extend(os.environ.get('CFLAGS', '').strip().split()) + self.compile_options_debug.extend(os.environ.get('CFLAGS', '').strip().split()) + self.ldflags_shared.extend(os.environ.get('LDFLAGS', '').strip().split()) + self.ldflags_shared_debug.extend(os.environ.get('LDFLAGS', '').strip().split()) + self._ldflags = { (CCompiler.EXECUTABLE, None): self.ldflags_exe, (CCompiler.EXECUTABLE, False): self.ldflags_exe, diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py index da4b21d..a1455e0 100644 --- a/Lib/distutils/msvc9compiler.py +++ b/Lib/distutils/msvc9compiler.py @@ -331,6 +331,7 @@ class MSVCCompiler(CCompiler) : CCompiler.__init__ (self, verbose, dry_run, force) self.__version = VERSION self.__root = r"Software\Microsoft\VisualStudio" + self.__product = "Visual Studio version %s" % self.__version # self.__macros = MACROS self.__paths = [] # target platform (.plat_name is consistent with 'bdist') @@ -349,14 +350,14 @@ class MSVCCompiler(CCompiler) : raise DistutilsPlatformError("--plat-name must be one of %s" % (ok_plats,)) - if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): + if "DISTUTILS_USE_SDK" in os.environ: # Assume that the SDK set up everything alright; don't try to be # smarter - self.cc = "cl.exe" - self.linker = "link.exe" - self.lib = "lib.exe" - self.rc = "rc.exe" - self.mc = "mc.exe" + self.cc = os.environ.get('CC', 'cl.exe').strip() + self.linker = os.environ.get('LD', 'link.exe').strip() + self.lib = os.environ.get('AR', 'lib.exe').strip() + self.rc = os.environ.get('RC', 'rc.exe').strip() + self.mc = os.environ.get('MC', 'mc.exe').strip() else: # On x86, 'vcvars32.bat amd64' creates an env that doesn't work; # to cross compile, you use 'x86_amd64'. @@ -414,13 +415,19 @@ class MSVCCompiler(CCompiler) : '/Z7', '/D_DEBUG'] self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] + cflags_env = os.environ.get('CFLAGS', '').strip().split() + ldflags_env = os.environ.get('LDFLAGS', '').strip().split() if self.__version >= 7: self.ldflags_shared_debug = [ '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG' ] + self.ldflags_shared_debug.extend(ldflags_env) self.ldflags_static = [ '/nologo'] self.initialized = True + self.compile_options.extend(cflags_env) + self.compile_options_debug.extend(cflags_env) + self.ldflags_shared.extend(ldflags_env) # -- Worker methods ------------------------------------------------ @@ -769,7 +776,7 @@ class MSVCCompiler(CCompiler) : # Helper methods for using the MSVC registry settings def find_exe(self, exe): - """Return path to an MSVC executable program. + """Return path to an executable program. Tries to find the program in several places: first, one of the MSVC program search paths from the registry; next, the directories @@ -785,7 +792,8 @@ class MSVCCompiler(CCompiler) : # didn't find it; try existing path for p in os.environ['Path'].split(';'): fn = os.path.join(os.path.abspath(p),exe) - if os.path.isfile(fn): - return fn + for abs_path in [fn, fn+'.exe']: + if os.path.isfile(abs_path): + return abs_path return exe diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py index 1048cd4..1d93af9 100644 --- a/Lib/distutils/msvccompiler.py +++ b/Lib/distutils/msvccompiler.py @@ -247,14 +247,14 @@ class MSVCCompiler(CCompiler) : def initialize(self): self.__paths = [] - if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): + if "DISTUTILS_USE_SDK" in os.environ: # Assume that the SDK set up everything alright; don't try to be # smarter - self.cc = "cl.exe" - self.linker = "link.exe" - self.lib = "lib.exe" - self.rc = "rc.exe" - self.mc = "mc.exe" + self.cc = os.environ.get('CC', 'cl.exe').strip() + self.linker = os.environ.get('LD', 'link.exe').strip() + self.lib = os.environ.get('AR', 'lib.exe').strip() + self.rc = os.environ.get('RC', 'rc.exe').strip() + self.mc = os.environ.get('MC', 'mc.exe').strip() else: self.__paths = self.get_msvc_paths("path") @@ -295,6 +295,8 @@ class MSVCCompiler(CCompiler) : '/Z7', '/D_DEBUG'] self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] + cflags_env = os.environ.get('CFLAGS', '').strip().split() + ldflags_env = os.environ.get('LDFLAGS', '').strip().split() if self.__version >= 7: self.ldflags_shared_debug = [ '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG' @@ -303,9 +305,13 @@ class MSVCCompiler(CCompiler) : self.ldflags_shared_debug = [ '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG' ] + self.ldflags_shared_debug.extend(ldflags_env) self.ldflags_static = [ '/nologo'] self.initialized = True + self.compile_options.extend(cflags_env) + self.compile_options_debug.extend(cflags_env) + self.ldflags_shared.extend(ldflags_env) # -- Worker methods ------------------------------------------------ @@ -563,7 +569,7 @@ class MSVCCompiler(CCompiler) : # Helper methods for using the MSVC registry settings def find_exe(self, exe): - """Return path to an MSVC executable program. + """Return path to an executable program. Tries to find the program in several places: first, one of the MSVC program search paths from the registry; next, the directories @@ -579,8 +585,9 @@ class MSVCCompiler(CCompiler) : # didn't find it; try existing path for p in os.environ['Path'].split(';'): fn = os.path.join(os.path.abspath(p),exe) - if os.path.isfile(fn): - return fn + for abs_path in [fn, fn+'.exe']: + if os.path.isfile(abs_path): + return abs_path return exe -- 1.9.1