' $Id: configure.vbs 96285 2022-08-18 08:01:23Z vboxsync $ '' @file ' The purpose of this script is to check for all external tools, headers, and ' libraries VBox OSE depends on. ' ' The script generates the build configuration file 'AutoConfig.kmk' and the ' environment setup script 'env.bat'. A log of what has been done is ' written to 'configure.log'. ' ' ' Copyright (C) 2006-2022 Oracle Corporation ' ' This file is part of VirtualBox Open Source Edition (OSE), as ' available from http://www.virtualbox.org. This file is free software; ' you can redistribute it and/or modify it under the terms of the GNU ' General Public License (GPL) as published by the Free Software ' Foundation, in version 2 as it comes in the "COPYING" file of the ' VirtualBox OSE distribution. VirtualBox OSE is distributed in the ' hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Header Files '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' ' Includes a vbscript file relative to the script. sub IncludeFile(strFilename) dim objFile, objFileSys set objFileSys = WScript.CreateObject("Scripting.FileSystemObject") dim strPath : strPath = objFileSys.BuildPath(objFileSys.GetParentFolderName(Wscript.ScriptFullName), strFilename) set objFile = objFileSys.openTextFile(strPath) executeglobal objFile.readAll() objFile.close set objFileSys = nothing end sub IncludeFile "tools\win\vbscript\helpers.vbs" '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Global Variables ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' dim g_strPath, g_strEnvFile, g_strLogFile, g_strCfgFile g_strPath = Left(Wscript.ScriptFullName, Len(Wscript.ScriptFullName) - Len("\configure.vbs")) g_strEnvFile = g_strPath & "\env.bat" g_strCfgFile = g_strPath & "\AutoConfig.kmk" g_strLogFile = g_strPath & "\configure.log" 'g_strTmpFile = g_strPath & "\configure.tmp" ' kBuild stuff. dim g_strPathkBuild, g_strPathkBuildBin, g_strPathDev, g_arrPathDev g_strPathkBuild = "" g_strPathkBuildBin = "" g_strPathDev = "" g_arrPathDev = Array(":placeholder:") dim g_strTargetArch, g_StrTargetArchWin g_strTargetArch = "" g_StrTargetArchWin = "" dim g_strHostArch, g_strHostArchWin g_strHostArch = "" g_strHostArchWin = "" ' Visual C++ info. dim g_strPathVCC, g_strVCCVersion g_strPathVCC = "" g_strVCCVersion = "" ' SDK and DDK. dim g_strPathSDK10, g_strPathPSDK, g_strVerPSDK, g_strPathDDK g_strPathSDK10 = "" g_strPathPSDK = "" g_strVerPSDK = "" g_strPathDDK = "" ' COM disabling. dim g_blnDisableCOM, g_strDisableCOM g_blnDisableCOM = False g_strDisableCOM = "" ' Whether to try the internal stuff first or last. dim g_blnInternalFirst g_blnInternalFirst = True ' List of program files locations. dim g_arrProgramFiles if EnvGet("ProgramFiles(x86)") <> "" then g_arrProgramFiles = Array(EnvGet("ProgramFiles"), EnvGet("ProgramFiles(x86)")) else g_arrProgramFiles = Array(EnvGet("ProgramFiles")) end if '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Helpers: Logging and Logged operations ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' ' Write a log header with some basic info. sub LogInit FileDelete g_strLogFile LogPrint "# Log file generated by " & Wscript.ScriptFullName for i = 1 to WScript.Arguments.Count LogPrint "# Arg #" & i & ": " & WScript.Arguments.Item(i - 1) next if Wscript.Arguments.Count = 0 then LogPrint "# No arguments given" end if LogPrint "# Reconstructed command line: " & GetCommandline() ' some Wscript stuff LogPrint "# Wscript properties:" LogPrint "# ScriptName: " & Wscript.ScriptName LogPrint "# Version: " & Wscript.Version LogPrint "# Build: " & Wscript.BuildVersion LogPrint "# Name: " & Wscript.Name LogPrint "# Full Name: " & Wscript.FullName LogPrint "# Path: " & Wscript.Path LogPrint "#" ' the environment LogPrint "# Environment:" dim objEnv for each strVar in g_objShell.Environment("PROCESS") LogPrint "# " & strVar next LogPrint "#" end sub '' ' Append text to the log file. sub LogPrint(str) FileAppendLine g_strLogFile, str 'Wscript.Echo "dbg: " & str end sub '' ' Debug output. sub DbgPrint(str) 'FileAppendLine g_strLogFile, str 'Wscript.Echo "dbg: " & str end sub '' ' Checks if the file exists and logs failures. function LogFileExists(strPath, strFilename) LogFileExists = FileExists(strPath & "/" & strFilename) if LogFileExists = False then LogPrint "Testing '" & strPath & "': " & strFilename & " not found" end if end function '' ' Checks if the file exists and logs failures. function LogFileExists1(strPath) LogFileExists1 = FileExists(strPath) if LogFileExists1 = False then LogPrint "Testing '" & strPath & "': file not found" end if end function '' ' Checks if the directory exists and logs failures. function LogDirExists(strPath) LogDirExists = DirExists(strPath) if LogDirExists = False then LogPrint "Testing '" & strPath & "': not found (or not dir)" end if end function '' ' Finds the first file matching the pattern. ' If no file is found, log the failure. function LogFindFile(strPath, strPattern) dim str, strOutput ' ' Yes, there are some facy database kinda interface to the filesystem ' however, breaking down the path and constructing a usable query is ' too much hassle. So, we'll do it the unix way... ' if Shell("dir /B """ & DosSlashes(strPath) & "\" & DosSlashes(strPattern) & """", True, strOutput) = 0 _ And InStr(1, strOutput, Chr(13)) > 1 _ then ' return the first word. LogFindFile = Left(strOutput, InStr(1, strOutput, Chr(13)) - 1) else LogPrint "Testing '" & strPath & "': " & strPattern & " not found" LogFindFile = "" end if end function '' ' Finds the first directory matching the pattern. ' If no directory is found, log the failure, ' else return the complete path to the found directory. function LogFindDir(strPath, strPattern) dim str, strOutput ' ' Yes, there are some facy database kinda interface to the filesystem ' however, breaking down the path and constructing a usable query is ' too much hassle. So, we'll do it the unix way... ' ' List the alphabetically last names as first entries (with /O-N). if Shell("dir /B /AD /O-N """ & DosSlashes(strPath) & "\" & DosSlashes(strPattern) & """", True, strOutput) = 0 _ And InStr(1, strOutput, Chr(13)) > 1 _ then ' return the first word. LogFindDir = strPath & "/" & Left(strOutput, InStr(1, strOutput, Chr(13)) - 1) else LogPrint "Testing '" & strPath & "': " & strPattern & " not found" LogFindDir = "" end if end function '' ' Wrapper around RegGetString that logs successes. function LogRegGetString(strName) LogRegGetString = RegGetString(strName) if LogRegGetString <> "" then LogPrint "RegGetString(" & strName & ") -> " & LogRegGetString end function '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Helpers: Configuration and Batch Script Writers ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' ' Initializes the config file. sub CfgInit FileDelete g_strCfgFile CfgPrint "# -*- Makefile -*-" CfgPrint "#" CfgPrint "# Build configuration generated by " & GetCommandline() CfgPrint "#" CfgPrintAssign "VBOX_OSE", "1" CfgPrintAssignRecursive "VBOX_VCC_WERR", "$(NO_SUCH_VARIABLE)" end sub '' ' Prints a string to the config file. sub CfgPrint(str) FileAppendLine g_strCfgFile, str end sub '' ' Prints a simple assignment to the config file. sub CfgPrintAssign(strVar, strValue) if strValue = "" then FileAppendLine g_strCfgFile, RightPad(strVar, 23) & " :=" else FileAppendLine g_strCfgFile, RightPad(strVar, 23) & " := " & strValue end if end sub '' ' Prints a recursive assignment to the config file. sub CfgPrintAssignRecursive(strVar, strValue) FileAppendLine g_strCfgFile, RightPad(strVar, 23) & " = " & strValue end sub '' ' Initializes the environment batch script. sub EnvInit FileDelete g_strEnvFile EnvPrint "@echo off" EnvPrint "rem" EnvPrint "rem Environment setup script generated by " & GetCommandline() EnvPrint "rem" end sub '' ' Prints a string to the environment batch script. sub EnvPrint(str) FileAppendLine g_strEnvFile, str end sub '' ' Helper for EnvPrintPrepend and EnvPrintAppend. sub EnvPrintCleanup(strEnv, strValue, strSep) dim cchValueAndSep FileAppendLine g_strEnvFile, "set " & strEnv & "=%" & strEnv & ":" & strSep & strValue & strSep & "=" & strSep & "%" cchValueAndSep = Len(strValue) + Len(strSep) FileAppendLine g_strEnvFile, "if ""%" & strEnv & "%""==""" & strValue & """ set " & strEnv & "=" FileAppendLine g_strEnvFile, "if ""%" & strEnv & ":~0," & cchValueAndSep & "%""==""" & strValue & strSep & """ set " & strEnv & "=%" & strEnv & ":~" & cchValueAndSep & "%" FileAppendLine g_strEnvFile, "if ""%" & strEnv & ":~-" & cchValueAndSep & "%""==""" & strSep & strValue & """ set " & strEnv & "=%" & strEnv & ":~0,-" & cchValueAndSep & "%" end sub '' Use by EnvPrintPrepend to skip ';' stripping. dim g_strPrependCleanEnvVars '' ' Print a statement prepending strValue to strEnv, removing duplicate values. sub EnvPrintPrepend(strEnv, strValue, strSep) ' Remove old values and any leading separators. EnvPrintCleanup strEnv, strValue, strSep if InStr(1, g_strPrependCleanEnvVars, "|" & strEnv & "|") = 0 then FileAppendLine g_strEnvFile, "if ""%" & strEnv & ":~0,1%""==""" & strSep & """ set " & strEnv & "=%" & strEnv & ":~1%" FileAppendLine g_strEnvFile, "if ""%" & strEnv & ":~0,1%""==""" & strSep & """ set " & strEnv & "=%" & strEnv & ":~1%" g_strPrependCleanEnvVars = g_strPrependCleanEnvVars & "|" & strEnv & "|" end if ' Do the setting FileAppendLine g_strEnvFile, "set " & strEnv & "=" & strValue & strSep & "%" & strEnv & "%" end sub '' Use by EnvPrintPrepend to skip ';' stripping. dim g_strAppendCleanEnvVars '' ' Print a statement appending strValue to strEnv, removing duplicate values. sub EnvPrintAppend(strEnv, strValue, strSep) ' Remove old values and any trailing separators. EnvPrintCleanup strEnv, strValue, strSep if InStr(1, g_strAppendCleanEnvVars, "|" & strEnv & "|") = 0 then FileAppendLine g_strEnvFile, "if ""%" & strEnv & ":~-1%""==""" & strSep & """ set " & strEnv & "=%" & strEnv & ":~0,-1%" FileAppendLine g_strEnvFile, "if ""%" & strEnv & ":~-1%""==""" & strSep & """ set " & strEnv & "=%" & strEnv & ":~0,-1%" g_strAppendCleanEnvVars = g_strAppendCleanEnvVars & "|" & strEnv & "|" end if ' Do the setting. FileAppendLine g_strEnvFile, "set " & strEnv & "=%" & strEnv & "%" & strSep & strValue end sub '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Feature disabling ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' ' No COM sub DisableCOM(strReason) if g_blnDisableCOM = False then LogPrint "Disabled COM components: " & strReason g_blnDisableCOM = True g_strDisableCOM = strReason CfgPrintAssign "VBOX_WITH_MAIN", "" CfgPrintAssign "VBOX_WITH_QTGUI", "" CfgPrintAssign "VBOX_WITH_VBOXSDL", "" CfgPrintAssign "VBOX_WITH_DEBUGGER_GUI", "" end if end sub '' ' No UDPTunnel sub DisableUDPTunnel(strReason) if g_blnDisableUDPTunnel = False then LogPrint "Disabled UDPTunnel network transport: " & strReason g_blnDisableUDPTunnel = True g_strDisableUDPTunnel = strReason CfgPrintAssign "VBOX_WITH_UDPTUNNEL", "" end if end sub '' ' No SDL sub DisableSDL(strReason) if g_blnDisableSDL = False then LogPrint "Disabled SDL frontend: " & strReason g_blnDisableSDL = True g_strDisableSDL = strReason CfgPrintAssign "VBOX_WITH_VBOXSDL", "" end if end sub '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Tool/Library Locating and Checking ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' ' Generic helper for looking for a tools under g_strPathDev. ' ' The callback function takes the '.../tools/win.arch/tool/version' dir and ' varUser as arguments, returning an non-empty string if it was found suitable. ' function SearchToolsEx(strTool, strVerPrefix, ByRef fnCallback, ByRef varUser, ByRef arrToolsDirs) dim strToolsDir, arrDirs, strDir SearchToolsEx = "" for each strToolsDir in arrToolsDirs arrDirs = GetSubdirsStartingWithRVerSorted(strToolsDir, strVerPrefix) for each strDir in arrDirs SearchToolsEx = fnCallback(strToolsDir & "/" & strDir, varUser) if SearchToolsEx <> "" then exit function end if next next end function '' Search under g_strPathDev for a tool, target arch only. function SearchTargetTools(strTool, strVerPrefix, ByRef fnCallback, ByRef varUser) dim i redim arrToolsDirs(ArraySize(g_arrPathDev) - 1) for i = 0 to UBound(g_arrPathDev) arrToolsDirs(i) = g_arrPathDev(i) & "/win." & g_strTargetArch & "/" & strTool next SearchTargetTools = SearchToolsEx(strTool, strVerPrefix, fnCallback, varUser, arrToolsDirs) end function '' Search under g_strPathDev for a tool, target arch and alternative arches. function SearchTargetPlusTools(strTool, strVerPrefix, ByRef fnCallback, ByRef varUser) dim i redim arrToolsDirs(ArraySize(g_arrPathDev)*3 - 1) for i = 0 to UBound(g_arrPathDev) arrToolsDirs(i*3 + 0) = g_arrPathDev(i) & "/win." & g_strTargetArch & "/" & strTool arrToolsDirs(i*3 + 1) = g_arrPathDev(i) & "/win.x86/" & strTool arrToolsDirs(i*3 + 2) = g_arrPathDev(i) & "/win.amd64/" & strTool next SearchTargetPlusTools = SearchToolsEx(strTool, strVerPrefix, fnCallback, varUser, arrToolsDirs) end function '' Search under g_strPathDev for a tool, host arch first. function SearchHostTools(strTool, strVerPrefix, ByRef fnCallback, ByRef varUser) dim i redim arrToolsDirs(ArraySize(g_arrPathDev) * 3 - 1) for i = 0 to UBound(g_arrPathDev) arrToolsDirs(i*3 + 0) = g_arrPathDev(i) & "/win." & g_strHostArch & "/" & strTool arrToolsDirs(i*3 + 1) = g_arrPathDev(i) & "/win.x86/" & strTool arrToolsDirs(i*3 + 2) = g_arrPathDev(i) & "/win.amd64/" & strTool next SearchHostTools = SearchToolsEx(strTool, strVerPrefix, fnCallback, varUser, arrToolsDirs) end function '' Search under g_strPathDev for a tool, common dir first. function SearchCommonTools(strTool, strVerPrefix, ByRef fnCallback, ByRef varUser) dim i redim arrToolsDirs(ArraySize(g_arrPathDev) * 4 - 1) for i = 0 to UBound(g_arrPathDev) arrToolsDirs(i*4 + 0) = g_arrPathDev(i) & "/win.common/" & strTool arrToolsDirs(i*4 + 1) = g_arrPathDev(i) & "/win." & g_strTargetArch & "/" & strTool arrToolsDirs(i*4 + 2) = g_arrPathDev(i) & "/win.x86/" & strTool arrToolsDirs(i*4 + 3) = g_arrPathDev(i) & "/win.amd64/" & strTool next SearchCommonTools = SearchToolsEx(strTool, strVerPrefix, fnCallback, varUser, arrToolsDirs) end function '' ' Checks the the path doesn't contain characters the tools cannot deal with. ' sub CheckSourcePath dim sPwd sPwd = PathAbsLong(g_strPath) ' Must check the long version. if InStr(1, sPwd, " ") > 0 then MsgError "Source path contains spaces! Please move it. (" & sPwd & ")" end if if InStr(1, sPwd, "$") > 0 then MsgError "Source path contains the '$' char! Please move it. (" & sPwd & ")" end if if InStr(1, sPwd, "%") > 0 then MsgError "Source path contains the '%' char! Please move it. (" & sPwd & ")" end if if InStr(1, sPwd, Chr(10)) > 0 _ or InStr(1, sPwd, Chr(13)) > 0 _ or InStr(1, sPwd, Chr(9)) > 0 _ then MsgError "Source path contains control characters! Please move it. (" & sPwd & ")" end if Print "Source path: OK" end sub '' ' Checks for kBuild - very simple :) ' sub CheckForkBuild(strOptkBuild) dim blnNeedEnvVars, strOutput PrintHdr "kBuild" ' ' Check if there is a 'kmk' in the path somewhere without ' any KBUILD_*PATH stuff around. ' blnNeedEnvVars = True g_strPathkBuild = strOptkBuild g_strPathkBuildBin = "" if (g_strPathkBuild = "") _ And (EnvGetFirst("KBUILD_PATH", "PATH_KBUILD") = "") _ And (EnvGetFirst("KBUILD_BIN_PATH", "PATH_KBUILD_BIN") = "") _ And (Shell("kmk.exe --version", True, strOutput) = 0) _ And (InStr(1,strOutput, "kBuild Make 0.1") > 0) _ And (InStr(1,strOutput, "KBUILD_PATH") > 0) _ And (InStr(1,strOutput, "KBUILD_BIN_PATH") > 0) then '' @todo Need to parse out the KBUILD_PATH and KBUILD_BIN_PATH values to complete the other tests. 'blnNeedEnvVars = False MsgWarning "You've installed kBuild it seems. configure.vbs hasn't been updated to " _ & "deal with that yet and will use the one it ships with. Sorry." end if ' ' Check for the KBUILD_PATH env.var. and fall back on root/kBuild otherwise. ' if g_strPathkBuild = "" then g_strPathkBuild = EnvGetFirst("KBUILD_PATH", "PATH_KBUILD") if (g_strPathkBuild <> "") and (FileExists(g_strPathkBuild & "/footer.kmk") = False) then MsgWarning "Ignoring incorrect kBuild path (KBUILD_PATH=" & g_strPathkBuild & ")" g_strPathkBuild = "" end if if g_strPathkBuild = "" then g_strPathkBuild = g_strPath & "/kBuild" end if end if g_strPathkBuild = UnixSlashes(PathAbs(g_strPathkBuild)) ' ' Check for env.vars that kBuild uses (do this early to set g_strTargetArch). ' str = EnvGetFirst("KBUILD_TYPE", "BUILD_TYPE") if (str <> "") _ And (InStr(1, "|release|debug|profile|kprofile", str) <= 0) then EnvPrint "set KBUILD_TYPE=release" EnvSet "KBUILD_TYPE", "release" MsgWarning "Found unknown KBUILD_TYPE value '" & str &"' in your environment. Setting it to 'release'." end if str = EnvGetFirst("KBUILD_TARGET", "BUILD_TARGET") if (str <> "") _ And (InStr(1, "win|win32|win64", str) <= 0) then '' @todo later only 'win' will be valid. remember to fix this check! EnvPrint "set KBUILD_TARGET=win" EnvSet "KBUILD_TARGET", "win" MsgWarning "Found unknown KBUILD_TARGET value '" & str &"' in your environment. Setting it to 'win32'." end if str = EnvGetFirst("KBUILD_TARGET_ARCH", "BUILD_TARGET_ARCH") if (str <> "") _ And (InStr(1, "x86|amd64", str) <= 0) then EnvPrint "set KBUILD_TARGET_ARCH=x86" EnvSet "KBUILD_TARGET_ARCH", "x86" MsgWarning "Found unknown KBUILD_TARGET_ARCH value '" & str &"' in your environment. Setting it to 'x86'." str = "x86" end if if g_strTargetArch = "" then '' command line parameter --target-arch=x86|amd64 has priority if str <> "" then g_strTargetArch = str elseif (EnvGet("PROCESSOR_ARCHITEW6432") = "AMD64" ) _ Or (EnvGet("PROCESSOR_ARCHITECTURE") = "AMD64" ) then g_strTargetArch = "amd64" else g_strTargetArch = "x86" end if else if InStr(1, "x86|amd64", g_strTargetArch) <= 0 then EnvPrint "set KBUILD_TARGET_ARCH=x86" EnvSet "KBUILD_TARGET_ARCH", "x86" MsgWarning "Unknown --target-arch=" & str &". Setting it to 'x86'." end if end if LogPrint " Target architecture: " & g_strTargetArch & "." Wscript.Echo " Target architecture: " & g_strTargetArch & "." EnvPrint "set KBUILD_TARGET_ARCH=" & g_strTargetArch ' Windows variant of the arch name. g_strTargetArchWin = g_strTargetArch if g_strTargetArchWin = "amd64" then g_strTargetArchWin = "x64" str = EnvGetFirst("KBUILD_TARGET_CPU", "BUILD_TARGET_CPU") ' perhaps a bit pedantic this since this isn't clearly define nor used much... if (str <> "") _ And (InStr(1, "i386|i486|i686|i786|i868|k5|k6|k7|k8", str) <= 0) then EnvPrint "set BUILD_TARGET_CPU=i386" EnvSet "KBUILD_TARGET_CPU", "i386" MsgWarning "Found unknown KBUILD_TARGET_CPU value '" & str &"' in your environment. Setting it to 'i386'." end if str = EnvGetFirst("KBUILD_HOST", "BUILD_PLATFORM") if (str <> "") _ And (InStr(1, "win|win32|win64", str) <= 0) then '' @todo later only 'win' will be valid. remember to fix this check! EnvPrint "set KBUILD_HOST=win" EnvSet "KBUILD_HOST", "win" MsgWarning "Found unknown KBUILD_HOST value '" & str &"' in your environment. Setting it to 'win32'." end if str = EnvGetFirst("KBUILD_HOST_ARCH", "BUILD_PLATFORM_ARCH") if str <> "" then if InStr(1, "x86|amd64", str) <= 0 then str = "x86" MsgWarning "Found unknown KBUILD_HOST_ARCH value '" & str &"' in your environment. Setting it to 'x86'." end if elseif (EnvGet("PROCESSOR_ARCHITEW6432") = "AMD64" ) _ Or (EnvGet("PROCESSOR_ARCHITECTURE") = "AMD64" ) then str = "amd64" else str = "x86" end if LogPrint " Host architecture: " & str & "." Wscript.Echo " Host architecture: " & str & "." EnvPrint "set KBUILD_HOST_ARCH=" & str g_strHostArch = str ' Windows variant of the arch name. g_strHostArchWin = g_strHostArch if g_strHostArchWin = "amd64" then g_strHostArchWin = "x64" str = EnvGetFirst("KBUILD_HOST_CPU", "BUILD_PLATFORM_CPU") ' perhaps a bit pedantic this since this isn't clearly define nor used much... if (str <> "") _ And (InStr(1, "i386|i486|i686|i786|i868|k5|k6|k7|k8", str) <= 0) then EnvPrint "set KBUILD_HOST_CPU=i386" EnvSet "KBUILD_HOST_CPU", "i386" MsgWarning "Found unknown KBUILD_HOST_CPU value '" & str &"' in your environment. Setting it to 'i386'." end if ' ' Determin the location of the kBuild binaries. ' if g_strPathkBuildBin = "" then g_strPathkBuildBin = g_strPathkBuild & "/bin/win." & g_strHostArch if FileExists(g_strPathkBuildBin & "/kmk.exe") = False then g_strPathkBuildBin = g_strPathkBuild & "/bin/win.x86" end if end if g_strPathkBuildBin = UnixSlashes(PathAbs(g_strPathkBuildBin)) ' ' Perform basic validations of the kBuild installation. ' if (FileExists(g_strPathkBuild & "/footer.kmk") = False) _ Or (FileExists(g_strPathkBuild & "/header.kmk") = False) _ Or (FileExists(g_strPathkBuild & "/rules.kmk") = False) then MsgFatal "Can't find valid kBuild at '" & g_strPathkBuild & "'. Either there is an " _ & "incorrect KBUILD_PATH in the environment or the checkout didn't succeed." exit sub end if if (FileExists(g_strPathkBuildBin & "/kmk.exe") = False) _ Or (FileExists(g_strPathkBuildBin & "/kmk_ash.exe") = False) then MsgFatal "Can't find valid kBuild binaries at '" & g_strPathkBuildBin & "'. Either there is an " _ & "incorrect KBUILD_PATH in the environment or the checkout didn't succeed." exit sub end if if (Shell(DosSlashes(g_strPathkBuildBin & "/kmk.exe") & " --version", True, strOutput) <> 0) then MsgFatal "Can't execute '" & g_strPathkBuildBin & "/kmk.exe --version'. check configure.log for the out." exit sub end if ' ' If KBUILD_DEVTOOLS is set, check that it's pointing to something useful. ' str = UnixSlashes(EnvGet("KBUILD_DEVTOOLS")) g_strPathDev = str if str <> "" _ and LogDirExists(str & "/bin") _ and LogDirExists(str & "/win.amd64/bin") _ and LogDirExists(str & "/win.x86/bin") _ then LogPrint "Found KBUILD_DEVTOOLS='" & str & "'." elseif str <> "" then MsgWarning "Ignoring bogus KBUILD_DEVTOOLS='" & str &"' in your environment!" g_strPathDev = strNew end if if g_strPathDev = "" then g_strPathDev = UnixSlashes(g_strPath & "/tools") LogPrint "Using KBUILD_DEVTOOLS='" & g_strPathDev & "'." if str <> "" then EnvPrint "set KBUILD_DEVTOOLS=" & g_strPathDev EnvSet "KBUILD_DEVTOOLS", g_strPathDev end if end if g_arrPathDev(ArrayFindString(g_arrPathDev, ":placeholder:")) = g_strPathDev ' ' Write KBUILD_PATH and updated PATH to the environment script if necessary. ' if blnNeedEnvVars = True then EnvPrint "set KBUILD_PATH=" & g_strPathkBuild EnvSet "KBUILD_PATH", g_strPathkBuild if Right(g_strPathkBuildBin, 7) = "win.x86" then EnvPrintCleanup "PATH", DosSlashes(Left(g_strPathkBuildBin, Len(g_strPathkBuildBin) - 7) & "win.amd64"), ";" end if if Right(g_strPathkBuildBin, 9) = "win.amd64" then EnvPrintCleanup "PATH", DosSlashes(Left(g_strPathkBuildBin, Len(g_strPathkBuildBin) - 9) & "win.x86"), ";" end if EnvPrintPrepend "PATH", DosSlashes(g_strPathkBuildBin), ";" EnvPrependPathItem "PATH", g_strPathkBuildBin, ";" end if PrintResult "kBuild", g_strPathkBuild PrintResult "kBuild binaries", g_strPathkBuildBin end sub '' ' Checks for Visual C++ version 16 (2019), 15 (2017), 14 (2015), 12 (2013), 11 (2012) or 10 (2010). ' sub CheckForVisualCPP(strOptVC, strOptVCCommon) PrintHdr "Visual C++" ' ' Try find it... ' dim objState, strProgFiles set objState = new VisualCPPState objState.check strOptVC, strOptVCCommon if g_blnInternalFirst = True then objState.checkInternal objState.checkProgItems "2019" objState.checkProgFiles "Microsoft Visual Studio\2019\BuildTools\VC" objState.checkProgFiles "Microsoft Visual Studio\2019\Professional\VC" objState.checkProgFiles "Microsoft Visual Studio\2019\Community\VC" objState.checkRegistry "Microsoft\VisualStudio\SxS\VS7\16.0", "VC", "" ' doesn't work. objState.checkProgItems "2017" objState.checkProgFiles "Microsoft Visual Studio\2017\BuildTools\VC" objState.checkProgFiles "Microsoft Visual Studio\2017\Professional\VC" objState.checkProgFiles "Microsoft Visual Studio\2017\Community\VC" objState.checkProgFiles "Microsoft Visual Studio\2017\Express\VC" objState.checkRegistry "Microsoft\VisualStudio\SxS\VS7\15.0", "VC", "" objState.checkRegistry "Microsoft\VisualStudio\SxS\VS7\14.0", "VC", "Common7" objState.checkRegistry "Microsoft\VisualStudio\SxS\VS7\12.0", "VC", "Common7" '? objState.checkRegistry "Microsoft\VisualStudio\SxS\VS7\11.0", "VC", "Common7" '? objState.checkProg "cl.exe" objState.checkRegistry "Microsoft\VisualStudio\10.0\Setup\VS\ProductDir", "VC", "Common7" if g_blnInternalFirst = False then objState.checkInternal if objState.m_blnFound = False then MsgError "Cannot find cl.exe (Visual C++) anywhere on your system. Check the build requirements." exit sub end if g_strPathVCC = objState.m_strPathVC g_strVCCVersion = objState.m_strVersion ' ' Ok, emit build config variables. ' CfgPrintAssign "VBOX_VCC_TOOL_STEM", objState.m_strVersion CfgPrintAssign "PATH_TOOL_" & objState.m_strVersion, g_strPathVCC CfgPrintAssign "PATH_TOOL_" & objState.m_strVersion & "X86", "$(PATH_TOOL_" & objState.m_strVersion & ")" CfgPrintAssign "PATH_TOOL_" & objState.m_strVersion & "AMD64", "$(PATH_TOOL_" & objState.m_strVersion & ")" if objState.m_strVersion = "VCC100" _ or objState.m_strVersion = "VCC110" _ or objState.m_strVersion = "VCC120" _ or objState.m_strVersion = "VCC140" _ then CfgPrintAssign "VBOX_WITH_NEW_VCC", "" '?? for VCC110+ else CfgPrintAssign "VBOX_WITH_NEW_VCC", "1" end if PrintResult "Visual C++ " & objState.m_strVersion, g_strPathVCC ' And the env.bat path fix. if objState.m_strPathVCCommon <> "" then EnvPrintAppend "PATH", DosSlashes(objState.m_strPathVCCommon) & "\IDE", ";" end if end sub '' Class we use for detecting Visual C++ class VisualCPPState public m_blnFound public m_strPathVC public m_strPathVCCommon public m_strVersion public m_strClVersion public m_blnNewLayout private sub Class_Initialize m_blnFound = False m_strPathVC = "" m_strPathVCCommon = "" m_strVersion = "" m_strClVersion = "" m_blnNewLayout = false end sub public function checkClExe(strClExe) ' We'll have to make sure mspdbXX.dll is somewhere in the PATH. dim strSavedPath, rcExit, strOutput strSavedPath = EnvGet("PATH") if (m_strPathVCCommon <> "") then EnvAppendPathItem "PATH", m_strPathVCCommon & "/IDE", ";" end if rcExit = Shell(DosSlashes(strClExe), True, strOutput) EnvSet "PATH", strSavedPath checkClExe = False if rcExit = 0 then ' Extract the ' Version xx.yy.build.zz for arch' bit. dim offVer, offEol, strVer strVer = "" offVer = InStr(1, strOutput, " Version ") if offVer > 0 then offVer = offVer + Len(" Version ") offEol = InStr(offVer, strOutput, Chr(13)) if offEol > 0 then strVer = Trim(Mid(strOutput, offVer, offEol - offVer)) end if end if ' Check that it's a supported version checkClExe = True if InStr(1, strVer, "16.") = 1 then m_strVersion = "VCC100" elseif InStr(1, strVer, "17.") = 1 then m_strVersion = "VCC110" LogPrint "The Visual C++ compiler ('" & strClExe & "') version isn't really supported, but may work: " & strVer elseif InStr(1, strVer, "18.") = 1 then m_strVersion = "VCC120" LogPrint "The Visual C++ compiler ('" & strClExe & "') version isn't really supported, but may work: " & strVer elseif InStr(1, strVer, "19.0") = 1 then m_strVersion = "VCC140" LogPrint "The Visual C++ compiler ('" & strClExe & "') version isn't really supported, but may work: " & strVer elseif InStr(1, strVer, "19.1") = 1 then m_strVersion = "VCC141" LogPrint "The Visual C++ compiler ('" & strClExe & "') version isn't really supported, but may work: " & strVer elseif InStr(1, strVer, "19.2") = 1 then m_strVersion = "VCC142" else LogPrint "The Visual C++ compiler we found ('" & strClExe & "') isn't in the 10.0-19.2x range (" & strVer & ")." LogPrint "Check the build requirements and select the appropriate compiler version." checkClExe = False exit function end if LogPrint "'" & strClExe & "' = " & m_strVersion & " (" & strVer & ")" else LogPrint "Executing '" & strClExe & "' (which we believe to be the Visual C++ compiler driver) failed (rcExit=" & rcExit & ")." end if end function public function checkInner(strPathVC) ' For the new layout only if m_blnFound = False then if LogDirExists(strPathVC & "/bin") _ and LogDirExists(strPathVC & "/lib") _ and LogDirExists(strPathVC & "/include") _ and LogFileExists(strPathVC, "include/stdarg.h") _ and LogFileExists(strPathVC, "lib/x64/libcpmt.lib") _ and LogFileExists(strPathVC, "lib/x86/libcpmt.lib") _ and LogFileExists(strPathVC, "bin/Host" & g_strHostArchWin & "/" & g_strTargetArchWin & "/cl.exe") _ and LogFileExists(strPathVC, "bin/Host" & g_strHostArchWin & "/" & g_strHostArchWin & "/cl.exe") _ then LogPrint " => seems okay. new layout." m_blnFound = checkClExe(strPathVC & "/bin/Host" & g_strHostArchWin & "/" & g_strTargetArchWin & "/cl.exe") if m_blnFound then m_strPathVC = strPathVC end if end if end if checkInner = m_blnFound end function public function check(strPathVC, strPathVCommon) if (m_blnFound = False) and (strPathVC <> "") then m_strPathVC = UnixSlashes(PathAbs(strPathVC)) m_strPathVCCommon = strPathVCCommon m_strVersion = "" LogPrint "Trying: strPathVC=" & m_strPathVC & " strPathVCCommon=" & m_strPathVCCommon if LogDirExists(m_strPathVC) then ' 15.0+ layout? This is fun because of the multiple CL versions (/tools/msvc/xx.yy.bbbbb/). ' OTOH, the user may have pointed us directly to one of them. if LogDirExists(m_strPathVC & "/Tools/MSVC") then m_blnNewLayout = True LogPrint " => seems okay. new layout." dim arrFolders, i arrFolders = GetSubdirsStartingWithVerSorted(m_strPathVC & "/Tools/MSVC", "14.2") if UBound(arrFolders) < 0 then arrFolders = GetSubdirsStartingWithVerSorted(m_strPathVC & "/Tools/MSVC", "14.1") if UBound(arrFolders) < 0 then arrFolders = GetSubdirsStartingWithVerSorted(m_strPathVC & "/Tools/MSVC", "1") for i = UBound(arrFolders) to LBound(arrFolders) step -1 if checkInner(m_strPathVC & "/Tools/MSVC/" & arrFolders(i)) then exit for ' modifies m_strPathVC on success next elseif LogDirExists(m_strPathVC & "/bin/HostX64") _ or LogDirExists(m_strPathVC & "/bin/HostX86") then checkInner(m_strPathVC) ' 14.0 and older layout? elseif LogFileExists(m_strPathVC, "/bin/cl.exe") then m_blnNewLayout = False if LogFileExists(m_strPathVC, "bin/link.exe") _ and LogFileExists(m_strPathVC, "include/string.h") _ and LogFileExists(m_strPathVC, "lib/libcmt.lib") _ and LogFileExists(m_strPathVC, "lib/msvcrt.lib") _ then LogPrint " => seems okay. old layout." m_blnFound = checkClExe(m_strPathVC & "/bin/cl.exe") end if end if end if end if check = m_bldFound end function public function checkProg(strProg) if m_blnFound = False then dim str, i, offNewLayout str = Which(strProg) if str <> "" then LogPrint "checkProg: '" & strProg & "' -> '" & str & "'" if FileExists(PathStripFilename(str) & "/build.exe") then Warning "Ignoring DDK cl.exe (" & str & ")." ' don't know how to deal with this cl. else ' Assume we've got cl.exe from somewhere under the 'bin' directory.. m_strPathVC = PathParent(PathStripFilename(str)) for i = 1 To 5 if LogDirExists(m_strPathVC & "/include") then m_strPathVCCommon = PathParent(m_strPathVC) & "/Common7" if DirExists(m_strPathVCCommon) = False then m_strPathVCCommon = "" ' New layout? offNewLayout = InStr(1, LCase(DosSlashes(m_strPathVC)), "\tools\msvc\") if offNewLayout > 0 then m_strPathVC = Left(m_strPathVC, offNewLayout) end if check m_strPathVC, m_strPathVCCommon exit for end if m_strPathVC = PathParent(m_strPathVC) next end if end if end if checkProg = m_bldFound end function public function checkProgFiles(strSubdir) if m_blnFound = False then dim strProgFiles for each strProgFiles in g_arrProgramFiles check strProgFiles & "/" & strSubdir, "" next end if checkProgFiles = m_blnFound end function public function checkRegistry(strValueNm, strVCSubdir, strVCommonSubdir) if m_blnFound = False then dim str, strPrefix, arrPrefixes arrPrefixes = Array("HKLM\SOFTWARE\Wow6432Node\", "HKLM\SOFTWARE\", "HKCU\SOFTWARE\Wow6432Node\", "HKCU\SOFTWARE\") for each strPrefix in arrPrefixes str = LogRegGetString(strPrefix & strValueNm) if str <> "" then LogPrint "checkRegistry: '" & strPrefix & strValueNm & "' -> '" & str & "'" if check(str & strVCSubdir, str & strVCommonSubdir) = True then exit for end if end if next end if checkRegistry = m_bldFound end function public function checkProgItems(strVersionYear) if m_blnFound = False then dim strCandidate for each strCandidate in CollectFromProgramItemLinks(GetRef("VisualCPPCallback"), strVersionYear) check strCandidate, "" next end if checkProgItems = m_blnFound end function public function checkInternal dim strPathDev for each strPathDev in g_arrPathDev : check strPathDev & "/win.amd64/vcc/v14.2", "" : next for each strPathDev in g_arrPathDev : check strPathDev & "/win.amd64/vcc/v14.2", "" : next for each strPathDev in g_arrPathDev : check strPathDev & "/win.amd64/vcc/v14.1", "" : next for each strPathDev in g_arrPathDev : check strPathDev & "/win.amd64/vcc/v14.0", "" : next for each strPathDev in g_arrPathDev : check strPathDev & "/win.amd64/vcc/v10sp1", "" : next for each strPathDev in g_arrPathDev : check strPathDev & "/win.x86/vcc/v10sp1", "" : next checkInternal = m_blnFound end function end class ' See checkProgItems() function VisualCPPCallback(ByRef arrStrings, cStrings, ByRef strVersionYear) VisualCPPCallback = "" ' We're looking for items with three strings like this: ' C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2019\Visual Studio Tools\VC\x64 Native Tools Command Prompt for VS 2019.lnk ' C:\Windows\system32\cmd.exe ' /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat" if cStrings >= 3 then if InStr(1, arrStrings(0), strVersionYear) > 0 then dim strTail : strTail = "\Auxiliary\Build\vcvars64.bat""" dim str : str = arrStrings(UBound(arrStrings)) if StrComp(Right(str, Len(strTail)), strTail, vbTextCompare) = 0 then dim offColon : offColon = InStr(1, str, ":") if offColon > 1 then VisualCPPCallback = Mid(str, offColon - 1, Len(str) - (offColon - 2) - Len(strTail)) end if end if end if end if end function '' ' Checks for a windows 10 SDK (later also WDK). ' sub CheckForSDK10(strOptSDK10, strOptSDK10Version) dim strPathSDK10, strSDK10Version, str PrintHdr "Windows 10 SDK/WDK" '' @todo implement strOptSDK10Version ' ' Try find the Windows 10 kit. ' strSDK10Version = "" strPathSDK10 = CheckForSDK10Sub(strOptSDK10, strSDK10Version) if strPathSDK10 = "" and g_blnInternalFirst = true then strPathSDK10 = SearchTargetPlusTools("sdk", "v10.", GetRef("CheckForSDK10Sub"), strSDK10Version) end if if strPathSDK10 = "" then str = LogRegGetString("HKLM\SOFTWARE\Microsoft\Windows Kits\Installed Roots\KitsRoot10") strPathSDK10 = CheckForSDK10Sub(str, strSDK10Version) end if if strPathSDK10 = "" then for each str in g_arrProgramFiles strPathSDK10 = CheckForSDK10Sub(str & "/Windows Kits/10", strSDK10Version) if strPathSDK10 <> "" then exit for next end if if strPathSDK10 = "" and g_blnInternalFirst = true then strPathSDK10 = SearchTargetPlusTools("sdk", "v10.", GetRef("CheckForSDK10Sub"), strSDK10Version) end if if strPathSDK10 = "" then MsgError "Cannot find a suitable Windows 10 SDK. Check configure.log and the build requirements." exit sub end if ' ' Emit the config. ' strPathSDK10 = UnixSlashes(PathAbs(strPathSDK10)) CfgPrintAssign "PATH_SDK_WINSDK10", strPathSDK10 CfgPrintAssign "SDK_WINSDK10_VERSION", strSDK10Version PrintResult "Windows 10 SDK", strPathSDK10 PrintResultMsg "Windows 10 SDK version", strSDK10Version g_strPathSDK10 = strPathSDK10 end sub '' Checks if the specified path points to a usable Windows 10 SDK/WDK. function CheckForSDK10Sub(strPathSDK10, ByRef strSDK10Version) CheckForSDK10Sub = "" if strPathSDK10 <> "" then LogPrint "Trying: strPathSDK10=" & strPathSDK10 if LogDirExists(strPathSDK10) then if LogDirExists(strPathSDK10 & "/Bin") _ and LogDirExists(strPathSDK10 & "/Include") _ and LogDirExists(strPathSDK10 & "/Lib") _ and LogDirExists(strPathSDK10 & "/Redist") _ then ' Only testing the highest one, for now. '' @todo incorporate strOptSDK10Version dim arrVersions arrVersions = GetSubdirsStartingWithVerSorted(strPathSDK10 & "/Include", "10.0.") if UBound(arrVersions) >= 0 then dim strVersion strVersion = arrVersions(UBound(arrVersions)) LogPrint "Trying version: " & strVersion if LogFileExists(strPathSDK10, "include/" & strVersion & "/um/Windows.h") _ and LogFileExists(strPathSDK10, "include/" & strVersion & "/ucrt/malloc.h") _ and LogFileExists(strPathSDK10, "include/" & strVersion & "/ucrt/stdio.h") _ and LogFileExists(strPathSDK10, "lib/" & strVersion & "/um/" & g_strTargetArchWin & "/kernel32.lib") _ and LogFileExists(strPathSDK10, "lib/" & strVersion & "/um/" & g_strTargetArchWin & "/user32.lib") _ and LogFileExists(strPathSDK10, "lib/" & strVersion & "/ucrt/" & g_strTargetArchWin & "/libucrt.lib") _ and LogFileExists(strPathSDK10, "lib/" & strVersion & "/ucrt/" & g_strTargetArchWin & "/ucrt.lib") _ and LogFileExists(strPathSDK10, "bin/" & strVersion & "/" & g_strHostArchWin & "/rc.exe") _ and LogFileExists(strPathSDK10, "bin/" & strVersion & "/" & g_strHostArchWin & "/midl.exe") _ then if StrComp(strVersion, "10.0.17134.0") >= 0 then strSDK10Version = strVersion CheckForSDK10Sub = strPathSDK10 else LogPrint "Version " & strVersion & " is too low, minimum: 10.0.17134.0" end if end if else LogPrint "Found no 10.0.* subdirectories under '" & strPathSDK10 & "/Include'!" end if end if end if end if end function '' ' Locating a Windows 7 Driver Kit. ' sub CheckForWinDDK(strOptDDK) dim strPathDDK, str, strSubKeys PrintHdr "Windows DDK v7.1" ' ' Find the DDK. ' strPathDDK = CheckForWinDDKSub(strOptDDK, True) ' The tools location (first). if strPathDDK = "" and g_blnInternalFirst = true then for each str in g_arrPathDev strPathDDK = CheckForWinDDKSub(str & "/win.x86/ddk/7600.16385.1", False) if strPathDDK <> "" then exit for next end if ' Check the environment if strPathDDK = "" then strPathDDK = CheckForWinDDKSub(PathParent(PathParent(EnvGet("DDK_INC_PATH"))), True) if strPathDDK = "" then strPathDDK = CheckForWinDDKSub(EnvGet("BASEDIR"), True) ' Some array constants to ease the work. arrSoftwareKeys = array("SOFTWARE", "SOFTWARE\Wow6432Node") arrRoots = array("HKLM", "HKCU") ' Windows 7 WDK. if strPathDDK = "" then arrLocations = array() for each strSoftwareKey in arrSoftwareKeys for each strSubKey in RegEnumSubKeysFull("HKLM", strSoftwareKey & "\Microsoft\KitSetup\configured-kits") for each strSubKey2 in RegEnumSubKeysFull("HKLM", strSubKey) str = LogRegGetString("HKLM\" & strSubKey2 & "\setup-install-location") if str <> "" then arrLocations = ArrayAppend(arrLocations, PathAbsLong(str)) end if next next next arrLocations = ArrayRVerSortStrings(arrLocations) ' Check the locations we've gathered. for each str in arrLocations strPathDDK = CheckForWinDDKSub(str, True) if strPathDDK <> "" then exit for next end if ' The tools location (post). if strPathDDK = "" and g_blnInternalFirst = false then for each str in g_arrPathDev strPathDDK = CheckForWinDDKSub(str & "/win.x86/ddk/7600.16385.1", False) if strPathDDK <> "" then exit for next end if ' Give up. if strPathDDK = "" then MsgError "Cannot find the Windows DDK v7.1. Check configure.log and the build requirements." exit sub end if ' ' Emit the config. ' strPathDDK = UnixSlashes(PathAbs(strPathDDK)) CfgPrintAssign "PATH_SDK_WINDDK71", strPathDDK PrintResult "Windows DDK v7.1", strPathDDK g_strPathDDK = strPathDDK end sub '' Quick check if the DDK is in the specified directory or not. function CheckForWinDDKSub(strPathDDK, blnCheckBuild) CheckForWinDDKSub = "" if strPathDDK <> "" then dim strOutput LogPrint "Trying: strPathDDK=" & strPathDDK & " blnCheckBuild=" & blnCheckBuild if LogFileExists(strPathDDK, "inc/api/ntdef.h") _ And LogFileExists(strPathDDK, "lib/win7/i386/int64.lib") _ And LogFileExists(strPathDDK, "lib/wlh/i386/int64.lib") _ And LogFileExists(strPathDDK, "lib/wnet/i386/int64.lib") _ And LogFileExists(strPathDDK, "lib/wxp/i386/int64.lib") _ And Not LogFileExists(strPathDDK, "lib/win8/i386/int64.lib") _ And LogFileExists(strPathDDK, "bin/x86/rc.exe") _ then if Not blnCheckBuild then CheckForWinDDKSub = strPathDDK '' @todo Find better build check. elseif Shell("""" & DosSlashes(strPathDDK & "/bin/x86/rc.exe") & """" , True, strOutput) <> 0 _ and InStr(1, strOutput, "Resource Compiler Version 6.1.") > 0 _ then CheckForWinDDKSub = strPathDDK end if end if end if end function '' ' Locating midl.exe ' sub CheckForMidl(strOptMidl) dim strMidl, str PrintHdr "Midl.exe" ' Skip if no COM/ATL. if g_blnDisableCOM then PrintResultMsg "Midl.exe", "Skipped (" & g_strDisableCOM & ")" exit sub end if strMidl = CheckForMidlSub(strOptMidl) if strMidl = "" then strMidl = CheckForMidlSub(g_strPathSDK10 & "/bin/" & g_strHostArchWin & "/Midl.exe") if strMidl = "" then strMidl = CheckForMidlSub(g_strPathSDK10 & "/bin/x86/Midl.exe") if strMidl = "" then strMidl = CheckForMidlSub(g_strPathPSDK & "/bin/Midl.exe") if strMidl = "" then strMidl = CheckForMidlSub(g_strPathVCC & "/Common7/Tools/Bin/Midl.exe") if strMidl = "" then strMidl = CheckForMidlSub(g_strPathDDK & "/bin/" & g_strHostArchWin & "/Midl.exe") if strMidl = "" then strMidl = CheckForMidlSub(g_strPathDDK & "/bin/x86/Midl.exe") if strMidl = "" then strMidl = CheckForMidlSub(g_strPathDDK & "/bin/Midl.exe") if strMidl = "" then for each str in g_arrPathDev strMidl = CheckForMidlSub(str & "/win." & g_strHostArchWin & "/bin/Midl.exe") if strMidl <> "" then exit for strMidl = CheckForMidlSub(str & "/win.x86/bin/Midl.exe") if strMidl <> "" then exit for next end if if strMidl = "" then PrintResultMsg "Midl.exe", "not found" else CfgPrintAssign "VBOX_MAIN_IDL", strMidl PrintResult "Midl.exe", strMidl end if end sub function CheckForMidlSub(strMidl) CheckForMidlSub = "" if strMidl <> "" then if LogFileExists1(strMidl) then CheckForMidlSub = UnixSlashes(PathAbs(strMidl)) end if end if end function '' ' Locating yasm.exe ' sub CheckForYasm(strOptYasm) dim strPathYasm, strVersion PrintHdr "yasm" strVersion = "" strPathYasm = CheckForYasmSub(strOptYasm, strVersion) if strPathYasm = "" then strPathYasm = CheckForYasmSub(PathStripFilename(strOptYasm), strVersion) if strPathYasm = "" and g_blnInternalFirst = true then strPathYasm = SearchHostTools("yasm", "v", GetRef("CheckForYasmSub"), strVersion) end if if strPathYasm = "" then strPathYasm = CheckForYasmSub(PathStripFilename(Which("yasm.exe")), strVersion) if strPathYasm = "" and g_blnInternalFirst = false then strPathYasm = SearchHostTools("yasm", "v", GetRef("CheckForYasmSub"), strVersion) end if if strPathYasm = "" then PrintResultMsg "yasm", "not found" MsgError "Unable to locate yasm!" else CfgPrintAssign "PATH_TOOL_YASM", strPathYasm PrintResult "yasm v" & strVersion, strPathYasm end if end sub function CheckForYasmSub(strPathYasm, ByRef strVersion) CheckForYasmSub = "" if strPathYasm <> "" then if LogFileExists(strPathYasm, "yasm.exe") then dim strOutput if Shell("""" & DosSlashes(strPathYasm & "\yasm.exe") & """ --version", True, strOutput) = 0 then dim strPreamble : strPreamble = "yasm" dim strVer : strVer = Trim(StrGetFirstLine(strOutput)) if StrComp(Left(strVer, Len(strPreamble)), strPreamble, vbTextCompare) = 0 then strVersion = StrGetFirstWord(Trim(Mid(strVer, Len(strPreamble) + 1))) if StrVersionCompare(strVersion, "1.3.0") >= 0 and strVersion <> "" then LogPrint "Found yasm version: " & strVer CheckForYasmSub = UnixSlashes(PathAbs(strPathYasm)) else LogPrint "yasm version is older than 1.3.0: " & strVersion end if else LogPrint "Not yasm: " & strVer end if end if end if end if end function '' ' Locating nasm.exe ' sub CheckForNasm(strOptNasm) dim strPathNasm, strVersion PrintHdr "nasm" strPathNasm = CheckForNasmSub(strOptNasm, strVersion) if strPathNasm = "" then strPathNasm = CheckForNasmSub(PathStripFilename(strOptNasm), strVersion) if strPathNasm = "" and g_blnInternalFirst = true then strPathNasm = SearchHostTools("nasm", "v", GetRef("CheckForNasmSub"), strVersion) end if if strPathNasm = "" then strPathNasm = CheckForNasmSub(LogRegGetString("HKLM\SOFTWARE\nasm\"), strVersion) if strPathNasm = "" then strPathNasm = CheckForNasmSub(LogRegGetString("HKCU\SOFTWARE\nasm\"), strVersion) if strPathNasm = "" then for each strCandidate in CollectFromProgramItemLinks(GetRef("NasmProgramItemCallback"), strPathNasm) strPathNasm = CheckForNasmSub(strCandidate, strVersion) next end if if strPathNasm = "" then strPathNasm = CheckForNasmSub(PathStripFilename(Which("nasm.exe")), strVersion) if strPathNasm = "" and g_blnInternalFirst = false then strPathNasm = SearchHostTools("nasm", "v", GetRef("CheckForNasmSub"), strVersion) end if if strPathNasm = "" then PrintResultMsg "nasm", "not found" else CfgPrintAssign "PATH_TOOL_NASM", strPathNasm PrintResult "nasm v" & strVersion, strPathNasm end if end sub function NasmProgramItemCallback(ByRef arrStrings, cStrings, ByRef strUnused) dim str, off NasmProgramItemCallback = "" if cStrings > 1 then str = arrStrings(1) off = InStr(1, str, "\nasm.exe", vbTextCompare) if off > 0 then NasmProgramItemCallback = Left(str, off - 1) end if end if end function function CheckForNasmSub(strPathNasm, ByRef strVersion) CheckForNasmSub = "" if strPathNasm <> "" then if LogFileExists(strPathNasm, "nasm.exe") then dim strOutput if Shell("""" & DosSlashes(strPathNasm & "\nasm.exe") & """ -version", True, strOutput) = 0 then dim strPreamble : strPreamble = "NASM version" dim strVer : strVer = Trim(StrGetFirstLine(strOutput)) if StrComp(Left(strVer, Len(strPreamble)), strPreamble, vbTextCompare) = 0 then strVersion = StrGetFirstWord(Trim(Mid(strVer, Len(strPreamble) + 1))) if StrVersionCompare(strVersion, "2.12.0") >= 0 and strVersion <> "" then LogPrint "Found nasm version: " & strVersion CheckForNasmSub = UnixSlashes(PathAbs(strPathNasm)) else LogPrint "nasm version is older than 2.12.0: " & strVersion end if else LogPrint "Not nasm: " & strVer end if end if end if end if end function '' ' Locating OpenWatcom 1.9 ' sub CheckForOpenWatcom(strOptOpenWatcom) dim strPathOW, strCandidate, strVersion PrintHdr "OpenWatcom" strPathOW = CheckForOpenWatcomSub(strOptOpenWatcom, strVersion) if strPathOW = "" and g_blnInternalFirst = true then strPathOW = SearchCommonTools("openwatcom", "v", GetRef("CheckForOpenWatcomSub"), strVersion) end if if strPathOW = "" then for each strCandidate in CollectFromProgramItemLinks(GetRef("OpenWatcomProgramItemCallback"), strPathOW) if strPathOW = "" then strPathOW = CheckForOpenWatcomSub(strCandidate, strVersion) next end if if strPathOW = "" then strPathOW = CheckForOpenWatcomSub(EnvGet("WATCOM"), strVersion) if strPathOW = "" then strPathOW = CheckForOpenWatcomSub(PathParent(PathStripFilename(Which("wcc386.exe"))), strVersion) if strPathOW = "" and g_blnInternalFirst = false then strPathOW = SearchCommonTools("openwatcom", "v", GetRef("CheckForOpenWatcomSub"), strVersion) end if if strPathOW = "" then PrintResultMsg "OpenWatcom", "not found" CfgPrintAssign "VBOX_WITH_OPEN_WATCOM", "" exit sub end if CfgPrintAssign "VBOX_WITH_OPEN_WATCOM", "1" CfgPrintAssign "PATH_TOOL_OPENWATCOM", strPathOW PrintResult "OpenWatcom v" & strVersion, strPathOW if StrVersionCompare(strVersion, "2.0") >= 0 then MsgWarning "We only test building with OpenWatcom 1.9." end if end sub function OpenWatcomProgramItemCallback(ByRef arrStrings, cStrings, ByRef strUnused) dim str, off OpenWatcomProgramItemCallback = "" if cStrings > 1 then str = arrStrings(1) off = InStr(1, str, "\binnt\", vbTextCompare) if off > 0 then OpenWatcomProgramItemCallback = Left(str, off - 1) end if end if end function function CheckForOpenWatcomSub(strPathOW, ByRef strVersion) CheckForOpenWatcomSub = "" if strPathOW <> "" then LogPrint "Trying: " & strPathOW if LogDirExists(strPathOW) then if LogDirExists(strPathOW & "/binnt") _ and LogDirExists(strPathOW & "/h") _ and LogDirExists(strPathOW & "/eddat") _ and LogFileExists(strPathOW, "binnt/wcc386.exe") _ and LogFileExists(strPathOW, "binnt/wcc.exe") _ and LogFileExists(strPathOW, "binnt/wlink.exe") _ and LogFileExists(strPathOW, "binnt/wcl386.exe") _ and LogFileExists(strPathOW, "binnt/wcl.exe") _ and LogFileExists(strPathOW, "binnt/wlib.exe") _ and LogFileExists(strPathOW, "binnt/wasm.exe") _ and LogFileExists(strPathOW, "h/stdarg.h") _ then ' Some wcl/wcl386 option parsing quirk allows us to specify /whatever ' and just get the logo text and exit code 0. We use /y as it's a valid option. dim strOutput if Shell("""" & DosSlashes(strPathOW & "\binnt\wcl.exe") & """ /y", True, strOutput) = 0 then dim strPreamble : strPreamble = "Open Watcom C/C++16 Compile and Link Utility Version" strOutput = StrGetFirstLine(strOutput) if StrStartsWithI(strOutput, strPreamble) then strVersion = StrGetFirstWord(Trim(Mid(strOutput, Len(strPreamble) + 1))) if StrVersionCompare(strVersion, "1.9") >= 0 then CheckForOpenWatcomSub = UnixSlashes(PathAbs(strPathOW)) else LogPrint "OpenWatcom version id older than 1.9: " & strVersion end if else LogPrint "Not OpenWatcom: " & strOutput end if end if end if end if end if end function '' ' Checks for any libSDL binaries. ' sub CheckForlibSDL(strOptlibSDL) dim strPathLibSDL, strVersion PrintHdr "libSDL" ' ' Try find some SDL library. ' strPathLibSDL = CheckForLibSDLSub(strOptlibSDL, strVersion) if strPathlibSDL = "" and g_blnInternalFirst = true then strPathLibSDL = SearchTargetTools("libsdl", "v", GetRef("CheckForLibSDLSub"), strVersion) end if ' Poke about in the LIB and PATH env.vars. if strPathlibSDL = "" then strPathLibSDL = CheckForlibSDLSub(PathParent(PathStripFilename(WhichEx("LIB", "SDLmain.lib"))), strVersion) if strPathlibSDL = "" then strPathLibSDL = CheckForlibSDLSub(PathParent(PathStripFilename(Which("..\lib\SDLmain.lib"))), strVersion) if strPathlibSDL = "" then strPathLibSDL = CheckForlibSDLSub(PathParent(PathStripFilename(Which("SDLmain.lib"))), strVersion) if strPathlibSDL = "" then strPathLibSDL = CheckForlibSDLSub(PathParent(PathStripFilename(Which("SDL.dll"))), strVersion) ' The tools again. if strPathlibSDL = "" and g_blnInternalFirst = false then strPathLibSDL = SearchTargetTools("libsdl", "v", GetRef("CheckForLibSDLSub"), strVersion) end if ' Success? if strPathlibSDL = "" then if strOptlibSDL = "" then MsgError "Can't locate libSDL. Try specify the path with the --with-libSDL= argument. " _ & "If still no luck, consult the configure.log and the build requirements." else MsgError "Can't locate libSDL. Please consult the configure.log and the build requirements." end if exit sub end if strPathLibSDL = UnixSlashes(PathAbs(strPathLibSDL)) CfgPrintAssign "PATH_SDK_LIBSDL", strPathlibSDL PrintResult "libSDL", strPathlibSDL end sub '' Checks if the specified path points to an usable libSDL or not. function CheckForLibSDLSub(strPathlibSDL, strVersion) CheckForlibSDLSub = "" if strPathLibSDL <> "" then LogPrint "Trying: strPathLibSDL=" & strPathLibSDL if LogFileExists(strPathLibSDL, "lib/SDL.lib") _ and LogFileExists(strPathLibSDL, "lib/SDLmain.lib") _ and LogFileExists(strPathLibSDL, "lib/SDL.dll") _ then dim strIncSub : strIncSub = "include" if DirExists(strPathlibSDL & "/include/SDL") then strIncSub = "include/SDL" if LogFileExists(strPathLibSDL, strIncSub & "/SDL.h") _ and LogFileExists(strPathLibSDL, strIncSub & "/SDL_syswm.h") _ and LogFileExists(strPathLibSDL, strIncSub & "/SDL_version.h") _ then strVersion = "" CheckForLibSDLSub = strPathLibSDL end if end if end if end function '' ' Checks for libxml2. ' sub CheckForXml2(strOptXml2) dim strPathXml2, str PrintHdr "libxml2" ' ' Part of tarball / svn, so we can exit immediately if no path was specified. ' if (strOptXml2 = "") then PrintResultMsg "libxml2", "src/lib/libxml2-*" exit sub end if ' Skip if no COM/ATL. if g_blnDisableCOM then PrintResultMsg "libxml2", "Skipped (" & g_strDisableCOM & ")" exit sub end if ' ' Try find some xml2 dll/lib. ' strPathXml2 = "" if (strPathXml2 = "") And (strOptXml2 <> "") then if CheckForXml2Sub(strOptXml2) then strPathXml2 = strOptXml2 end if if strPathXml2 = "" then str = Which("libxml2.lib") if str <> "" then str = PathParent(PathStripFilename(str)) if CheckForXml2Sub(str) then strPathXml2 = str end if end if ' Success? if strPathXml2 = "" then if strOptXml2 = "" then MsgError "Can't locate libxml2. Try specify the path with the --with-libxml2= argument. " _ & "If still no luck, consult the configure.log and the build requirements." else MsgError "Can't locate libxml2. Please consult the configure.log and the build requirements." end if exit sub end if strPathXml2 = UnixSlashes(PathAbs(strPathXml2)) CfgPrintAssign "SDK_VBOX_LIBXML2_DEFS", "_REENTRANT" CfgPrintAssign "SDK_VBOX_LIBXML2_INCS", strPathXml2 & "/include" CfgPrintAssign "SDK_VBOX_LIBXML2_LIBS", strPathXml2 & "/lib/libxml2.lib" PrintResult "libxml2", strPathXml2 end sub '' Checks if the specified path points to an usable libxml2 or not. function CheckForXml2Sub(strPathXml2) dim str CheckForXml2Sub = False LogPrint "trying: strPathXml2=" & strPathXml2 if LogFileExists(strPathXml2, "include/libxml/xmlexports.h") _ And LogFileExists(strPathXml2, "include/libxml/xmlreader.h") _ then str = LogFindFile(strPathXml2, "bin/libxml2.dll") if str <> "" then if LogFindFile(strPathXml2, "lib/libxml2.lib") <> "" then CheckForXml2Sub = True end if end if end if end function '' Checks for openssl sub CheckForSsl(strOptSsl, bln32Bit) dim strPathSsl, str PrintHdr "openssl" strOpenssl = "openssl" if bln32Bit = True then strOpenssl = "openssl32" end if ' ' Part of tarball / svn, so we can exit immediately if no path was specified. ' if (strOptSsl = "") then PrintResult strOpenssl, "src/libs/openssl-*" exit sub end if ' ' Try find some openssl dll/lib. ' strPathSsl = "" if (strPathSsl = "") And (strOptSsl <> "") then if CheckForSslSub(strOptSsl) then strPathSsl = strOptSsl end if if strPathSsl = "" then str = Which("libssl.lib") if str <> "" then str = PathParent(PathStripFilename(str)) if CheckForSslSub(str) then strPathSsl = str end if end if ' Success? if strPathSsl = "" then if strOptSsl = "" then MsgError "Can't locate " & strOpenssl & ". " _ & "Try specify the path with the --with-" & strOpenssl & "= argument. " _ & "If still no luck, consult the configure.log and the build requirements." else MsgError "Can't locate " & strOpenssl & ". " _ & "Please consult the configure.log and the build requirements." end if exit sub end if strPathSsl = UnixSlashes(PathAbs(strPathSsl)) if bln32Bit = True then CfgPrintAssign "SDK_VBOX_OPENSSL-x86_INCS", strPathSsl & "/include" CfgPrintAssign "SDK_VBOX_OPENSSL-x86_LIBS", strPathSsl & "/lib/libcrypto.lib" & " " & strPathSsl & "/lib/libssl.lib" CfgPrintAssign "SDK_VBOX_BLD_OPENSSL-x86_LIBS", strPathSsl & "/lib/libcrypto.lib" & " " & strPathSsl & "/lib/libssl.lib" else CfgPrintAssign "SDK_VBOX_OPENSSL_INCS", strPathSsl & "/include" CfgPrintAssign "SDK_VBOX_OPENSSL_LIBS", strPathSsl & "/lib/libcrypto.lib" & " " & strPathSsl & "/lib/libssl.lib" CfgPrintAssign "SDK_VBOX_BLD_OPENSSL_LIBS", strPathSsl & "/lib/libcrypto.lib" & " " & strPathSsl & "/lib/libssl.lib" end if PrintResult strOpenssl, strPathSsl end sub '' Checks if the specified path points to an usable openssl or not. function CheckForSslSub(strPathSsl) CheckForSslSub = False LogPrint "trying: strPathSsl=" & strPathSsl if LogFileExists(strPathSsl, "include/openssl/md5.h") _ And LogFindFile(strPathSsl, "lib/libssl.lib") <> "" _ then CheckForSslSub = True end if end function '' ' Checks for libcurl ' sub CheckForCurl(strOptCurl, bln32Bit) dim strPathCurl, str PrintHdr "libcurl" strCurl = "libcurl" if bln32Bit = True then strCurl = "libcurl32" end if ' ' Part of tarball / svn, so we can exit immediately if no path was specified. ' if (strOptCurl = "") then PrintResult strCurl, "src/libs/curl-*" exit sub end if ' ' Try find some cURL dll/lib. ' strPathCurl = "" if (strPathCurl = "") And (strOptCurl <> "") then if CheckForCurlSub(strOptCurl) then strPathCurl = strOptCurl end if if strPathCurl = "" then str = Which("libcurl.lib") if str <> "" then str = PathParent(PathStripFilename(str)) if CheckForCurlSub(str) then strPathCurl = str end if end if ' Success? if strPathCurl = "" then if strOptCurl = "" then MsgError "Can't locate " & strCurl & ". " _ & "Try specify the path with the --with-" & strCurl & "= argument. " _ & "If still no luck, consult the configure.log and the build requirements." else MsgError "Can't locate " & strCurl & ". " _ & "Please consult the configure.log and the build requirements." end if exit sub end if strPathCurl = UnixSlashes(PathAbs(strPathCurl)) if bln32Bit = True then CfgPrintAssign "SDK_VBOX_LIBCURL-x86_INCS", strPathCurl & "/include" CfgPrintAssign "SDK_VBOX_LIBCURL-x86_LIBS.x86", strPathCurl & "/libcurl.lib" else CfgPrintAssign "SDK_VBOX_LIBCURL_INCS", strPathCurl & "/include" CfgPrintAssign "SDK_VBOX_LIBCURL_LIBS", strPathCurl & "/libcurl.lib" end if PrintResult strCurl, strPathCurl end sub '' Checks if the specified path points to an usable libcurl or not. function CheckForCurlSub(strPathCurl) CheckForCurlSub = False LogPrint "trying: strPathCurl=" & strPathCurl if LogFileExists(strPathCurl, "include/curl/curl.h") _ And LogFindFile(strPathCurl, "libcurl.dll") <> "" _ And LogFindFile(strPathCurl, "libcurl.lib") <> "" _ then CheckForCurlSub = True end if end function '' ' Checks for any Qt5 binaries. ' sub CheckForQt(strOptQt5, strOptInfix) dim strPathQt5, strInfixQt5, arrFolders, arrVccInfixes, strVccInfix, strPathDev PrintHdr "Qt5" ' ' Try to find the Qt5 installation (user specified path with --with-qt5) ' LogPrint "Checking for user specified path of Qt5 ... " strPathQt5 = CheckForQt5Sub(UnixSlashes(strOptQt5), strOptInfix, strInfixQt5) if strPathQt5 = "" and g_blnInternalFirst = true then strPathQt5 = CheckForQt5Internal(strOptInfix, strInfixQt5) if strPathQt5 = "" then ' ' Collect links from "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\UFH\SHC" ' ' Typical string list: ' C:\Users\someuser\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Qt\5.x.y\MSVC 20zz (64-bit)\Qt 5.x.y (MSVC 20zz 64-bit).lnk ' C:\Windows\System32\cmd.exe ' /A /Q /K E:\qt\installed\5.x.y\msvc20zz_64\bin\qtenv2.bat ' dim arrCandidates, strCandidate arrCandidates = CollectFromProgramItemLinks(GetRef("Qt5ProgramItemCallback"), strPathQt5) LogPrint "Testing qtenv2.bat links (" & ArraySize(arrCandidates) & ") ..." ' VC infixes/subdir names to consider (ASSUMES 64bit) if g_strVCCVersion = "VCC142" or g_strVCCVersion = "" then arrVccInfixes = Array("msvc2019_64", "msvc2017_64", "msvc2015_64") elseif g_strVCCVersion = "VCC141" then arrVccInfixes = Array("msvc2017_64", "msvc2015_64", "msvc2019_64") elseif g_strVCCVersion = "VCC140" then arrVccInfixes = Array("msvc2015_64", "msvc2017_64", "msvc2019_64") elseif g_strVCCVersion = "VCC120" then arrVccInfixes = Array("msvc2013_64") elseif g_strVCCVersion = "VCC110" then arrVccInfixes = Array("msvc2012_64") elseif g_strVCCVersion = "VCC100" then arrVccInfixes = Array("msvc2010_64") else MsgFatal "Unexpected VC version: " & g_strVCCVersion arrVccInfixes = Array() end if for each strVccInfix in arrVccInfixes for each strCandidate in arrCandidates if InStr(1, LCase(strCandidate), strVccInfix) > 0 then strPathQt5 = CheckForQt5Sub(strCandidate, strOptInfix, strInfixQt5) if strPathQt5 <> "" then exit for end if next if strPathQt5 <> "" then exit for next end if ' Check the dev tools - prefer ones matching the compiler. if strPathQt5 = "" and g_blnInternalFirst = false then strPathQt5 = CheckForQt5Internal(strOptInfix, strInfixQt5) ' ' Display the result and output the config. ' if strPathQt5 <> "" then PrintResult "Qt5", strPathQt5 PrintResultMsg "Qt5 infix", strInfixQt5 CfgPrintAssign "PATH_SDK_QT5", strPathQt5 CfgPrintAssign "PATH_TOOL_QT5", "$(PATH_SDK_QT5)" CfgPrintAssign "VBOX_PATH_QT", "$(PATH_SDK_QT5)" CfgPrintAssign "VBOX_QT_INFIX", strInfixQt5 CfgPrintAssign "VBOX_WITH_QT_PAYLOAD", "1" else PrintResultMsg "Qt5", "not found" CfgPrintAssign "VBOX_WITH_QTGUI", "" end if end sub function CheckForQt5Internal(strOptInfix, ByRef strInfixQt5) dim strPathDev, arrFolders, arrVccInfixes, strVccInfix, i CheckForQt5Internal = "" for each strPathDev in g_arrPathDev LogPrint "Testing tools dir (" & strPathDev & "/win." & g_strTargetArch & "/qt/v5*) ..." arrFolders = GetSubdirsStartingWithVerSorted(strPathDev & "/win." & g_strTargetArch & "/qt", "v5") arrVccInfixes = Array(LCase(g_strVCCVersion), Left(LCase(g_strVCCVersion), Len(g_strVCCVersion) - 1), "") for each strVccInfix in arrVccInfixes for i = UBound(arrFolders) to LBound(arrFolders) step -1 if strVccInfix = "" or InStr(1, LCase(arrFolders(i)), strVccInfix) > 0 then LogPrint "i="&i&" strVccInfix="&strVccInfix strPathQt5 = CheckForQt5Sub(strPathDev & "/win." & g_strTargetArch & "/qt/" & arrFolders(i), strOptInfix, strInfixQt5) if strPathQt5 <> "" then CheckForQt5Internal = strPathQt5 exit function end if end if next next next end function function Qt5ProgramItemCallback(ByRef arrStrings, cStrings, ByRef strUnused) dim str, off Qt5ProgramItemCallback = "" if cStrings >= 3 then str = Trim(arrStrings(UBound(arrStrings))) if LCase(Right(str, Len("\bin\qtenv2.bat"))) = "\bin\qtenv2.bat" _ and InStr(1, LCase(str), "\msvc20") > 0 _ and InStr(1, str, ":") > 0 _ then off = InStr(1, str, ":") - 1 Qt5ProgramItemCallback = Mid(str, off, Len(str) - off - Len("\bin\qtenv2.bat") + 1) end if end if end function function CheckForQt5Sub(strPathQt5, strOptInfix, ByRef strInfixQt5) CheckForQt5Sub = "" if strPathQt5 <> "" then LogPrint "Trying: strPathQt5=" & strPathQt5 if LogFileExists(strPathQt5, "bin/moc.exe") _ and LogFileExists(strPathQt5, "bin/uic.exe") _ and LogFileExists(strPathQt5, "include/QtWidgets/qwidget.h") _ and LogFileExists(strPathQt5, "include/QtWidgets/QApplication") _ and LogFileExists(strPathQt5, "include/QtGui/QImage") _ and LogFileExists(strPathQt5, "include/QtNetwork/QHostAddress") _ then ' Infix testing. if LogFileExists(strPathQt5, "lib/Qt5Core.lib") _ and LogFileExists(strPathQt5, "lib/Qt5Network.lib") then LogPrint "found it w/o infix" strInfixQt5 = "" CheckForQt5Sub = UnixSlashes(PathAbs(strPathQt5)) elseif LogFileExists(strPathQt5, "lib/Qt5Core" & strOptInfix & ".lib") _ and LogFileExists(strPathQt5, "lib/Qt5Network" & strOptInfix & ".lib") then LogPrint "found it w/ infix: " & strOptInfix & " (option)" strInfixQt5 = strOptInfix CheckForQt5Sub = UnixSlashes(PathAbs(strPathQt5)) elseif LogFileExists(strPathQt5, "lib/Qt5CoreVBox.lib") _ and LogFileExists(strPathQt5, "lib/Qt5NetworkVBox.lib") then LogPrint "found it w/ infix: VBox" strInfixQt5 = "VBox" CheckForQt5Sub = UnixSlashes(PathAbs(strPathQt5)) end if end if end if end function '' ' Checks for python. ' function CheckForPython(strOptPython) dim strPathPython, arrVersions, strVer, str PrintHdr "Python" CheckForPython = False ' ' Locate it. ' strPathPython = CheckForPythonSub(strOptPython) if strPathPython = "" then arrVersions = Array("3.12", "3.11", "3.10", "3.9", "3.8", "3.7", "3.6", "3.5", "2.7") for each strVer in arrVersions strPathPython = CheckForPythonSub(LogRegGetString("HKLM\SOFTWARE\Python\PythonCore\" & strVer & "\InstallPath\")) if strPathPython <> "" then exit for next end if if strPathPython = "" then strPathPython = CheckForPythonSub(PathStripFilename(Which("python.exe"))) ' ' Output config & result. ' CheckForPython = strPathPython <> "" if CheckForPython then CfgPrintAssign "VBOX_BLD_PYTHON", strPathPython PrintResult "Python", strPathPython else PrintResultMsg "Python", "not found" end if end function function CheckForPythonSub(strPathPython) CheckForPythonSub = "" if strPathPython <> "" then if LogFileExists(strPathPython, "python.exe") _ and LogDirExists(strPathPython & "/DLLs") _ then CheckForPythonSub = UnixSlashes(PathAbs(strPathPython & "/python.exe")) end if end if end function '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Main function and usage ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '' ' Show usage. ' sub usage Print "Usage: cscript configure.vbs [options]" Print "" Print "Configuration:" Print " -h, --help Display this." Print " --target-arch=x86|amd64 The target architecture." Print " --continue-on-error Do not stop on errors." Print " --internal-last Check internal tools (tools/win.*) last." Print " --internal-first Check internal tools (tools/win.*) first (default)." Print "" Print "Components:" Print " --disable-COM Disables all frontends and API." Print " --disable-SDL Disables the SDL frontend." Print " --disable-UDPTunnel" Print " --disable-pylint Disable use of pylint." Print "" Print "Locations:" Print " --with-kBuild=PATH Where kBuild is to be found." Print " --with-libSDL=PATH Where libSDL is to be found." Print " --with-Qt5=PATH Where Qt5 is to be found (optional)." Print " --with-DDK=PATH Where the WDK is to be found." Print " --with-SDK=PATH Where the Windows SDK is to be found." Print " --with-SDK10=PATH Where the Windows 10 SDK/WDK is to be found." Print " --with-VC=PATH Where the Visual C++ compiler is to be found." Print " (Expecting bin, include and lib subdirs.)" Print " --with-VC-Common=PATH Maybe needed for 2015 and older to" Print " locate the Common7 directory." Print " --with-python=PATH The python to use." Print " --with-midl=PATH Where midl.exe is to be found." Print " --with-yasm=PATH Where YASM is to be found." Print " --with-nasm=PATH Where NASM is to be found (optional)" Print " --with-openwatcom=PATH Where OpenWatcom 1.9 is to be found (optional)." Print " --with-libxml2=PATH To use a libxml2 other than the VBox one (opt)." Print " --with-openssl=PATH To use an openssl other than the VBox one (opt)." Print " --with-openssl32=PATH The 32-bit variant of openssl (optional)." Print " --with-libcurl=PATH To use a cURL other than the VBox one (optional)." Print " --with-libcurl32=PATH The 32-bit variant of cURL (optional)." Print "" Print " --append-tools-dir=PATH, --prepend-tools-dir=PATH" Print " Adds an alternative tools directory to search." Print " --append-tools-dir=PATH, --prepend-prog-files=PATH" Print " Adds an alternative Program Files dir to search." Print " --append-ewdk-drive=DRIVE, --prepend-ewdk-drive=DRIVE" Print " Adds an EWDK drive the search list." end sub '' ' The main() like function. ' function Main dim strOutput ' ' Write the log header and check that we're not using wscript. ' LogInit if UCase(Right(Wscript.FullName, 11)) = "WSCRIPT.EXE" then Wscript.Echo "This script must be run under CScript." Main = 1 exit function end if SelfTest ' ' Parse arguments. ' strOptDDK = "" strOptkBuild = "" strOptlibSDL = "" strOptQt5 = "" strOptQt5Infix = "" strOptSDK10 = "" strOptSDK10Version = "" strOptVC = "" strOptVCCommon = "" strOptMidl = "" strOptYasm = "" strOptNasm = "" strOptOpenWatcom = "" strOptXml2 = "" strOptSsl = "" strOptSsl32 = "" strOptCurl = "" strOptCurl32 = "" strOptPython = "" blnOptDisableCOM = False blnOptDisableUDPTunnel = False blnOptDisableSDL = False for i = 1 to Wscript.Arguments.Count dim str, strArg, strPath ' Separate argument and path value str = Wscript.Arguments.item(i - 1) if InStr(1, str, "=") > 0 then strArg = Mid(str, 1, InStr(1, str, "=") - 1) strPath = Mid(str, InStr(1, str, "=") + 1) if strPath = "" then MsgFatal "Syntax error! Argument #" & i & " is missing the path." else strArg = str strPath = "" end if ' Process the argument select case LCase(strArg) ' --with-something: case "--with-ddk" strOptDDK = strPath case "--with-dxsdk" MsgWarning "Ignoring --with-dxsdk (the DirectX SDK is no longer required)." case "--with-kbuild" strOptkBuild = strPath case "--with-libsdl" strOptlibSDL = strPath case "--with-mingw32" ' ignore case "--with-mingw-w64" ' ignore case "--with-qt5" strOptQt5 = strPath case "--with-qt5-infix" strOptQt5Infix = strPath case "--with-sdk" MsgWarning "Ignoring --with-sdk (the legacy Platform SDK is no longer required)." case "--with-sdk10" strOptSDK10 = strPath case "--with-sdk10-version" strOptSDK10Version = strPath case "--with-vc" strOptVC = strPath case "--with-vc-common" strOptVCCommon = strPath case "--with-vc-express-edition" ' ignore case "--with-w32api" ' ignore case "--with-midl" strOptMidl = strPath case "--with-yasm" strOptYasm = strPath case "--with-nasm" strOptNasm = strPath case "--with-openwatcom" strOptOpenWatcom = strPath case "--with-libxml2" strOptXml2 = strPath case "--with-openssl" strOptSsl = strPath case "--with-openssl32" strOptSsl32 = strPath case "--with-libcurl" strOptCurl = strPath case "--with-libcurl32" strOptCurl32 = strPath case "--with-python" strOptPython = strPath ' Search lists. case "--append-tools-dir" g_arrToolsDirs = ArrayAppend(g_arrPathDev, strPath) case "--prepend-tools-dir" g_arrToolsDirs = ArrayPrepend(g_arrPathDev, strPath) case "--append-prog-files" g_arrProgramFiles = ArrayAppend(g_arrProgramFiles, strPath) case "--prepend-prog-files" g_arrProgramFiles = ArrayPrepend(g_arrProgramFiles, strPath) case "--append-ewdk-drive" g_arrProgramFiles = ArrayAppend(g_arrProgramFiles, strPath & "\Program Files") case "--prepend-ewdk-drive" g_arrProgramFiles = ArrayPrepend(g_arrProgramFiles, strPath & "\Program Files") ' --disable-something/--enable-something case "--disable-com" blnOptDisableCOM = True case "--enable-com" blnOptDisableCOM = False case "--disable-udptunnel" blnOptDisableUDPTunnel = True case "--enable-udptunnel" blnOptDisableUDPTunnel = False case "--disable-sdl" blnOptDisableSDL = True case "--endable-sdl" blnOptDisableSDL = False case "--disable-pylint" blnOptDisablePylint = True case "--enable-pylint" blnOptDisablePylint = False ' Other stuff. case "--continue-on-error" g_blnContinueOnError = True case "--internal-first" g_blnInternalFirst = True case "--internal-last" g_blnInternalFirst = False case "--target-arch" g_strTargetArch = strPath case "-h", "--help", "-?" usage Main = 0 exit function case else Wscript.echo "syntax error: Unknown option '" & str &"'." usage Main = 2 exit function end select next ' ' Initialize output files. ' CfgInit EnvInit ' ' Check that the Shell function is sane. ' g_objShell.Environment("PROCESS")("TESTING_ENVIRONMENT_INHERITANCE") = "This works" if Shell("set TESTING_ENVIRONMENT_INHERITANC", False, strOutput) <> 0 then ' The 'E' is missing on purpose (4nt). MsgFatal "shell execution test failed!" end if if strOutput <> "TESTING_ENVIRONMENT_INHERITANCE=This works" & CHR(13) & CHR(10) then Print "Shell test Test -> '" & strOutput & "'" MsgFatal "shell inheritance or shell execution isn't working right. Make sure you use cmd.exe." end if g_objShell.Environment("PROCESS")("TESTING_ENVIRONMENT_INHERITANCE") = "" Print "Shell inheritance test: OK" ' ' Do the checks. ' if blnOptDisableCOM = True then DisableCOM "--disable-com" end if if blnOptDisableUDPTunnel = True then DisableUDPTunnel "--disable-udptunnel" end if if blnOptDisablePylint = True then CfgPrintAssign "override VBOX_WITH_PYLINT", "" end if CheckSourcePath CheckForkBuild strOptkBuild CheckForWinDDK strOptDDK CheckForVisualCPP strOptVC, strOptVCCommon CheckForSDK10 strOptSDK10, strOptSDK10Version CheckForMidl strOptMidl CheckForYasm strOptYasm CheckForNasm strOptNasm CheckForOpenWatcom strOptOpenWatcom if blnOptDisableSDL = True then DisableSDL "--disable-sdl" else CheckForlibSDL strOptlibSDL end if CheckForXml2 strOptXml2 CheckForSsl strOptSsl, False if g_strTargetArch = "amd64" then ' 32-bit openssl required as well CheckForSsl strOptSsl32, True end if CheckForCurl strOptCurl, False if g_strTargetArch = "amd64" then ' 32-bit Curl required as well CheckForCurl strOptCurl32, True end if CheckForQt strOptQt5, strOptQt5Infix CheckForPython strOptPython CfgPrintAssign "VBOX_WITH_LIBVPX", "" '' @todo look for libvpx 1.1.0+ CfgPrintAssign "VBOX_WITH_LIBOGG", "" '' @todo look for libogg 1.3.5+ CfgPrintAssign "VBOX_WITH_LIBVORBIS", "" '' @todo look for libvorbis 1.3.7+ EnvPrintAppend "PATH", DosSlashes(g_strPath & "\tools\win." & g_strHostArch & "\bin"), ";" if g_strHostArch = "amd64" then EnvPrintAppend "PATH", DosSlashes(g_strPath & "\tools\win.x86\bin"), ";" else EnvPrintCleanup "PATH", DosSlashes(g_strPath & "\tools\win.amd64\bin"), ";" end if Print "" Print "Execute env.bat once before you start to build VBox:" Print "" Print " env.bat" Print " kmk" Print "" if g_rcScript <> 0 then Print "Warning: ignored errors. See above or in configure.log." end if Main = g_rcScript end function ' ' What crt0.o typically does: ' WScript.Quit(Main())