From d7c753889dc9494de241b04d06f1117f4704bdf3 Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Thu, 26 Jan 2017 12:11:53 +0000 Subject: [PATCH 1/3] build,tools: add support for VS2017 to gyp Add support for creating VS2017 projects to gyp. --- tools/gyp/pylib/gyp/MSVSVersion.py | 33 ++++++++++++++++++++++++++- tools/gyp/pylib/gyp/generator/msvs.py | 14 ++++++++++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/tools/gyp/pylib/gyp/MSVSVersion.py b/tools/gyp/pylib/gyp/MSVSVersion.py index d9bfa684fa30c2..1ed016502a7531 100644 --- a/tools/gyp/pylib/gyp/MSVSVersion.py +++ b/tools/gyp/pylib/gyp/MSVSVersion.py @@ -84,6 +84,10 @@ def SetupScript(self, target_arch): # vcvars32, which it can only find if VS??COMNTOOLS is set, which it # isn't always. if target_arch == 'x86': + if self.short_name == '2017': + return [os.path.normpath( + os.path.join(self.path, 'Common7/Tools/VsDevCmd.bat')), '/no_logo', + '/arch=x86'] if self.short_name >= '2013' and self.short_name[-1] != 'e' and ( os.environ.get('PROCESSOR_ARCHITECTURE') == 'AMD64' or os.environ.get('PROCESSOR_ARCHITEW6432') == 'AMD64'): @@ -96,6 +100,10 @@ def SetupScript(self, target_arch): os.path.join(self.path, 'Common7/Tools/vsvars32.bat'))] else: assert target_arch == 'x64' + if self.short_name == '2017': + return [os.path.normpath( + os.path.join(self.path, 'Common7/Tools/VsDevCmd.bat')), '/no_logo', + '/arch=x64'] arg = 'x86_amd64' # Use the 64-on-64 compiler if we're not using an express # edition and we're running on a 64bit OS. @@ -226,6 +234,15 @@ def _CreateVersion(name, path, sdk_based=False): if path: path = os.path.normpath(path) versions = { + '2017': VisualStudioVersion('2017', + 'Visual Studio 2017', + solution_version='12.00', + project_version='14.0', + flat_sln=False, + uses_vcxproj=True, + path=path, + sdk_based=sdk_based, + default_toolset='v141'), '2015': VisualStudioVersion('2015', 'Visual Studio 2015', solution_version='12.00', @@ -346,6 +363,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express): 2012(e) - Visual Studio 2012 (11) 2013(e) - Visual Studio 2013 (12) 2015 - Visual Studio 2015 (14) + 2017 - Visual Studio 2017 (15) Where (e) is e for express editions of MSVS and blank otherwise. """ version_to_year = { @@ -355,6 +373,7 @@ def _DetectVisualStudioVersions(versions_to_check, force_express): '11.0': '2012', '12.0': '2013', '14.0': '2015', + '15.0': '2017', } versions = [] for version in versions_to_check: @@ -395,6 +414,17 @@ def _DetectVisualStudioVersions(versions_to_check, force_express): versions.append(_CreateVersion(version_to_year[version] + 'e', os.path.join(path, '..'), sdk_based=True)) + if version == '15.0': + # The VC++ 2017 install location needs to be located using COM instead of + # the registry. For details see: + # https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/ + # For now we use a hardcoded default with an environment variable + # override. + path = r'C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional' + path = os.environ.get('vs2017_install', path) + if os.path.exists(path): + versions.append(_CreateVersion('2017', path)) + return versions @@ -410,7 +440,7 @@ def SelectVisualStudioVersion(version='auto', allow_fallback=True): if version == 'auto': version = os.environ.get('GYP_MSVS_VERSION', 'auto') version_map = { - 'auto': ('14.0', '12.0', '10.0', '9.0', '8.0', '11.0'), + 'auto': ('15.0', '14.0', '12.0', '10.0', '9.0', '8.0', '11.0'), '2005': ('8.0',), '2005e': ('8.0',), '2008': ('9.0',), @@ -422,6 +452,7 @@ def SelectVisualStudioVersion(version='auto', allow_fallback=True): '2013': ('12.0',), '2013e': ('12.0',), '2015': ('14.0',), + '2017': ('15.0',), } override_path = os.environ.get('GYP_MSVS_OVERRIDE_PATH') if override_path: diff --git a/tools/gyp/pylib/gyp/generator/msvs.py b/tools/gyp/pylib/gyp/generator/msvs.py index 44cc1304a2e8ed..7dd24f68403652 100644 --- a/tools/gyp/pylib/gyp/generator/msvs.py +++ b/tools/gyp/pylib/gyp/generator/msvs.py @@ -2622,7 +2622,7 @@ def _GetMSBuildProjectConfigurations(configurations): return [group] -def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name): +def _GetMSBuildGlobalProperties(spec, version, guid, gyp_file_name): namespace = os.path.splitext(gyp_file_name)[0] properties = [ ['PropertyGroup', {'Label': 'Globals'}, @@ -2662,6 +2662,15 @@ def _GetMSBuildGlobalProperties(spec, guid, gyp_file_name): else: properties[0].append(['ApplicationType', 'Windows Store']) + msvs_windows_sdk_version = None + if msvs_windows_sdk_version == None and version.ShortName() == '2017': + vs2017_sdk = '10.0.14393.0' + vs2017_sdk = os.environ.get('vs2017_sdk', vs2017_sdk) + if vs2017_sdk: + msvs_windows_sdk_version = vs2017_sdk + if msvs_windows_sdk_version: + properties[0].append(['WindowsTargetPlatformVersion', + str(msvs_windows_sdk_version)]) return properties def _GetMSBuildConfigurationDetails(spec, build_file): @@ -3295,7 +3304,8 @@ def _GenerateMSBuildProject(project, options, version, generator_flags): }] content += _GetMSBuildProjectConfigurations(configurations) - content += _GetMSBuildGlobalProperties(spec, project.guid, project_file_name) + content += _GetMSBuildGlobalProperties(spec, version, project.guid, + project_file_name) content += import_default_section content += _GetMSBuildConfigurationDetails(spec, project.build_file) if spec.get('msvs_enable_winphone'): From a1d8608496157b704f96462fd7572c37689aa3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Wed, 15 Mar 2017 13:31:44 +0000 Subject: [PATCH 2/3] win,build: add Visual Studio 2017 support Add support for Visual Studio 2017. A C# script, compiled and executed by PowerShell, is used to query the COM server about the location of VS installation and installed SDK version, filtering installations that miss the required components. --- .gitignore | 1 + BUILDING.md | 3 + tools/Find-VS2017.cs | 269 +++++++++++++++++++++++++++++++++++++++++++ vcbuild.bat | 32 ++++- 4 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 tools/Find-VS2017.cs diff --git a/.gitignore b/.gitignore index 4f129c4581ba8f..b3f74791c07383 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,7 @@ ipch/ *.VC.opendb .vs/ .vscode/ +/Set_VS*.bat /config.mk /config.gypi diff --git a/BUILDING.md b/BUILDING.md index a28759e1c7cc1e..3ca51bec38ab2c 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -111,6 +111,9 @@ Prerequisites: * [Visual Studio 2015 Update 3](https://www.visualstudio.com/), all editions including the Community edition (remember to select "Common Tools for Visual C++ 2015" feature during installation). + * [Visual Studio 2017](https://www.visualstudio.com/), all editions. The + required components are "VC++ 2017 v141 toolset", "Visual Studio C++ core + features" and one of the "Windows 10 SDK". * Basic Unix tools required for some tests, [Git for Windows](http://git-scm.com/download/win) includes Git Bash and tools which can be included in the global `PATH`. diff --git a/tools/Find-VS2017.cs b/tools/Find-VS2017.cs new file mode 100644 index 00000000000000..6d8b28b9e79773 --- /dev/null +++ b/tools/Find-VS2017.cs @@ -0,0 +1,269 @@ +// Copyright 2017 - Refael Ackermann +// Distributed under MIT style license +// See accompanying file LICENSE at https://github.com/node4good/windows-autoconf + +// Usage: +// powershell -ExecutionPolicy Unrestricted -Version "2.0" -Command "&{Add-Type -Path Find-VS2017.cs; [VisualStudioConfiguration.Main]::Query()}" +using System; +using System.Text; +using System.Runtime.InteropServices; + +namespace VisualStudioConfiguration +{ + [Flags] + public enum InstanceState : uint + { + None = 0, + Local = 1, + Registered = 2, + NoRebootRequired = 4, + NoErrors = 8, + Complete = 4294967295, + } + + [Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface IEnumSetupInstances + { + + void Next([MarshalAs(UnmanagedType.U4), In] int celt, + [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt, + [MarshalAs(UnmanagedType.U4)] out int pceltFetched); + + void Skip([MarshalAs(UnmanagedType.U4), In] int celt); + + void Reset(); + + [return: MarshalAs(UnmanagedType.Interface)] + IEnumSetupInstances Clone(); + } + + [Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupConfiguration + { + } + + [Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupConfiguration2 : ISetupConfiguration + { + + [return: MarshalAs(UnmanagedType.Interface)] + IEnumSetupInstances EnumInstances(); + + [return: MarshalAs(UnmanagedType.Interface)] + ISetupInstance GetInstanceForCurrentProcess(); + + [return: MarshalAs(UnmanagedType.Interface)] + ISetupInstance GetInstanceForPath([MarshalAs(UnmanagedType.LPWStr), In] string path); + + [return: MarshalAs(UnmanagedType.Interface)] + IEnumSetupInstances EnumAllInstances(); + } + + [Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupInstance + { + } + + [Guid("89143C9A-05AF-49B0-B717-72E218A2185C")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupInstance2 : ISetupInstance + { + [return: MarshalAs(UnmanagedType.BStr)] + string GetInstanceId(); + + [return: MarshalAs(UnmanagedType.Struct)] + System.Runtime.InteropServices.ComTypes.FILETIME GetInstallDate(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetInstallationName(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetInstallationPath(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetInstallationVersion(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetDisplayName([MarshalAs(UnmanagedType.U4), In] int lcid); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetDescription([MarshalAs(UnmanagedType.U4), In] int lcid); + + [return: MarshalAs(UnmanagedType.BStr)] + string ResolvePath([MarshalAs(UnmanagedType.LPWStr), In] string pwszRelativePath); + + [return: MarshalAs(UnmanagedType.U4)] + InstanceState GetState(); + + [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)] + ISetupPackageReference[] GetPackages(); + + ISetupPackageReference GetProduct(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetProductPath(); + + [return: MarshalAs(UnmanagedType.VariantBool)] + bool IsLaunchable(); + + [return: MarshalAs(UnmanagedType.VariantBool)] + bool IsComplete(); + + [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)] + ISetupPropertyStore GetProperties(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetEnginePath(); + } + + [Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupPackageReference + { + + [return: MarshalAs(UnmanagedType.BStr)] + string GetId(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetVersion(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetChip(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetLanguage(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetBranch(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetType(); + + [return: MarshalAs(UnmanagedType.BStr)] + string GetUniqueId(); + + [return: MarshalAs(UnmanagedType.VariantBool)] + bool GetIsExtension(); + } + + [Guid("c601c175-a3be-44bc-91f6-4568d230fc83")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [ComImport] + public interface ISetupPropertyStore + { + + [return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] + string[] GetNames(); + + object GetValue([MarshalAs(UnmanagedType.LPWStr), In] string pwszName); + } + + [Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")] + [CoClass(typeof(SetupConfigurationClass))] + [ComImport] + public interface SetupConfiguration : ISetupConfiguration2, ISetupConfiguration + { + } + + [Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")] + [ClassInterface(ClassInterfaceType.None)] + [ComImport] + public class SetupConfigurationClass + { + } + + public static class Main + { + public static void Query() + { + ISetupConfiguration query = new SetupConfiguration(); + ISetupConfiguration2 query2 = (ISetupConfiguration2)query; + IEnumSetupInstances e = query2.EnumAllInstances(); + + int pceltFetched; + ISetupInstance2[] rgelt = new ISetupInstance2[1]; + while (true) + { + e.Next(1, rgelt, out pceltFetched); + if (pceltFetched <= 0) + { + Console.WriteLine("No usable installation of VS2017 found"); + return; + } + if (CheckInstance(rgelt[0])) + return; + } + } + + private static bool CheckInstance(ISetupInstance2 setupInstance2) + { + // Visual Studio Community 2017 component directory: + // https://www.visualstudio.com/en-us/productinfo/vs2017-install-product-Community.workloads + + string path = setupInstance2.GetInstallationPath(); + Console.WriteLine(String.Format("Found VS2017 installation at: {0}", path)); + + bool hasMSBuild = false; + bool hasVCTools = false; + uint Win10SDKVer = 0; + bool hasWin8SDK = false; + + foreach (ISetupPackageReference package in setupInstance2.GetPackages()) + { + const string Win10SDKPrefix = "Microsoft.VisualStudio.Component.Windows10SDK."; + + string id = package.GetId(); + if (id == "Microsoft.VisualStudio.VC.MSBuild.Base") + hasMSBuild = true; + else if (id == "Microsoft.VisualStudio.Component.VC.Tools.x86.x64") + hasVCTools = true; + else if (id.StartsWith(Win10SDKPrefix)) + Win10SDKVer = Math.Max(Win10SDKVer, UInt32.Parse(id.Substring(Win10SDKPrefix.Length))); + else if (id == "Microsoft.VisualStudio.Component.Windows81SDK") + hasWin8SDK = true; + else + continue; + + Console.WriteLine(String.Format(" - Found {0}", id)); + } + + if (!hasMSBuild) + Console.WriteLine(" - Missing Visual Studio C++ core features (Microsoft.VisualStudio.VC.MSBuild.Base)"); + if (!hasVCTools) + Console.WriteLine(" - Missing VC++ 2017 v141 toolset (x86,x64) (Microsoft.VisualStudio.Component.VC.Tools.x86.x64)"); + if ((Win10SDKVer == 0) && (!hasWin8SDK)) + Console.WriteLine(" - Missing a Windows SDK (Microsoft.VisualStudio.Component.Windows10SDK.* or Microsoft.VisualStudio.Component.Windows81SDK)"); + + if (hasMSBuild && hasVCTools) + { + if (Win10SDKVer > 0) + { + Console.WriteLine(" - Using this installation with Windows 10 SDK"); + string[] lines = { String.Format("set \"VS2017_INSTALL={0}\"", path), String.Format("set \"VS2017_SDK=10.0.{0}.0\"", Win10SDKVer) }; + System.IO.File.WriteAllLines(@"Set_VS2017.bat", lines); + return true; + } + else if (hasWin8SDK) + { + Console.WriteLine(" - Using this installation with Windows 8.1 SDK"); + string[] lines = { String.Format("set \"VS2017_INSTALL={0}\"", path), "set \"VS2017_SDK=8.1\"" }; + System.IO.File.WriteAllLines(@"Set_VS2017.bat", lines); + return true; + } + } + + Console.WriteLine(" - Some required components are missing, not using this installation"); + return false; + } + } +} diff --git a/vcbuild.bat b/vcbuild.bat index f07c50b0fbfc91..4cfdad57cf18f3 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -50,6 +50,7 @@ if /i "%1"=="ia32" set target_arch=x86&goto arg-ok if /i "%1"=="x86" set target_arch=x86&goto arg-ok if /i "%1"=="x64" set target_arch=x64&goto arg-ok if /i "%1"=="vc2015" set target_env=vc2015&goto arg-ok +if /i "%1"=="vc2017" set target_env=vc2017&goto arg-ok if /i "%1"=="noprojgen" set noprojgen=1&goto arg-ok if /i "%1"=="nobuild" set nobuild=1&goto arg-ok if /i "%1"=="nosign" set "sign="&echo Note: vcbuild no longer signs by default. "nosign" is redundant.&goto arg-ok @@ -137,7 +138,36 @@ if defined noprojgen if defined nobuild if not defined sign if not defined msi g @rem Set environment for msbuild +@rem Look for Visual Studio 2017 +:vc-set-2017 +if defined target_env if "%target_env%" NEQ "vc2017" goto vc-set-2015 +echo Looking for Visual Studio 2017 +del /F /Q Set_VS2017.bat > nul 2> nul +"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Unrestricted -Command ^ + "&{Add-Type -Path .\tools\Find-VS2017.cs; [VisualStudioConfiguration.Main]::Query()}" 2> nul +if not exist Set_VS2017.bat goto vc-set-2015 +call Set_VS2017.bat +if not defined VS2017_INSTALL goto vc-set-2015 +if not defined VS2017_SDK goto vc-set-2015 +echo Found Visual Studio 2017 +if defined msi ( + echo Cannot build the MSI with Visual Studio 2017 - it is not yet supported by WiX + goto vc-set-2015 +) +if "%target_arch%"=="x86" set "VSARCH=-arch=x86" +if "%target_arch%"=="x64" set "VSARCH=-arch=amd64" +if "%VCVARS_VER%" NEQ "150" ( + call "%VS2017_INSTALL%\Common7\Tools\VsDevCmd.bat" %VSARCH% /no_logo + set VCVARS_VER=150 +) +if not defined VCINSTALLDIR goto vc-set-2015 +set GYP_MSVS_VERSION=2017 +set PLATFORM_TOOLSET=v141 +goto msbuild-found + @rem Look for Visual Studio 2015 +:vc-set-2015 +if defined target_env if "%target_env%" NEQ "vc2015" goto msbuild-not-found echo Looking for Visual Studio 2015 if not defined VS140COMNTOOLS goto msbuild-not-found if not exist "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" goto msbuild-not-found @@ -372,7 +402,7 @@ echo Failed to create vc project files. goto exit :help -echo vcbuild.bat [debug/release] [msi] [test-all/test-uv/test-inspector/test-internet/test-pummel/test-simple/test-message] [clean] [noprojgen] [small-icu/full-icu/without-intl] [nobuild] [sign] [x86/x64] [vc2015] [download-all] [enable-vtune] +echo vcbuild.bat [debug/release] [msi] [test-all/test-uv/test-inspector/test-internet/test-pummel/test-simple/test-message] [clean] [noprojgen] [small-icu/full-icu/without-intl] [nobuild] [sign] [x86/x64] [vc2015/vc2017] [download-all] [enable-vtune] echo Examples: echo vcbuild.bat : builds release build echo vcbuild.bat debug : builds debug build From d085fcf95fb5d248b2de46a936c0ea61be554147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Reis?= Date: Thu, 16 Mar 2017 19:19:49 +0000 Subject: [PATCH 3/3] fixup: setPath string --- tools/Find-VS2017.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/Find-VS2017.cs b/tools/Find-VS2017.cs index 6d8b28b9e79773..54a812ee160316 100644 --- a/tools/Find-VS2017.cs +++ b/tools/Find-VS2017.cs @@ -246,17 +246,18 @@ private static bool CheckInstance(ISetupInstance2 setupInstance2) if (hasMSBuild && hasVCTools) { + string setPath = String.Format("set \"VS2017_INSTALL={0}\"", path); if (Win10SDKVer > 0) { Console.WriteLine(" - Using this installation with Windows 10 SDK"); - string[] lines = { String.Format("set \"VS2017_INSTALL={0}\"", path), String.Format("set \"VS2017_SDK=10.0.{0}.0\"", Win10SDKVer) }; + string[] lines = { setPath, String.Format("set \"VS2017_SDK=10.0.{0}.0\"", Win10SDKVer) }; System.IO.File.WriteAllLines(@"Set_VS2017.bat", lines); return true; } else if (hasWin8SDK) { Console.WriteLine(" - Using this installation with Windows 8.1 SDK"); - string[] lines = { String.Format("set \"VS2017_INSTALL={0}\"", path), "set \"VS2017_SDK=8.1\"" }; + string[] lines = { setPath, "set \"VS2017_SDK=8.1\"" }; System.IO.File.WriteAllLines(@"Set_VS2017.bat", lines); return true; }