summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-06-01 14:28:16 +0800
committerruki <[email protected]>2017-06-01 14:28:16 +0800
commit8ed5f9977095c45dbca9d4c383c6998077b3176a (patch)
tree65786c6d0267b22a156495c29b4daf92fa01fdef
parent9fe0d2ac3ef006dacd8596ee9d3254e687c0240f (diff)
fix filter and improve check vs env on windows
-rw-r--r--xmake/core/base/filter.lua35
-rw-r--r--xmake/core/sandbox/modules/val.lua19
-rw-r--r--xmake/modules/detect/sdk/find_vstudio.lua55
-rw-r--r--xmake/platforms/windows/check.lua173
-rw-r--r--xmake/platforms/windows/environment.lua15
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)