summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstar9029 <[email protected]>2024-11-14 18:33:37 +0800
committerstar9029 <[email protected]>2024-11-14 18:33:37 +0800
commitef7e37c8833d59455a7d30d7b7b244e3e230ea1d (patch)
tree81814b4617c37c687cb616810dde899f86727e4c
parent2c9034a9c7b6e567ba6f23089323d4908519d547 (diff)
Support custom vc build tools
-rw-r--r--xmake/modules/detect/sdks/find_vstudio.lua56
-rw-r--r--xmake/platforms/windows/xmake.lua2
-rw-r--r--xmake/plugins/project/clang/compile_commands.lua19
-rw-r--r--xmake/toolchains/msvc/check.lua29
4 files changed, 96 insertions, 10 deletions
diff --git a/xmake/modules/detect/sdks/find_vstudio.lua b/xmake/modules/detect/sdks/find_vstudio.lua
index b58e9cb91..b0a085547 100644
--- a/xmake/modules/detect/sdks/find_vstudio.lua
+++ b/xmake/modules/detect/sdks/find_vstudio.lua
@@ -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
+ local file = io.readfile(opt.bat)
+ if file then
+ local variables = {}
+ for line in file:gmatch("[^\r\n]+") do
+ local key, value = line:match("set%s+(.-)=(.*)")
+ 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")
+ end
+end
+
-- load vcvarsall environment variables
function _load_vcvarsall(vcvarsall, vsver, arch, opt)
opt = opt or {}
diff --git a/xmake/platforms/windows/xmake.lua b/xmake/platforms/windows/xmake.lua
index 2b1bf4014..fdec2cd68 100644
--- a/xmake/platforms/windows/xmake.lua
+++ b/xmake/platforms/windows/xmake.lua
@@ -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" }
, {category = "Cuda SDK Configuration" }
, {nil, "cuda", "kv", "auto", "The Cuda SDK Directory" }
, {category = "Qt SDK Configuration" }
diff --git a/xmake/plugins/project/clang/compile_commands.lua b/xmake/plugins/project/clang/compile_commands.lua
index fa32ea7ca..9996b4ed5 100644
--- a/xmake/plugins/project/clang/compile_commands.lua
+++ b/xmake/plugins/project/clang/compile_commands.lua
@@ -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
diff --git a/xmake/toolchains/msvc/check.lua b/xmake/toolchains/msvc/check.lua
index 6d5772733..92e4d18ba 100644
--- a/xmake/toolchains/msvc/check.lua
+++ b/xmake/toolchains/msvc/check.lua
@@ -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)
@@ -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