diff options
| author | ruki <[email protected]> | 2025-10-09 07:39:52 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-10-09 07:39:52 +0800 |
| commit | 79879d1815c0dce96ad327c13d411d512777dbc4 (patch) | |
| tree | dcfec25d1bac9cefcc58b43a5b8519acbeaebaa9 | |
| parent | e4b2bc29c1aca3959e5f08ebc99f7e048b7e2191 (diff) | |
| parent | 0821767a626d2446e2191f1dfc3a52c93685eb1a (diff) | |
Merge pull request #6904 from xmake-io/msvc
Improve clang to support for msvc envs
| -rw-r--r-- | xmake/modules/private/utils/toolchain.lua | 93 | ||||
| -rw-r--r-- | xmake/toolchains/clang-cl/check.lua | 120 | ||||
| -rw-r--r-- | xmake/toolchains/clang/check.lua | 69 | ||||
| -rw-r--r-- | xmake/toolchains/icc/check.lua | 81 | ||||
| -rw-r--r-- | xmake/toolchains/icx/check.lua | 81 | ||||
| -rw-r--r-- | xmake/toolchains/ifort/check.lua | 81 | ||||
| -rw-r--r-- | xmake/toolchains/ifx/check.lua | 81 | ||||
| -rw-r--r-- | xmake/toolchains/msvc/check.lua | 112 |
8 files changed, 162 insertions, 556 deletions
diff --git a/xmake/modules/private/utils/toolchain.lua b/xmake/modules/private/utils/toolchain.lua index da2e9febf..28cbc23c0 100644 --- a/xmake/modules/private/utils/toolchain.lua +++ b/xmake/modules/private/utils/toolchain.lua @@ -17,10 +17,103 @@ -- @author ruki -- @file toolchain.lua -- + +-- imports +import("core.base.option") +import("core.project.config") import("core.base.semver") import("core.tool.linker") import("core.tool.compiler") import("core.language.language") +import("lib.detect.find_tool") +import("detect.sdks.find_vstudio") + +-- attempt to check vs environment +function _check_vsenv(toolchain, check) + + -- have been checked? + local vs = toolchain:config("vs") or config.get("vs") + if vs then + vs = tostring(vs) + end + local vcvars = toolchain:config("vcvars") + if vs and vcvars then + return vs + end + + -- find vstudio + local vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") + local vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") + local vstudio = find_vstudio({toolset = vs_toolset, sdkver = vs_sdkver}) + if vstudio then + + -- make order vsver + local vsvers = {} + for vsver, _ in pairs(vstudio) do + if not vs or vs ~= vsver then + table.insert(vsvers, vsver) + end + end + table.sort(vsvers, function (a, b) return tonumber(a) > tonumber(b) end) + if vs then + table.insert(vsvers, 1, vs) + end + + -- get vcvarsall + for _, vsver in ipairs(vsvers) do + local vcvarsall = (vstudio[vsver] or {}).vcvarsall or {} + local vcvars = vcvarsall[toolchain:arch()] + if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then + toolchain:config_set("vcvars", vcvars) + toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) + toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) + toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) + if check and check(toolchain, vcvars) then + return vsver + end + end + end + end +end + +-- check the visual studio +function check_vstudio(toolchain, check) + local vs = _check_vsenv(toolchain, check) + if vs then + if toolchain:is_global() then + config.set("vs", vs, {force = true, readonly = true}) + end + toolchain:config_set("vs", vs) + cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs) + else + cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch()) + end + return vs +end + +-- check vc build tools sdk +function check_vc_build_tools(toolchain, sdkdir, check) + local opt = {} + opt.sdkdir = sdkdir + opt.vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") + opt.vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") + + local vcvarsall = find_vstudio.find_build_tools(opt) + if not vcvarsall then + return + end + + local vcvars = vcvarsall[toolchain:arch()] + if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then + toolchain:config_set("vcvars", vcvars) + toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) + toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) + toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) + if check and check(toolchain, vcvars) then + return vcvars + end + end +end -- is the compatible with the host? function is_compatible_with_host(name) diff --git a/xmake/toolchains/clang-cl/check.lua b/xmake/toolchains/clang-cl/check.lua index 8925e9ee2..b7e417d69 100644 --- a/xmake/toolchains/clang-cl/check.lua +++ b/xmake/toolchains/clang-cl/check.lua @@ -21,119 +21,20 @@ -- imports import("core.base.option") import("core.project.config") -import("detect.sdks.find_vstudio") import("lib.detect.find_tool") +import("private.utils.toolchain", {alias = "toolchain_utils"}) -function _find_clang_cl(vcvars) +function _check_clang_cl(toolchain, vcvars) local paths local pathenv = os.getenv("PATH") if pathenv then paths = path.splitenv(pathenv) end - return find_tool("clang-cl", {version = true, force = true, paths = paths, envs = vcvars}) -end - --- attempt to check vs environment -function _check_vsenv(toolchain) - - -- has been checked? - local vs = toolchain:config("vs") or config.get("vs") - if vs then - vs = tostring(vs) - end - local vcvars = toolchain:config("vcvars") - if vs and vcvars then - return vs - end - - -- find vstudio - local vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") - local vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") - local vstudio = find_vstudio({toolset = vs_toolset, sdkver = vs_sdkver}) - if vstudio then - - -- make order vsver - local vsvers = {} - for vsver, _ in pairs(vstudio) do - if not vs or vs ~= vsver then - table.insert(vsvers, vsver) - end - end - table.sort(vsvers, function (a, b) return tonumber(a) > tonumber(b) end) - if vs then - table.insert(vsvers, 1, vs) - end - - -- get vcvarsall - for _, vsver in ipairs(vsvers) do - local vcvarsall = (vstudio[vsver] or {}).vcvarsall or {} - local vcvars = vcvarsall[toolchain:arch()] - if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then - - -- save vcvars - toolchain:config_set("vcvars", vcvars) - toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) - toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) - toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) - - -- check compiler - local program - local tool = _find_clang_cl(vcvars) - if tool then - program = tool.program - end - if program then - return vsver, tool - end - end - end - end -end - --- check the visual studio -function _check_vstudio(toolchain) - local vs, clang_cl = _check_vsenv(toolchain) - if vs then - if toolchain:is_global() then - config.set("vs", vs, {force = true, readonly = true}) - end - toolchain:config_set("vs", vs) - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs) - if clang_cl and clang_cl.version then - cprint("checking for LLVM Clang C/C++ Compiler (%s) version ... ${color.success}%s", toolchain:arch(), clang_cl.version) - end - else - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch()) - end - return vs -end - -function _check_vc_build_tools(toolchain, sdkdir) - local opt = {} - opt.sdkdir = sdkdir - opt.vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") - opt.vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") - - local vcvarsall = find_vstudio.find_build_tools(opt) - if not vcvarsall then - return - end - - local vcvars = vcvarsall[toolchain:arch()] - if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then - -- save vcvars - toolchain:config_set("vcvars", vcvars) - toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) - toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) - toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) - - -- check compiler - local clang_cl = _find_clang_cl(vcvars) - if clang_cl and clang_cl.version then - cprint("checking for LLVM Clang C/C++ Compiler (%s) version ... ${color.success}%s", toolchain:arch(), clang_cl.version) - end - return vcvars + local result = find_tool("clang-cl", {force = true, paths = paths, envs = vcvars}) + if result then + cprint("checking for LLVM Clang C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch()) end + return result end function main(toolchain) @@ -150,21 +51,18 @@ function main(toolchain) if cc == "clang-cl" or cxx == "clang-cl" or mrc == "rc" then local sdkdir = toolchain:sdkdir() if sdkdir then - return _check_vc_build_tools(toolchain, sdkdir) + return toolchain_utils.check_vc_build_tools(toolchain, sdkdir, _check_clang_cl) else - -- find it from packages for _, package in ipairs(toolchain:packages()) do local installdir = package:installdir() if installdir and os.isdir(installdir) then - local result = _check_vc_build_tools(toolchain, installdir) + local result = toolchain_utils.check_vc_build_tools(toolchain, installdir, _check_clang_cl) if result then return result end end end - - -- find it from system - return _check_vstudio(toolchain) + return toolchain_utils.check_vstudio(toolchain, _check_clang_cl) end end end diff --git a/xmake/toolchains/clang/check.lua b/xmake/toolchains/clang/check.lua index febb0bbd3..107410a0b 100644 --- a/xmake/toolchains/clang/check.lua +++ b/xmake/toolchains/clang/check.lua @@ -18,41 +18,22 @@ -- @file xmake.lua -- -import("detect.sdks.find_vstudio") -import("lib.detect.find_tool") +-- imports import("core.project.config") +import("lib.detect.find_tool") +import("private.utils.toolchain", {alias = "toolchain_utils"}) -function _check_vc_build_tools(toolchain, sdkdir, suffix) - local opt = {} - opt.sdkdir = sdkdir - opt.vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") - opt.vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") - - local vcvarsall = find_vstudio.find_build_tools(opt) - if not vcvarsall then - return +function _check_clang(toolchain, vcvars, suffix) + local paths + local pathenv = os.getenv("PATH") + if pathenv then + paths = path.splitenv(pathenv) end - - local vcvars = vcvarsall[toolchain:arch()] - if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then - -- save vcvars - toolchain:config_set("vcvars", vcvars) - toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) - toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) - toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) - - -- check compiler - local paths - local pathenv = os.getenv("PATH") - if pathenv then - paths = path.splitenv(pathenv) - end - local clang = find_tool("clang" .. suffix, {version = true, force = true, paths = paths, envs = vcvars}) - if clang and clang.version then - cprint("checking for LLVM Clang C/C++ Compiler (%s) version ... ${color.success}%s", toolchain:arch(), clang.version) - end - return vcvars + local result = find_tool("clang" .. suffix, {force = true, paths = paths, envs = vcvars}) + if result then + cprint("checking for LLVM Clang C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch()) end + return result end function main(toolchain, suffix) @@ -62,8 +43,28 @@ function main(toolchain, suffix) return end - local sdkdir = toolchain:sdkdir() - if sdkdir then - return _check_vc_build_tools(toolchain, sdkdir, suffix) + -- @see https://github.com/xmake-io/xmake/pull/679 + local cc = path.basename(config.get("cc") or "clang"):lower() + local cxx = path.basename(config.get("cxx") or "clang++"):lower() + if cc == "clang" or cxx == "clang" or cxx == "clang++" then + local check = function (toolchain, vcvars) + return _check_clang(toolchain, vcvars, suffix) + end + local sdkdir = toolchain:sdkdir() + if sdkdir then + return toolchain_utils.check_vc_build_tools(toolchain, sdkdir, check) + else + for _, package in ipairs(toolchain:packages()) do + local installdir = package:installdir() + if installdir and os.isdir(installdir) then + local result = toolchain_utils.check_vc_build_tools(toolchain, installdir, check) + if result then + return result + end + end + end + return toolchain_utils.check_vstudio(toolchain, check) + end end end + diff --git a/xmake/toolchains/icc/check.lua b/xmake/toolchains/icc/check.lua index a88e309af..324fe9a36 100644 --- a/xmake/toolchains/icc/check.lua +++ b/xmake/toolchains/icc/check.lua @@ -22,84 +22,11 @@ import("core.base.option") import("core.project.config") import("detect.sdks.find_iccenv") -import("detect.sdks.find_vstudio") import("lib.detect.find_tool") +import("private.utils.toolchain", {alias = "toolchain_utils"}) --- attempt to check vs environment -function _check_vsenv(toolchain) - - -- has been checked? - local vs = toolchain:config("vs") or config.get("vs") - if vs then - vs = tostring(vs) - end - local vcvars = toolchain:config("vcvars") - if vs and vcvars then - return vs - end - - -- find vstudio - local vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") - local vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") - local vstudio = find_vstudio({toolset = vs_toolset, sdkver = vs_sdkver}) - if vstudio then - - -- make order vsver - local vsvers = {} - for vsver, _ in pairs(vstudio) do - if not vs or vs ~= vsver then - table.insert(vsvers, vsver) - end - end - table.sort(vsvers, function (a, b) return tonumber(a) > tonumber(b) end) - if vs then - table.insert(vsvers, 1, vs) - end - - -- get vcvarsall - for _, vsver in ipairs(vsvers) do - local vcvarsall = (vstudio[vsver] or {}).vcvarsall or {} - local vcvars = vcvarsall[toolchain:arch()] - if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then - - -- save vcvars - toolchain:config_set("vcvars", vcvars) - toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) - toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) - toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) - - -- check compiler - local program - local paths - local pathenv = os.getenv("PATH") - if pathenv then - paths = path.splitenv(pathenv) - end - local tool = find_tool("cl.exe", {force = true, paths = paths, envs = vcvars}) - if tool then - program = tool.program - end - if program then - return vsver - end - end - end - end -end - --- check the visual studio -function _check_vstudio(toolchain) - local vs = _check_vsenv(toolchain) - if vs then - if toolchain:is_global() then - config.set("vs", vs, {force = true, readonly = true}) - end - toolchain:config_set("vs", vs) - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs) - else - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch()) - end - return vs +function _check_cl(toolchain, vcvars) + return find_tool("cl.exe", {force = true, envs = vcvars}) end -- check intel on windows @@ -121,7 +48,7 @@ function _check_intel_on_windows(toolchain) if tool then cprint("checking for Intel C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch()) toolchain:config_set("varsall", iclvarsall) - return _check_vstudio(toolchain) + return toolchain_utils.check_vstudio(toolchain, _check_cl) end end end diff --git a/xmake/toolchains/icx/check.lua b/xmake/toolchains/icx/check.lua index 29fc56a7c..069d925b0 100644 --- a/xmake/toolchains/icx/check.lua +++ b/xmake/toolchains/icx/check.lua @@ -22,84 +22,11 @@ import("core.base.option") import("core.project.config") import("detect.sdks.find_icxenv") -import("detect.sdks.find_vstudio") import("lib.detect.find_tool") +import("private.utils.toolchain", {alias = "toolchain_utils"}) --- attempt to check vs environment -function _check_vsenv(toolchain) - - -- has been checked? - local vs = toolchain:config("vs") or config.get("vs") - if vs then - vs = tostring(vs) - end - local vcvars = toolchain:config("vcvars") - if vs and vcvars then - return vs - end - - -- find vstudio - local vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") - local vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") - local vstudio = find_vstudio({toolset = vs_toolset, sdkver = vs_sdkver}) - if vstudio then - - -- make order vsver - local vsvers = {} - for vsver, _ in pairs(vstudio) do - if not vs or vs ~= vsver then - table.insert(vsvers, vsver) - end - end - table.sort(vsvers, function (a, b) return tonumber(a) > tonumber(b) end) - if vs then - table.insert(vsvers, 1, vs) - end - - -- get vcvarsall - for _, vsver in ipairs(vsvers) do - local vcvarsall = (vstudio[vsver] or {}).vcvarsall or {} - local vcvars = vcvarsall[toolchain:arch()] - if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then - - -- save vcvars - toolchain:config_set("vcvars", vcvars) - toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) - toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) - toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) - - -- check compiler - local program - local paths - local pathenv = os.getenv("PATH") - if pathenv then - paths = path.splitenv(pathenv) - end - local tool = find_tool("cl.exe", {force = true, paths = paths, envs = vcvars}) - if tool then - program = tool.program - end - if program then - return vsver - end - end - end - end -end - --- check the visual studio -function _check_vstudio(toolchain) - local vs = _check_vsenv(toolchain) - if vs then - if toolchain:is_global() then - config.set("vs", vs, {force = true, readonly = true}) - end - toolchain:config_set("vs", vs) - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs) - else - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch()) - end - return vs +function _check_cl(toolchain, vcvars) + return find_tool("cl.exe", {force = true, envs = vcvars}) end -- check intel on windows @@ -121,7 +48,7 @@ function _check_intel_on_windows(toolchain) if tool then cprint("checking for Intel LLVM C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch()) toolchain:config_set("varsall", icxvarsall) - return _check_vstudio(toolchain) + return toolchain_utils.check_vstudio(toolchain, _check_cl) end end end diff --git a/xmake/toolchains/ifort/check.lua b/xmake/toolchains/ifort/check.lua index e9dd5c133..717494b86 100644 --- a/xmake/toolchains/ifort/check.lua +++ b/xmake/toolchains/ifort/check.lua @@ -22,84 +22,11 @@ import("core.base.option") import("core.project.config") import("detect.sdks.find_ifortenv") -import("detect.sdks.find_vstudio") import("lib.detect.find_tool") +import("private.utils.toolchain", {alias = "toolchain_utils"}) --- attempt to check vs environment -function _check_vsenv(toolchain) - - -- has been checked? - local vs = toolchain:config("vs") or config.get("vs") - if vs then - vs = tostring(vs) - end - local vcvars = toolchain:config("vcvars") - if vs and vcvars then - return vs - end - - -- find vstudio - local vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") - local vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") - local vstudio = find_vstudio({toolset = vs_toolset, sdkver = vs_sdkver}) - if vstudio then - - -- make order vsver - local vsvers = {} - for vsver, _ in pairs(vstudio) do - if not vs or vs ~= vsver then - table.insert(vsvers, vsver) - end - end - table.sort(vsvers, function (a, b) return tonumber(a) > tonumber(b) end) - if vs then - table.insert(vsvers, 1, vs) - end - - -- get vcvarsall - for _, vsver in ipairs(vsvers) do - local vcvarsall = (vstudio[vsver] or {}).vcvarsall or {} - local vcvars = vcvarsall[toolchain:arch()] - if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then - - -- save vcvars - toolchain:config_set("vcvars", vcvars) - toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) - toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) - toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) - - -- check compiler - local program - local paths - local pathenv = os.getenv("PATH") - if pathenv then - paths = path.splitenv(pathenv) - end - local tool = find_tool("cl.exe", {force = true, paths = paths, envs = vcvars}) - if tool then - program = tool.program - end - if program then - return vsver - end - end - end - end -end - --- check the visual studio -function _check_vstudio(toolchain) - local vs = _check_vsenv(toolchain) - if vs then - if toolchain:is_global() then - config.set("vs", vs, {force = true, readonly = true}) - end - toolchain:config_set("vs", vs) - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs) - else - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch()) - end - return vs +function _check_cl(toolchain, vcvars) + return find_tool("cl.exe", {force = true, envs = vcvars}) end -- check intel on windows @@ -121,7 +48,7 @@ function _check_intel_on_windows(toolchain) if tool then cprint("checking for Intel Fortran Compiler (%s) ... ${color.success}${text.success}", toolchain:arch()) toolchain:config_set("varsall", ifortvarsall) - return _check_vstudio(toolchain) + return toolchain_utils.check_vstudio(toolchain, _check_cl) end end end diff --git a/xmake/toolchains/ifx/check.lua b/xmake/toolchains/ifx/check.lua index 7a10a5865..91fb026a6 100644 --- a/xmake/toolchains/ifx/check.lua +++ b/xmake/toolchains/ifx/check.lua @@ -22,84 +22,11 @@ import("core.base.option") import("core.project.config") import("detect.sdks.find_ifxenv") -import("detect.sdks.find_vstudio") import("lib.detect.find_tool") +import("private.utils.toolchain", {alias = "toolchain_utils"}) --- attempt to check vs environment -function _check_vsenv(toolchain) - - -- has been checked? - local vs = toolchain:config("vs") or config.get("vs") - if vs then - vs = tostring(vs) - end - local vcvars = toolchain:config("vcvars") - if vs and vcvars then - return vs - end - - -- find vstudio - local vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") - local vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") - local vstudio = find_vstudio({toolset = vs_toolset, sdkver = vs_sdkver}) - if vstudio then - - -- make order vsver - local vsvers = {} - for vsver, _ in pairs(vstudio) do - if not vs or vs ~= vsver then - table.insert(vsvers, vsver) - end - end - table.sort(vsvers, function (a, b) return tonumber(a) > tonumber(b) end) - if vs then - table.insert(vsvers, 1, vs) - end - - -- get vcvarsall - for _, vsver in ipairs(vsvers) do - local vcvarsall = (vstudio[vsver] or {}).vcvarsall or {} - local vcvars = vcvarsall[toolchain:arch()] - if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then - - -- save vcvars - toolchain:config_set("vcvars", vcvars) - toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) - toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) - toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) - - -- check compiler - local program - local paths - local pathenv = os.getenv("PATH") - if pathenv then - paths = path.splitenv(pathenv) - end - local tool = find_tool("cl.exe", {force = true, paths = paths, envs = vcvars}) - if tool then - program = tool.program - end - if program then - return vsver, - end - end - end - end -end - --- check the visual studio -function _check_vstudio(toolchain) - local vs = _check_vsenv(toolchain) - if vs then - if toolchain:is_global() then - config.set("vs", vs, {force = true, readonly = true}) - end - toolchain:config_set("vs", vs) - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs) - else - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch()) - end - return vs +function _check_cl(toolchain, vcvars) + return find_tool("cl.exe", {force = true, envs = vcvars}) end -- check intel on windows @@ -121,7 +48,7 @@ function _check_intel_on_windows(toolchain) if tool then cprint("checking for Intel LLVM Fortran Compiler (%s) ... ${color.success}${text.success}", toolchain:arch()) toolchain:config_set("varsall", ifxvarsall) - return _check_vstudio(toolchain) + return toolchain_utils.check_vstudio(toolchain, _check_cl) end end end diff --git a/xmake/toolchains/msvc/check.lua b/xmake/toolchains/msvc/check.lua index 37f38b53c..d5b1d9407 100644 --- a/xmake/toolchains/msvc/check.lua +++ b/xmake/toolchains/msvc/check.lua @@ -21,106 +21,15 @@ -- imports import("core.base.option") import("core.project.config") -import("detect.sdks.find_vstudio") import("lib.detect.find_tool") +import("private.utils.toolchain", {alias = "toolchain_utils"}) --- attempt to check vs environment -function _check_vsenv(toolchain) - - -- have been checked? - local vs = toolchain:config("vs") or config.get("vs") - if vs then - vs = tostring(vs) - end - local vcvars = toolchain:config("vcvars") - if vs and vcvars then - return vs - end - - -- find vstudio - local vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") - local vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") - local vstudio = find_vstudio({toolset = vs_toolset, sdkver = vs_sdkver}) - if vstudio then - - -- make order vsver - local vsvers = {} - for vsver, _ in pairs(vstudio) do - if not vs or vs ~= vsver then - table.insert(vsvers, vsver) - end - end - table.sort(vsvers, function (a, b) return tonumber(a) > tonumber(b) end) - if vs then - table.insert(vsvers, 1, vs) - end - - -- get vcvarsall - for _, vsver in ipairs(vsvers) do - local vcvarsall = (vstudio[vsver] or {}).vcvarsall or {} - local vcvars = vcvarsall[toolchain:arch()] - if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then - - -- save vcvars - toolchain:config_set("vcvars", vcvars) - toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) - toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) - toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) - - -- check compiler - local program = nil - local tool = find_tool("cl.exe", {force = true, envs = vcvars}) - if tool then - program = tool.program - end - if program then - return vsver - end - end - end - end -end - --- check the visual studio -function _check_vstudio(toolchain) - local vs = _check_vsenv(toolchain) - if vs then - if toolchain:is_global() then - config.set("vs", vs, {force = true, readonly = true}) - end - toolchain:config_set("vs", vs) - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs) - else - cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch()) - end - return vs -end - -function _check_vc_build_tools(toolchain, sdkdir) - local opt = {} - opt.sdkdir = sdkdir - opt.vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") - opt.vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") - - local vcvarsall = find_vstudio.find_build_tools(opt) - if not vcvarsall then - return - end - - local vcvars = vcvarsall[toolchain:arch()] - if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then - toolchain:config_set("vcvars", vcvars) - toolchain:config_set("vcarchs", table.orderkeys(vcvarsall)) - toolchain:config_set("vs_toolset", vcvars.VCToolsVersion) - toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion) - - -- check compiler - local cl = find_tool("cl.exe", {force = true, envs = vcvars}) - if cl then - cprint("checking for Microsoft C/C++ Compiler (%s) ... ${color.success}", toolchain:arch()) - end - return vcvars +function _check_cl(toolchain, vcvars) + local cl = find_tool("cl.exe", {force = true, envs = vcvars}) + if cl then + cprint("checking for Microsoft C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch()) end + return cl end function main(toolchain) @@ -137,22 +46,19 @@ function main(toolchain) if cc == "cl" or cxx == "cl" or mrc == "rc" then local sdkdir = toolchain:sdkdir() if sdkdir then - sdkdir = _check_vc_build_tools(toolchain, sdkdir) + sdkdir = toolchain_utils.check_vc_build_tools(toolchain, sdkdir, _check_cl) end if not sdkdir then - -- find it from packages for _, package in ipairs(toolchain:packages()) do local installdir = package:installdir() if installdir and os.isdir(installdir) then - local result = _check_vc_build_tools(toolchain, installdir) + local result = toolchain_utils.check_vc_build_tools(toolchain, installdir, _check_cl) if result then return result end end end - - -- find it from system - sdkdir = _check_vstudio(toolchain) + sdkdir = toolchain_utils.check_vstudio(toolchain, _check_cl) end return sdkdir end |
