From 20b3b3eaa74935d4854b63f75d893def27a4248e Mon Sep 17 00:00:00 2001 From: JGoutin Date: Mon, 20 Mar 2017 17:45:57 +0100 Subject: Update for MS BuildTools 2017 --- setuptools/msvc.py | 96 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 81 insertions(+), 15 deletions(-) (limited to 'setuptools') diff --git a/setuptools/msvc.py b/setuptools/msvc.py index d41daec4..71fe24cd 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -13,6 +13,7 @@ Microsoft Visual C++ 10.0: Microsoft Visual C++ 14.0: Microsoft Visual C++ Build Tools 2015 (x86, x64, arm) + Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64) """ import os @@ -150,6 +151,7 @@ def msvc14_get_vc_env(plat_spec): ------------------------- Microsoft Visual C++ 14.0: Microsoft Visual C++ Build Tools 2015 (x86, x64, arm) + Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64) Parameters ---------- @@ -411,7 +413,7 @@ class RegistryInfo: ------ str: value """ - node64 = '' if self.pi.current_is_x86() or x86 else r'\Wow6432Node' + node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node' return os.path.join('Software', node64, 'Microsoft', key) def lookup(self, key, name): @@ -483,12 +485,13 @@ class SystemInfo: """ Find all available Microsoft Visual C++ versions. """ - vckeys = (self.ri.vc, self.ri.vc_for_python) + ms = self.ri.microsoft + vckeys = (self.ri.vc, self.ri.vc_for_python, self.ri.vs) vc_vers = [] for hkey in self.ri.HKEYS: for key in vckeys: try: - bkey = winreg.OpenKey(hkey, key, 0, winreg.KEY_READ) + bkey = winreg.OpenKey(hkey, ms(key), 0, winreg.KEY_READ) except (OSError, IOError): continue subkeys, values, _ = winreg.QueryInfoKey(bkey) @@ -525,9 +528,24 @@ class SystemInfo: """ Microsoft Visual C++ directory. """ - # Default path - default = r'Microsoft Visual Studio %0.1f\VC' % self.vc_ver - guess_vc = os.path.join(self.ProgramFilesx86, default) + self.VSInstallDir + + # Default path starting VS2017 + guess_vc = '' + if self.vc_ver > 14.0: + default = r'VC\Tools\MSVC' + guess_vc = os.path.join(self.VSInstallDir, default) + # Subdir with VC exact version as name + try: + vc_exact_ver = os.listdir(guess_vc)[-1] + guess_vc = os.path.join(guess_vc, vc_exact_ver) + except (OSError, IOError, IndexError): + guess_vc = '' + + # Legacy default path + if not guess_vc: + default = r'Microsoft Visual Studio %0.1f\VC' % self.vc_ver + guess_vc = os.path.join(self.ProgramFilesx86, default) # Try to get "VC++ for Python" path from registry as default path reg_path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver) @@ -725,9 +743,19 @@ class SystemInfo: bits: int Platform number of bits: 32 or 64. """ - # Find actual .NET version + # Find actual .NET version in registry ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits) or '' + # If nothing in registry, look in Framework folder + if not ver: + dot_net_dir = (self.FrameworkDir32 if bits == 32 else + self.FrameworkDir64) + for dir_name in reversed(os.listdir(dot_net_dir)): + if (os.path.isdir(os.path.join(dot_net_dir, dir_name)) and + dir_name.startswith('v')): + ver = dir_name + break + # Set .NET versions for specified MSVC++ version if self.vc_ver >= 12.0: frameworkver = (ver, 'v4.0') @@ -810,7 +838,10 @@ class EnvironmentInfo: """ Microsoft Visual C++ & Microsoft Foundation Class Libraries """ - arch_subdir = self.pi.target_dir(hidex86=True) + if self.vc_ver >= 15.0: + arch_subdir = self.pi.target_dir(x64=True) + else: + arch_subdir = self.pi.target_dir(hidex86=True) paths = ['Lib%s' % arch_subdir, r'ATLMFC\Lib%s' % arch_subdir] if self.vc_ver >= 14.0: @@ -840,10 +871,20 @@ class EnvironmentInfo: if arch_subdir: tools += [os.path.join(si.VCInstallDir, 'Bin%s' % arch_subdir)] - if self.vc_ver >= 14.0: + if self.vc_ver == 14.0: path = 'Bin%s' % self.pi.current_dir(hidex86=True) tools += [os.path.join(si.VCInstallDir, path)] + elif self.vc_ver >= 15.0: + host_dir = (r'bin\HostX86%s' if self.pi.current_is_x86() else + r'bin\HostX64%s') + tools += [os.path.join( + si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))] + + if self.pi.current_cpu != self.pi.target_cpu: + tools += [os.path.join( + si.VCInstallDir, host_dir % self.pi.current_dir(x64=True))] + else: tools += [os.path.join(si.VCInstallDir, 'Bin')] @@ -933,8 +974,11 @@ class EnvironmentInfo: """ Microsoft Windows SDK Tools """ - bin_dir = 'Bin' if self.vc_ver <= 11.0 else r'Bin\x86' - tools = [os.path.join(self.si.WindowsSdkDir, bin_dir)] + if self.vc_ver < 15.0: + bin_dir = 'Bin' if self.vc_ver <= 11.0 else r'Bin\x86' + tools = [os.path.join(self.si.WindowsSdkDir, bin_dir)] + else: + tools = [] if not self.pi.current_is_x86(): arch_subdir = self.pi.current_dir(x64=True) @@ -949,6 +993,12 @@ class EnvironmentInfo: path = r'Bin\NETFX 4.0 Tools%s' % arch_subdir tools += [os.path.join(self.si.WindowsSdkDir, path)] + elif self.vc_ver >= 15.0: + path = os.path.join(self.si.WindowsSdkDir, 'Bin') + arch_subdir = self.pi.current_dir(x64=True) + sdkver = self._get_content_dirname(path, slash=False) + tools += [os.path.join(path, r'%s%s' % (sdkver, arch_subdir))] + if self.si.WindowsSDKExecutablePath: tools += [self.si.WindowsSDKExecutablePath] @@ -1023,10 +1073,21 @@ class EnvironmentInfo: """ if self.vc_ver < 12.0: return [] + elif self.vc_ver < 15.0: + base_path = self.si.ProgramFilesx86 + arch_subdir = self.pi.current_dir(hidex86=True) + else: + base_path = self.si.VSInstallDir + arch_subdir = '' - arch_subdir = self.pi.current_dir(hidex86=True) path = r'MSBuild\%0.1f\bin%s' % (self.vc_ver, arch_subdir) - return [os.path.join(self.si.ProgramFilesx86, path)] + build = [os.path.join(base_path, path)] + + if self.vc_ver >= 15.0: + # Add Roslyn C# & Visual Basic Compiler + build += [os.path.join(base_path, path, 'Roslyn')] + + return build @property def HTMLHelpWorkshop(self): @@ -1170,7 +1231,7 @@ class EnvironmentInfo: seen_add(k) yield element - def _get_content_dirname(self, path): + def _get_content_dirname(self, path, slash=True): """ Return name of the first dir in path or '' if no dir found. @@ -1178,6 +1239,8 @@ class EnvironmentInfo: ---------- path: str Path where search dir. + slash: bool + If not True, only return "name" not "name\" Return ------ @@ -1187,7 +1250,10 @@ class EnvironmentInfo: try: name = os.listdir(path) if name: - return '%s\\' % name[0] + name = name[0] + if slash: + return '%s\\' % name + return name return '' except (OSError, IOError): return '' -- cgit v1.2.1 From ac59ef12d16c13533ead6401bdb4727016be77e3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 7 Apr 2017 21:52:18 -0400 Subject: extract two functions for guessing the VC version; ref #995 --- setuptools/msvc.py | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) (limited to 'setuptools') diff --git a/setuptools/msvc.py b/setuptools/msvc.py index 71fe24cd..cf556ad3 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -530,22 +530,7 @@ class SystemInfo: """ self.VSInstallDir - # Default path starting VS2017 - guess_vc = '' - if self.vc_ver > 14.0: - default = r'VC\Tools\MSVC' - guess_vc = os.path.join(self.VSInstallDir, default) - # Subdir with VC exact version as name - try: - vc_exact_ver = os.listdir(guess_vc)[-1] - guess_vc = os.path.join(guess_vc, vc_exact_ver) - except (OSError, IOError, IndexError): - guess_vc = '' - - # Legacy default path - if not guess_vc: - default = r'Microsoft Visual Studio %0.1f\VC' % self.vc_ver - guess_vc = os.path.join(self.ProgramFilesx86, default) + guess_vc = self._guess_vc() or self._guess_vc_legacy() # Try to get "VC++ for Python" path from registry as default path reg_path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver) @@ -561,6 +546,30 @@ class SystemInfo: return path + def _guess_vc(self): + """ + Locate Visual C for 2017 + """ + + if self.vc_ver <= 14.0: + return + + default = r'VC\Tools\MSVC' + guess_vc = os.path.join(self.VSInstallDir, default) + # Subdir with VC exact version as name + try: + vc_exact_ver = os.listdir(guess_vc)[-1] + return os.path.join(guess_vc, vc_exact_ver) + except (OSError, IOError, IndexError): + pass + + def _guess_vc_legacy(self): + """ + Locate Visual C for versions prior to 2017 + """ + default = r'Microsoft Visual Studio %0.1f\VC' % self.vc_ver + return os.path.join(self.ProgramFilesx86, default) + @property def WindowsSdkVersion(self): """ -- cgit v1.2.1 From 934d6707b1d8c55c930d458e39b11038e9276a4d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 7 Apr 2017 22:07:30 -0400 Subject: Extract method for finding .Net in the framework folder. Ref #995. --- setuptools/msvc.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'setuptools') diff --git a/setuptools/msvc.py b/setuptools/msvc.py index cf556ad3..1588cd2e 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -753,17 +753,9 @@ class SystemInfo: Platform number of bits: 32 or 64. """ # Find actual .NET version in registry - ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits) or '' - - # If nothing in registry, look in Framework folder - if not ver: - dot_net_dir = (self.FrameworkDir32 if bits == 32 else - self.FrameworkDir64) - for dir_name in reversed(os.listdir(dot_net_dir)): - if (os.path.isdir(os.path.join(dot_net_dir, dir_name)) and - dir_name.startswith('v')): - ver = dir_name - break + reg_ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits) + dot_net_dir = getattr(self, 'FrameworkDir%d' % bits) + ver = reg_ver or self._find_dot_net_in(dot_net_dir) or '' # Set .NET versions for specified MSVC++ version if self.vc_ver >= 12.0: @@ -777,6 +769,18 @@ class SystemInfo: frameworkver = ('v3.0', 'v2.0.50727') return frameworkver + def _find_dot_net_in(self, dot_net_dir): + """ + Find .Net in the Framework folder + """ + matching_dirs = ( + dir_name + for dir_name in reversed(os.listdir(dot_net_dir)) + if os.path.isdir(os.path.join(dot_net_dir, dir_name)) + and dir_name.startswith('v') + ) + return next(matching_dirs, None) + class EnvironmentInfo: """ -- cgit v1.2.1 From 9430e92f888a7c41f295373bd8a6ef8af967e2e1 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 7 Apr 2017 22:19:06 -0400 Subject: Move initialization into a single location. Ref #995. --- setuptools/msvc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/msvc.py b/setuptools/msvc.py index 1588cd2e..baf2021e 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -987,11 +987,11 @@ class EnvironmentInfo: """ Microsoft Windows SDK Tools """ + tools = [] + if self.vc_ver < 15.0: bin_dir = 'Bin' if self.vc_ver <= 11.0 else r'Bin\x86' - tools = [os.path.join(self.si.WindowsSdkDir, bin_dir)] - else: - tools = [] + tools += [os.path.join(self.si.WindowsSdkDir, bin_dir)] if not self.pi.current_is_x86(): arch_subdir = self.pi.current_dir(x64=True) -- cgit v1.2.1 From 3fa9efcbb390b87304ddc64551e9fca823694773 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 7 Apr 2017 22:23:18 -0400 Subject: Extract generator for simpler syntax. Ref #995. --- setuptools/msvc.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'setuptools') diff --git a/setuptools/msvc.py b/setuptools/msvc.py index baf2021e..c5a8aea0 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -987,16 +987,17 @@ class EnvironmentInfo: """ Microsoft Windows SDK Tools """ - tools = [] + return list(self._sdk_tools()) + def _sdk_tools(self): if self.vc_ver < 15.0: bin_dir = 'Bin' if self.vc_ver <= 11.0 else r'Bin\x86' - tools += [os.path.join(self.si.WindowsSdkDir, bin_dir)] + yield os.path.join(self.si.WindowsSdkDir, bin_dir) if not self.pi.current_is_x86(): arch_subdir = self.pi.current_dir(x64=True) path = 'Bin%s' % arch_subdir - tools += [os.path.join(self.si.WindowsSdkDir, path)] + yield os.path.join(self.si.WindowsSdkDir, path) if self.vc_ver == 10.0 or self.vc_ver == 11.0: if self.pi.target_is_x86(): @@ -1004,18 +1005,16 @@ class EnvironmentInfo: else: arch_subdir = self.pi.current_dir(hidex86=True, x64=True) path = r'Bin\NETFX 4.0 Tools%s' % arch_subdir - tools += [os.path.join(self.si.WindowsSdkDir, path)] + yield os.path.join(self.si.WindowsSdkDir, path) elif self.vc_ver >= 15.0: path = os.path.join(self.si.WindowsSdkDir, 'Bin') arch_subdir = self.pi.current_dir(x64=True) sdkver = self._get_content_dirname(path, slash=False) - tools += [os.path.join(path, r'%s%s' % (sdkver, arch_subdir))] + yield os.path.join(path, r'%s%s' % (sdkver, arch_subdir)) if self.si.WindowsSDKExecutablePath: - tools += [self.si.WindowsSDKExecutablePath] - - return tools + yield self.si.WindowsSDKExecutablePath @property def SdkSetup(self): -- cgit v1.2.1 From f357a32fdc9ce8e6a862efcbb9a0229f6f0a685c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 7 Apr 2017 22:30:49 -0400 Subject: Simplify _get_content_dirname by simply removing the trailing backslash. Ref #995. --- setuptools/msvc.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'setuptools') diff --git a/setuptools/msvc.py b/setuptools/msvc.py index c5a8aea0..9a911834 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -1010,7 +1010,7 @@ class EnvironmentInfo: elif self.vc_ver >= 15.0: path = os.path.join(self.si.WindowsSdkDir, 'Bin') arch_subdir = self.pi.current_dir(x64=True) - sdkver = self._get_content_dirname(path, slash=False) + sdkver = self._get_content_dirname(path).rstrip('\\') yield os.path.join(path, r'%s%s' % (sdkver, arch_subdir)) if self.si.WindowsSDKExecutablePath: @@ -1243,7 +1243,7 @@ class EnvironmentInfo: seen_add(k) yield element - def _get_content_dirname(self, path, slash=True): + def _get_content_dirname(self, path): """ Return name of the first dir in path or '' if no dir found. @@ -1251,8 +1251,6 @@ class EnvironmentInfo: ---------- path: str Path where search dir. - slash: bool - If not True, only return "name" not "name\" Return ------ @@ -1262,10 +1260,7 @@ class EnvironmentInfo: try: name = os.listdir(path) if name: - name = name[0] - if slash: - return '%s\\' % name - return name + return '%s\\' % name[0] return '' except (OSError, IOError): return '' -- cgit v1.2.1 From cd13a8c0c4ee765a8bd083863338dec4ba618d08 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 7 Apr 2017 22:33:28 -0400 Subject: Remove unnecessary raw string. Ref #995. --- setuptools/msvc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/msvc.py b/setuptools/msvc.py index 9a911834..35c02129 100644 --- a/setuptools/msvc.py +++ b/setuptools/msvc.py @@ -1011,7 +1011,7 @@ class EnvironmentInfo: path = os.path.join(self.si.WindowsSdkDir, 'Bin') arch_subdir = self.pi.current_dir(x64=True) sdkver = self._get_content_dirname(path).rstrip('\\') - yield os.path.join(path, r'%s%s' % (sdkver, arch_subdir)) + yield os.path.join(path, '%s%s' % (sdkver, arch_subdir)) if self.si.WindowsSDKExecutablePath: yield self.si.WindowsSDKExecutablePath -- cgit v1.2.1