From fbffeeb7b9f23cb1a6b1d4643a57f25d8cd5c17b Mon Sep 17 00:00:00 2001 From: Rohit Jamuar Date: Thu, 10 Dec 2015 17:14:53 -0600 Subject: [PATCH] Choosing compiler/linker/archiver (on Win) using env vars + extending distutils to respect CFLAGS/LDFLAGS --- Lib/distutils/msvc9compiler.py | 49 +++++++++++++++++++++++++--------------- Lib/distutils/msvccompiler.py | 51 +++++++++++++++++++++++++----------------- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py index 82bbad0..f9be126 100644 --- a/Lib/distutils/msvc9compiler.py +++ b/Lib/distutils/msvc9compiler.py @@ -358,12 +358,16 @@ 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"): + compiler_to_use = os.environ.get('CC', 'cl').strip() + linker_to_use = os.environ.get('LD', 'link').strip() + archiver_to_use = os.environ.get('AR', 'lib').strip() + if all(["DISTUTILS_USE_SDK" in os.environ, "MSSdk" in os.environ, + self.find_exe(compiler_to_use)]): # 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.cc = compiler_to_use + self.linker = linker_to_use + self.lib = archiver_to_use self.rc = "rc.exe" self.mc = "mc.exe" else: @@ -393,9 +397,9 @@ class MSVCCompiler(CCompiler) : "version of the compiler, but it isn't installed." % self.__product) - self.cc = self.find_exe("cl.exe") - self.linker = self.find_exe("link.exe") - self.lib = self.find_exe("lib.exe") + self.cc = self.find_exe(compiler_to_use) + self.linker = self.find_exe(linker_to_use) + self.lib = self.find_exe(archiver_to_use) self.rc = self.find_exe("rc.exe") # resource compiler self.mc = self.find_exe("mc.exe") # message compiler #self.set_path_env_var('lib') @@ -424,13 +428,20 @@ class MSVCCompiler(CCompiler) : '/Z7', '/D_DEBUG'] self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] + ldflags_env = os.environ.get('LDFLAGS', '').strip().split() + cflags_env = os.environ.get('CFLAGS', '').strip().split() if self.__version >= 7: self.ldflags_shared_debug = [ '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG', '/pdb:None' ] + 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 ------------------------------------------------ @@ -778,24 +789,26 @@ class MSVCCompiler(CCompiler) : # Helper methods for using the MSVC registry settings - def find_exe(self, exe): - """Return path to an MSVC executable program. + def find_exe(self, cmd): + """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 + program search paths from the registry; next, the directories in the PATH environment variable. If any of those work, return an absolute path that is known to exist. If none of them work, just - return the original program name, 'exe'. + return the original program name, 'cmd'. """ for p in self.__paths: - fn = os.path.join(os.path.abspath(p), exe) - if os.path.isfile(fn): - return fn + fn = os.path.join(os.path.abspath(p), cmd) + for abs_path in [fn, fn+'.exe']: + if os.path.isfile(abs_path): + return abs_path # 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 + fn = os.path.join(os.path.abspath(p), cmd) + for abs_path in [fn, fn+'.exe']: + if os.path.isfile(abs_path): + return abs_path - return exe + return cmd diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py index be34b78..35b0c16 100644 --- a/Lib/distutils/msvccompiler.py +++ b/Lib/distutils/msvccompiler.py @@ -251,12 +251,16 @@ 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"): + compiler_to_use = os.environ.get('CC', 'cl').strip() + linker_to_use = os.environ.get('LD', 'link').strip() + archiver_to_use = os.environ.get('AR', 'lib').strip() + if all(["DISTUTILS_USE_SDK" in os.environ, "MSSdk" in os.environ, + self.find_exe(compiler_to_use)]): # 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.cc = compiler_to_use + self.linker = linker_to_use + self.lib = archiver_to_use self.rc = "rc.exe" self.mc = "mc.exe" else: @@ -268,9 +272,9 @@ class MSVCCompiler (CCompiler) : "and extensions need to be built with the same " "version of the compiler, but it isn't installed." % self.__product) - self.cc = self.find_exe("cl.exe") - self.linker = self.find_exe("link.exe") - self.lib = self.find_exe("lib.exe") + self.cc = self.find_exe(compiler_to_use) + self.linker = self.find_exe(linker_to_use) + self.lib = self.find_exe(archiver_to_use) self.rc = self.find_exe("rc.exe") # resource compiler self.mc = self.find_exe("mc.exe") # message compiler self.set_path_env_var('lib') @@ -310,6 +314,12 @@ class MSVCCompiler (CCompiler) : self.ldflags_static = [ '/nologo'] self.initialized = True + ldflags_env = os.environ.get('LDFLAGS', '').strip().split() + cflags_env = os.environ.get('CFLAGS', '').strip().split() + self.compile_options.extend(cflags_env) + self.compile_options_debug.extend(cflags_env) + self.ldflags_shared.extend(ldflags_env) + self.ldflags_shared_debug.extend(ldflags_env) # -- Worker methods ------------------------------------------------ @@ -576,28 +586,29 @@ class MSVCCompiler (CCompiler) : # Helper methods for using the MSVC registry settings - def find_exe(self, exe): - """Return path to an MSVC executable program. + def find_exe(self, cmd): + """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 + program search paths from the registry; next, the directories in the PATH environment variable. If any of those work, return an absolute path that is known to exist. If none of them work, just - return the original program name, 'exe'. + return the original program name, 'cmd'. """ for p in self.__paths: - fn = os.path.join(os.path.abspath(p), exe) - if os.path.isfile(fn): - return fn + fn = os.path.join(os.path.abspath(p), cmd) + for abs_path in [fn, fn+'.exe']: + if os.path.isfile(abs_path): + return abs_path # didn't find it; try existing path - for p in string.split(os.environ['Path'],';'): - fn = os.path.join(os.path.abspath(p),exe) - if os.path.isfile(fn): - return fn + for p in string.split(os.environ['Path'], ';'): + fn = os.path.join(os.path.abspath(p), cmd) + for abs_path in [fn, fn+'.exe']: + if os.path.isfile(abs_path): + return abs_path - return exe + return cmd def get_msvc_paths(self, path, platform='x86'): """Get a list of devstudio directories (include, lib or path). -- 1.9.1