diff options
| author | ruki <[email protected]> | 2026-02-04 11:16:33 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-02-04 11:16:33 +0800 |
| commit | 8f34a923760d6af7225df86683fa591bbac667e8 (patch) | |
| tree | 2575132b179615d8c71548fb50f547aa344f8331 | |
| parent | 1bcce9d85f07cae1f7ac9f3a3099047539d26c84 (diff) | |
| parent | eea6cdd0be89085cf72b8277ea9dba31af07ad3b (diff) | |
Merge pull request #7290 from xmake-io/vs
improve vcvars
| -rw-r--r-- | xmake/modules/detect/sdks/find_vstudio.lua | 145 |
1 files changed, 82 insertions, 63 deletions
diff --git a/xmake/modules/detect/sdks/find_vstudio.lua b/xmake/modules/detect/sdks/find_vstudio.lua index 22f5dea6b..8a805aae6 100644 --- a/xmake/modules/detect/sdks/find_vstudio.lua +++ b/xmake/modules/detect/sdks/find_vstudio.lua @@ -28,35 +28,8 @@ import("lib.detect.find_tool") import("lib.detect.find_directory") import("core.cache.global_detectcache") --- init vc variables -local vcvars = {"path", - "lib", - "libpath", - "include", - "DevEnvdir", - "VSInstallDir", - "VCInstallDir", - "WindowsSdkDir", - "WindowsLibPath", - "WindowsSDKVersion", - "WindowsSdkBinPath", - "WindowsSdkVerBinPath", - "ExtensionSdkDir", - "UniversalCRTSdkDir", - "UCRTVersion", - "VCToolsVersion", - "VCIDEInstallDir", - "VCToolsInstallDir", - "VCToolsRedistDir", - "VisualStudioVersion", - "VSCMD_VER", - "VSCMD_ARG_app_plat", - "VSCMD_ARG_HOST_ARCH", - "VSCMD_ARG_TGT_ARCH"} - -- init vsvers -local vsvers = -{ +local vsvers = { ["18.0"] = "2026" , ["17.0"] = "2022" , ["16.0"] = "2019" @@ -75,8 +48,7 @@ local vsvers = } -- init vsenvs -local vsenvs = -{ +local vsenvs = { ["18.0"] = "VS180COMNTOOLS" , ["17.0"] = "VS170COMNTOOLS" , ["16.0"] = "VS160COMNTOOLS" @@ -99,6 +71,32 @@ local _env_orgs = {} -- get all known Visual Studio environment variables function get_vcvars() + local vcvars = { + "PATH", + "LIB", + "LIBPATH", + "INCLUDE", + "DevEnvdir", + "VSInstallDir", + "VCInstallDir", + "WindowsSdkDir", + "WindowsLibPath", + "WindowsSDKVersion", + "WindowsSdkBinPath", + "WindowsSdkVerBinPath", + "ExtensionSdkDir", + "UniversalCRTSdkDir", + "UCRTVersion", + "VCToolsVersion", + "VCIDEInstallDir", + "VCToolsInstallDir", + "VCToolsRedistDir", + "VisualStudioVersion", + "VSCMD_VER", + "VSCMD_ARG_app_plat", + "VSCMD_ARG_HOST_ARCH", + "VSCMD_ARG_TGT_ARCH"} + local realvcvars = vcvars for _, v in pairs(vsenvs) do table.insert(realvcvars, v) @@ -310,39 +308,36 @@ function _load_vcvarsall_impl(vcvarsall, vsver, arch, opt) local p = line:find('=', 1, true) if p then local name = line:sub(1, p - 1):trim() - local value = line:sub(p + 1):trim() - variables[name] = value + if #name > 0 then + local value = line:sub(p + 1):trim() + if #value > 0 then + variables[name] = value + end + end end end -- check if the environment variables are truncated _check_vcvarsall_env(variables) - if not variables.path then + if not variables.PATH then return end - -- remove some empty entries - for _, name in ipairs(vcvars) do - if variables[name] and #variables[name]:trim() == 0 then - variables[name] = nil - end - end - -- fix WindowsSDKVersion - local WindowsSDKVersion = variables["WindowsSDKVersion"] + local WindowsSDKVersion = variables.WindowsSDKVersion if WindowsSDKVersion then WindowsSDKVersion = WindowsSDKVersion:gsub("\\", ""):trim() if WindowsSDKVersion ~= "" then - variables["WindowsSDKVersion"] = WindowsSDKVersion + variables.WindowsSDKVersion = WindowsSDKVersion end else -- sometimes the variable `WindowsSDKVersion` is not available -- then parse it from `WindowsSdkBinPath`, such as: `C:\\Program Files (x86)\\Windows Kits\\8.1\\bin` - local WindowsSdkBinPath = variables["WindowsSdkBinPath"] + local WindowsSdkBinPath = variables.WindowsSdkBinPath if WindowsSdkBinPath then WindowsSDKVersion = string.match(WindowsSdkBinPath, "\\(%d+%.%d+)\\bin$") if WindowsSDKVersion then - variables["WindowsSDKVersion"] = WindowsSDKVersion + variables.WindowsSDKVersion = WindowsSDKVersion end end end @@ -351,31 +346,21 @@ function _load_vcvarsall_impl(vcvarsall, vsver, arch, opt) -- -- @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"] + local UCRTVersion = variables.UCRTVersion if UCRTVersion and WindowsSDKVersion and UCRTVersion ~= WindowsSDKVersion and WindowsSDKVersion ~= "" then - local lib = variables["lib"] + local lib = variables.LIB if lib then lib = lib:gsub(UCRTVersion, WindowsSDKVersion) - variables["lib"] = lib + variables.LIB = lib end - local include = variables["include"] + local include = variables.INCLUDE if include then include = include:gsub(UCRTVersion, WindowsSDKVersion) - variables["include"] = include + variables.INCLUDE = include end UCRTVersion = WindowsSDKVersion - variables["UCRTVersion"] = UCRTVersion + variables.UCRTVersion = UCRTVersion end - - -- convert path/lib/include to PATH/LIB/INCLUDE - variables.PATH = variables.path - variables.LIB = variables.lib - variables.LIBPATH = variables.libpath - variables.INCLUDE = variables.include - variables.path = nil - variables.lib = nil - variables.include = nil - variables.libpath = nil return variables end @@ -406,7 +391,7 @@ function _check_vcvarsall_env(vars) end value_org = _env_orgs[name] end - local value_new = vars[name] or vars[name:lower()] + local value_new = vars[name] if value_org and value_new and #value_org > 0 then local values_new = hashset.from(path.splitenv(value_new)) for _, p in ipairs(value_org) do @@ -562,7 +547,7 @@ function _find_vstudio(opt) if vsenvs[version] then table.insert(paths, format("$(env %s)\\..\\..\\VC", vsenvs[version])) end - + if vswhere_VCAuxiliaryBuildDir then for _, vc_path in ipairs(vswhere_VCAuxiliaryBuildDir) do if os.isdir(vc_path) then @@ -695,6 +680,33 @@ function _get_last_mtime(vstudio) return mtime end +function _show_vstudio_diagnosis_result(vstudio) + local found = {} + for vsver, msvc in pairs(vstudio) do + if type(msvc) == "table" and msvc.version then + local toolset + local vcvarsall = msvc.vcvarsall + if type(vcvarsall) == "table" then + for _, envs in pairs(vcvarsall) do + if type(envs) == "table" and envs.VCToolsVersion then + toolset = _strip_toolset_ver(envs.VCToolsVersion) + break + end + end + end + if toolset then + table.insert(found, tostring(vsver) .. "(" .. tostring(msvc.version) .. ", toolset:" .. tostring(toolset) .. ")") + else + table.insert(found, tostring(vsver) .. "(" .. tostring(msvc.version) .. ")") + end + else + table.insert(found, tostring(vsver)) + end + end + table.sort(found, function (a, b) return a > b end) + cprint("${dim}detecting vstudio environment ... ${color.success}%s", table.concat(found, ", ")) +end + -- find vstudio environment -- -- @param opt the options, e.g. {toolset = 14.0, sdkver = "10.0.15063.0"} @@ -729,6 +741,7 @@ function main(opt) end -- find and cache result + cprint("${color.warning}Detecting Visual Studio environment (cached); run `xmake global --clean` first if vs updated.") vstudio = _find_vstudio(opt) if vstudio then local mtime = _get_last_mtime(vstudio) @@ -736,6 +749,12 @@ function main(opt) global_detectcache:set2(key, "mtime", mtime) global_detectcache:save() end + if option.get("diagnosis") then + if vstudio and not table.empty(vstudio) then + _show_vstudio_diagnosis_result(vstudio) + else + cprint("${dim}detecting vstudio environment ...${color.failure}${text.failure}") + end + end return vstudio end - |
