Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom vc build tools #5823

Merged
merged 13 commits into from
Nov 20, 2024
56 changes: 56 additions & 0 deletions xmake/modules/detect/sdks/find_vstudio.lua
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,62 @@ function get_vcvars()
return realvcvars
end

function load_custom_vcenv(opt)
opt = opt or {}

if opt.bat and os.isfile(opt.bat) then
star-hengxing marked this conversation as resolved.
Show resolved Hide resolved
local file = io.readfile(opt.bat)
if file then
local variables = {}
for line in file:gmatch("[^\r\n]+") do
star-hengxing marked this conversation as resolved.
Show resolved Hide resolved
local key, value = line:match("set%s+(.-)=(.*)")
star-hengxing marked this conversation as resolved.
Show resolved Hide resolved
if key and value then
value = value:gsub("%%%{(.-)%}", variables)
if value == "%~dp0" then
value = path.directory(opt.bat) .. "\\"
else
for match in value:gmatch("%%(.-)%%") do
value = value:gsub("%%" .. match .. "%%", variables[match] or "")
end
end
variables[key] = value
end
end

for _, name in ipairs(vcvars) do
if variables[name] and #variables[name]:trim() == 0 then
variables[name] = nil
end
end

local vcvarsall = {}
if not variables["VCToolsVersion"] then
variables.VCToolsVersion = path.filename(variables["VCToolsInstallDir"])
end
vcvarsall[variables["VSCMD_ARG_TGT_ARCH"]] = variables
return vcvarsall
end
end

-- TODO: custom search
local vs_build_tools = opt.vs_build_tools
if vs_build_tools then
local VCToolsInstallDir
local VCToolsInstallDirs = os.dirs(path.join(vs_build_tools, "VC/Tools/MSVC/*"))
for _, ver in ipairs(VCToolsInstallDirs) do
if ver == opt.vs_toolset then
VCToolsInstallDir = ver
end
end

if not VCToolsInstallDir and #VCToolsInstallDirs ~= 0 then
VCToolsInstallDir = VCToolsInstallDirs[1]
end

local WindowsSDKDir = path.join(vs_build_tools, "Windows Kits/10")
star-hengxing marked this conversation as resolved.
Show resolved Hide resolved
end
end

-- load vcvarsall environment variables
function _load_vcvarsall(vcvarsall, vsver, arch, opt)
opt = opt or {}
Expand Down
2 changes: 2 additions & 0 deletions xmake/platforms/windows/xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ platform("windows")
, " e.g. --vs_sdkver=10.0.15063.0" }
, {nil, "vs_runtime", "kv", nil, "The Runtime library of Visual Studio (deprecated, please use --runtimes)"
, values = {"MT", "MTd", "MD", "MDd"} }
, {nil, "vc_bat", "kv", nil, "The BuildTools bat file"
, " e.g. --vc_bat=C:/BuildTools/devcmd.bat" }
star-hengxing marked this conversation as resolved.
Show resolved Hide resolved
, {category = "Cuda SDK Configuration" }
, {nil, "cuda", "kv", "auto", "The Cuda SDK Directory" }
, {category = "Qt SDK Configuration" }
Expand Down
19 changes: 10 additions & 9 deletions xmake/plugins/project/clang/compile_commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,27 +60,28 @@ function _get_windows_sdk_arguments(target)
local args = {}
local msvc = target:toolchain("msvc")
if msvc then
local includedirs = {}
local envs = msvc:runenvs()
local WindowsSdkDir = envs.WindowsSdkDir
local WindowsSDKVersion = envs.WindowsSDKVersion
local VCToolsInstallDir = envs.VCToolsInstallDir
if WindowsSdkDir and WindowsSDKVersion then
local includedirs = os.dirs(path.join(WindowsSdkDir, "Include", envs.WindowsSDKVersion, "*"))
table.join2(includedirs, os.dirs(path.join(WindowsSdkDir, "Include", envs.WindowsSDKVersion, "*")))
for _, tool in ipairs({"atlmfc", "diasdk"}) do
local tool_dir = path.join(WindowsSdkDir, tool, "include")
if os.isdir(tool_dir) then
table.insert(includedirs, tool_dir)
end
end
end

if VCToolsInstallDir then
table.insert(includedirs, path.join(VCToolsInstallDir, "include"))
end
local VCToolsInstallDir = envs.VCToolsInstallDir
if VCToolsInstallDir then
table.insert(includedirs, path.join(VCToolsInstallDir, "include"))
end

for _, dir in ipairs(includedirs) do
table.insert(args, "-imsvc")
table.insert(args, dir)
end
for _, dir in ipairs(includedirs) do
table.insert(args, "-imsvc")
table.insert(args, dir)
end
end
return args
Expand Down
29 changes: 28 additions & 1 deletion xmake/toolchains/msvc/check.lua
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,28 @@ function _check_vstudio(toolchain)
return vs
end

-- check the visual studio
function _check_vc_build_tools(toolchain, bat)
local opt = {}
opt.bat = bat
local vcvarsall = find_vstudio.load_custom_vcenv(opt)
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 cl = find_tool("cl.exe", {version = true, force = true, envs = vcvars})
if cl and cl.version then
cprint("checking for Microsoft C/C++ Compiler (%s) version ... ${color.success}%s", toolchain:arch(), cl.version)
end
return vcvars
end
end

-- main entry
function main(toolchain)

Expand All @@ -113,7 +135,12 @@ function main(toolchain)
local cxx = path.basename(config.get("cxx") or "cl"):lower()
local mrc = path.basename(config.get("mrc") or "rc"):lower()
if cc == "cl" or cxx == "cl" or mrc == "rc" then
return _check_vstudio(toolchain)
local vc_bat = option.get("vc_bat")
if vc_bat then
return _check_vc_build_tools(toolchain, vc_bat)
else
return _check_vstudio(toolchain)
end
end
end

Loading