summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2024-05-23 13:05:44 +0800
committerGitHub <[email protected]>2024-05-23 13:05:44 +0800
commit6c1c0397c2c7db8ba78b248f650fb3364c00339a (patch)
treecc1a6b9ec8cb059bf26ed8f48b8ba577ede3c333
parentcfafccfa0bae60f83d27fdda1cb593da9aa0d309 (diff)
parent2322a631b30ca69cd719e0acb1ba4ec735a26b81 (diff)
Merge pull request #5132 from xmake-io/icx
add icx for windows
-rw-r--r--xmake/modules/detect/sdks/find_iccenv.lua6
-rw-r--r--xmake/modules/detect/sdks/find_icxenv.lua93
-rw-r--r--xmake/modules/detect/sdks/find_ifortenv.lua6
-rw-r--r--xmake/toolchains/icc/check.lua84
-rw-r--r--xmake/toolchains/icc/load.lua58
-rw-r--r--xmake/toolchains/icx/check.lua126
-rw-r--r--xmake/toolchains/icx/load.lua113
-rw-r--r--xmake/toolchains/ifort/check.lua84
-rw-r--r--xmake/toolchains/ifort/load.lua58
9 files changed, 600 insertions, 28 deletions
diff --git a/xmake/modules/detect/sdks/find_iccenv.lua b/xmake/modules/detect/sdks/find_iccenv.lua
index 68428f6fb..29a7bbb56 100644
--- a/xmake/modules/detect/sdks/find_iccenv.lua
+++ b/xmake/modules/detect/sdks/find_iccenv.lua
@@ -116,6 +116,12 @@ function _find_intel_on_windows(opt)
"$(env ICPP_COMPILER23)"
}
iclvars_bat = find_file("../../../setvars.bat", paths)
+ if not iclvars_bat then
+ paths = {
+ "$(env ICPP_COMPILER24)"
+ }
+ iclvars_bat = find_file("../../setvars.bat", paths)
+ end
end
if iclvars_bat then
diff --git a/xmake/modules/detect/sdks/find_icxenv.lua b/xmake/modules/detect/sdks/find_icxenv.lua
index 55cd7d56e..4e2293415 100644
--- a/xmake/modules/detect/sdks/find_icxenv.lua
+++ b/xmake/modules/detect/sdks/find_icxenv.lua
@@ -22,11 +22,100 @@
import("lib.detect.find_file")
import("lib.detect.find_tool")
--- find intel c/c++ envirnoment on windows
+-- init icx variables
+local icxvars = {"path",
+ "lib",
+ "libpath",
+ "include",
+ "DevEnvdir",
+ "VSInstallDir",
+ "VCInstallDir",
+ "WindowsSdkDir",
+ "WindowsLibPath",
+ "WindowsSDKVersion",
+ "WindowsSdkBinPath",
+ "UniversalCRTSdkDir",
+ "UCRTVersion"}
+
+-- load icxvars_bat environment variables
+function _load_icxvars(icxvars_bat, arch, opt)
+
+ -- make the genicxvars.bat
+ opt = opt or {}
+ local genicxvars_bat = os.tmpfile() .. "_genicxvars.bat"
+ local genicxvars_dat = os.tmpfile() .. "_genicxvars.txt"
+ local file = io.open(genicxvars_bat, "w")
+ file:print("@echo off")
+ file:print("call \"%s\" -arch %s > nul", icxvars_bat, arch)
+ for idx, var in ipairs(icxvars) do
+ file:print("echo " .. var .. " = %%" .. var .. "%% %s %s", idx == 1 and ">" or ">>", genicxvars_dat)
+ end
+ file:close()
+
+ -- run genicxvars.bat
+ os.run(genicxvars_bat)
+
+ -- load all envirnoment variables
+ local variables = {}
+ for _, line in ipairs((io.readfile(genicxvars_dat) or ""):split("\n")) do
+ 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
+ end
+ end
+ if not variables.path then
+ return
+ end
+
+ -- remove some empty entries
+ for _, name in ipairs(icxvars) do
+ if variables[name] and #variables[name]:trim() == 0 then
+ variables[name] = nil
+ end
+ end
+
+ -- fix bin path for ia32
+ if variables.path and arch == "ia32" then
+ variables.path = variables.path:gsub("windows\\bin\\intel64;", "windows\\bin\\intel64_ia32;")
+ 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
+
+-- find intel llvm c/c++ envirnoment on windows
function _find_intel_on_windows(opt)
+ opt = opt or {}
+
+ -- find icxvars_bat.bat
+ local paths = {"$(env ONEAPI_ROOT)"}
+ local icxvars_bat = find_file("setvars.bat", paths)
+ if not icxvars_bat then
+ paths = {}
+ local keys = winos.registry_keys("HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Intel\\DPCPPSuites\\**\\DPC++")
+ for _, key in ipairs(keys) do
+ table.insert(paths, format("$(reg %s;ProductDir)", key))
+ end
+ icxvars_bat = find_file("../../setvars.bat", paths)
+ end
+ if icxvars_bat then
+ local icxvars_x86 = _load_icxvars(icxvars_bat, "ia32", opt)
+ local icxvars_x64 = _load_icxvars(icxvars_bat, "intel64", opt)
+ return {icxvars_bat = icxvars_bat, icxvars = {x86 = icxvars_x86, x64 = icxvars_x64}}
+ end
end
--- find intel c/c++ envirnoment on linux
+-- find intel llvm c/c++ envirnoment on linux
function _find_intel_on_linux(opt)
-- attempt to find the sdk directory
diff --git a/xmake/modules/detect/sdks/find_ifortenv.lua b/xmake/modules/detect/sdks/find_ifortenv.lua
index b0adceb06..7c9665506 100644
--- a/xmake/modules/detect/sdks/find_ifortenv.lua
+++ b/xmake/modules/detect/sdks/find_ifortenv.lua
@@ -116,6 +116,12 @@ function _find_intel_on_windows(opt)
"$(env IFORT_COMPILER23)"
}
ifortvars_bat = find_file("../../../setvars.bat", paths)
+ if not ifortvars_bat then
+ paths = {
+ "$(env IFORT_COMPILER24)"
+ }
+ ifortvars_bat = find_file("../../setvars.bat", paths)
+ end
end
if ifortvars_bat then
diff --git a/xmake/toolchains/icc/check.lua b/xmake/toolchains/icc/check.lua
index 9dde538f0..9ca496a63 100644
--- a/xmake/toolchains/icc/check.lua
+++ b/xmake/toolchains/icc/check.lua
@@ -22,8 +22,90 @@
import("core.base.option")
import("core.project.config")
import("detect.sdks.find_iccenv")
+import("detect.sdks.find_vstudio")
import("lib.detect.find_tool")
+-- 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({vcvars_ver = 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", {version = true, force = true, paths = paths, envs = 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, 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)
+ toolchain:configs_save()
+ cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs)
+ if cl and cl.version then
+ cprint("checking for LLVM Clang C/C++ Compiler (%s) version ... ${color.success}%s", toolchain:arch(), cl.version)
+ end
+ else
+ cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch())
+ end
+ return vs
+end
+
-- check intel on windows
function _check_intel_on_windows(toolchain)
@@ -44,7 +126,7 @@ function _check_intel_on_windows(toolchain)
cprint("checking for Intel C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
toolchain:config_set("varsall", iclvarsall)
toolchain:configs_save()
- return true
+ return _check_vstudio(toolchain)
end
end
end
diff --git a/xmake/toolchains/icc/load.lua b/xmake/toolchains/icc/load.lua
index e1ceba260..21cb0170b 100644
--- a/xmake/toolchains/icc/load.lua
+++ b/xmake/toolchains/icc/load.lua
@@ -21,9 +21,34 @@
-- imports
import("core.base.option")
import("core.project.config")
+import("detect.sdks.find_vstudio")
+
+-- add the given vs environment
+function _add_vsenv(toolchain, name, curenvs)
+
+ -- get vcvars
+ local vcvars = toolchain:config("vcvars")
+ if not vcvars then
+ return
+ end
+
+ -- get the paths for the vs environment
+ local new = vcvars[name]
+ if new then
+ -- fix case naming conflict for cmake/msbuild between the new msvc envs and current environment, if we are running xmake in vs prompt.
+ -- @see https://github.com/xmake-io/xmake/issues/4751
+ for k, c in pairs(curenvs) do
+ if name:lower() == k:lower() and name ~= k then
+ name = k
+ break
+ end
+ end
+ toolchain:add("runenvs", name, table.unpack(path.splitenv(new)))
+ end
+end
-- add the given icl environment
-function _add_iclenv(toolchain, name)
+function _add_iclenv(toolchain, name, curenvs)
-- get iclvarsall
local iclvarsall = toolchain:config("varsall")
@@ -36,9 +61,17 @@ function _add_iclenv(toolchain, name)
local iclenv = iclvarsall[arch] or {}
-- get the paths for the icl environment
- local env = iclenv[name]
- if env then
- toolchain:add("runenvs", name:upper(), path.splitenv(env))
+ local new = iclenv[name]
+ if new then
+ -- fix case naming conflict for cmake/msbuild between the new msvc envs and current environment, if we are running xmake in vs prompt.
+ -- @see https://github.com/xmake-io/xmake/issues/4751
+ for k, c in pairs(curenvs) do
+ if name:lower() == k:lower() and name ~= k then
+ name = k
+ break
+ end
+ end
+ toolchain:add("runenvs", name, table.unpack(path.splitenv(new)))
end
end
@@ -68,11 +101,18 @@ function _load_intel_on_windows(toolchain)
toolchain:set("toolset", "as", "icc")
end
- -- add icl environments
- _add_iclenv(toolchain, "PATH")
- _add_iclenv(toolchain, "LIB")
- _add_iclenv(toolchain, "INCLUDE")
- _add_iclenv(toolchain, "LIBPATH")
+ -- add vs/icl environments
+ local expect_vars = {"PATH", "LIB", "INCLUDE", "LIBPATH"}
+ local curenvs = os.getenvs()
+ for _, name in ipairs(expect_vars) do
+ _add_vsenv(toolchain, name, curenvs)
+ _add_iclenv(toolchain, name, curenvs)
+ end
+ for _, name in ipairs(find_vstudio.get_vcvars()) do
+ if not table.contains(expect_vars, name:upper()) then
+ _add_vsenv(toolchain, name, curenvs)
+ end
+ end
end
-- load intel on linux
diff --git a/xmake/toolchains/icx/check.lua b/xmake/toolchains/icx/check.lua
index 4d627915b..c65e3ff81 100644
--- a/xmake/toolchains/icx/check.lua
+++ b/xmake/toolchains/icx/check.lua
@@ -22,19 +22,128 @@
import("core.base.option")
import("core.project.config")
import("detect.sdks.find_icxenv")
+import("detect.sdks.find_vstudio")
import("lib.detect.find_tool")
--- main entry
-function main(toolchain)
+-- 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({vcvars_ver = 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", {version = true, force = true, paths = paths, envs = 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, 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)
+ toolchain:configs_save()
+ cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs)
+ if cl and cl.version then
+ cprint("checking for LLVM Clang C/C++ Compiler (%s) version ... ${color.success}%s", toolchain:arch(), cl.version)
+ end
+ else
+ cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch())
+ end
+ return vs
+end
+
+-- check intel on windows
+function _check_intel_on_windows(toolchain)
+
+ -- have been checked?
+ local varsall = toolchain:config("varsall")
+ if varsall then
+ return true
+ end
+
+ -- find intel llvm c/c++ compiler environment
+ local icxenv = find_icxenv()
+ if icxenv and icxenv.icxvars then
+ local icxvarsall = icxenv.icxvars
+ local icxenv = icxvarsall[toolchain:arch()]
+ if icxenv and icxenv.PATH and icxenv.INCLUDE and icxenv.LIB then
+ local tool = find_tool("icx.exe", {force = true, envs = icxenv, version = true})
+ if tool then
+ cprint("checking for Intel LLVM C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
+ toolchain:config_set("varsall", icxvarsall)
+ toolchain:configs_save()
+ return _check_vstudio(toolchain)
+ end
+ end
+ end
+end
+
+-- check intel on linux
+function _check_intel_on_linux(toolchain)
local icxenv = toolchain:config("icxenv")
if icxenv then
return true
end
icxenv = find_icxenv()
if icxenv then
- local tool = find_tool("icx", {force = true, paths = icxenv.bindir})
+ local ldname = is_host("macosx") and "DYLD_LIBRARY_PATH" or "LD_LIBRARY_PATH"
+ local tool = find_tool("icx", {force = true, envs = {[ldname] = icxenv.libdir}, paths = icxenv.bindir})
if tool then
- cprint("checking for Intel LLVM C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
+ cprint("checking for Intel C/C++ Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
toolchain:config_set("icxenv", icxenv)
toolchain:config_set("bindir", icxenv.bindir)
toolchain:configs_save()
@@ -44,3 +153,12 @@ function main(toolchain)
end
end
+-- main entry
+function main(toolchain)
+ if is_host("windows") then
+ return _check_intel_on_windows(toolchain)
+ else
+ return _check_intel_on_linux(toolchain)
+ end
+end
+
diff --git a/xmake/toolchains/icx/load.lua b/xmake/toolchains/icx/load.lua
index 4608c15ae..0e7d2a685 100644
--- a/xmake/toolchains/icx/load.lua
+++ b/xmake/toolchains/icx/load.lua
@@ -21,9 +21,102 @@
-- imports
import("core.base.option")
import("core.project.config")
+import("detect.sdks.find_vstudio")
--- main entry
-function main(toolchain)
+-- add the given vs environment
+function _add_vsenv(toolchain, name, curenvs)
+
+ -- get vcvars
+ local vcvars = toolchain:config("vcvars")
+ if not vcvars then
+ return
+ end
+
+ -- get the paths for the vs environment
+ local new = vcvars[name]
+ if new then
+ -- fix case naming conflict for cmake/msbuild between the new msvc envs and current environment, if we are running xmake in vs prompt.
+ -- @see https://github.com/xmake-io/xmake/issues/4751
+ for k, c in pairs(curenvs) do
+ if name:lower() == k:lower() and name ~= k then
+ name = k
+ break
+ end
+ end
+ toolchain:add("runenvs", name, table.unpack(path.splitenv(new)))
+ end
+end
+
+-- add the given icx environment
+function _add_icxenv(toolchain, name, curenvs)
+
+ -- get icxvarsall
+ local icxvarsall = toolchain:config("varsall")
+ if not icxvarsall then
+ return
+ end
+
+ -- get icx environment for the current arch
+ local arch = toolchain:arch()
+ local icxenv = icxvarsall[arch] or {}
+
+ -- get the paths for the icx environment
+ local new = icxenv[name]
+ if new then
+ -- fix case naming conflict for cmake/msbuild between the new msvc envs and current environment, if we are running xmake in vs prompt.
+ -- @see https://github.com/xmake-io/xmake/issues/4751
+ for k, c in pairs(curenvs) do
+ if name:lower() == k:lower() and name ~= k then
+ name = k
+ break
+ end
+ end
+ toolchain:add("runenvs", name, table.unpack(path.splitenv(new)))
+ end
+end
+
+-- load intel on windows
+function _load_intel_on_windows(toolchain)
+
+ -- set toolset
+ if toolchain:is_plat("windows") then
+ toolchain:set("toolset", "cc", "icx.exe")
+ toolchain:set("toolset", "cxx", "icx.exe")
+ toolchain:set("toolset", "mrc", "rc.exe")
+ if toolchain:is_arch("x64") then
+ toolchain:set("toolset", "as", "ml64.exe")
+ else
+ toolchain:set("toolset", "as", "ml.exe")
+ end
+ toolchain:set("toolset", "ld", "link.exe")
+ toolchain:set("toolset", "sh", "link.exe")
+ toolchain:set("toolset", "ar", "link.exe")
+ else
+ toolchain:set("toolset", "cc", "icx")
+ toolchain:set("toolset", "cxx", "icpx", "icx")
+ toolchain:set("toolset", "ld", "icpx", "icx")
+ toolchain:set("toolset", "sh", "icpx", "icx")
+ toolchain:set("toolset", "ar", "ar")
+ toolchain:set("toolset", "strip", "strip")
+ toolchain:set("toolset", "as", "icx")
+ end
+
+ -- add vs/icx environments
+ local expect_vars = {"PATH", "LIB", "INCLUDE", "LIBPATH"}
+ local curenvs = os.getenvs()
+ for _, name in ipairs(expect_vars) do
+ _add_vsenv(toolchain, name, curenvs)
+ _add_icxenv(toolchain, name, curenvs)
+ end
+ for _, name in ipairs(find_vstudio.get_vcvars()) do
+ if not table.contains(expect_vars, name:upper()) then
+ _add_vsenv(toolchain, name, curenvs)
+ end
+ end
+end
+
+-- load intel on linux
+function _load_intel_on_linux(toolchain)
-- set toolset
toolchain:set("toolset", "cc", "icx")
@@ -47,5 +140,21 @@ function main(toolchain)
toolchain:add("ldflags", march)
toolchain:add("shflags", march)
end
+
+ -- get icx environments
+ local icxenv = toolchain:config("icxenv")
+ if icxenv then
+ local ldname = is_host("macosx") and "DYLD_LIBRARY_PATH" or "LD_LIBRARY_PATH"
+ toolchain:add("runenvs", ldname, icxenv.libdir)
+ end
+end
+
+-- main entry
+function main(toolchain)
+ if is_host("windows") then
+ return _load_intel_on_windows(toolchain)
+ else
+ return _load_intel_on_linux(toolchain)
+ end
end
diff --git a/xmake/toolchains/ifort/check.lua b/xmake/toolchains/ifort/check.lua
index 285f5c86c..8ba2a3881 100644
--- a/xmake/toolchains/ifort/check.lua
+++ b/xmake/toolchains/ifort/check.lua
@@ -22,8 +22,90 @@
import("core.base.option")
import("core.project.config")
import("detect.sdks.find_ifortenv")
+import("detect.sdks.find_vstudio")
import("lib.detect.find_tool")
+-- 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({vcvars_ver = 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", {version = true, force = true, paths = paths, envs = 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, 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)
+ toolchain:configs_save()
+ cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs)
+ if cl and cl.version then
+ cprint("checking for LLVM Clang C/C++ Compiler (%s) version ... ${color.success}%s", toolchain:arch(), cl.version)
+ end
+ else
+ cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch())
+ end
+ return vs
+end
+
-- check intel on windows
function _check_intel_on_windows(toolchain)
@@ -44,7 +126,7 @@ function _check_intel_on_windows(toolchain)
cprint("checking for Intel Fortran Compiler (%s) ... ${color.success}${text.success}", toolchain:arch())
toolchain:config_set("varsall", ifortvarsall)
toolchain:configs_save()
- return true
+ return _check_vstudio(toolchain)
end
end
end
diff --git a/xmake/toolchains/ifort/load.lua b/xmake/toolchains/ifort/load.lua
index 2cb212a57..2dadba240 100644
--- a/xmake/toolchains/ifort/load.lua
+++ b/xmake/toolchains/ifort/load.lua
@@ -21,9 +21,34 @@
-- imports
import("core.base.option")
import("core.project.config")
+import("detect.sdks.find_vstudio")
+
+-- add the given vs environment
+function _add_vsenv(toolchain, name, curenvs)
+
+ -- get vcvars
+ local vcvars = toolchain:config("vcvars")
+ if not vcvars then
+ return
+ end
+
+ -- get the paths for the vs environment
+ local new = vcvars[name]
+ if new then
+ -- fix case naming conflict for cmake/msbuild between the new msvc envs and current environment, if we are running xmake in vs prompt.
+ -- @see https://github.com/xmake-io/xmake/issues/4751
+ for k, c in pairs(curenvs) do
+ if name:lower() == k:lower() and name ~= k then
+ name = k
+ break
+ end
+ end
+ toolchain:add("runenvs", name, table.unpack(path.splitenv(new)))
+ end
+end
-- add the given ifort environment
-function _add_ifortenv(toolchain, name)
+function _add_ifortenv(toolchain, name, curenvs)
-- get ifortvarsall
local ifortvarsall = toolchain:config("varsall")
@@ -36,9 +61,17 @@ function _add_ifortenv(toolchain, name)
local ifortenv = ifortvarsall[arch] or {}
-- get the paths for the ifort environment
- local env = ifortenv[name]
- if env then
- toolchain:add("runenvs", name:upper(), path.splitenv(env))
+ local new = ifortenv[name]
+ if new then
+ -- fix case naming conflict for cmake/msbuild between the new msvc envs and current environment, if we are running xmake in vs prompt.
+ -- @see https://github.com/xmake-io/xmake/issues/4751
+ for k, c in pairs(curenvs) do
+ if name:lower() == k:lower() and name ~= k then
+ name = k
+ break
+ end
+ end
+ toolchain:add("runenvs", name, table.unpack(path.splitenv(new)))
end
end
@@ -57,11 +90,18 @@ function _load_intel_on_windows(toolchain)
toolchain:set("toolset", "fcsh", "ifort.exe")
toolchain:set("toolset", "ar", "link.exe")
- -- add ifort environments
- _add_ifortenv(toolchain, "PATH")
- _add_ifortenv(toolchain, "LIB")
- _add_ifortenv(toolchain, "INCLUDE")
- _add_ifortenv(toolchain, "LIBPATH")
+ -- add ifort and vs environments
+ local expect_vars = {"PATH", "LIB", "INCLUDE", "LIBPATH"}
+ local curenvs = os.getenvs()
+ for _, name in ipairs(expect_vars) do
+ _add_vsenv(toolchain, name, curenvs)
+ _add_ifortenv(toolchain, name, curenvs)
+ end
+ for _, name in ipairs(find_vstudio.get_vcvars()) do
+ if not table.contains(expect_vars, name:upper()) then
+ _add_vsenv(toolchain, name, curenvs)
+ end
+ end
end
-- load intel on linux