diff options
| -rw-r--r-- | xmake/modules/detect/sdks/find_vstudio.lua | 144 | ||||
| -rw-r--r-- | xmake/platforms/windows/xmake.lua | 2 | ||||
| -rw-r--r-- | xmake/toolchains/msvc/check.lua | 24 |
3 files changed, 115 insertions, 55 deletions
diff --git a/xmake/modules/detect/sdks/find_vstudio.lua b/xmake/modules/detect/sdks/find_vstudio.lua index b0a085547..9ecf1a20e 100644 --- a/xmake/modules/detect/sdks/find_vstudio.lua +++ b/xmake/modules/detect/sdks/find_vstudio.lua @@ -97,60 +97,116 @@ function get_vcvars() return realvcvars end -function load_custom_vcenv(opt) +function find_build_tools(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 + local sdkdir = opt.sdkdir + if not sdkdir or not os.isdir(sdkdir) then + return + end + + local variables = {} + local VCToolsVersion + local VCToolsVersionDirs = os.dirs(path.join(sdkdir, "VC/Tools/MSVC/*")) + for _, dir in ipairs(VCToolsVersionDirs) do + local ver = path.filename(dir) + if ver == opt.vs_toolset then + VCToolsVersion = ver + break 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 + if not VCToolsVersion and #VCToolsVersionDirs ~= 0 then + VCToolsVersion = path.filename(VCToolsVersionDirs[1]) + else + return + end + variables.VCToolsVersion = VCToolsVersion + variables.VCToolsInstallDir = path.join(sdkdir, "VC/Tools/MSVC", VCToolsVersion) + + local WindowsSDKVersion + local WindowsSDKVersionsDirs = os.dirs(path.join(sdkdir, "Windows Kits/10/bin/*")) + for _, dir in ipairs(WindowsSDKVersionsDirs) do + local ver = path.filename(dir) + if ver == opt.vs_sdkver then + WindowsSDKVersion = ver + break end + end + + if not WindowsSDKVersion and #WindowsSDKVersionsDirs ~= 0 then + WindowsSDKVersion = path.filename(WindowsSDKVersionsDirs[1]) + else + return + end + variables.WindowsSDKVersion = WindowsSDKVersion + variables.WindowsSDKDir = path.join(sdkdir, "Windows Kits/10") + + local includedirs = { + path.join(variables.VCToolsInstallDir, "include"), + path.join(variables.WindowsSDKDir, "Include", WindowsSDKVersion, "ucrt"), + path.join(variables.WindowsSDKDir, "Include", WindowsSDKVersion, "shared"), + path.join(variables.WindowsSDKDir, "Include", WindowsSDKVersion, "um"), + path.join(variables.WindowsSDKDir, "Include", WindowsSDKVersion, "winrt"), + path.join(variables.WindowsSDKDir, "Include", WindowsSDKVersion, "cppwinrt"), + } + + local linkdirs = { + path.join(variables.VCToolsInstallDir, "lib"), + path.join(variables.WindowsSDKDir, "Lib", WindowsSDKVersion, "ucrt"), + path.join(variables.WindowsSDKDir, "Lib", WindowsSDKVersion, "um"), + } + + local archs = { + "x86", + "x64", + "arm", + "arm64", + } - if not VCToolsInstallDir and #VCToolsInstallDirs ~= 0 then - VCToolsInstallDir = VCToolsInstallDirs[1] + local vcvars = { + BUILD_TOOLS_ROOT = sdkdir, + INCLUDE = path.joinenv(includedirs), + WindowsSDKDir = variables.WindowsSDKDir, + WindowsSDKVersion = WindowsSDKVersion, + VCToolsInstallDir = variables.VCToolsInstallDir, + VSCMD_ARG_HOST_ARCH = "x64", + } + + local vcvarsall = {} + for _, target_arch in ipairs(archs) do + local lib = {} + for _, lib_dir in ipairs(linkdirs) do + local dir = path.join(lib_dir, target_arch) + if os.isdir(dir) then + table.insert(lib, dir) + end end - local WindowsSDKDir = path.join(vs_build_tools, "Windows Kits/10") + if #lib ~= 0 then + local host_dir = "Host" .. vcvars.VSCMD_ARG_HOST_ARCH + local buidl_tools_bin = { + path.join(vcvars.VCToolsInstallDir, "bin", host_dir, target_arch), + path.join(vcvars.WindowsSDKDir, "bin", WindowsSDKVersion), + path.join(vcvars.WindowsSDKDir, "bin", WindowsSDKVersion, "ucrt"), + } + + vcvars.VSCMD_ARG_TGT_ARCH = target_arch + vcvars.LIB = path.joinenv(lib) + vcvars.BUILD_TOOLS_BIN = path.joinenv(buidl_tools_bin) + + local PATH = buidl_tools_bin + table.join2(PATH, path.splitenv(os.getenv("PATH"))) + vcvars.PATH = path.joinenv(PATH) + + vcvarsall[target_arch] = vcvars + end end + -- for _, host_arch in ipairs(archs) do + -- local host_dir = "Host" .. arch + -- end + + return vcvarsall end -- load vcvarsall environment variables diff --git a/xmake/platforms/windows/xmake.lua b/xmake/platforms/windows/xmake.lua index fdec2cd68..2b1bf4014 100644 --- a/xmake/platforms/windows/xmake.lua +++ b/xmake/platforms/windows/xmake.lua @@ -43,8 +43,6 @@ 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/toolchains/msvc/check.lua b/xmake/toolchains/msvc/check.lua index 92e4d18ba..37eb45255 100644 --- a/xmake/toolchains/msvc/check.lua +++ b/xmake/toolchains/msvc/check.lua @@ -100,11 +100,17 @@ function _check_vstudio(toolchain) return vs end --- check the visual studio -function _check_vc_build_tools(toolchain, bat) +function _check_vc_build_tools(toolchain, sdkdir) local opt = {} - opt.bat = bat - local vcvarsall = find_vstudio.load_custom_vcenv(opt) + opt.sdkdir = sdkdir + opt.vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset") + opt.vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver") + + local vcvarsall = find_vstudio.find_build_tools(opt) + if not vcvarsall then + return + end + local vcvars = vcvarsall[toolchain:arch()] if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then -- save vcvars @@ -125,8 +131,8 @@ end -- main entry function main(toolchain) - -- only for windows - if not is_host("windows") then + -- only for windows or linux (msvc-wine) + if not is_host("windows", "linux") then return end @@ -135,9 +141,9 @@ 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 - local vc_bat = option.get("vc_bat") - if vc_bat then - return _check_vc_build_tools(toolchain, vc_bat) + local sdkdir = option.get("sdk") or toolchain:config("sdk") or config.get("sdk") + if sdkdir then + return _check_vc_build_tools(toolchain, sdkdir) else return _check_vstudio(toolchain) end |
