From 19829f49a644d4377c082df90b812a891d4d403c Mon Sep 17 00:00:00 2001 From: Roy Ivy III Date: Sun, 14 Oct 2018 22:12:22 -0500 Subject: fix "fix UCRTVersion" logic for possibly missing WindowsSDKVersion * some versions (especially early versions) of MSVC/VS may not define the WindowsSDKVersion environment variable --- xmake/modules/detect/sdks/find_vstudio.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/modules/detect/sdks/find_vstudio.lua b/xmake/modules/detect/sdks/find_vstudio.lua index 2e8083768..5ed3b310c 100644 --- a/xmake/modules/detect/sdks/find_vstudio.lua +++ b/xmake/modules/detect/sdks/find_vstudio.lua @@ -93,7 +93,7 @@ function _load_vcvarsall(vcvarsall, arch) -- @note vcvarsall.bat maybe detect error if install WDK and SDK at same time (multi-sdk version exists in include directory). -- local UCRTVersion = variables["UCRTVersion"] - if UCRTVersion and UCRTVersion ~= WindowsSDKVersion and WindowsSDKVersion ~= "" then + if UCRTVersion and WindowsSDKVersion and UCRTVersion ~= WindowsSDKVersion and WindowsSDKVersion ~= "" then local lib = variables["lib"] if lib then lib = lib:gsub(UCRTVersion, WindowsSDKVersion) -- cgit v1.3.1 From ca72eb0cf60c3e0747444859d9fc738b98ecc4b5 Mon Sep 17 00:00:00 2001 From: Roy Ivy III Date: Sun, 14 Oct 2018 22:16:24 -0500 Subject: fix find_vstudio when executing from an already defined MSVC command prompt .# Discussion Older MSVC/VS versions don't define the "VisualStudioVersion" environment variable. Prior to this fix, when executing within an already prepared environment (eg, the "Visual Studio Command Prompt") with those older MSVC/VS builds, the search logic would incorrectly try to search for all installed versions and read their environments. But since the environment had already been prepped, executing `vsvarsall` for any found MSVC/VS versions resulted in a superimposed and confused/invalid environment. For the older MSVC/VS versions without "VisualStudioVersion", this fix does use heuristics to guess at the correct version (and it's corresponding vsvers value [used as the results key value]). But, even if the wrong version is guessed, the results from find_vstudio are clean, without any environmental superposition, and fully usable for compilation. --- xmake/modules/detect/sdks/find_vstudio.lua | 37 ++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/xmake/modules/detect/sdks/find_vstudio.lua b/xmake/modules/detect/sdks/find_vstudio.lua index 5ed3b310c..eb6c565a9 100644 --- a/xmake/modules/detect/sdks/find_vstudio.lua +++ b/xmake/modules/detect/sdks/find_vstudio.lua @@ -152,13 +152,40 @@ function main() , ["4.2"] = "VS42COMNTOOLS" } - -- find vs from environment variables + -- find the single current MSVC/VS from environment variables local VCInstallDir = os.getenv("VCInstallDir") - local VisualStudioVersion = os.getenv("VisualStudioVersion") - if VCInstallDir and VisualStudioVersion then + if VCInstallDir and (VCInstallDir ~= "") then + local VisualStudioVersion = os.getenv("VisualStudioVersion") + if not VisualStudioVersion or (VisualStudioVersion == "") then + + -- heuristic for VisualStudioVersion value (early MSVC/VS versions don't set VisualStudioVersion) + local VSInstallDir = os.getenv("VSInstallDir") or "" + VisualStudioVersion = VSInstallDir:match('(%d+[.]?%d*)\\?%s*$') + if not VisualStudioVersion then VisualStudioVersion = VCInstallDir:match('(%d+[.]?%d*)\\VC\\?%s*$') end + if not VisualStudioVersion then VisualStudioVersion = "0" end + if not VisualStudioVersion:match('[.]') then VisualStudioVersion = VisualStudioVersion .. '.0' end + + -- find highest known version which is less than or equal to VisualStudioVersion + if not vsvers[VisualStudioVersion] then + local versions = {} + local count = 0 + for k in pairs(vsvers) do table.insert(versions, tonumber(k)); count = count + 1 end + table.sort(versions) + local i = 0 + local v = tonumber(VisualStudioVersion) + while ((i < count) and (versions[i+1] <= v)) do i = i + 1 end + VisualStudioVersion = versions[i] or "0" + end + end - -- find vcvarsall.bat - local vcvarsall = path.join(VCInstallDir, "Auxiliary", "Build", "vcvarsall.bat") + -- find vcvarsall.bat or vcvars32.bat + local pathes = + { + VCInstallDir.."\\Auxiliary\\Build", + VCInstallDir.."\\bin", + VCInstallDir + } + local vcvarsall = find_file("vcvarsall.bat", pathes) or find_file("vcvars32.bat", pathes) if os.isfile(vcvarsall) then -- load vcvarsall -- cgit v1.3.1