Skip to content

Commit

Permalink
Merge pull request #5132 from xmake-io/icx
Browse files Browse the repository at this point in the history
add icx for windows
  • Loading branch information
waruqi committed May 23, 2024
2 parents cfafccf + 2322a63 commit 6c1c039
Show file tree
Hide file tree
Showing 9 changed files with 600 additions and 28 deletions.
6 changes: 6 additions & 0 deletions xmake/modules/detect/sdks/find_iccenv.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
93 changes: 91 additions & 2 deletions xmake/modules/detect/sdks/find_icxenv.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions xmake/modules/detect/sdks/find_ifortenv.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
84 changes: 83 additions & 1 deletion xmake/toolchains/icc/check.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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
Expand Down
58 changes: 49 additions & 9 deletions xmake/toolchains/icc/load.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 6c1c039

Please sign in to comment.