diff options
| author | star9029 <[email protected]> | 2024-11-14 18:33:37 +0800 |
|---|---|---|
| committer | star9029 <[email protected]> | 2024-11-14 18:33:37 +0800 |
| commit | ef7e37c8833d59455a7d30d7b7b244e3e230ea1d (patch) | |
| tree | 81814b4617c37c687cb616810dde899f86727e4c | |
| parent | 2c9034a9c7b6e567ba6f23089323d4908519d547 (diff) | |
Support custom vc build tools
| -rw-r--r-- | xmake/modules/detect/sdks/find_vstudio.lua | 56 | ||||
| -rw-r--r-- | xmake/platforms/windows/xmake.lua | 2 | ||||
| -rw-r--r-- | xmake/plugins/project/clang/compile_commands.lua | 19 | ||||
| -rw-r--r-- | xmake/toolchains/msvc/check.lua | 29 |
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 |
