diff options
| author | ruki <[email protected]> | 2017-06-01 14:28:16 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-06-01 14:28:16 +0800 |
| commit | 8ed5f9977095c45dbca9d4c383c6998077b3176a (patch) | |
| tree | 65786c6d0267b22a156495c29b4daf92fa01fdef | |
| parent | 9fe0d2ac3ef006dacd8596ee9d3254e687c0240f (diff) | |
fix filter and improve check vs env on windows
| -rw-r--r-- | xmake/core/base/filter.lua | 35 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/val.lua | 19 | ||||
| -rw-r--r-- | xmake/modules/detect/sdk/find_vstudio.lua | 55 | ||||
| -rw-r--r-- | xmake/platforms/windows/check.lua | 173 | ||||
| -rw-r--r-- | xmake/platforms/windows/environment.lua | 15 |
5 files changed, 121 insertions, 176 deletions
diff --git a/xmake/core/base/filter.lua b/xmake/core/base/filter.lua index 27442cf7c..f9744bf61 100644 --- a/xmake/core/base/filter.lua +++ b/xmake/core/base/filter.lua @@ -98,7 +98,7 @@ function filter:register(name, handler) end -- get variable value -function filter:get(variable, handler) +function filter:get(variable) -- check assert(variable) @@ -120,20 +120,16 @@ function filter:get(variable, handler) -- handler it local result = nil - if handler then + for name, handler in pairs(self._HANDLERS) do result = handler(variable) - else - for name, handler in pairs(self._HANDLERS) do - result = handler(variable) - if result then - break - end + if result then + break end end -- TODO need improve -- handle mode - if mode then + if mode and result then if mode == "upper" then result = result:upper() elseif mode == "lower" then @@ -159,23 +155,10 @@ function filter:handle(value) -- check assert(type(value) == "string") - -- filter value for all handlers - local count = 0 - for name, handler in pairs(self._HANDLERS) do - - -- filter the builtin variables - value, count = value:gsub("%$%((.-)%)", function (variable) - return self:get(variable, handler) or "" - end) - - -- end? - if count == 0 then - break - end - end - - -- return old value - return value + -- filter the builtin variables + return (value:gsub("%$%((.-)%)", function (variable) + return self:get(variable) or "" + end)) end -- return module: filter diff --git a/xmake/core/sandbox/modules/val.lua b/xmake/core/sandbox/modules/val.lua index fe02addae..a93eed5b5 100644 --- a/xmake/core/sandbox/modules/val.lua +++ b/xmake/core/sandbox/modules/val.lua @@ -19,7 +19,7 @@ -- Copyright (C) 2015 - 2017, TBOOX Open Source Group. -- -- @author ruki --- @file get.lua +-- @file val.lua -- -- load modules @@ -29,12 +29,12 @@ local sandbox = require("sandbox/sandbox") -- -- .e.g -- --- get("host") --- get("env PATH") --- get("shell echo hello xmake!") --- get("reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name") +-- local value = val("host") +-- local value = val("env PATH") +-- local value = val("shell echo hello xmake!") +-- local value = val("reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\XXXX;Name") -- -function get(name) +function val(name) -- get the current sandbox instance local instance = sandbox.instance() @@ -43,10 +43,13 @@ function get(name) -- get filter from the current sandbox local filter = instance:filter() if filter then - return filter:get(name) + return filter:get(name) or "" end + + -- no this variable + return "" end -- return module -return get +return val diff --git a/xmake/modules/detect/sdk/find_vstudio.lua b/xmake/modules/detect/sdk/find_vstudio.lua index 1e2c88f1a..1a06d1e90 100644 --- a/xmake/modules/detect/sdk/find_vstudio.lua +++ b/xmake/modules/detect/sdk/find_vstudio.lua @@ -25,10 +25,53 @@ -- imports import("lib.detect.find_file") +-- load vcvarsall environment variables +function _load_vcvarsall(vcvarsall, arch) + + -- make the genvcvars.bat + local genvcvars_bat = os.tmpfile() .. "_genvcvars.bat" + local genvcvars_dat = os.tmpfile() .. "_genvcvars.dat" + local file = io.open(genvcvars_bat, "w") + file:print("@echo off") + file:print("call \"%s\" %s > nul", vcvarsall, arch) + file:print("echo { > %s", genvcvars_dat) + file:print("echo path = \"%%path%%\" >> %s", genvcvars_dat) + file:print("echo , lib = \"%%lib%%\" >> %s", genvcvars_dat) + file:print("echo , libpath = \"%%libpath%%\" >> %s", genvcvars_dat) + file:print("echo , include = \"%%include%%\" >> %s", genvcvars_dat) + file:print("echo , devenvdir = \"%%devenvdir%%\" >> %s", genvcvars_dat) + file:print("echo , vsinstalldir = \"%%vsinstalldir%%\" >> %s", genvcvars_dat) + file:print("echo , vcinstalldir = \"%%vcinstalldir%%\" >> %s", genvcvars_dat) + file:print("echo } >> %s", genvcvars_dat) + file:close() + + -- run genvcvars.bat + os.run(genvcvars_bat) + + -- replace "\" => "\\" + io.gsub(genvcvars_dat, "\\", "\\\\") + + -- load all envirnoment variables + local variables = io.load(genvcvars_dat) + if not variables then + return + end + + -- remove some empty entries + for _, name in ipairs({"path", "lib", "libpath", "include", "devenvdir", "vsinstalldir", "vcinstalldir"}) do + if variables[name] and #variables[name]:trim() == 0 then + variables[name] = nil + end + end + + -- ok + return variables +end + -- find vstudio environment -- --- @return { 2008 = {version = "9.0", vcvarsall = "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"} --- , 2017 = {version = "15.0", vcvarsall = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat"}} +-- @return { 2008 = {version = "9.0", vcvarsall = {x86 = {path = .., lib = .., include = ..}}} +-- , 2017 = {version = "15.0", vcvarsall = {x64 = {path = .., lib = ..}}}} -- function main() @@ -78,7 +121,13 @@ function main() -- found? if vcvarsall then - results[vsvers[version]] = {version = version, vcvarsall = vcvarsall} + + -- load vcvarsall + local vcvarsall_x86 = _load_vcvarsall(vcvarsall, "x86") + local vcvarsall_x64 = _load_vcvarsall(vcvarsall, "x64") + + -- save results + results[vsvers[version]] = {version = version, vcvarsall = {x86 = vcvarsall_x86, x64 = vcvarsall_x64}} end end diff --git a/xmake/platforms/windows/check.lua b/xmake/platforms/windows/check.lua index 8a442a0fe..f74fbb42e 100644 --- a/xmake/platforms/windows/check.lua +++ b/xmake/platforms/windows/check.lua @@ -27,101 +27,54 @@ import("core.tool.tool") import("core.base.option") import("platforms.checker", {rootdir = os.programdir()}) import("environment") +import("detect.sdk.find_vstudio") --- attempt to apply vs environment -function _apply_vsenv(config, vs) +-- attempt to check vs environment +function _check_vsenv(config) - -- version => envname - local version2envname = - { - ["2015"] = "VS140COMNTOOLS" - , ["2013"] = "VS120COMNTOOLS" - , ["2012"] = "VS110COMNTOOLS" - , ["2010"] = "VS100COMNTOOLS" - , ["2008"] = "VS90COMNTOOLS" - , ["2005"] = "VS80COMNTOOLS" - , ["2003"] = "VS71COMNTOOLS" - , ["7.0"] = "VS70COMNTOOLS" - , ["6.0"] = "VS60COMNTOOLS" - , ["5.0"] = "VS50COMNTOOLS" - , ["4.2"] = "VS42COMNTOOLS" - } - - -- get the envname - local envname = version2envname[vs] - - -- attempt to get vcvarsall.bat from environment variables - local vcvarsall = nil - if envname then - local envalue = os.getenv(envname) - if envalue then - vcvarsall = format("%s\\..\\..\\VC\\vcvarsall.bat", envalue) - end + -- have been checked? + local vs = config.get("vs") + if vs and config.get("__vcvarsall") then + return vs end - -- attempt to get vcvarsall.bat from the full pathes - if vcvarsall == nil or not os.isfile(vcvarsall) then - vcvarsall = nil - for _, driver in ipairs({'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'X', 'Y', 'Z'}) do - for _, programdir in ipairs({"Program Files (x86)", "Program Files"}) do - for _, kind in ipairs({"Community", "Professional", "Enterprise"}) do - local filepath = format("%s:\\%s\\Microsoft Visual Studio\\%s\\%s\\VC\\Auxiliary\\Build\\vcvarsall.bat", driver, programdir, vs, kind) - if os.isfile(filepath) then - vcvarsall = filepath - break - end - end - if vcvarsall then - break - end - end - if vcvarsall then - break + -- find vstudio + local vstudio = find_vstudio() + if vstudio then + + -- make order vsver + local vsvers = {} + for vsver, _ in pairs(vstudio) do + if not vs or vs ~= vsver then + table.insert(vsvers, vsver) end end - end - - -- vcvarsall.bat not found - if vcvarsall == nil or not os.isfile(vcvarsall) then - if vcvarsall and option.get("verbose") then - print("not found %s", vcvarsall) + table.sort(vsvers, function (a, b) return a > b end) + if vs then + table.insert(vsvers, 1, vs) end - return - end - - -- make the genvcvars.bat - local genvcvars_bat = os.tmpfile() .. "_genvcvars.bat" - local genvcvars_dat = os.tmpfile() .. "_genvcvars.dat" - local file = io.open(genvcvars_bat, "w") - file:print("@echo off") - file:print("call \"%s\" %s > nul", vcvarsall, config.get("arch")) - file:print("echo { > %s", genvcvars_dat) - file:print("echo path = \"%%path%%\" >> %s", genvcvars_dat) - file:print("echo , lib = \"%%lib%%\" >> %s", genvcvars_dat) - file:print("echo , libpath = \"%%libpath%%\" >> %s", genvcvars_dat) - file:print("echo , include = \"%%include%%\" >> %s", genvcvars_dat) - file:print("echo , devenvdir = \"%%devenvdir%%\" >> %s", genvcvars_dat) - file:print("echo , vsinstalldir = \"%%vsinstalldir%%\" >> %s", genvcvars_dat) - file:print("echo , vcinstalldir = \"%%vcinstalldir%%\" >> %s", genvcvars_dat) - file:print("echo } >> %s", genvcvars_dat) - file:close() - -- run genvcvars.bat - os.run(genvcvars_bat) + -- get vcvarsall + for _, vsver in ipairs(vsvers) do + local vcvarsall = (vstudio[vsver] or {}).vcvarsall or {} + local vsenv = vcvarsall[config.get("arch") or ""] + if vsenv and vsenv.path and vsenv.include and vsenv.lib then - -- replace "\" => "\\" - io.gsub(genvcvars_dat, "\\", "\\\\") + -- save vsenv + config.set("__vcvarsall", vcvarsall) - -- load all envirnoment variables - local variables = io.load(genvcvars_dat) + -- check compiler + environment.enter("toolchains") + local toolpath = tool.check("cl.exe") + environment.leave("toolchains") - -- save the variables - for k, v in pairs(variables) do - config.set("__vsenv_" .. k, v) + -- ok? + if toolpath then + return vsver + end + end + end end - - -- ok - return true end -- clean temporary global configs @@ -129,59 +82,14 @@ function _clean_global(config) -- clean it for global config (need not it) config.set("arch", nil) - config.set("__vsenv_path", nil) - config.set("__vsenv_lib", nil) - config.set("__vsenv_include", nil) - config.set("__vsenv_libpath", nil) - config.set("__vsenv_devenvdir", nil) - config.set("__vsenv_vsinstalldir", nil) - config.set("__vsenv_vcinstalldir", nil) -end - --- attempt to check complier -function _check_compiler(config, vs) - - -- apply vs envirnoment - if not _apply_vsenv(config, vs) then - return - end - - -- enter environment - environment.enter("toolchains") - - -- done - local toolpath = tool.check("cl.exe") - - -- leave environment - environment.leave("toolchains") - - -- ok? - return toolpath + config.set("__vcvarsall", nil) end -- check the visual stdio function _check_vs(config) -- attempt to check the given vs version first - local vs = config.get("vs") - if vs and _check_compiler(config, vs) then - return - end - - -- attempt to check them from the envirnoment variables again - vs = nil - if not vs then - for _, version in ipairs({"2017", "2015", "2013", "2012", "2010", "2008", "2005", "2003", "7.0", "6.0", "5.0", "4.2"}) do - - -- attempt to check it - if _check_compiler(config, version) then - vs = version - break - end - end - end - - -- check ok? update it + local vs = _check_vsenv(config) if vs then -- save it @@ -269,11 +177,6 @@ function main(kind, toolkind) -- import the given config local config = import("core.project." .. kind) - -- apply vs envirnoment (maybe config.arch has been updated) - if not _apply_vsenv(config, config.get("vs")) then - return - end - -- enter environment environment.enter("toolchains") diff --git a/xmake/platforms/windows/environment.lua b/xmake/platforms/windows/environment.lua index 98f071f0b..5281880e0 100644 --- a/xmake/platforms/windows/environment.lua +++ b/xmake/platforms/windows/environment.lua @@ -29,9 +29,18 @@ import("core.project.global") -- enter the given environment function _enter(name) + -- get vcvarsall + local vcvarsall = config.get("__vcvarsall") or global.get("__vcvarsall") + if not vcvarsall then + return + end + + -- get vs environment for the current arch + local vsenv = vcvarsall[config.get("arch") or ""] or {} + -- get the pathes for the vs environment local old = nil - local new = config.get("__vsenv_" .. name) or global.get("__vsenv_" .. name) + local new = vsenv[name] if new then -- get the current pathes @@ -45,7 +54,7 @@ function _enter(name) end -- return the previous environment - return old; + return old end -- leave the given environment @@ -64,7 +73,6 @@ function _enter_toolchains() _g.libs = _enter("lib") _g.includes = _enter("include") _g.libpathes = _enter("libpath") - end -- leave the toolchains environment (vs) @@ -74,7 +82,6 @@ function _leave_toolchains() _leave("lib", _g.libs) _leave("include", _g.includes) _leave("libpath", _g.libpathes) - end -- enter the toolchains environment (vs) |
