Skip to content

Commit a1d8608

Browse files
committed
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.
1 parent d7c7538 commit a1d8608

File tree

4 files changed

+304
-1
lines changed

4 files changed

+304
-1
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ ipch/
5959
*.VC.opendb
6060
.vs/
6161
.vscode/
62+
/Set_VS*.bat
6263

6364
/config.mk
6465
/config.gypi

BUILDING.md

+3
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ Prerequisites:
111111
* [Visual Studio 2015 Update 3](https://www.visualstudio.com/), all editions
112112
including the Community edition (remember to select
113113
"Common Tools for Visual C++ 2015" feature during installation).
114+
* [Visual Studio 2017](https://www.visualstudio.com/), all editions. The
115+
required components are "VC++ 2017 v141 toolset", "Visual Studio C++ core
116+
features" and one of the "Windows 10 SDK".
114117
* Basic Unix tools required for some tests,
115118
[Git for Windows](http://git-scm.com/download/win) includes Git Bash
116119
and tools which can be included in the global `PATH`.

tools/Find-VS2017.cs

+269
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
// Copyright 2017 - Refael Ackermann
2+
// Distributed under MIT style license
3+
// See accompanying file LICENSE at https://github.com/node4good/windows-autoconf
4+
5+
// Usage:
6+
// powershell -ExecutionPolicy Unrestricted -Version "2.0" -Command "&{Add-Type -Path Find-VS2017.cs; [VisualStudioConfiguration.Main]::Query()}"
7+
using System;
8+
using System.Text;
9+
using System.Runtime.InteropServices;
10+
11+
namespace VisualStudioConfiguration
12+
{
13+
[Flags]
14+
public enum InstanceState : uint
15+
{
16+
None = 0,
17+
Local = 1,
18+
Registered = 2,
19+
NoRebootRequired = 4,
20+
NoErrors = 8,
21+
Complete = 4294967295,
22+
}
23+
24+
[Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")]
25+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
26+
[ComImport]
27+
public interface IEnumSetupInstances
28+
{
29+
30+
void Next([MarshalAs(UnmanagedType.U4), In] int celt,
31+
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt,
32+
[MarshalAs(UnmanagedType.U4)] out int pceltFetched);
33+
34+
void Skip([MarshalAs(UnmanagedType.U4), In] int celt);
35+
36+
void Reset();
37+
38+
[return: MarshalAs(UnmanagedType.Interface)]
39+
IEnumSetupInstances Clone();
40+
}
41+
42+
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
43+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
44+
[ComImport]
45+
public interface ISetupConfiguration
46+
{
47+
}
48+
49+
[Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")]
50+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
51+
[ComImport]
52+
public interface ISetupConfiguration2 : ISetupConfiguration
53+
{
54+
55+
[return: MarshalAs(UnmanagedType.Interface)]
56+
IEnumSetupInstances EnumInstances();
57+
58+
[return: MarshalAs(UnmanagedType.Interface)]
59+
ISetupInstance GetInstanceForCurrentProcess();
60+
61+
[return: MarshalAs(UnmanagedType.Interface)]
62+
ISetupInstance GetInstanceForPath([MarshalAs(UnmanagedType.LPWStr), In] string path);
63+
64+
[return: MarshalAs(UnmanagedType.Interface)]
65+
IEnumSetupInstances EnumAllInstances();
66+
}
67+
68+
[Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")]
69+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
70+
[ComImport]
71+
public interface ISetupInstance
72+
{
73+
}
74+
75+
[Guid("89143C9A-05AF-49B0-B717-72E218A2185C")]
76+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
77+
[ComImport]
78+
public interface ISetupInstance2 : ISetupInstance
79+
{
80+
[return: MarshalAs(UnmanagedType.BStr)]
81+
string GetInstanceId();
82+
83+
[return: MarshalAs(UnmanagedType.Struct)]
84+
System.Runtime.InteropServices.ComTypes.FILETIME GetInstallDate();
85+
86+
[return: MarshalAs(UnmanagedType.BStr)]
87+
string GetInstallationName();
88+
89+
[return: MarshalAs(UnmanagedType.BStr)]
90+
string GetInstallationPath();
91+
92+
[return: MarshalAs(UnmanagedType.BStr)]
93+
string GetInstallationVersion();
94+
95+
[return: MarshalAs(UnmanagedType.BStr)]
96+
string GetDisplayName([MarshalAs(UnmanagedType.U4), In] int lcid);
97+
98+
[return: MarshalAs(UnmanagedType.BStr)]
99+
string GetDescription([MarshalAs(UnmanagedType.U4), In] int lcid);
100+
101+
[return: MarshalAs(UnmanagedType.BStr)]
102+
string ResolvePath([MarshalAs(UnmanagedType.LPWStr), In] string pwszRelativePath);
103+
104+
[return: MarshalAs(UnmanagedType.U4)]
105+
InstanceState GetState();
106+
107+
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
108+
ISetupPackageReference[] GetPackages();
109+
110+
ISetupPackageReference GetProduct();
111+
112+
[return: MarshalAs(UnmanagedType.BStr)]
113+
string GetProductPath();
114+
115+
[return: MarshalAs(UnmanagedType.VariantBool)]
116+
bool IsLaunchable();
117+
118+
[return: MarshalAs(UnmanagedType.VariantBool)]
119+
bool IsComplete();
120+
121+
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
122+
ISetupPropertyStore GetProperties();
123+
124+
[return: MarshalAs(UnmanagedType.BStr)]
125+
string GetEnginePath();
126+
}
127+
128+
[Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")]
129+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
130+
[ComImport]
131+
public interface ISetupPackageReference
132+
{
133+
134+
[return: MarshalAs(UnmanagedType.BStr)]
135+
string GetId();
136+
137+
[return: MarshalAs(UnmanagedType.BStr)]
138+
string GetVersion();
139+
140+
[return: MarshalAs(UnmanagedType.BStr)]
141+
string GetChip();
142+
143+
[return: MarshalAs(UnmanagedType.BStr)]
144+
string GetLanguage();
145+
146+
[return: MarshalAs(UnmanagedType.BStr)]
147+
string GetBranch();
148+
149+
[return: MarshalAs(UnmanagedType.BStr)]
150+
string GetType();
151+
152+
[return: MarshalAs(UnmanagedType.BStr)]
153+
string GetUniqueId();
154+
155+
[return: MarshalAs(UnmanagedType.VariantBool)]
156+
bool GetIsExtension();
157+
}
158+
159+
[Guid("c601c175-a3be-44bc-91f6-4568d230fc83")]
160+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
161+
[ComImport]
162+
public interface ISetupPropertyStore
163+
{
164+
165+
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
166+
string[] GetNames();
167+
168+
object GetValue([MarshalAs(UnmanagedType.LPWStr), In] string pwszName);
169+
}
170+
171+
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
172+
[CoClass(typeof(SetupConfigurationClass))]
173+
[ComImport]
174+
public interface SetupConfiguration : ISetupConfiguration2, ISetupConfiguration
175+
{
176+
}
177+
178+
[Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")]
179+
[ClassInterface(ClassInterfaceType.None)]
180+
[ComImport]
181+
public class SetupConfigurationClass
182+
{
183+
}
184+
185+
public static class Main
186+
{
187+
public static void Query()
188+
{
189+
ISetupConfiguration query = new SetupConfiguration();
190+
ISetupConfiguration2 query2 = (ISetupConfiguration2)query;
191+
IEnumSetupInstances e = query2.EnumAllInstances();
192+
193+
int pceltFetched;
194+
ISetupInstance2[] rgelt = new ISetupInstance2[1];
195+
while (true)
196+
{
197+
e.Next(1, rgelt, out pceltFetched);
198+
if (pceltFetched <= 0)
199+
{
200+
Console.WriteLine("No usable installation of VS2017 found");
201+
return;
202+
}
203+
if (CheckInstance(rgelt[0]))
204+
return;
205+
}
206+
}
207+
208+
private static bool CheckInstance(ISetupInstance2 setupInstance2)
209+
{
210+
// Visual Studio Community 2017 component directory:
211+
// https://www.visualstudio.com/en-us/productinfo/vs2017-install-product-Community.workloads
212+
213+
string path = setupInstance2.GetInstallationPath();
214+
Console.WriteLine(String.Format("Found VS2017 installation at: {0}", path));
215+
216+
bool hasMSBuild = false;
217+
bool hasVCTools = false;
218+
uint Win10SDKVer = 0;
219+
bool hasWin8SDK = false;
220+
221+
foreach (ISetupPackageReference package in setupInstance2.GetPackages())
222+
{
223+
const string Win10SDKPrefix = "Microsoft.VisualStudio.Component.Windows10SDK.";
224+
225+
string id = package.GetId();
226+
if (id == "Microsoft.VisualStudio.VC.MSBuild.Base")
227+
hasMSBuild = true;
228+
else if (id == "Microsoft.VisualStudio.Component.VC.Tools.x86.x64")
229+
hasVCTools = true;
230+
else if (id.StartsWith(Win10SDKPrefix))
231+
Win10SDKVer = Math.Max(Win10SDKVer, UInt32.Parse(id.Substring(Win10SDKPrefix.Length)));
232+
else if (id == "Microsoft.VisualStudio.Component.Windows81SDK")
233+
hasWin8SDK = true;
234+
else
235+
continue;
236+
237+
Console.WriteLine(String.Format(" - Found {0}", id));
238+
}
239+
240+
if (!hasMSBuild)
241+
Console.WriteLine(" - Missing Visual Studio C++ core features (Microsoft.VisualStudio.VC.MSBuild.Base)");
242+
if (!hasVCTools)
243+
Console.WriteLine(" - Missing VC++ 2017 v141 toolset (x86,x64) (Microsoft.VisualStudio.Component.VC.Tools.x86.x64)");
244+
if ((Win10SDKVer == 0) && (!hasWin8SDK))
245+
Console.WriteLine(" - Missing a Windows SDK (Microsoft.VisualStudio.Component.Windows10SDK.* or Microsoft.VisualStudio.Component.Windows81SDK)");
246+
247+
if (hasMSBuild && hasVCTools)
248+
{
249+
if (Win10SDKVer > 0)
250+
{
251+
Console.WriteLine(" - Using this installation with Windows 10 SDK");
252+
string[] lines = { String.Format("set \"VS2017_INSTALL={0}\"", path), String.Format("set \"VS2017_SDK=10.0.{0}.0\"", Win10SDKVer) };
253+
System.IO.File.WriteAllLines(@"Set_VS2017.bat", lines);
254+
return true;
255+
}
256+
else if (hasWin8SDK)
257+
{
258+
Console.WriteLine(" - Using this installation with Windows 8.1 SDK");
259+
string[] lines = { String.Format("set \"VS2017_INSTALL={0}\"", path), "set \"VS2017_SDK=8.1\"" };
260+
System.IO.File.WriteAllLines(@"Set_VS2017.bat", lines);
261+
return true;
262+
}
263+
}
264+
265+
Console.WriteLine(" - Some required components are missing, not using this installation");
266+
return false;
267+
}
268+
}
269+
}

vcbuild.bat

+31-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ if /i "%1"=="ia32" set target_arch=x86&goto arg-ok
5050
if /i "%1"=="x86" set target_arch=x86&goto arg-ok
5151
if /i "%1"=="x64" set target_arch=x64&goto arg-ok
5252
if /i "%1"=="vc2015" set target_env=vc2015&goto arg-ok
53+
if /i "%1"=="vc2017" set target_env=vc2017&goto arg-ok
5354
if /i "%1"=="noprojgen" set noprojgen=1&goto arg-ok
5455
if /i "%1"=="nobuild" set nobuild=1&goto arg-ok
5556
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
137138

138139
@rem Set environment for msbuild
139140

141+
@rem Look for Visual Studio 2017
142+
:vc-set-2017
143+
if defined target_env if "%target_env%" NEQ "vc2017" goto vc-set-2015
144+
echo Looking for Visual Studio 2017
145+
del /F /Q Set_VS2017.bat > nul 2> nul
146+
"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Unrestricted -Command ^
147+
"&{Add-Type -Path .\tools\Find-VS2017.cs; [VisualStudioConfiguration.Main]::Query()}" 2> nul
148+
if not exist Set_VS2017.bat goto vc-set-2015
149+
call Set_VS2017.bat
150+
if not defined VS2017_INSTALL goto vc-set-2015
151+
if not defined VS2017_SDK goto vc-set-2015
152+
echo Found Visual Studio 2017
153+
if defined msi (
154+
echo Cannot build the MSI with Visual Studio 2017 - it is not yet supported by WiX
155+
goto vc-set-2015
156+
)
157+
if "%target_arch%"=="x86" set "VSARCH=-arch=x86"
158+
if "%target_arch%"=="x64" set "VSARCH=-arch=amd64"
159+
if "%VCVARS_VER%" NEQ "150" (
160+
call "%VS2017_INSTALL%\Common7\Tools\VsDevCmd.bat" %VSARCH% /no_logo
161+
set VCVARS_VER=150
162+
)
163+
if not defined VCINSTALLDIR goto vc-set-2015
164+
set GYP_MSVS_VERSION=2017
165+
set PLATFORM_TOOLSET=v141
166+
goto msbuild-found
167+
140168
@rem Look for Visual Studio 2015
169+
:vc-set-2015
170+
if defined target_env if "%target_env%" NEQ "vc2015" goto msbuild-not-found
141171
echo Looking for Visual Studio 2015
142172
if not defined VS140COMNTOOLS goto msbuild-not-found
143173
if not exist "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" goto msbuild-not-found
@@ -372,7 +402,7 @@ echo Failed to create vc project files.
372402
goto exit
373403

374404
:help
375-
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]
405+
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]
376406
echo Examples:
377407
echo vcbuild.bat : builds release build
378408
echo vcbuild.bat debug : builds debug build

0 commit comments

Comments
 (0)