VirtualBox

root/trunk/configure.vbs

Revision 8155, 69.9 kB (checked in by vboxsync, 3 months ago)

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Id
Line 
1 ' $Id$
2 '' @file
3 ' The purpose of this script is to check for all external tools, headers, and
4 ' libraries VBox OSE depends on.
5 '
6 ' The script generates the build configuration file 'AutoConfig.kmk' and the
7 ' environment setup script 'env.bat'. A log of what has been done is
8 ' written to 'configure.log'.
9 '
10
11 '
12 ' Copyright (C) 2006-2007 Sun Microsystems, Inc.
13 '
14 ' This file is part of VirtualBox Open Source Edition (OSE), as
15 ' available from http://www.virtualbox.org. This file is free software;
16 ' you can redistribute it and/or modify it under the terms of the GNU
17 ' General Public License (GPL) as published by the Free Software
18 ' Foundation, in version 2 as it comes in the "COPYING" file of the
19 ' VirtualBox OSE distribution. VirtualBox OSE is distributed in the
20 ' hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
21 '
22 ' Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
23 ' Clara, CA 95054 USA or visit http://www.sun.com if you need
24 ' additional information or have any questions.
25 '
26
27
28 '*****************************************************************************
29 '* Global Variables                                                          *
30 '*****************************************************************************
31 dim g_strPath, g_strEnvFile, g_strLogFile, g_strCfgFile, g_strShellOutput
32 g_strPath = Left(Wscript.ScriptFullName, Len(Wscript.ScriptFullName) - Len("\configure.vbs"))
33 g_strEnvFile = g_strPath & "\env.bat"
34 g_strCfgFile = g_strPath & "\AutoConfig.kmk"
35 g_strLogFile = g_strPath & "\configure.log"
36 'g_strTmpFile = g_strPath & "\configure.tmp"
37
38 dim g_objShell, g_objFileSys
39 Set g_objShell = WScript.CreateObject("WScript.Shell")
40 Set g_objFileSys = WScript.CreateObject("Scripting.FileSystemObject")
41
42 dim g_strPathkBuild, g_strPathkBuildBin, g_strPathDev, g_strPathVCC, g_strPathPSDK, g_strPathDDK, g_strSubOutput
43 g_strPathkBuild = ""
44 g_strPathDev = ""
45 g_strPathVCC = ""
46 g_strPathPSDK = ""
47 g_strPathDDK = ""
48
49 dim g_blnDisableCOM, g_strDisableCOM
50 g_blnDisableCOM = False
51 g_strDisableCOM = ""
52
53 ' The internal mode is primarily for skipping the xerces and xalan monsters.
54 dim g_blnInternalMode
55 g_blnInternalMode = False
56
57 ' Whether to try the internal stuff first or last.
58 dim g_blnInternalFirst
59 g_blnInternalFirst = True
60
61
62
63 ''
64 ' Converts to unix slashes
65 function UnixSlashes(str)
66    UnixSlashes = replace(str, "\", "/")
67 end function
68
69
70 ''
71 ' Converts to dos slashes
72 function DosSlashes(str)
73    DosSlashes = replace(str, "/", "\")
74 end function
75
76
77 ''
78 ' Read a file (typically the tmp file) into a string.
79 function FileToString(strFilename)
80    const ForReading = 1, TristateFalse = 0
81    dim objLogFile, str
82
83    set objFile = g_objFileSys.OpenTextFile(DosSlashes(strFilename), ForReading, False, TristateFalse)
84    str = objFile.ReadAll()
85    objFile.Close()
86
87    FileToString = str
88 end function
89
90
91 ''
92 ' Deletes a file
93 sub FileDelete(strFilename)
94    if g_objFileSys.FileExists(DosSlashes(strFilename)) then
95       g_objFileSys.DeleteFile(DosSlashes(strFilename))
96    end if
97 end sub
98
99
100 ''
101 ' Appends a line to an ascii file.
102 sub FileAppendLine(strFilename, str)
103    const ForAppending = 8, TristateFalse = 0
104    dim objFile
105
106    set objFile = g_objFileSys.OpenTextFile(DosSlashes(strFilename), ForAppending, True, TristateFalse)
107    objFile.WriteLine(str)
108    objFile.Close()
109 end sub
110
111
112 ''
113 ' Checks if the file exists.
114 function FileExists(strFilename)
115    FileExists = g_objFileSys.FileExists(DosSlashes(strFilename))
116 end function
117
118
119 ''
120 ' Checks if the directory exists.
121 function DirExists(strDirectory)
122    DirExists = g_objFileSys.FolderExists(DosSlashes(strDirectory))
123 end function
124
125
126 ''
127 ' Checks if this is a WOW64 process.
128 function IsWow64()
129    if g_objShell.Environment("PROCESS")("PROCESSOR_ARCHITEW6432") <> "" then
130       IsWow64 = 1
131    else
132       IsWow64 = 0
133    end if
134 end function
135
136
137 ''
138 ' Translates a register root name to a value
139 function RegTransRoot(strRoot)
140    const HKEY_LOCAL_MACHINE = &H80000002
141    const HKEY_CURRENT_USER  = &H80000001
142    select case strRoot
143       case "HKLM"
144          RegTransRoot = HKEY_LOCAL_MACHINE
145       case "HKCU"
146          RegTransRoot = HKEY_CURRENT_USER
147       case else
148          MsgFatal "RegEnumSubKeys: Unknown root: " & strRoot
149          RegTransRoot = 0
150    end select
151 end function
152
153
154 '' The registry globals
155 dim g_objReg, g_objRegCtx
156 dim g_blnRegistry
157 g_blnRegistry = false
158
159
160 ''
161 ' Init the register provider globals.
162 function RegInit()
163    RegInit = false
164    On Error Resume Next
165    if g_blnRegistry = false then
166       set g_objRegCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
167       ' Comment out the following for lines if the cause trouble on your windows version.
168       if IsWow64() then
169          g_objRegCtx.Add "__ProviderArchitecture", 64
170          g_objRegCtx.Add "__RequiredArchitecture", true
171       end if
172       set objLocator = CreateObject("Wbemscripting.SWbemLocator")
173       set objServices = objLocator.ConnectServer("", "root\default", "", "", , , , g_objRegCtx)
174       set g_objReg = objServices.Get("StdRegProv")
175       g_blnRegistry = true
176    end if
177    RegInit = true
178 end function
179
180
181 ''
182 ' Gets a value from the registry. Returns "" if string wasn't found / valid.
183 function RegGetString(strName)
184    RegGetString = ""
185    if RegInit() then
186       dim strRoot, strKey, strValue
187       dim iRoot
188
189       ' split up into root, key and value parts.
190       strRoot = left(strName, instr(strName, "\") - 1)
191       strKey = mid(strName, instr(strName, "\") + 1, instrrev(strName, "\") - instr(strName, "\"))
192       strValue = mid(strName, instrrev(strName, "\") + 1)
193
194       ' Must use ExecMethod to call the GetStringValue method because of the context.
195       Set InParms = g_objReg.Methods_("GetStringValue").Inparameters
196       InParms.hDefKey     = RegTransRoot(strRoot)
197       InParms.sSubKeyName = strKey
198       InParms.sValueName  = strValue
199       On Error Resume Next
200       set OutParms = g_objReg.ExecMethod_("GetStringValue", InParms, , g_objRegCtx)
201       if OutParms.ReturnValue = 0 then
202          RegGetString = OutParms.sValue
203       end if
204    else
205       ' fallback mode
206       On Error Resume Next
207       RegGetString = g_objShell.RegRead(strName)
208    end if
209 end function
210
211
212 ''
213 ' Returns an array of subkey strings.
214 function RegEnumSubKeys(strRoot, strKeyPath)
215    dim iRoot
216    iRoot = RegTransRoot(strRoot)
217    RegEnumSubKeys = Array()
218
219    if RegInit() then
220       ' Must use ExecMethod to call the EnumKey method because of the context.
221       Set InParms = g_objReg.Methods_("EnumKey").Inparameters
222       InParms.hDefKey     = RegTransRoot(strRoot)
223       InParms.sSubKeyName = strKeyPath
224       On Error Resume Next
225       set OutParms = g_objReg.ExecMethod_("EnumKey", InParms, , g_objRegCtx)
226       if OutParms.ReturnValue = 0 then
227          RegEnumSubKeys = OutParms.sNames
228       end if
229    else
230       ' fallback mode
231       dim objReg, rc, arrSubKeys
232       set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
233       On Error Resume Next
234       rc = objReg.EnumKey(iRoot, strKeyPath, arrSubKeys)
235       if rc = 0 then
236          RegEnumSubKeys = arrSubKeys
237       end if
238    end if
239 end function
240
241
242 ''
243 ' Gets the commandline used to invoke the script.
244 function GetCommandline()
245    dim str, i
246
247    '' @todo find an api for querying it instead of reconstructing it like this...
248    GetCommandline = "cscript configure.vbs"
249    for i = 1 to WScript.Arguments.Count
250       str = WScript.Arguments.Item(i - 1)
251       if str = "" then
252          str = """"""
253       elseif (InStr(1, str, " ")) then
254          str = """" & str & """"
255       end if
256       GetCommandline = GetCommandline & " " & str
257    next
258 end function
259
260
261 ''
262 ' Gets an environment variable.
263 function EnvGet(strName)
264    EnvGet = g_objShell.Environment("PROCESS")(strName)
265 end function
266
267
268 ''
269 ' Sets an environment variable.
270 sub EnvSet(strName, strValue)
271    g_objShell.Environment("PROCESS")(strName) = strValue
272    LogPrint "EnvSet: " & strName & "=" & strValue
273 end sub
274
275
276 ''
277 ' Appends a string to an environment variable
278 sub EnvAppend(strName, strValue)
279    dim str
280    str = g_objShell.Environment("PROCESS")(strName)
281    g_objShell.Environment("PROCESS")(strName) =  str & strValue
282    LogPrint "EnvAppend: " & strName & "=" & str & strValue
283 end sub
284
285
286 ''
287 ' Prepends a string to an environment variable
288 sub EnvPrepend(strName, strValue)
289    dim str
290    str = g_objShell.Environment("PROCESS")(strName)
291    g_objShell.Environment("PROCESS")(strName) =  strValue & str
292    LogPrint "EnvPrepend: " & strName & "=" & strValue & str
293 end sub
294
295
296 ''
297 ' Get the path of the parent directory. Returns root if root was specified.
298 ' Expects abs path.
299 function PathParent(str)
300    PathParent = g_objFileSys.GetParentFolderName(DosSlashes(str))
301 end function
302
303
304 ''
305 ' Strips the filename from at path.
306 function PathStripFilename(str)
307    PathStripFilename = g_objFileSys.GetParentFolderName(DosSlashes(str))
308 end function
309
310
311 ''
312 ' Get the abs path, use the short version if necessary.
313 function PathAbs(str)
314    PathAbs = g_objFileSys.GetAbsolutePathName(DosSlashes(str))
315    if  (InStr(1, PathAbs, " ") > 0) _
316     Or (InStr(1, PathAbs, "&") > 0) _
317     Or (InStr(1, PathAbs, "$") > 0) _
318       then
319          if FileExists(PathAbs) then
320             dim objFile
321             set objFile = g_objFileSys.GetFile(PathAbs)
322             PathAbs = objFile.ShortPath
323          elseif DirExists(PathAbs) then
324             dim objFolder
325             set objFolder = g_objFileSys.GetFolder(PathAbs)
326             PathAbs = objFolder.ShortPath
327          else
328             ' ignore non-existing paths.
329          end if
330    end if
331
332
333    if (FileExists(PathAbs) Or DirExists(PathAbs)) _
334     And (   (InStr(1, PathAbs, " ") > 0) _
335          Or (InStr(1, PathAbs, "&") > 0) _
336          Or (InStr(1, PathAbs, "$") > 0)) _
337       then
338       MsgFatal "PathAbs(" & str & ") attempted to return filename with problematic " _
339              & "characters in it (" & PathAbs & "). The tool/sdk referenced will probably " _
340              & "need to be copied or reinstalled to a location without 'spaces', '$', ';' " _
341              & "or '&' in the path name. (Unless it's a problem with this script of course...)"
342    end if
343 end function
344
345
346 ''
347 ' Executes a command in the shell catching output in g_strShellOutput
348 function Shell(strCommand, blnBoth)
349    dim strShell, strCmdline, objExec, str
350
351    strShell = g_objShell.ExpandEnvironmentStrings("%ComSpec%")
352    if blnBoth = true then
353       strCmdline = strShell & " /c " & strCommand & " 2>&1"
354    else
355       strCmdline = strShell & " /c " & strCommand & " 2>nul"
356    end if
357
358    LogPrint "# Shell: " & strCmdline
359    Set objExec = g_objShell.Exec(strCmdLine)
360    g_strShellOutput = objExec.StdOut.ReadAll()
361    objExec.StdErr.ReadAll()
362    do while objExec.Status = 0
363       Wscript.Sleep 20
364       g_strShellOutput = g_strShellOutput & objExec.StdOut.ReadAll()
365       objExec.StdErr.ReadAll()
366    loop
367
368    LogPrint "# Status: " & objExec.ExitCode
369    LogPrint "# Start of Output"
370    LogPrint g_strShellOutput
371    LogPrint "# End of Output"
372
373    Shell = objExec.ExitCode
374 end function
375
376
377 ''
378 ' Try find the specified file in the path.
379 function Which(strFile)
380    dim strPath, iStart, iEnd, str
381
382    ' the path
383    strPath = EnvGet("Path")
384    iStart = 1
385    do while iStart <= Len(strPath)
386       iEnd = InStr(iStart, strPath, ";")
387       if iEnd <= 0 then iEnd = Len(strPath) + 1
388       if iEnd > iStart then
389          str = Mid(strPath, iStart, iEnd - iStart) & "/" & strFile
390          if FileExists(str) then
391             Which = str
392             exit function
393          end if
394       end if
395       iStart = iEnd + 1
396    loop
397
398    ' registry or somewhere?
399
400    Which = ""
401 end function
402
403
404 ''
405 ' Append text to the log file and echo it to stdout
406 sub Print(str)
407    LogPrint str
408    Wscript.Echo str
409 end sub
410
411
412 ''
413 ' Prints a test header
414 sub PrintHdr(strTest)
415    LogPrint "***** Checking for " & strTest & " *****"
416    Wscript.Echo "Checking for " & StrTest & "..."
417 end sub
418
419
420 ''
421 ' Prints a success message
422 sub PrintResult(strTest, strResult)
423    LogPrint "** " & strTest & ": " & strResult
424    Wscript.Echo " Found "& strTest & ": " & strResult
425 end sub
426
427
428 ''
429 ' Warning message.
430 sub MsgWarning(strMsg)
431    Print "warning: " & strMsg
432 end sub
433
434
435 ''
436 ' Fatal error.
437 sub MsgFatal(strMsg)
438    Print "fatal error: " & strMsg
439    Wscript.Quit
440 end sub
441
442
443 ''
444 ' Error message, fatal unless flag to ignore errors is given.
445 sub MsgError(strMsg)
446    Print "error: " & strMsg
447    if g_blnInternalMode = False then
448       Wscript.Quit
449    end if
450 end sub
451
452
453 ''
454 ' Write a log header with some basic info.
455 sub LogInit
456    FileDelete g_strLogFile
457    LogPrint "# Log file generated by " & Wscript.ScriptFullName
458    for i = 1 to WScript.Arguments.Count
459       LogPrint "# Arg #" & i & ": " & WScript.Arguments.Item(i - 1)
460    next
461    if Wscript.Arguments.Count = 0 then
462       LogPrint "# No arguments given"
463    end if
464    LogPrint "# Reconstructed command line: " & GetCommandline()
465
466    ' some Wscript stuff
467    LogPrint "# Wscript properties:"
468    LogPrint "#   ScriptName: " & Wscript.ScriptName
469    LogPrint "#   Version:    " & Wscript.Version
470    LogPrint "#   Build:      " & Wscript.BuildVersion
471    LogPrint "#   Name:       " & Wscript.Name
472    LogPrint "#   Full Name:  " & Wscript.FullName
473    LogPrint "#   Path:       " & Wscript.Path
474    LogPrint "#"
475
476
477    ' the environment
478    LogPrint "# Environment:"
479    dim objEnv
480    for each strVar in g_objShell.Environment("PROCESS")
481       LogPrint "#   " & strVar
482    next
483    LogPrint "#"
484 end sub
485
486
487 ''
488 ' Append text to the log file.
489 sub LogPrint(str)
490    FileAppendLine g_strLogFile, str
491    'Wscript.Echo "dbg: " & str
492 end sub
493
494
495 ''
496 ' Checks if the file exists and logs failures.
497 function LogFileExists(strPath, strFilename)
498    LogFileExists = FileExists(strPath & "/" & strFilename)
499    if LogFileExists = False then
500       LogPrint "Testing '" & strPath & "': " & strFilename & " not found"
501    end if
502
503 end function
504
505
506 ''
507 ' Finds the first file matching the pattern.
508 ' If no file is found, log the failure.
509 function LogFindFile(strPath, strPattern)
510    dim str
511
512    '
513    ' Yes, there are some facy database kinda interface to the filesystem
514    ' however, breaking down the path and constructing a usable query is
515    ' too much hassle. So, we'll do it the unix way...
516    '
517    if Shell("dir /B """ & DosSlashes(strPath) & "\" & DosSlashes(strPattern) & """", True) = 0 _
518     And InStr(1, g_strShellOutput, Chr(13)) > 1 _
519       then
520       ' return the first word.
521       LogFindFile = Left(g_strShellOutput, InStr(1, g_strShellOutput, Chr(13)) - 1)
522    else
523       LogPrint "Testing '" & strPath & "': " & strPattern & " not found"
524       LogFindFile = ""
525    end if
526 end function
527
528
529 ''
530 ' Finds the first directory matching the pattern.
531 ' If no directory is found, log the failure,
532 ' else return the complete path to the found directory.
533 function LogFindDir(strPath, strPattern)
534    dim str
535
536    '
537    ' Yes, there are some facy database kinda interface to the filesystem
538    ' however, breaking down the path and constructing a usable query is
539    ' too much hassle. So, we'll do it the unix way...
540    '
541
542    ' List the alphabetically last names as first entries (with /O-N).
543    if Shell("dir /B /AD /O-N """ & DosSlashes(strPath) & "\" & DosSlashes(strPattern) & """", True) = 0 _
544     And InStr(1, g_strShellOutput, Chr(13)) > 1 _
545       then
546       ' return the first word.
547       LogFindDir = strPath & "/" & Left(g_strShellOutput, InStr(1, g_strShellOutput, Chr(13)) - 1)
548    else
549       LogPrint "Testing '" & strPath & "': " & strPattern & " not found"
550       LogFindDir = ""
551    end if
552 end function
553
554
555 ''
556 ' Initializes the config file.
557 sub CfgInit
558    FileDelete g_strCfgFile
559    CfgPrint "# -*- Makefile -*-"
560    CfgPrint "#"
561    CfgPrint "# Build configuration generated by " & GetCommandline()
562    CfgPrint "#"
563    if g_blnInternalMode = False then
564       CfgPrint "VBOX_OSE := 1"
565    end if
566 end sub
567
568
569 ''
570 ' Prints a string to the config file.
571 sub CfgPrint(str)
572    FileAppendLine g_strCfgFile, str
573 end sub
574
575
576 ''
577 ' Initializes the environment batch script.
578 sub EnvInit
579    FileDelete g_strEnvFile
580    EnvPrint "@echo off"
581    EnvPrint "rem"
582    EnvPrint "rem Environment setup script generated by " & GetCommandline()
583    EnvPrint "rem"
584 end sub
585
586
587 ''
588 ' Prints a string to the environment batch script.
589 sub EnvPrint(str)
590    FileAppendLine g_strEnvFile, str
591 end sub
592
593
594 ''
595 ' No COM
596 sub DisableCOM(strReason)
597    if g_blnDisableCOM = False then
598       LogPrint "Disabled COM components: " & strReason
599       g_blnDisableCOM = True
600       g_strDisableCOM = strReason
601       CfgPrint "VBOX_WITH_MAIN="
602       CfgPrint "VBOX_WITH_QTGUI="
603       CfgPrint "VBOX_WITH_VBOXSDL="
604       CfgPrint "VBOX_WITH_DEBUGGER_GUI="
605       CfgPrint "VBOX_WITHOUT_COM=1"
606    end if
607 end sub
608
609
610 ''
611 ' Checks the the path doesn't contain characters the tools cannot deal with.
612 sub CheckSourcePath
613    dim sPwd
614
615    sPwd = PathAbs(g_strPath)
616    if InStr(1, sPwd, " ") > 0 then
617       MsgError "Source path contains spaces! Please move it. (" & sPwd & ")"
618    end if
619    if InStr(1, sPwd, "$") > 0 then
620       MsgError "Source path contains the '$' char! Please move it. (" & sPwd & ")"
621    end if
622    if InStr(1, sPwd, "%") > 0 then
623       MsgError "Source path contains the '%' char! Please move it. (" & sPwd & ")"
624    end if
625    if  InStr(1, sPwd, Chr(10)) > 0 _
626     Or InStr(1, sPwd, Chr(13)) > 0 _
627     Or InStr(1, sPwd, Chr(9)) > 0 _
628     then
629       MsgError "Source path contains control characters! Please move it. (" & sPwd & ")"
630    end if
631    Print "Source path: OK"
632 end sub
633
634
635 ''
636 ' Checks for kBuild - very simple :)
637 sub CheckForkBuild(strOptkBuild)
638    PrintHdr "kBuild"
639
640    '
641    ' Check if there is a 'kmk' in the path somewhere without
642    ' any PATH_KBUILD* stuff around.
643    '
644    blnNeedEnvVars = True
645    g_strPathkBuild = strOptkBuild
646    g_strPathkBuildBin = ""
647    if   (g_strPathkBuild = "") _
648     And (EnvGet("PATH_KBUILD") = "") _
649     And (EnvGet("PATH_KBUILD_BIN") = "") _
650     And (Shell("kmk.exe --version", True) = 0) _
651     And (InStr(1,g_strShellOutput, "kBuild Make 0.1") > 0) _
652     And (InStr(1,g_strShellOutput, "PATH_KBUILD") > 0) _
653     And (InStr(1,g_strShellOutput, "PATH_KBUILD_BIN") > 0) then
654       '' @todo Need to parse out the PATH_KBUILD and PATH_KBUILD_BIN values to complete the other tests.
655       'blnNeedEnvVars = False
656       MsgWarning "You've installed kBuild it seems. configure.vbs hasn't been updated to " _
657          & "deal with that yet and will use the one it ships with. Sorry."
658    end if
659
660    '
661    ' Check for the PATH_KBUILD env.var. and fall back on root/kBuild otherwise.
662    '
663    if g_strPathkBuild = "" then
664       g_strPathkBuild = EnvGet("PATH_KBUILD")
665       if (g_strPathkBuild <> "") and (FileExists(g_strPathkBuild & "/footer.kmk") = False) then
666          MsgWarning "Ignoring incorrect kBuild path (PATH_KBUILD=" & g_strPathkBuild & ")"
667          g_strPathkBuild = ""
668       end if
669
670       if g_strPathkBuild = "" then
671          g_strPathkBuild = g_strPath & "/kBuild"
672       end if
673    end if
674
675    g_strPathkBuild = UnixSlashes(PathAbs(g_strPathkBuild))
676
677    '
678    ' Determin the location of the kBuild binaries.
679    '
680    if g_strPathkBuildBin = "" then
681       dim str2
682       if EnvGet("PROCESSOR_ARCHITECTURE") = "x86" then
683          g_strPathkBuildBin = g_strPathkBuild & "/bin/win.x86"
684       else ' boldly assumes there is only x86 and amd64.
685          g_strPathkBuildBin = g_strPathkBuild & "/bin/win.amd64"
686          if FileExists(g_strPathkBuild & "/kmk.exe") = False then
687             g_strPathkBuildBin = g_strPathkBuild & "/bin/win.x86"
688          end if
689       end if
690       if FileExists(g_strPathkBuild & "/kmk.exe") = False then
691          g_strPathkBuildBin = g_strPathkBuild & "/bin/win.x86"
692       end if
693    end if
694
695    '
696    ' Perform basic validations of the kBuild installation.
697    '
698    if  (FileExists(g_strPathkBuild & "/footer.kmk") = False) _
699     Or (FileExists(g_strPathkBuild & "/header.kmk") = False) _
700     Or (FileExists(g_strPathkBuild & "/rules.kmk") = False) then
701       MsgFatal "Can't find valid kBuild at '" & g_strPathkBuild & "'. Either there is an " _
702          & "incorrect PATH_KBUILD in the environment or the checkout didn't succeed."
703       exit sub
704    end if
705    if  (FileExists(g_strPathkBuildBin & "/kmk.exe") = False) _
706     Or (FileExists(g_strPathkBuildBin & "/kmk_ash.exe") = False) then
707       MsgFatal "Can't find valid kBuild binaries at '" & g_strPathkBuildBin & "'. Either there is an " _
708          & "incorrect PATH_KBUILD in the environment or the checkout didn't succeed."
709       exit sub
710    end if
711
712    if (Shell(DosSlashes(g_strPathkBuildBin & "/kmk.exe") & " --version", True) <> 0) Then
713       MsgFatal "Can't execute '" & g_strPathkBuildBin & "/kmk.exe --version'. check configure.log for the out."
714       exit sub
715    end if
716
717    '
718    ' Check for env.vars that kBuild uses.
719    '
720    str = EnvGet("BUILD_TYPE")
721    if   (str <> "") _
722     And (InStr(1, "|release|debug|profile|kprofile", str) <= 0) then
723       EnvPrint "set BUILD_TYPE=release"
724       EnvSet "BUILD_TYPE", "release"
725       MsgWarning "Found unknown BUILD_TYPE value '" & str &"' in your environment. Setting it to 'release'."
726    end if
727
728    str = EnvGet("BUILD_TARGET")
729    if   (str <> "") _
730     And (InStr(1, "win|win32|win64", str) <= 0) then '' @todo later only 'win' will be valid. remember to fix this check!
731       EnvPrint "set BUILD_TARGET=win"
732       EnvSet "BUILD_TARGET", "win"
733       MsgWarning "Found unknown BUILD_TARGET value '" & str &"' in your environment. Setting it to 'win32'."
734    end if
735
736    str = EnvGet("BUILD_TARGET_ARCH")
737    if   (str <> "") _
738     And (InStr(1, "x86|amd64", str) <= 0) then
739       EnvPrint "set BUILD_TARGET_ARCH=x86"
740       EnvSet "BUILD_TARGET_ARCH", "x86"
741       MsgWarning "Found unknown BUILD_TARGET_ARCH value '" & str &"' in your environment. Setting it to 'x86'."
742    end if
743
744    str = EnvGet("BUILD_TARGET_CPU")
745     ' perhaps a bit pedantic this since this isn't clearly define nor used much...
746    if   (str <> "") _
747     And (InStr(1, "i386|i486|i686|i786|i868|k5|k6|k7|k8", str) <= 0) then
748       EnvPrint "set BUILD_TARGET_CPU=i386"
749       EnvSet "BUILD_TARGET_CPU", "i386"
750       MsgWarning "Found unknown BUILD_TARGET_CPU value '" & str &"' in your environment. Setting it to 'i386'."
751    end if
752
753    str = EnvGet("BUILD_PLATFORM")
754    if   (str <> "") _
755     And (InStr(1, "win|win32|win64", str) <= 0) then '' @todo later only 'win' will be valid. remember to fix this check!
756       EnvPrint "set BUILD_PLATFORM=win"
757       EnvSet "BUILD_PLATFORM", "win"
758       MsgWarning "Found unknown BUILD_PLATFORM value '" & str &"' in your environment. Setting it to 'win32'."
759    end if
760
761    str = EnvGet("BUILD_PLATFORM_ARCH")
762    if   (str <> "") _
763     And (InStr(1, "x86|amd64", str) <= 0) then
764       EnvPrint "set BUILD_PLATFORM_ARCH=x86"
765       EnvSet "BUILD_PLATFORM_ARCH", "x86"
766       MsgWarning "Found unknown BUILD_PLATFORM_ARCH value '" & str &"' in your environment. Setting it to 'x86'."
767    end if
768
769    str = EnvGet("BUILD_PLATFORM_CPU")
770     ' perhaps a bit pedantic this since this isn't clearly define nor used much...
771    if   (str <> "") _
772     And (InStr(1, "i386|i486|i686|i786|i868|k5|k6|k7|k8", str) <= 0) then
773       EnvPrint "set BUILD_PLATFORM_CPU=i386"
774       EnvSet "BUILD_PLATFORM_CPU", "i386"
775       MsgWarning "Found unknown BUILD_PLATFORM_CPU value '" & str &"' in your environment. Setting it to 'i386'."
776    end if
777
778    '
779    ' If PATH_DEV is set, check that it's pointing to something useful.
780    '
781    str = EnvGet("PATH_DEV")
782    g_strPathDev = str
783    if (str <> "") _
784     And False then '' @todo add some proper tests here.
785       strNew = UnixSlashes(g_strPath & "/tools")
786       EnvPrint "set PATH_DEV=" & strNew
787       EnvSet "PATH_DEV", strNew
788       MsgWarning "Found PATH_DEV='" & str &"' in your environment. Setting it to '" & strNew & "'."
789       g_strPathDev = strNew
790    end if
791    if g_strPathDev = "" then g_strPathDev = UnixSlashes(g_strPath & "/tools")
792
793    '
794    ' Write PATH_KBUILD to the environment script if necessary.
795    '
796    if blnNeedEnvVars = True then
797       EnvPrint "set PATH_KBUILD=" & g_strPathkBuild
798       EnvSet "PATH_KBUILD", g_strPathkBuild
799       EnvPrint "set PATH=" & g_strPathkBuildBin & ";%PATH%"
800       EnvPrepend "PATH", g_strPathkBuildBin & ";"
801    end if
802
803    PrintResult "kBuild", g_strPathkBuild
804    PrintResult "kBuild binaries", g_strPathkBuildBin
805 end sub
806
807
808 ''
809 ' Checks for Visual C++ version 7 or 8.
810 sub CheckForVisualCPP(strOptVC, strOptVCCommon, blnOptVCExpressEdition)
811    dim strPathVC, strPathVCCommon, str, str2, blnNeedMsPDB
812    PrintHdr "Visual C++"
813
814    '
815    ' Try find it...
816    '
817    strPathVC = ""
818    strPathVCCommon = ""
819    if (strPathVC = "") And (strOptVC <> "") then
820       if CheckForVisualCPPSub(strOptVC, strOptVCCommon, blnOptVCExpressEdition) then
821          strPathVC = strOptVC
822          strPathVCCommon = strOptVCCommon
823       end if
824    end if
825
826    if (strPathVC = "") And (g_blnInternalFirst = True) Then
827       strPathVC = g_strPathDev & "/win.x86/vcc/v8"
828       if CheckForVisualCPPSub(strPathVC, "", blnOptVCExpressEdition) = False then
829          strPathVC = g_strPathDev & "/win.x86/vcc/v7"
830          if CheckForVisualCPPSub(strPathVC, "", blnOptVCExpressEdition) = False then
831             strPathVC = ""
832          end if
833       end if
834    end if
835
836    if   (strPathVC = "") _
837     And (Shell("cl.exe", True) = 0) then
838       str = Which("cl.exe")
839       if FileExists(PathStripFilename(strClExe) & "/build.exe") then
840          ' don't know how to deal with this cl.
841          Warning "Ignoring DDK cl.exe (" & str & ")."
842       else
843          strPathVC = PathParent(PathStripFilename(str))
844          strPathVCCommon = PathParent(strPathVC) & "/Common7"
845       end if
846    end if
847
848    if strPathVC = "" then
849       str = RegGetString("HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\8.0\Setup\VS\ProductDir")
850       str2 = RegGetString("HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\8.0\Setup\VS\EnvironmentDirectory")
851       if str <> "" And str2 <> "" Then
852          str = str & "VC"
853          str2 = PathParent(str2)
854          if CheckForVisualCPPSub(str, str2, blnOptVCExpressEdition) then
855             strPathVC = str
856             strPathVCCommon = str2
857          end if
858       end if
859    end if
860
861    if strPathVC = "" then
862       str = RegGetString("HKLM\SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS\ProductDir")
863       str2 = RegGetString("HKLM\SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS\EnvironmentDirectory")
864       if str <> "" And str2 <> "" Then
865          str = str & "VC"
866          str2 = PathParent(str2)
867          if CheckForVisualCPPSub(str, str2, blnOptVCExpressEdition) then
868             strPathVC = str
869             strPathVCCommon = str2
870          end if
871       end if
872    end if
873
874    if strPathVC = "" then
875       '' @todo check what this really looks like on 7.1
876       str = RegGetString("HKLM\SOFTWARE\Microsoft\VisualStudio\7.1\Setup\VS\ProductDir")
877       str2 = RegGetString("HKLM\SOFTWARE\Microsoft\VisualStudio\7.1\Setup\VS\EnvironmentDirectory")
878       if str <> "" And str2 <> "" Then
879          str = str & "VC7"
880          str2 = PathParent(str2)
881          if CheckForVisualCPPSub(str, str2, blnOptVCExpressEdition) then
882             strPathVC = str
883             strPathVCCommon = str2
884          end if
885       end if
886    end if
887
888    if strPathVC = "" then
889       str = RegGetString("HKLM\SOFTWARE\Microsoft\VisualStudio\7.0\Setup\VS\ProductDir")
890       str2 = RegGetString("HKLM\SOFTWARE\Microsoft\VisualStudio\7.0\Setup\VS\EnvironmentDirectory")
891       if str <> "" And str2 <> "" Then
892          str = str & "VC7"
893          str2 = PathParent(str2)
894          if CheckForVisualCPPSub(str, str2, blnOptVCExpressEdition) then
895             strPathVC = str
896             strPathVCCommon = str2
897          end if
898       end if
899    end if
900
901    if strPathVC = "" then
902       str = RegGetString("HKLM\SOFTWARE\Microsoft\Wow6432Node\VisualStudio\SxS\VC7\8.0")
903       if str <> "" then
904          str2 = PathParent(str) & "/Common7"
905          if CheckForVisualCPPSub(str, str2, blnOptVCExpressEdition) then
906             strPathVC = str
907             strPathVCCommon = str2
908          end if
909       end if
910    end if
911
912    if strPathVC = "" then
913       str = RegGetString("HKLM\SOFTWARE\Microsoft\VisualStudio\SxS\VC7\8.0")
914       if str <> "" then
915          str2 = PathParent(str) & "/Common7"
916          if CheckForVisualCPPSub(str, str2, blnOptVCExpressEdition) then
917             strPathVC = str
918             strPathVCCommon = str2
919          end if
920       end if
921    end if
922
923    ' finally check for the express edition.
924    if strPathVC = "" then
925       str = RegGetString("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Visual C++ 2005 Express Edition - ENU\InstallLocation")
926       if str <> "" then
927          str2 = str & "Common7"
928          str = str & "VC/"
929          if CheckForVisualCPPSub(str, str2, blnOptVCExpressEdition) then
930             strPathVC = str
931             strPathVCCommon = str2
932          end if
933       end if
934    end if
935
936    if (strPathVC = "") And (g_blnInternalFirst = False) Then
937       strPathVC = g_strPathDev & "/win.x86/vcc/v8"
938       if CheckForVisualCPPSub(strPathVC, "", blnOptVCExpressEdition) = False then
939          strPathVC = g_strPathDev & "/win.x86/vcc/v7"
940          if CheckForVisualCPPSub(strPathVC, "", blnOptVCExpressEdition) = False then
941             strPathVC = ""
942          end if
943       end if
944    end if
945
946    if strPathVC = "" then
947       MsgError "Cannot find cl.exe (Visual C++) anywhere on your system. Check the build requirements."
948       exit sub
949    end if
950
951    '
952    ' Clean up the path and determin the VC directory.
953    '
954    strPathVC = UnixSlashes(PathAbs(strPathVC))
955    g_strPathVCC = strPathVC
956
957    '
958    ' Check the version.
959    ' We'll have to make sure mspdbXX.dll is somewhere in the PATH.
960    '
961    if (strPathVCCommon <> "") Then
962       EnvAppend "PATH", ";" & strPathVCCommon & "/IDE"
963    end if
964    if Shell(DosSlashes(strPathVC & "/bin/cl.exe"), True) <> 0 then
965       MsgError "Executing '" & strClExe & "' (which we believe to be the Visual C++ compiler driver) failed."
966       exit sub
967    end if
968
969    if   (InStr(1, g_strShellOutput, "Version 13.10") <= 0) _
970     And (InStr(1, g_strShellOutput, "Version 14.") <= 0) then
971       MsgError "The Visual C++ compiler we found ('" & strPathVC & "') isn't 7.1 or 8.0. Check the build requirements."
972       exit sub
973    end if
974
975    '
976    ' Ok, emit build config variables.
977    '
978    if InStr(1, g_strShellOutput, "Version 14.") > 0 then
979       CfgPrint "VBOX_USE_VCC80        := 1"
980       CfgPrint "PATH_TOOL_VCC80       := " & g_strPathVCC
981       CfgPrint "PATH_TOOL_VCC80X86     = $(PATH_TOOL_VCC80)"
982       CfgPrint "PATH_TOOL_VCC80AMD64   = $(PATH_TOOL_VCC80)"
983       if   blnOptVCExpressEdition _
984        And LogFileExists(strPathVC, "atlmfc/include/atlbase.h") = False _
985          then
986          CfgPrint "TOOL_VCC80X86_MT = $(PATH_SDK_WINPSDK)/Bin/mt.exe"
987          CfgPrint "TOOL_VCC80AMD64_MT = $(TOOL_VCC80X86_MT)"
988          CfgPrint "VBOX_WITHOUT_COMPILER_REDIST=1"
989          DisableCOM "No ATL"
990          PrintResult "Visual C++ v8 (or later) without ATL", g_strPathVCC
991       else
992          PrintResult "Visual C++ v8 (or later)", g_strPathVCC
993       end if
994    else
995       CfgPrint "PATH_TOOL_VCC70 := " & g_strPathVCC
996       if   blnOptVCExpressEdition _
997        And LogFileExists(strPathVC, "atlmfc/include/atlbase.h") = False _
998          then
999          CfgPrint "VBOX_WITHOUT_COMPILER_REDIST=1"
1000          DisableCOM "No ATL"
1001          PrintResult "Visual C++ v7.1 without ATL", g_strPathVCC
1002       else
1003          PrintResult "Visual C++ v7.1", g_strPathVCC
1004       end if
1005    end if
1006
1007    ' and the env.bat path fix.
1008    if strPathVCCommon <> "" then
1009       EnvPrint "set PATH=%PATH%;" & strPathVCCommon & "/IDE;"
1010    end if
1011 end sub
1012
1013 ''
1014 ' Checks if the specified path points to a usable PSDK.
1015 function CheckForVisualCPPSub(strPathVC, strPathVCCommon, blnOptVCExpressEdition)
1016    strPathVC = UnixSlashes(PathAbs(strPathVC))
1017    CheckForVisualCPPSub = False
1018    LogPrint "trying: strPathVC=" & strPathVC & " strPathVCCommon=" & strPathVCCommon & " blnOptVCExpressEdition=" & blnOptVCExpressEdition
1019    if   LogFileExists(strPathVC, "bin/cl.exe") _
1020     And LogFileExists(strPathVC, "bin/link.exe") _
1021     And LogFileExists(strPathVC, "include/string.h") _
1022     And LogFileExists(strPathVC, "lib/libcmt.lib") _
1023     And LogFileExists(strPathVC, "lib/msvcrt.lib") _
1024       then
1025       if blnOptVCExpressEdition _
1026        Or (    LogFileExists(strPathVC, "atlmfc/include/atlbase.h") _
1027            And LogFileExists(strPathVC, "atlmfc/lib/atls.lib")) _
1028          Then
1029          '' @todo figure out a way we can verify the version/build!
1030          CheckForVisualCPPSub = True
1031       end if
1032    end if
1033 end function
1034
1035
1036 ''
1037 ' Checks for a platform SDK that works with the compiler
1038 sub CheckForPlatformSDK(strOptSDK)
1039    dim strPathPSDK, str
1040    PrintHdr "Windows Platform SDK (recent)"
1041
1042    strPathPSDK = ""
1043
1044    ' Check the supplied argument first.
1045    str = strOptSDK
1046    if str <> "" then
1047       if CheckForPlatformSDKSub(str) then strPathPSDK = str
1048    end if
1049
1050    ' The tools location (first).
1051    if (strPathPSDK = "") And (g_blnInternalFirst = True) then
1052       str = g_strPathDev & "/win.x86/sdk/200604"
1053       if CheckForPlatformSDKSub(str) then strPathPSDK = str
1054    end if
1055
1056    if (strPathPSDK = "") And (g_blnInternalFirst = True) then
1057       str = g_strPathDev & "/win.x86/sdk/200504"
1058       if CheckForPlatformSDKSub(str) then strPathPSDK = str
1059    end if
1060
1061    if (strPathPSDK = "") And (g_blnInternalFirst = True) then
1062       str = g_strPathDev & "/win.x86/sdk/200209"
1063       if CheckForPlatformSDKSub(str) then strPathPSDK = str
1064    end if
1065
1066    ' Look for it in the environment
1067    str = EnvGet("MSSdk")
1068    if (strPathPSDK = "") And (str <> "") then
1069       if CheckForPlatformSDKSub(str) then strPathPSDK = str
1070    end if
1071
1072    str = EnvGet("Mstools")
1073    if (strPathPSDK = "") And (str <> "") then
1074       if CheckForPlatformSDKSub(str) then strPathPSDK = str
1075    end if
1076
1077    ' Check if there is one installed with the compiler.
1078    if (strPathPSDK = "") And (str <> "") then
1079       str = g_strPathVCC & "/PlatformSDK"
1080       if CheckForPlatformSDKSub(str) then strPathPSDK = str
1081    end if
1082
1083    ' Check the registry next. (first pair is vista, second is pre-vista)
1084    arrSubKeys = RegEnumSubKeys("HKLM", "SOFTWARE\Microsoft\Microsoft SDKs\Windows")
1085    for Each strSubKey In arrSubKeys
1086       str = RegGetString("HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\" & strSubKey & "\InstallationFolder")
1087       if (strPathPSDK = "") And (str <> "") then
1088          if CheckForPlatformSDKSub(str) then strPathPSDK = str
1089       end if
1090    Next
1091    arrSubKeys = RegEnumSubKeys("HKCU", "SOFTWARE\Microsoft\Microsoft SDKs\Windows")
1092    for Each strSubKey In arrSubKeys
1093       str = RegGetString("HKCU\SOFTWARE\Microsoft\Microsoft SDKs\Windows\" & strSubKey & "\InstallationFolder")
1094       if (strPathPSDK = "") And (str <> "") then
1095          if CheckForPlatformSDKSub(str) then strPathPSDK = str
1096       end if
1097    Next
1098
1099    arrSubKeys = RegEnumSubKeys("HKLM", "SOFTWARE\Microsoft\MicrosoftSDK\InstalledSDKs")
1100    for Each strSubKey In arrSubKeys
1101       str = RegGetString("HKLM\SOFTWARE\Microsoft\MicrosoftSDK\InstalledSDKs\" & strSubKey & "\Install Dir")
1102       if (strPathPSDK = "") And (str <> "") then
1103          if CheckForPlatformSDKSub(str) then strPathPSDK = str
1104       end if
1105    Next
1106    arrSubKeys = RegEnumSubKeys("HKCU", "SOFTWARE\Microsoft\MicrosoftSDK\InstalledSDKs")
1107    for Each strSubKey In arrSubKeys
1108       str = RegGetString("HKCU\SOFTWARE\Microsoft\MicrosoftSDK\InstalledSDKs\" & strSubKey & "\Install Dir")
1109       if (strPathPSDK = "") And (str <> "") then
1110          if CheckForPlatformSDKSub(str) then strPathPSDK = str
1111       end if
1112    Next
1113
1114    ' The tools location (post).
1115    if (strPathPSDK = "") And (g_blnInternalFirst = False) then
1116       str = g_strPathDev & "/win.x86/sdk/200604"
1117       if CheckForPlatformSDKSub(str) then strPathPSDK = str
1118    end if
1119
1120    if (strPathPSDK = "") And (g_blnInternalFirst = False) then
1121       str = g_strPathDev & "/win.x86/sdk/200504"
1122       if CheckForPlatformSDKSub(str) then strPathPSDK = str
1123    end if
1124
1125    if (strPathPSDK = "") And (g_blnInternalFirst = False) then
1126       str = g_strPathDev & "/win.x86/sdk/200209"
1127       if CheckForPlatformSDKSub(str) then strPathPSDK = str
1128    end if
1129
1130    ' Give up.
1131    if strPathPSDK = "" then
1132       MsgError "Cannot find a suitable Platform SDK. Check configure.log and the build requirements."
1133       exit sub
1134    end if
1135
1136    '
1137    ' Emit the config.
1138    '
1139    strPathPSDK = UnixSlashes(PathAbs(strPathPSDK))
1140    CfgPrint "PATH_SDK_WINPSDK      := " & strPathPSDK
1141    CfgPrint "PATH_SDK_WINPSDKINCS   = $(PATH_SDK_WINPSDK)"
1142    CfgPrint "PATH_SDK_WIN32SDK      = $(PATH_SDK_WINPSDK)"
1143    CfgPrint "PATH_SDK_WIN64SDK      = $(PATH_SDK_WINPSDK)"
1144
1145    PrintResult "Windows Platform SDK", strPathPSDK
1146    g_strPathPSDK = strPathPSDK
1147 end sub
1148
1149 ''
1150 ' Checks if the specified path points to a usable PSDK.
1151 function CheckForPlatformSDKSub(strPathPSDK)
1152    CheckForPlatformSDKSub = False
1153    LogPrint "trying: strPathPSDK=" & strPathPSDK
1154    if    LogFileExists(strPathPSDK, "include/Windows.h") _
1155     And  LogFileExists(strPathPSDK, "lib/Kernel32.Lib") _
1156     And  LogFileExists(strPathPSDK, "lib/User32.Lib") _
1157       then
1158       CheckForPlatformSDKSub = True
1159    end if
1160 end function
1161
1162
1163 ''
1164 ' Checks for a Windows 2003 DDK that works with the compiler intrinsics.
1165 sub CheckForWin2k3DDK(strOptDDK)
1166    dim strPathDDK, str, strSubKeys
1167    PrintHdr "Windows 2003 DDK, build 3790 or later"
1168
1169    '
1170    ' Find the DDK.
1171    '
1172    strPathDDK = ""
1173    ' The specified path.
1174    if (strPathDDK = "") And (strOptDDK <> "") then
1175       if CheckForW