@@ -10,6 +10,9 @@ local ProgramFiles = os_arch ~= "x86" and "ProgramFiles(x86)" or "ProgramFiles"
1010local vswhere = os.getenv (ProgramFiles ).. " /Microsoft Visual Studio/Installer/vswhere.exe"
1111local need = { LIB = true , LIBPATH = true , PATH = true , INCLUDE = true }
1212
13+ local installationPath
14+ local UniversalCRTSdkDir
15+
1316local function writeall (filename , content )
1417 local f <close> = assert (io.open (filename , " w" ))
1518 if content then
@@ -26,11 +29,7 @@ local function strtrim(str)
2629 return str :gsub (" ^%s*(.-)%s*$" , " %1" )
2730end
2831
29- local InstallDir
3032local function installpath ()
31- if InstallDir then
32- return InstallDir
33- end
3433 local process = assert (sp .spawn {
3534 vswhere ,
3635 " -nologo" ,
@@ -50,8 +49,7 @@ local function installpath()
5049 if result == " " then
5150 log .fastfail (" [vswhere] VisualStudio not found." )
5251 end
53- InstallDir = result
54- return InstallDir
52+ return result
5553end
5654
5755local function parse_env (str )
@@ -110,15 +108,16 @@ local function find_winsdk()
110108end
111109
112110local function find_toolset ()
113- local verfile = installpath () .. " /VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt"
111+ local verfile = installationPath .. " /VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt"
114112 local raw = readall (verfile )
115113 local res = strtrim (raw )
116114 assert (res , (" `%s` parse failed." ):format (raw ))
117115 return res
118116end
119117
120118local function vsdevcmd (arch , winsdk , toolset , f )
121- local vsvars32 = installpath ().. " /Common7/Tools/VsDevCmd.bat"
119+ installationPath = installpath ()
120+ local vsvars32 = installationPath .. " /Common7/Tools/VsDevCmd.bat"
122121 local args = { vsvars32 }
123122 if arch then
124123 args [# args + 1 ] = (" -arch=%s" ):format (arch )
@@ -157,11 +156,20 @@ end
157156local function environment (arch , winsdk , toolset )
158157 local env = {}
159158 vsdevcmd (arch , winsdk , toolset , function (name , value )
159+ if name == " UniversalCRTSdkDir" then
160+ UniversalCRTSdkDir = value
161+ end
160162 name = name :upper ()
161163 if need [name ] then
162164 env [name ] = value
163165 end
164166 end )
167+ if not winsdk then
168+ globals .winsdk = find_winsdk ()
169+ end
170+ if not toolset then
171+ globals .toolset = find_toolset ()
172+ end
165173 return env
166174end
167175
@@ -198,7 +206,7 @@ build test: showIncludes test.c
198206end
199207
200208local function toolspath (toolset )
201- return installpath () .. " /VC/Tools/MSVC/" .. toolset
209+ return installationPath .. " /VC/Tools/MSVC/" .. toolset
202210end
203211
204212local function binpath (arch , toolset )
217225
218226local function vcrtpath (arch , optimize , toolset )
219227 local RedistVersion = (function ()
220- local verfile = installpath () .. " /VC/Auxiliary/Build/Microsoft.VCRedistVersion.default.txt"
228+ local verfile = installationPath .. " /VC/Auxiliary/Build/Microsoft.VCRedistVersion.default.txt"
221229 local r = readall (verfile )
222230 return strtrim (r )
223231 end )()
@@ -226,20 +234,14 @@ local function vcrtpath(arch, optimize, toolset)
226234 local r = readall (verfile )
227235 return r :match " #define%s+_MSVC_STL_VERSION%s+(%d+)"
228236 end )()
229- local path = installpath () .. " /VC/Redist/MSVC/" .. RedistVersion
237+ local path = installationPath .. " /VC/Redist/MSVC/" .. RedistVersion
230238 if optimize == " off" then
231239 return path .. " /debug_nonredist/" .. arch .. " /Microsoft.VC" .. ToolsetVersion .. " .DebugCRT"
232240 end
233241 return path .. " /" .. arch .. " /Microsoft.VC" .. ToolsetVersion .. " .CRT"
234242end
235243
236- local function ucrtpath (arch , optimize , winsdk , toolset )
237- local UniversalCRTSdkDir
238- vsdevcmd (arch , winsdk , toolset , function (name , value )
239- if name == " UniversalCRTSdkDir" then
240- UniversalCRTSdkDir = value
241- end
242- end )
244+ local function ucrtpath (arch , optimize )
243245 if not UniversalCRTSdkDir then
244246 return
245247 end
@@ -273,7 +275,7 @@ local function ucrtpath(arch, optimize, winsdk, toolset)
273275end
274276
275277local function llvmpath ()
276- local path = installpath () .. " /VC/Tools/Llvm/x64/lib/clang/"
278+ local path = installationPath .. " /VC/Tools/Llvm/x64/lib/clang/"
277279 for p in fs .pairs (path ) do
278280 local version = p :filename ():string ()
279281 return path .. version .. " /lib/windows/"
@@ -333,42 +335,57 @@ function m.cleanEnvConfig()
333335 fs .remove (EnvConfig )
334336end
335337
336- function m .createEnvConfig (arch , rebuild )
338+ function m .getEnv ()
339+ updateEnvConfig ()
340+ return env
341+ end
342+
343+ function m .getPrefix ()
344+ updateEnvConfig ()
345+ return msvc_deps_prefix
346+ end
347+
348+ function m .archAlias (arch )
349+ return ArchAlias [arch ]
350+ end
351+
352+ m .binpath = binpath
353+ m .vcrtpath = vcrtpath
354+ m .ucrtpath = ucrtpath
355+ m .llvmpath = llvmpath
356+
357+ do
358+ local arch = globals .arch
359+ local rebuild = arguments .what == " rebuild"
337360 local console_cp = getConsoleCP ()
338361 if not rebuild and m .hasEnvConfig () then
339362 local config = readEnvConfig ()
340363 if config .arch == arch
341364 and (not console_cp or config .console_cp == console_cp )
342- and config .toolset and fs .exists (toolspath (config .toolset ))
365+ and config .toolset
366+ and config .installationPath
367+ and fs .exists (config .installationPath .. " /VC/Tools/MSVC/" .. config .toolset )
343368 then
369+ installationPath = config .installationPath
344370 env = config .env
345371 msvc_deps_prefix = config .prefix
346372 globals .winsdk = config .winsdk
347373 globals .toolset = config .toolset
348374 return
349375 end
350376 end
351- local winsdk = globals .winsdk
352- if not winsdk then
353- winsdk = find_winsdk ()
354- globals .winsdk = winsdk
355- end
356- local toolset = globals .toolset
357- if not toolset then
358- toolset = find_toolset ()
359- globals .toolset = toolset
360- end
361- env = environment (ArchAlias [arch ], winsdk , toolset )
377+ env = environment (ArchAlias [arch ], globals .winsdk , globals .toolset )
362378 msvc_deps_prefix = getMsvcDepsPrefix (env )
363379
364380 local s = {}
365381 s [# s + 1 ] = " return {"
382+ s [# s + 1 ] = (" installationPath=%q," ):format (installationPath )
366383 s [# s + 1 ] = (" console_cp=%q," ):format (console_cp )
367384 s [# s + 1 ] = (" arch=%q," ):format (arch )
368- if winsdk then
369- s [# s + 1 ] = (" winsdk=%q," ):format (winsdk )
385+ if globals . winsdk then
386+ s [# s + 1 ] = (" winsdk=%q," ):format (globals . winsdk )
370387 end
371- s [# s + 1 ] = (" toolset=%q," ):format (toolset )
388+ s [# s + 1 ] = (" toolset=%q," ):format (globals . toolset )
372389 s [# s + 1 ] = (" prefix=%q," ):format (msvc_deps_prefix )
373390 s [# s + 1 ] = " env={"
374391 for name , value in pairs (env ) do
@@ -380,25 +397,4 @@ function m.createEnvConfig(arch, rebuild)
380397 writeEnvConfig (table.concat (s , " \n " ))
381398end
382399
383- function m .getEnv ()
384- updateEnvConfig ()
385- return env
386- end
387-
388- function m .getPrefix ()
389- updateEnvConfig ()
390- return msvc_deps_prefix
391- end
392-
393- function m .archAlias (arch )
394- return ArchAlias [arch ]
395- end
396-
397- m .binpath = binpath
398- m .vcrtpath = vcrtpath
399- m .ucrtpath = ucrtpath
400- m .llvmpath = llvmpath
401-
402- m .createEnvConfig (globals .arch , arguments .what == " rebuild" )
403-
404400return m
0 commit comments