VirtualBox

source: vbox/trunk/tools/envSub.vbs

Last change on this file was 106804, checked in by vboxsync, 4 weeks ago

tools/envSub.vbs: Visual C++ selection update, now adding Llvm's bin dir when present. jiraref:VBP-1253

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 18.8 KB
Line 
1' $Id: envSub.vbs 106804 2024-10-31 01:13:45Z vboxsync $
2'' @file
3' VBScript worker for env.cmd
4'
5
6'
7' Copyright (C) 2006-2024 Oracle and/or its affiliates.
8'
9' This file is part of VirtualBox base platform packages, as
10' available from https://www.virtualbox.org.
11'
12' This program is free software; you can redistribute it and/or
13' modify it under the terms of the GNU General Public License
14' as published by the Free Software Foundation, in version 3 of the
15' License.
16'
17' This program is distributed in the hope that it will be useful, but
18' WITHOUT ANY WARRANTY; without even the implied warranty of
19' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20' General Public License for more details.
21'
22' You should have received a copy of the GNU General Public License
23' along with this program; if not, see <https://www.gnu.org/licenses>.
24'
25' SPDX-License-Identifier: GPL-3.0-only
26'
27
28
29''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
30' Header Files
31''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
32''
33' Includes a vbscript file relative to the script.
34sub IncludeFile(strFilename)
35 dim objFile, objFileSys
36 set objFileSys = WScript.CreateObject("Scripting.FileSystemObject")
37 dim strPath : strPath = objFileSys.BuildPath(objFileSys.GetParentFolderName(Wscript.ScriptFullName), strFilename)
38 set objFile = objFileSys.openTextFile(strPath)
39 executeglobal objFile.readAll()
40 objFile.close
41 set objFileSys = nothing
42end sub
43
44IncludeFile "win\vbscript\helpers.vbs"
45
46
47''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
48' Global Variables '
49''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
50dim g_cntVerbose
51g_cntVerbose = 1
52
53
54sub LogPrint(str)
55 if g_cntVerbose > 1 then
56 WScript.StdErr.WriteLine "debug: " & str
57 end if
58end sub
59
60sub DbgPrint(str)
61 if g_cntVerbose > 2 then
62 WScript.StdErr.WriteLine "debug: " & str
63 end if
64end sub
65
66
67''
68' The main() like function.
69'
70function Main()
71 Main = 1
72
73 '
74 ' check that we're not using wscript.
75 '
76 if UCase(Right(Wscript.FullName, 11)) = "WSCRIPT.EXE" then
77 Wscript.Echo "This script must be run under CScript."
78 exit function
79 end if
80 SelfTest
81
82 '
83 ' Get our bearings.
84 '
85 dim strScriptDir
86 strScriptDir = g_objFileSys.GetParentFolderName(Wscript.ScriptFullName)
87
88 dim strRootDir
89 strRootDir = g_objFileSys.GetParentFolderName(strScriptDir)
90
91 dim strRealArch
92 strRealArch = Trim(EnvGet("PROCESSOR_ARCHITEW6432"))
93 if strRealArch = "" then strRealArch = Trim(EnvGet("PROCESSOR_ARCHITECTURE"))
94 if strRealArch = "" then strRealArch = "amd64"
95 strRealArch = LCase(strRealArch)
96 if strRealArch <> "amd64" and strRealArch <> "x86" and strRealArch <> "arm64" then
97 MsgError "Unsupported host architecture: " & strRealArch ' quits
98 end if
99
100 '
101 ' Guest the default configuration.
102 '
103 dim arrTypes : arrTypes = Array("debug", "release", "profile", "strict", "dbgopt")
104 dim arrTargetAndHosts : arrTargetAndHosts = Array("win", "linux", "solaris", "darwin", "os2", "freebsd")
105 dim arrArchitectures : arrArchitectures = Array("x86", "amd64", "arm32", "arm64", "sparc32", "sparc64")
106
107 dim strType
108 strType = EnvGetDefValid("KBUILD_TYPE", "debug", arrTypes)
109
110 dim strPathDevTools
111 strPathDevTools= EnvGetDef("KBUILD_DEVTOOLS", g_objFileSys.BuildPath(strRootDir, "tools"))
112
113 dim strPathkBuild
114 strPathkBuild = EnvGetDef("KBUILD_PATH", g_objFileSys.BuildPath(strRootDir, "kBuild"))
115
116 dim strTarget, strTargetArch
117 strTarget = EnvGetDefValid("KBUILD_TARGET", "win", arrTargetAndHosts)
118 strTargetArch = EnvGetDefValid("KBUILD_TARGET_ARCH", strRealArch, arrArchitectures)
119
120 dim strHost, strHostArch
121 strHost = EnvGetDefValid("KBUILD_HOST", "win", arrTargetAndHosts)
122 strHostArch = EnvGetDefValid("KBUILD_HOST_ARCH", strRealArch, arrArchitectures)
123
124 dim strAltHostArch
125 strAltHostArch = ""
126 if strHostArch = "arm64" then
127 strAltHostArch = "amd64"
128 end if
129
130 ' Where to look for host related tools.
131 dim arrArchToolsSuffixes : arrArchToolsSuffixes = Array("", strHostArch & ".")
132 if strAltHostArch <> "" then
133 arrArchToolsSuffixes = ArrayAppend(arrArchToolsSuffixes, strAltHostArch & ".")
134 end if
135 if strHostArch <> "x86" and strAltHostArch <> "x86" then
136 arrArchToolsSuffixes = ArrayAppend(arrArchToolsSuffixes, ".x86")
137 end if
138
139 '
140 ' Parse arguments.
141 '
142 dim arrValueOpts : arrValueOpts = Array("--type", "--arch", "--tmp-script")
143 dim arrCmdToExec : arrCmdToExec = Array()
144 dim blnDashDash : blnDashDash = false
145 dim strChdirTo : strChdirTo = strRootDir
146 dim strTmpScript : strTmpScript = g_objFileSys.BuildPath(strScriptDir, "envtmp.cmd")
147 dim i : i = 0
148 do while i < Wscript.Arguments.Count
149 dim strArg, strValue, off
150 strArg = Wscript.Arguments.item(i)
151 i = i + 1
152 if blnDashDash <> true then
153 ' Does it have an embedded value? Does it take a value?
154 off = InStr(2, strArg, "=")
155 if off <= 0 then off = InStr(2, strArg, ":")
156 if off > 0 then
157 strValue = Mid(strArg, off + 1)
158 strArg = Left(strArg, off - 1)
159 if not ArrayContainsString(arrValueOpts, strArg) then
160 MsgSyntaxError "'" & strArg & "' does not take a value" ' quits
161 end if
162 elseif ArrayContainsString(arrValueOpts, strArg) then
163 if i >= Wscript.Arguments.Count then
164 MsgSyntaxError "'" & strArg & "' takes a value" ' quits
165 end if
166 strValue = Wscript.Arguments.item(i)
167 i = i + 1
168 end if
169
170 ' Process it.
171 select case strArg
172 ' Build types:
173 case "--type"
174 if not ArrayContainsString(arrTypes, strValue) then
175 MsgSyntaxError "Invalid build type '" & strValue & "'. Valid types: " & ArrayJoinString(arrTypes, ", ") ' quits
176 else
177 strType = strValue
178 end if
179 case "--release"
180 strType = "release"
181 case "--debug"
182 strType = "debug"
183 case "--strict"
184 strType = "strict"
185 case "--dbgopt"
186 strType = "dbgopt"
187
188 ' Target architecture:
189 case "--arch"
190 if not ArrayContainsString(arrArchitectures, strValue) then
191 MsgSyntaxError "Invalid target architecture'" & strValue & "'. Valid ones: " _
192 & ArrayJoinString(arrArchitectures, ", ") ' quits
193 else
194 strTargetArch = strValue
195 end if
196 case "--amd64"
197 strTargetArch = "amd64"
198 case "--x86"
199 strTargetArch = "amd64"
200 case "--arm32"
201 strTargetArch = "arm32"
202 case "--arm64"
203 strTargetArch = "amd64"
204
205 ' Verbosity, env.sh compatibility and stuff
206 case "--quiet"
207 g_cntVerbose = 0
208 case "--verbose"
209 g_cntVerbose = g_cntVerbose + 1
210 case "--chdir"
211 strChdirTo = strValue
212 case "--no-chdir"
213 strChdirTo = ""
214
215 ' Internal.
216 case "--tmp-script"
217 strTmpScript = strValue
218
219 ' Standard options
220 case "-h", "-?", "--help"
221 Print "Sets the VBox development shell environment on Windows."
222 Print "usage: env.cmd [--type <type> | --release | --debug | --strict | --dbgopt]"
223 Print " [--arch <arch> | --amd64 | --x86 | --arm32 | --arm64]"
224 Print " [--no-chdir | --chdir <dir>] [--quiet | --verbose]"
225 Print " [--] [prog] [args...]"
226 Print "usage: env.cmd [--help | -h | -?]"
227 Print "usage: env.cmd [--version | -V]"
228 Main = 0
229 exit function
230 case "-V", "--version"
231 Print "x.y"
232 Main = 0
233 exit function
234
235 case "--"
236 blnDashDash = True
237
238 case else
239 MsgSyntaxError "Unknown option: " & strArg
240 end select
241 else
242 ' cscript may eat quoting... So we should consider using some windows API to get the raw command line
243 ' and look for the dash-dash instead. Maybe.
244 arrCmdToExec = ArrayAppend(arrCmdToExec, strArg)
245 end if
246 loop
247
248 '
249 ' Set up the environment.
250 '
251 dim str1
252
253 EnvSet "KBUILD_PATH", UnixSlashes(strPathkBuild)
254 EnvSet "KBUILD_DEVTOOLS", UnixSlashes(strPathDevTools)
255 EnvSet "KBUILD_TYPE", strType
256 EnvSet "KBUILD_TARGET", strTarget
257 EnvSet "KBUILD_TARGET_ARCH", strTargetArch
258 EnvSet "KBUILD_HOST", strHost
259 EnvSet "KBUILD_HOST_ARCH", strHostArch
260
261 ' Remove legacy variables.
262 dim arrObsolete
263 arrObsolete = Array("BUILD_TYPE", "BUILD_TARGET", "BUILD_TARGET_ARCH", "BUILD_PLATFORM", "BUILD_PLATFORM_ARCH", _
264 "PATH_DEVTOOLS", "KBUILD_TARGET_CPU", "KBUILD_PLATFORM_CPU")
265 for each str1 in arrObsolete
266 EnvUnset str1
267 next
268
269 ' cleanup path before we start adding to it
270 for each str1 in arrArchitectures
271 EnvRemovePathItem "Path", DosSlashes(strPathkBuild & "\bin\win." & str1), ";"
272 EnvRemovePathItem "Path", DosSlashes(strPathkBuild & "\bin\win." & str1 & "\wrappers"), ";"
273 EnvRemovePathItem "Path", DosSlashes(strPathDevTools & "\win." & str1) & "\bin", ";"
274 next
275
276 '
277 ' We skip the extra stuff like gnuwin32, windbg, cl.exe and mingw64 if
278 ' there is a command to execute.
279 '
280 if ArraySize(arrCmdToExec) = 0 then
281 ' Add the kbuild wrapper directory to the end of the path, these take
282 ' precedence over the dated gnuwin32 stuff.
283 EnvAppendPathItem "Path", DosSlashes(strPathkBuild & "\bin\win." & strHostArch & "\wrappers"), ";"
284 if strAltHostArch <> "" then EnvAppendPathItem "Path", DosSlashes(strPathkBuild & "\bin\win." & strAltHostArch & "\wrappers"), ";"
285
286 ' Add some gnuwin32 tools to the end of the path.
287 EnvAppendPathItem "Path", DosSlashes(strPathDevTools & "\win.x86\gnuwin32\r1\bin"), ";"
288
289 ' Add the newest debugger we can find to the front of the path.
290 dim strDir, blnStop
291 bldExitLoop = false
292 for each str1 in arrArchToolsSuffixes
293 strDir = strPathDevTools & "\win" & str1 & "\sdk"
294 for each strSubDir in GetSubdirsStartingWithRVerSorted(strDir, "v")
295 if FileExists(strDir & "\" & strSubDir & "\Debuggers\" & XlateArchitectureToWin(strHostArch) & "\windbg.exe") then
296 EnvPrependPathItem "Path", DosSlashes(strDir & "\" & strSubDir & "\Debuggers\" & XlateArchitectureToWin(strHostArch)), ";"
297 bldExitLoop = true
298 exit for
299 end if
300 next
301 if bldExitLoop then exit for
302 next
303
304 ' Add VCC and Llvm to the end of the path.
305 dim str2, strDir2, arrVccOldBinDirs
306 arrVccOldBinDirs = Array("\bin\" & strHostArch & "_" & strTargetArch, "\bin\" & strTargetArch, "\bin")
307 bldExitLoop = false
308 for each str1 in Array("", ".amd64", ".x86")
309 for each strDir in GetSubdirsStartingWithRVerSorted(strPathDevTools & "\win" & str1 & "\vcc", "v")
310 strDir = strPathDevTools & "\win" & str1 & "\vcc\" & strDir
311 if DirExists(strDir & "\Tools\MSVC") then
312 for each strDir2 in GetSubdirsStartingWithRVerSorted(strDir & "\Tools\MSVC", "1")
313 strDir2 = strDir & "\Tools\MSVC\" & strDir2 & "\bin\Host" & XlateArchitectureToWin(strHostArch) _
314 & "\" & XlateArchitectureToWin(strTargetArch)
315 if FileExists(strDir2 & "\cl.exe") then
316 EnvAppendPathItem "Path", DosSlashes(strDir2), ";"
317 if strTargetArch <> strHostArch then
318 EnvAppendPathItem "Path", DosSlashes(PathStripFilename(strDir2) & "\" & XlateArchitectureToWin(strHostArch)), ";"
319 end if
320 bldExitLoop = true
321 exit for
322 end if
323 next
324 if bldExitLoop and DirExists(strDir & "\Tools\Llvm\") then
325 if strHostArch = "x86" then
326 strDir2 = strDir & "\Tools\Llvm\bin"
327 else
328 strDir2 = strDir & "\Tools\Llvm\" & XlateArchitectureToWin(strHostArch) & "\bin"
329 end if
330 if DirExists(strDir2) then
331 EnvAppendPathItem "Path", DosSlashes(strDir2), ";"
332 end if
333 end if
334 elseif DirExists(strDir & "\bin") then
335 for each str2 in arrVccOldBinDirs
336 if FileExists(strDir & str2 & "\cl.exe") then
337 EnvAppendPathItem "Path", DosSlashes(strDir & str2), ";"
338 if str2 <> "\bin" then EnvAppendPathItem "Path", DosSlashes(strDir & "bin"), ";"
339 bldExitLoop = true
340 exit for
341 end if
342 next
343 end if
344 if bldExitLoop then exit for
345 next
346 if bldExitLoop then exit for
347 next
348
349 ' Add mingw64 if it's still there.
350 if strHostArch = "amd64" or strTargetArch = "amd64" then
351 str1 = strPathDev & "win.amd64\mingw-64\r1\bin"
352 if DirExists(str1) then EnvAppendPathItem "Path", DosSlashes(str1), ";"
353 end if
354 end if
355
356 ' Add the output tools and bin directories to the fron of the path, taking PATH_OUT_BASE into account.
357 dim strOutDir
358 strOutDir = EnvGetDef("PATH_OUT_BASE", strRootDir & "\out")
359 strOutDir = strOutDir & "\" & strTarget & "." & strTargetArch & "\" & strType
360 EnvPrependPathItem "Path", DosSlashes(strOutDir & "\bin\tools"), ";"
361 EnvPrependPathItem "Path", DosSlashes(strOutDir & "\bin"), ";"
362
363 ' Add kbuild binary directory to the front the the path.
364 if strAltHostArch <> "" then EnvPrependPathItem "Path", DosSlashes(strPathkBuild & "\bin\win." & strAltHostArch), ";"
365 EnvPrependPathItem "Path", DosSlashes(strPathkBuild & "\bin\win." & strHostArch), ";"
366
367 ' Finally, add the relevant tools/**/bin directories to the front of the path.
368 EnvPrependPathItem "Path", DosSlashes(strPathDevTools & "\bin"), ";"
369 if strHostArch = "amd64" then EnvPrependPathItem "Path", DosSlashes(strPathDevTools & "\win.x86\bin"), ";"
370 if strAltHostArch <> "" then EnvPrependPathItem "Path", DosSlashes(strPathDevTools & "\win." & strAltHostArch & "\bin"), ";"
371 EnvPrependPathItem "Path", DosSlashes(strPathDevTools & "\win." & strHostArch) & "\bin", ";"
372
373 '
374 ' Export if we are not executing a program.
375 '
376 Main = g_rcScript
377 if ArraySize(arrCmdToExec) = 0 then
378 dim objTmpScript
379 set objTmpScript = g_objFileSys.CreateTextFile(strTmpScript, true, false)
380 objTmpScript.WriteLine
381
382 for each str1 in Array("Path", "KBUILD_PATH", "KBUILD_DEVTOOLS", "KBUILD_TYPE", _
383 "KBUILD_TARGET", "KBUILD_TARGET_ARCH", "KBUILD_HOST", "KBUILD_HOST_ARCH")
384 objTmpScript.WriteLine "SET " & str1 & "=" & EnvGet(str1)
385 next
386 for each str1 in arrObsolete
387 if EnvExists(str1) then objTmpScript.WriteLine "SET " & str1 & "="
388 next
389
390 if strChdirTo <> "" then
391 objTmpScript.WriteLine "CD """ & strChdirTo & """"
392 if Mid(strChdirTo, 2, 1) = ":" then
393 objTmpScript.WriteLine Left(strChdirTo, 2)
394 end if
395 end if
396
397 objTmpScript.Close()
398 '
399 ' Run the specified program.
400 '
401 ' We must redirect stderr to stdout here, because vbscript doesn't seem to
402 ' have any way to reuse the same console/stdout/stererr as we use (Exec
403 ' creates two pipes, Run a new console), nor can vbscript service two
404 ' TextStream/pipe objects at the same time without the risk of deadlocking
405 ' with the child process (we read stdout, child waits for stderr space).
406 '
407 ' So, to make it work we use kmk_redirect.exe to stuff everything into stderr
408 ' and ignore stdout.
409 '
410 else
411 if strChdirTo <> "" then
412 g_objShell.CurrentDirectory = strChdirTo
413 end if
414
415 ' Prepate the command line.
416 dim strCmdLine, str
417 strCmdLine = """" & DosSlashes(strPathkBuild) & "\bin\win." & strHostArch & "\kmk_redirect.exe"" -d1=2 -c0 -- " _
418 & """" & arrCmdToExec(0) & """"
419 for i = 1 to UBound(arrCmdToExec)
420 str = arrCmdToExec(i)
421 if InStr(1, str, " ") > 0 then '' @todo There is more stuff that needs escaping
422 strCmdLine = strCmdLine & " """ & str & """"
423 else
424 strCmdLine = strCmdLine & " " & str
425 end if
426 next
427
428 ' Start it.
429 if g_cntVerbose > 0 then MsgInfo "Executing command: " & strCmdLine
430 dim objChild
431 set objChild = g_objShell.Exec(strCmdLine)
432
433 ' The fun output / wait. As mention above, we only need to bother with stderr here.
434 dim cMsSleepMin : cMsSleepMin = 8
435 dim cMsSleepMax : cMsSleepMax = 92
436 dim cMsSleep : cMsSleep = cMsSleepMin
437 do while objChild.Status = 0
438 if not objChild.StdErr.AtEndOfStream then ' Seems this bugger might do a 0x80
439 WScript.StdErr.WriteLine objChild.StdErr.ReadLine()
440 cMsSleep = cMsSleepMin
441 elseif objChild.Status = 0 then
442 Wscript.Sleep cMsSleep
443 ' We probably only end up here once stderr is closed/disconnected (i.e. never).
444 ' This was originally written with the idea that AtEndOfStream would use
445 ' PeekNamedPipe to see if there were anything to read, rather than block.
446 ' Let's keep it for now.
447 if cMsSleep < cMsSleepMax then cMsSleep = cMsSleep + 8
448 end if
449 loop
450
451 ' Flush any remaining output on the offchance that we could get out of the above loop with pending output.
452 WScript.StdErr.Write strStdErr & objChild.StdErr.ReadAll()
453 WScript.StdOut.Write strStdOut & objChild.StdOut.ReadAll()
454
455 ' Return the exit code to our parent.
456 if g_cntVerbose > 0 then MsgInfo "Exit code = " & objChild.ExitCode
457 Main = objChild.ExitCode
458 end if
459end function
460
461'
462' What crt0.o typically does:
463'
464WScript.Quit(Main())
465
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette