Skip to content
New issue

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

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

Already on GitHub? # to your account

Support custom vc build tools #5823

Draft
wants to merge 2 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改成 opt.devcmd

local file = io.readfile(opt.bat)
if file then
local variables = {}
for line in file:gmatch("[^\r\n]+") do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file:lines()

local key, value = line:match("set%s+(.-)=(.*)")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为啥不走运行捕获 envs,至少稳定可靠。

local outdata = try {function () return os.iorun(genvcvars_bat) end}

直接语法解析 set,不太稳吧。如果 set 是在 if 分支里呢,怎么判断取到的当前有效值

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")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没用到的代码 暂时去掉

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" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

改成 vs_devcmd 。。统一用 vs_ 前缀

, {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