From 44fd11396d7b073e6b5227894c5db02b3585302f Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 4 Jun 2015 22:28:15 +0800 Subject: impl auto rebuild and fix some bug --- install.bat | 1 + xmake/scripts/action/_build.lua | 15 +- xmake/scripts/base/config.lua | 62 +++++-- xmake/scripts/base/global.lua | 21 +-- xmake/scripts/base/main.lua | 53 +++--- xmake/scripts/base/option.lua | 29 ++++ xmake/scripts/platform/iphoneos/prober.lua | 4 +- xmake/scripts/platform/macosx/prober.lua | 2 +- xmake/scripts/platform/msvc/msvc.lua | 81 ---------- xmake/scripts/platform/msvc/prober.lua | 214 ------------------------- xmake/scripts/platform/msvc/tools/cl.lua | 78 --------- xmake/scripts/platform/msvc/tools/link.lua | 90 ----------- xmake/scripts/platform/msvc/tools/nmake.lua | 112 ------------- xmake/scripts/platform/windows/prober.lua | 214 +++++++++++++++++++++++++ xmake/scripts/platform/windows/tools/cl.lua | 78 +++++++++ xmake/scripts/platform/windows/tools/link.lua | 90 +++++++++++ xmake/scripts/platform/windows/tools/nmake.lua | 112 +++++++++++++ xmake/scripts/platform/windows/windows.lua | 81 ++++++++++ 18 files changed, 708 insertions(+), 629 deletions(-) delete mode 100644 xmake/scripts/platform/msvc/msvc.lua delete mode 100644 xmake/scripts/platform/msvc/prober.lua delete mode 100644 xmake/scripts/platform/msvc/tools/cl.lua delete mode 100644 xmake/scripts/platform/msvc/tools/link.lua delete mode 100644 xmake/scripts/platform/msvc/tools/nmake.lua create mode 100644 xmake/scripts/platform/windows/prober.lua create mode 100644 xmake/scripts/platform/windows/tools/cl.lua create mode 100644 xmake/scripts/platform/windows/tools/link.lua create mode 100644 xmake/scripts/platform/windows/tools/nmake.lua create mode 100644 xmake/scripts/platform/windows/windows.lua diff --git a/install.bat b/install.bat index 4c39de496..625e94c43 100644 --- a/install.bat +++ b/install.bat @@ -28,6 +28,7 @@ if %PROCESSOR_ARCHITECTURE%==x86_64 ( echo please input the install directory set /p xmake_dir_install=(default: %xmake_dir_install_default%): if "%xmake_dir_install%"=="" set xmake_dir_install=%xmake_dir_install_default% +if exist "%xmake_dir_install%" rmdir /s /q "%xmake_dir_install%" if not exist "%xmake_dir_install%" mkdir "%xmake_dir_install%" rem compile xmake-core diff --git a/xmake/scripts/action/_build.lua b/xmake/scripts/action/_build.lua index d07005eab..288485fc1 100644 --- a/xmake/scripts/action/_build.lua +++ b/xmake/scripts/action/_build.lua @@ -37,7 +37,7 @@ function _build.done() local target_name = config.get("target") -- rebuild it? - if config.get("rebuild") then + if config.get("rebuild") or config.get("__rebuild") then clean.remove(target_name) -- update it? elseif config.get("update") then @@ -53,6 +53,19 @@ function _build.done() return false end + -- clear rebuild mark and save configure to file + if config.get("__rebuild") then + + -- clear it + config.set("__rebuild", nil) + + -- save the configure + if not config.savexconf() then + -- error + utils.error("update configure failed!") + end + end + -- ok print("build ok!") return true diff --git a/xmake/scripts/base/config.lua b/xmake/scripts/base/config.lua index 6c8a22f58..41db332c4 100644 --- a/xmake/scripts/base/config.lua +++ b/xmake/scripts/base/config.lua @@ -230,8 +230,12 @@ end function config.set(name, value) -- check - assert(config._CURRENT) - assert(name and value and type(value) ~= "table") + assert(config._CURRENT and name) + + -- invalid value + if value and type(value) == "table" then + assert(false) + end -- get the current target local target = config._target() @@ -326,17 +330,38 @@ function config.loadxconf() -- save configs config._CONFIGS = newenv._CONFIGS - -- clear configs if the host has been changed + -- clear configs and mark as "rebuild" and "reconfig" if the host has been changed local target = config._target() if target and target.host ~= xmake._HOST then - -- clear configs - config._CONFIGS = {} + + -- clear configs and mark as "rebuild" + config._CONFIGS = { __rebuild = true } + + -- mark as "reconfig" if the current action is not "config" + if options._ACTION ~= "config" then + config._RECONFIG = true + end end - -- clear configs if the plat has been changed + -- clear configs and mark as "rebuild" if the plat has been changed if target and target.plat and options.plat and target.plat ~= options.plat then - -- clear configs - config._CONFIGS = {} + + -- clear configs and mark as "rebuild" + config._CONFIGS = { __rebuild = true } + end + + -- mark as "rebuild" if the arch has been changed + if target and target.arch and options.arch and target.arch ~= options.arch then + + -- mark as "rebuild" + config._CONFIGS.__rebuild = true + end + + -- mark as "rebuild" if the mode has been changed + if target and target.mode and options.mode and target.mode ~= options.mode then + + -- mark as "rebuild" + config._CONFIGS.__rebuild = true end elseif errors then -- error @@ -377,18 +402,21 @@ function config.loadxconf() end end - -- merge xmake._OPTIONS._DEFAULTS to target - for k, v in pairs(options._DEFAULTS) do + -- merge the default configure options to target + local defaults = option.defaults("config") + if defaults then + for k, v in pairs(defaults) do - -- check - assert(type(k) == "string") + -- check + assert(type(k) == "string") - -- skip some options - if config._need(k) then + -- skip some options + if config._need(k) then - -- save the default option to the target - if not target[k] then - target[k] = v + -- save the default option to the target + if not target[k] then + target[k] = v + end end end end diff --git a/xmake/scripts/base/global.lua b/xmake/scripts/base/global.lua index 2b3582a23..5b2f774f5 100644 --- a/xmake/scripts/base/global.lua +++ b/xmake/scripts/base/global.lua @@ -269,18 +269,21 @@ function global.loadxconf() end end - -- merge xmake._OPTIONS._DEFAULTS to the global configure - for k, v in pairs(options._DEFAULTS) do + -- merge the default global configure options to the global configure + local defaults = option.defaults("global") + if defaults then + for k, v in pairs(defaults) do - -- check - assert(type(k) == "string") + -- check + assert(type(k) == "string") - -- need configure it? - if global._need(k) then + -- need configure it? + if global._need(k) then - -- save the default option - if not configs[k] then - configs[k] = v + -- save the default option + if not configs[k] then + configs[k] = v + end end end end diff --git a/xmake/scripts/base/main.lua b/xmake/scripts/base/main.lua index 2624c8d53..2bd243ac4 100644 --- a/xmake/scripts/base/main.lua +++ b/xmake/scripts/base/main.lua @@ -425,13 +425,30 @@ function main._prepare_project() -- load xmake.xconf file first local errors = config.loadxconf() - if not errors then - -- load xmake.xproj file - errors = project.loadxproj(options.file) + if errors then return errors end + + -- xmake config or marked as "reconfig"? + if options._ACTION == "config" or config._RECONFIG then + + -- wrap the configure for more convenient to get and set values + local config_wrapped = {} + setmetatable(config_wrapped, + { + __index = function(tbl, key) + return config.get(key) + end, + __newindex = function(tbl, key, val) + config.set(key, val) + end + }) + + -- probe the current platform configure + platform.probe(config_wrapped, false) + end - -- ok? - return errors + -- load xmake.xproj file + return project.loadxproj(options.file) end -- done help @@ -527,25 +544,6 @@ function main._done_option() return false end - -- xmake config? - if options._ACTION == "config" then - - -- wrap the global configure for more convenient to get and set values - local config_wrapped = {} - setmetatable(config_wrapped, - { - __index = function(tbl, key) - return config.get(key) - end, - __newindex = function(tbl, key, val) - config.set(key, val) - end - }) - - -- probe the current platform configure - platform.probe(config_wrapped, false) - end - -- make the current platform configure if not platform.make() then -- error @@ -566,6 +564,13 @@ function main._done_option() -- dump platform platform.dump() + -- reconfig it first if marked as "reconfig" + if config._RECONFIG and not action.done("config") then + -- error + utils.error("reconfig failed for the changed host!") + return false + end + -- done action return action.done(options._ACTION or "build") end diff --git a/xmake/scripts/base/option.lua b/xmake/scripts/base/option.lua index cdf82adb5..820ba4e6a 100644 --- a/xmake/scripts/base/option.lua +++ b/xmake/scripts/base/option.lua @@ -402,6 +402,35 @@ function option.find(argv, name, shortname) end end +-- get all default options from the given action +function option.defaults(action) + + -- make defaults + local defaults = {} + + -- init the default value + for _, o in ipairs(option._MENU[action or "main"].options) do + + -- key=value? + if o[3] == "kv" then + + -- the key + local key = o[2] or o[1] + assert(key) + + -- save the default value + defaults[key] = o[4] + -- value with name? + elseif o[3] == "v" and o[2] then + -- save the default value + defaults[o[2]] = o[4] + end + end + + -- ok? + return defaults +end + -- print the menu function option.print_menu(action) diff --git a/xmake/scripts/platform/iphoneos/prober.lua b/xmake/scripts/platform/iphoneos/prober.lua index 589e3a4b1..d5de4a7c5 100644 --- a/xmake/scripts/platform/iphoneos/prober.lua +++ b/xmake/scripts/platform/iphoneos/prober.lua @@ -135,12 +135,12 @@ function prober.config(configs) if not prober._probe_xcode(configs) then return end -- probe the xcode sdk version - if not is_global and not prober._probe_xcode_sdkver(configs) then return end + if not prober._probe_xcode_sdkver(configs) then return end end -- probe the global configure -function prober.config(configs) +function prober.global(configs) -- probe the xcode application directory if not prober._probe_xcode(configs) then return end diff --git a/xmake/scripts/platform/macosx/prober.lua b/xmake/scripts/platform/macosx/prober.lua index e917d6817..3a3615293 100644 --- a/xmake/scripts/platform/macosx/prober.lua +++ b/xmake/scripts/platform/macosx/prober.lua @@ -129,7 +129,7 @@ end function prober.config(configs) -- probe the architecture - if prober._probe_arch(configs) then return end + if not prober._probe_arch(configs) then return end -- probe the xcode application directory if not prober._probe_xcode(configs) then return end diff --git a/xmake/scripts/platform/msvc/msvc.lua b/xmake/scripts/platform/msvc/msvc.lua deleted file mode 100644 index 332b2b5f7..000000000 --- a/xmake/scripts/platform/msvc/msvc.lua +++ /dev/null @@ -1,81 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file msvc.lua --- - --- define module: msvc -local msvc = msvc or {} - --- load modules -local config = require("base/config") - --- init host -msvc._HOST = "windows" - --- init architectures -msvc._ARCHS = {"x86", "x64"} - --- make configure -function msvc.make(configs) - - -- init the file formats - configs.formats = {} - configs.formats.static = {"", ".lib"} - configs.formats.object = {"", ".obj"} - configs.formats.shared = {"", ".dll"} - configs.formats.binary = {"", ".exe"} - - -- init the toolchains - configs.tools = {} - configs.tools.make = "nmake" - configs.tools.cc = config.get("cc") or "cl" - configs.tools.cxx = config.get("cxx") or "cl" - configs.tools.ld = config.get("ld") or "link" - configs.tools.ar = config.get("ar") or "link" - configs.tools.sh = config.get("sh") or "link" - -end - --- get the option menu for action: xmake config or global -function msvc.menu(action) - - -- init config option menu - msvc._MENU_CONFIG = msvc._MENU_CONFIG or - { {} - , {nil, "vs", "kv", "auto", "The Microsoft Visual Studio" } - , } - - -- init global option menu - msvc._MENU_GLOBAL = msvc._MENU_GLOBAL or - { {} - , {nil, "vs", "kv", "auto", "The Microsoft Visual Studio" } - , } - - -- get the option menu - if action == "config" then - return msvc._MENU_CONFIG - elseif action == "global" then - return msvc._MENU_GLOBAL - end -end - - --- return module: msvc -return msvc diff --git a/xmake/scripts/platform/msvc/prober.lua b/xmake/scripts/platform/msvc/prober.lua deleted file mode 100644 index c730ad9f1..000000000 --- a/xmake/scripts/platform/msvc/prober.lua +++ /dev/null @@ -1,214 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file prober.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") - --- define module: prober -local prober = prober or {} - --- probe the architecture -function prober._probe_arch(configs) - - -- get the architecture - local arch = configs.arch - - -- ok? - if arch then return true end - - -- init the default architecture - configs.arch = xmake._ARCH - - -- ok - return true -end - --- probe the vs version -function prober._probe_vs_version(configs) - - -- get the vs version - local vs = configs.vs - - -- ok? - if vs then return true end - - -- clear it first - vs = nil - - -- make the map table - local map = - { - VS120COMNTOOLS = "2013" - , VS110COMNTOOLS = "2012" - , VS100COMNTOOLS = "2010" - , VS90COMNTOOLS = "2008" - , VS80COMNTOOLS = "2005" - , VS71COMNTOOLS = "2003" - , VS70COMNTOOLS = "7.0" - , VS60COMNTOOLS = "6.0" - , VS50COMNTOOLS = "5.0" - , VS42COMNTOOLS = "4.2" - } - - -- attempt to get it from the envirnoment variable - if not vs then - for k, v in pairs(map) do - if os.getenv(k) then - vs = v - break - end - end - end - - -- probe ok? update it - if vs then - configs.vs = vs - else - -- failed - utils.error("The Microsoft Visual Studio is unknown now, please config it first!") - utils.error(" - xmake config --vs=xxx") - utils.error("or - xmake global --vs=xxx") - return false - end - - -- ok - return true -end - --- probe the vs path -function prober._probe_vs_path(configs) - - -- ok? - if configs.__vsenv_path then return true end - - -- get the vs version - local vs = configs.vs - assert(vs) - - -- make the map table - local map = - { - ["2013"] = "VS120COMNTOOLS" - , ["2012"] = "VS110COMNTOOLS" - , ["2010"] = "VS100COMNTOOLS" - , ["2008"] = "VS90COMNTOOLS" - , ["2005"] = "VS80COMNTOOLS" - , ["2003"] = "VS71COMNTOOLS" - , ["7.0"] = "VS70COMNTOOLS" - , ["6.0"] = "VS60COMNTOOLS" - , ["5.0"] = "VS50COMNTOOLS" - , ["4.2"] = "VS42COMNTOOLS" - } - - -- attempt to get the tools directory from the envirnoment variable - local toolsdir = map[vs] - if toolsdir then - toolsdir = os.getenv(toolsdir) - end - - -- the vsvars32.bat path - local vsvars32 = toolsdir .. "\\vsvars32.bat" - if not os.isfile(vsvars32) then - -- error - utils.error("not found %s", vsvars32) - return false - end - - -- get the temporary directory - local tmpdir = os.tmpdir() - assert(tmpdir) - - -- make the call(vsvars32.bat) file - local callpath = tmpdir .. "\\call_vsvars32.bat" - local callfile = io.open(callpath, "w") - assert(callfile) - - -- make call scripts - callfile:write("@echo off\n") - callfile:write(string.format("call \"%s\" > nul\n", vsvars32)) - callfile:write("echo return \n") - callfile:write("echo { \n") - callfile:write("echo path = \"%path%\"\n") - callfile:write("echo , lib = \"%lib%\"\n") - callfile:write("echo , libpath = \"%libpath%\"\n") - callfile:write("echo , include = \"%include%\"\n") - callfile:write("echo , devenvdir = \"%devenvdir%\"\n") - callfile:write("echo , vsinstalldir = \"%vsinstalldir%\"\n") - callfile:write("echo , vcinstalldir = \"%vcinstalldir%\"\n") - callfile:write("echo } \n") - - -- close the file - callfile:close() - - -- execute the call(vsvars32.bat) file and get all envirnoment variables - local cmd = io.popen(callpath) - local results = cmd:read("*all") - cmd:close() - - -- translate '\' => '\\' - results = results:gsub("\\", "\\\\") - - -- get all envirnoment variables - local variables = assert(loadstring(results))() - if not variables or not variables.path then - return false - end - - -- save the variables - for k, v in pairs(variables) do - configs["__vsenv_" .. k] = v - end - - -- ok - return true -end - --- probe the project configure -function prober.config(configs) - - -- probe the architecture - if not prober._probe_arch(configs) then return end - - -- probe the vs version - if not prober._probe_vs_version(configs) then return end - - -- probe the vs path - if not prober._probe_vs_path(configs) then return end - -end - --- probe the global configure -function prober.global(configs) - - -- probe the vs version - if not prober._probe_vs_version(configs) then return end - - -- probe the vs path - if not prober._probe_vs_path(configs) then return end - -end - --- return module: prober -return prober diff --git a/xmake/scripts/platform/msvc/tools/cl.lua b/xmake/scripts/platform/msvc/tools/cl.lua deleted file mode 100644 index a8ab807a7..000000000 --- a/xmake/scripts/platform/msvc/tools/cl.lua +++ /dev/null @@ -1,78 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file cl.lua --- - --- define module: cl -local cl = cl or {} - --- load modules -local utils = require("base/utils") -local string = require("base/string") -local config = require("base/config") - --- init the compiler -function cl.init(name) - - -- init cflags - cl.cflags = "-nologo" - - -- init cxxflags - cl.cxxflags = "-nologo" - -end - --- make the compiler command -function cl.command_compile(srcfile, objfile, flags) - - -- make it - return string.format("cl.exe -c %s -Fo%s %s", flags, objfile, srcfile) -end - --- make the define flag -function cl.flag_define(define) - - -- make it - return "-D" .. define -end - --- make the includedir flag -function cl.flag_includedir(includedir) - - -- make it - return "-I" .. includedir -end - --- map gcc flag to the current compiler flag -function cl.flag_map(flag) - - -- ok - return flag -end - --- the main function -function cl.main(...) - - -- ok - return true -end - --- return module: cl -return cl diff --git a/xmake/scripts/platform/msvc/tools/link.lua b/xmake/scripts/platform/msvc/tools/link.lua deleted file mode 100644 index 52528ca6c..000000000 --- a/xmake/scripts/platform/msvc/tools/link.lua +++ /dev/null @@ -1,90 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file link.lua --- - --- define module: link -local link = link or {} - --- load modules -local utils = require("base/utils") -local string = require("base/string") -local config = require("base/config") - --- init the compiler -function link.init(name) - - -- the architecture - local arch = config.get("arch") - assert(arch) - - -- init flags for architecture - local flags_arch = "" - if arch == "x86" then flags_arch = "-machine:x86" - elseif arch == "x64" then flags_arch = "-machine:x86_64" - end - - -- init ldflags - link.ldflags = "-nologo -dynamicbase -nxcompat -manifest -manifestuac:\"level='asInvoker' uiAccess='false'\" " .. flags_arch - - -- init arflags - link.arflags = "-lib -nologo " .. flags_arch - - -- init shflags - link.shflags = "-dll -nologo " .. flags_arch -end - --- make the linker command -function link.command_link(objfiles, targetfile, flags) - - -- make it - return string.format("link.exe %s -out:%s %s", flags, targetfile, objfiles) -end - --- make the link flag -function link.flag_link(link) - - -- make it - return link .. ".lib" -end - --- make the linkdir flag -function link.flag_linkdir(linkdir) - - -- make it - return "-libpath:" .. linkdir -end - --- map gcc flag to the current compiler flag -function link.flag_map(flag) - - -- ok - return flag -end - --- the main function -function link.main(...) - - -- ok - return true -end - --- return module: link -return link diff --git a/xmake/scripts/platform/msvc/tools/nmake.lua b/xmake/scripts/platform/msvc/tools/nmake.lua deleted file mode 100644 index 6d6b21258..000000000 --- a/xmake/scripts/platform/msvc/tools/nmake.lua +++ /dev/null @@ -1,112 +0,0 @@ ---!The Automatic Cross-platform Build Tool --- --- XMake is free software; you can redistribute it and/or modify --- it under the terms of the GNU Lesser General Public License as published by --- the Free Software Foundation; either version 2.1 of the License, or --- (at your option) any later version. --- --- XMake is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU Lesser General Public License for more details. --- --- You should have received a copy of the GNU Lesser General Public License --- along with XMake; --- If not, see http://www.gnu.org/licenses/ --- --- Copyright (C) 2009 - 2015, ruki All rights reserved. --- --- @author ruki --- @file nmake.lua --- - --- load modules -local os = require("base/os") -local path = require("base/path") -local utils = require("base/utils") -local string = require("base/string") -local config = require("base/config") - --- define module: nmake -local nmake = nmake or {} - --- enter the given environment -function nmake._enter(name) - - -- check - assert(name) - - -- get the pathes for the vs environment - local old = nil - local new = config.get("__vsenv_" .. name) - if new then - - -- get the current pathes - old = os.getenv(name) or "" - - -- append the current pathes - new = new .. ";" .. old - - -- update the pathes for the environment - os.setenv(name, new) - end - - -- return the previous environment - return old; -end - --- leave the given environment -function nmake._leave(name, old) - - -- check - assert(name) - - -- restore the previous environment - if old then - os.setenv(name, old) - end -end - --- the init function -function nmake.init(name) - - -- save name - nmake._NAME = name or "nmake.exe" - - -- is verbose? - nmake._VERBOSE = utils.ifelse(xmake._OPTIONS.verbose, "-v", "") - -end - --- the main function -function nmake.main(mkfile, target) - - -- enter the vs environment - local pathes = nmake._enter("path") - local libs = nmake._enter("lib") - local includes = nmake._enter("include") - local libpathes = nmake._enter("libpath") - - -- make command - local cmd = nil - if mkfile and os.isfile(mkfile) then - cmd = string.format("%s /f %s %s VERBOSE=%s 2> nul", nmake._NAME, mkfile, target or "", nmake._VERBOSE) - else - cmd = string.format("%s %s VERBOSE=%s 2> nul", nmake._NAME, target or "", nmake._VERBOSE) - end - - -- done - local ok = os.execute(cmd) - - -- leave the vs environment - nmake._leave("path", pathes) - nmake._leave("lib", libs) - nmake._leave("include", includes) - nmake._leave("libpath", libpathes) - - -- ok? - return utils.ifelse(ok == 0, true, false) -end - --- return module: nmake -return nmake diff --git a/xmake/scripts/platform/windows/prober.lua b/xmake/scripts/platform/windows/prober.lua new file mode 100644 index 000000000..c730ad9f1 --- /dev/null +++ b/xmake/scripts/platform/windows/prober.lua @@ -0,0 +1,214 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file prober.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") + +-- define module: prober +local prober = prober or {} + +-- probe the architecture +function prober._probe_arch(configs) + + -- get the architecture + local arch = configs.arch + + -- ok? + if arch then return true end + + -- init the default architecture + configs.arch = xmake._ARCH + + -- ok + return true +end + +-- probe the vs version +function prober._probe_vs_version(configs) + + -- get the vs version + local vs = configs.vs + + -- ok? + if vs then return true end + + -- clear it first + vs = nil + + -- make the map table + local map = + { + VS120COMNTOOLS = "2013" + , VS110COMNTOOLS = "2012" + , VS100COMNTOOLS = "2010" + , VS90COMNTOOLS = "2008" + , VS80COMNTOOLS = "2005" + , VS71COMNTOOLS = "2003" + , VS70COMNTOOLS = "7.0" + , VS60COMNTOOLS = "6.0" + , VS50COMNTOOLS = "5.0" + , VS42COMNTOOLS = "4.2" + } + + -- attempt to get it from the envirnoment variable + if not vs then + for k, v in pairs(map) do + if os.getenv(k) then + vs = v + break + end + end + end + + -- probe ok? update it + if vs then + configs.vs = vs + else + -- failed + utils.error("The Microsoft Visual Studio is unknown now, please config it first!") + utils.error(" - xmake config --vs=xxx") + utils.error("or - xmake global --vs=xxx") + return false + end + + -- ok + return true +end + +-- probe the vs path +function prober._probe_vs_path(configs) + + -- ok? + if configs.__vsenv_path then return true end + + -- get the vs version + local vs = configs.vs + assert(vs) + + -- make the map table + local map = + { + ["2013"] = "VS120COMNTOOLS" + , ["2012"] = "VS110COMNTOOLS" + , ["2010"] = "VS100COMNTOOLS" + , ["2008"] = "VS90COMNTOOLS" + , ["2005"] = "VS80COMNTOOLS" + , ["2003"] = "VS71COMNTOOLS" + , ["7.0"] = "VS70COMNTOOLS" + , ["6.0"] = "VS60COMNTOOLS" + , ["5.0"] = "VS50COMNTOOLS" + , ["4.2"] = "VS42COMNTOOLS" + } + + -- attempt to get the tools directory from the envirnoment variable + local toolsdir = map[vs] + if toolsdir then + toolsdir = os.getenv(toolsdir) + end + + -- the vsvars32.bat path + local vsvars32 = toolsdir .. "\\vsvars32.bat" + if not os.isfile(vsvars32) then + -- error + utils.error("not found %s", vsvars32) + return false + end + + -- get the temporary directory + local tmpdir = os.tmpdir() + assert(tmpdir) + + -- make the call(vsvars32.bat) file + local callpath = tmpdir .. "\\call_vsvars32.bat" + local callfile = io.open(callpath, "w") + assert(callfile) + + -- make call scripts + callfile:write("@echo off\n") + callfile:write(string.format("call \"%s\" > nul\n", vsvars32)) + callfile:write("echo return \n") + callfile:write("echo { \n") + callfile:write("echo path = \"%path%\"\n") + callfile:write("echo , lib = \"%lib%\"\n") + callfile:write("echo , libpath = \"%libpath%\"\n") + callfile:write("echo , include = \"%include%\"\n") + callfile:write("echo , devenvdir = \"%devenvdir%\"\n") + callfile:write("echo , vsinstalldir = \"%vsinstalldir%\"\n") + callfile:write("echo , vcinstalldir = \"%vcinstalldir%\"\n") + callfile:write("echo } \n") + + -- close the file + callfile:close() + + -- execute the call(vsvars32.bat) file and get all envirnoment variables + local cmd = io.popen(callpath) + local results = cmd:read("*all") + cmd:close() + + -- translate '\' => '\\' + results = results:gsub("\\", "\\\\") + + -- get all envirnoment variables + local variables = assert(loadstring(results))() + if not variables or not variables.path then + return false + end + + -- save the variables + for k, v in pairs(variables) do + configs["__vsenv_" .. k] = v + end + + -- ok + return true +end + +-- probe the project configure +function prober.config(configs) + + -- probe the architecture + if not prober._probe_arch(configs) then return end + + -- probe the vs version + if not prober._probe_vs_version(configs) then return end + + -- probe the vs path + if not prober._probe_vs_path(configs) then return end + +end + +-- probe the global configure +function prober.global(configs) + + -- probe the vs version + if not prober._probe_vs_version(configs) then return end + + -- probe the vs path + if not prober._probe_vs_path(configs) then return end + +end + +-- return module: prober +return prober diff --git a/xmake/scripts/platform/windows/tools/cl.lua b/xmake/scripts/platform/windows/tools/cl.lua new file mode 100644 index 000000000..a8ab807a7 --- /dev/null +++ b/xmake/scripts/platform/windows/tools/cl.lua @@ -0,0 +1,78 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file cl.lua +-- + +-- define module: cl +local cl = cl or {} + +-- load modules +local utils = require("base/utils") +local string = require("base/string") +local config = require("base/config") + +-- init the compiler +function cl.init(name) + + -- init cflags + cl.cflags = "-nologo" + + -- init cxxflags + cl.cxxflags = "-nologo" + +end + +-- make the compiler command +function cl.command_compile(srcfile, objfile, flags) + + -- make it + return string.format("cl.exe -c %s -Fo%s %s", flags, objfile, srcfile) +end + +-- make the define flag +function cl.flag_define(define) + + -- make it + return "-D" .. define +end + +-- make the includedir flag +function cl.flag_includedir(includedir) + + -- make it + return "-I" .. includedir +end + +-- map gcc flag to the current compiler flag +function cl.flag_map(flag) + + -- ok + return flag +end + +-- the main function +function cl.main(...) + + -- ok + return true +end + +-- return module: cl +return cl diff --git a/xmake/scripts/platform/windows/tools/link.lua b/xmake/scripts/platform/windows/tools/link.lua new file mode 100644 index 000000000..52528ca6c --- /dev/null +++ b/xmake/scripts/platform/windows/tools/link.lua @@ -0,0 +1,90 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file link.lua +-- + +-- define module: link +local link = link or {} + +-- load modules +local utils = require("base/utils") +local string = require("base/string") +local config = require("base/config") + +-- init the compiler +function link.init(name) + + -- the architecture + local arch = config.get("arch") + assert(arch) + + -- init flags for architecture + local flags_arch = "" + if arch == "x86" then flags_arch = "-machine:x86" + elseif arch == "x64" then flags_arch = "-machine:x86_64" + end + + -- init ldflags + link.ldflags = "-nologo -dynamicbase -nxcompat -manifest -manifestuac:\"level='asInvoker' uiAccess='false'\" " .. flags_arch + + -- init arflags + link.arflags = "-lib -nologo " .. flags_arch + + -- init shflags + link.shflags = "-dll -nologo " .. flags_arch +end + +-- make the linker command +function link.command_link(objfiles, targetfile, flags) + + -- make it + return string.format("link.exe %s -out:%s %s", flags, targetfile, objfiles) +end + +-- make the link flag +function link.flag_link(link) + + -- make it + return link .. ".lib" +end + +-- make the linkdir flag +function link.flag_linkdir(linkdir) + + -- make it + return "-libpath:" .. linkdir +end + +-- map gcc flag to the current compiler flag +function link.flag_map(flag) + + -- ok + return flag +end + +-- the main function +function link.main(...) + + -- ok + return true +end + +-- return module: link +return link diff --git a/xmake/scripts/platform/windows/tools/nmake.lua b/xmake/scripts/platform/windows/tools/nmake.lua new file mode 100644 index 000000000..6d6b21258 --- /dev/null +++ b/xmake/scripts/platform/windows/tools/nmake.lua @@ -0,0 +1,112 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file nmake.lua +-- + +-- load modules +local os = require("base/os") +local path = require("base/path") +local utils = require("base/utils") +local string = require("base/string") +local config = require("base/config") + +-- define module: nmake +local nmake = nmake or {} + +-- enter the given environment +function nmake._enter(name) + + -- check + assert(name) + + -- get the pathes for the vs environment + local old = nil + local new = config.get("__vsenv_" .. name) + if new then + + -- get the current pathes + old = os.getenv(name) or "" + + -- append the current pathes + new = new .. ";" .. old + + -- update the pathes for the environment + os.setenv(name, new) + end + + -- return the previous environment + return old; +end + +-- leave the given environment +function nmake._leave(name, old) + + -- check + assert(name) + + -- restore the previous environment + if old then + os.setenv(name, old) + end +end + +-- the init function +function nmake.init(name) + + -- save name + nmake._NAME = name or "nmake.exe" + + -- is verbose? + nmake._VERBOSE = utils.ifelse(xmake._OPTIONS.verbose, "-v", "") + +end + +-- the main function +function nmake.main(mkfile, target) + + -- enter the vs environment + local pathes = nmake._enter("path") + local libs = nmake._enter("lib") + local includes = nmake._enter("include") + local libpathes = nmake._enter("libpath") + + -- make command + local cmd = nil + if mkfile and os.isfile(mkfile) then + cmd = string.format("%s /f %s %s VERBOSE=%s 2> nul", nmake._NAME, mkfile, target or "", nmake._VERBOSE) + else + cmd = string.format("%s %s VERBOSE=%s 2> nul", nmake._NAME, target or "", nmake._VERBOSE) + end + + -- done + local ok = os.execute(cmd) + + -- leave the vs environment + nmake._leave("path", pathes) + nmake._leave("lib", libs) + nmake._leave("include", includes) + nmake._leave("libpath", libpathes) + + -- ok? + return utils.ifelse(ok == 0, true, false) +end + +-- return module: nmake +return nmake diff --git a/xmake/scripts/platform/windows/windows.lua b/xmake/scripts/platform/windows/windows.lua new file mode 100644 index 000000000..03e30864e --- /dev/null +++ b/xmake/scripts/platform/windows/windows.lua @@ -0,0 +1,81 @@ +--!The Automatic Cross-platform Build Tool +-- +-- XMake is free software; you can redistribute it and/or modify +-- it under the terms of the GNU Lesser General Public License as published by +-- the Free Software Foundation; either version 2.1 of the License, or +-- (at your option) any later version. +-- +-- XMake is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- +-- You should have received a copy of the GNU Lesser General Public License +-- along with XMake; +-- If not, see http://www.gnu.org/licenses/ +-- +-- Copyright (C) 2009 - 2015, ruki All rights reserved. +-- +-- @author ruki +-- @file windows.lua +-- + +-- define module: windows +local windows = windows or {} + +-- load modules +local config = require("base/config") + +-- init host +windows._HOST = "windows" + +-- init architectures +windows._ARCHS = {"x86", "x64"} + +-- make configure +function windows.make(configs) + + -- init the file formats + configs.formats = {} + configs.formats.static = {"", ".lib"} + configs.formats.object = {"", ".obj"} + configs.formats.shared = {"", ".dll"} + configs.formats.binary = {"", ".exe"} + + -- init the toolchains + configs.tools = {} + configs.tools.make = "nmake" + configs.tools.cc = config.get("cc") or "cl" + configs.tools.cxx = config.get("cxx") or "cl" + configs.tools.ld = config.get("ld") or "link" + configs.tools.ar = config.get("ar") or "link" + configs.tools.sh = config.get("sh") or "link" + +end + +-- get the option menu for action: xmake config or global +function windows.menu(action) + + -- init config option menu + windows._MENU_CONFIG = windows._MENU_CONFIG or + { {} + , {nil, "vs", "kv", "auto", "The Microsoft Visual Studio" } + , } + + -- init global option menu + windows._MENU_GLOBAL = windows._MENU_GLOBAL or + { {} + , {nil, "vs", "kv", "auto", "The Microsoft Visual Studio" } + , } + + -- get the option menu + if action == "config" then + return windows._MENU_CONFIG + elseif action == "global" then + return windows._MENU_GLOBAL + end +end + + +-- return module: windows +return windows -- cgit v1.3.1