diff options
| author | ruki <[email protected]> | 2015-05-15 21:53:25 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2015-05-15 21:53:25 +0800 |
| commit | 38fdeea020e688ada83a61783e5af9a9cb47ad0c (patch) | |
| tree | 6a21038abca7f7e6aef004fd21e5c43377a8410c | |
| parent | 8cfd830798ecf6a6f11bdeb341bc41344afa4e80 (diff) | |
impl preprocessor for configure
| -rw-r--r-- | xmake/scripts/base/config.lua | 144 | ||||
| -rw-r--r-- | xmake/scripts/base/preprocessor.lua | 144 |
2 files changed, 159 insertions, 129 deletions
diff --git a/xmake/scripts/base/config.lua b/xmake/scripts/base/config.lua index 0663b6d4b..ec2433026 100644 --- a/xmake/scripts/base/config.lua +++ b/xmake/scripts/base/config.lua @@ -44,122 +44,6 @@ function config._auto(name) return "unknown" end --- register configures -function config._register(env, names) - - -- check - assert(env) - assert(names and type(names) == "table") - - -- register all configures - for _, name in ipairs(names) do - - -- register the configure - env[name] = env[name] or function(...) - - -- check - local _current = env._current - assert(_current) - - -- init ldflags - _current[name] = _current[name] or {} - - -- get arguments - local arg = arg or {...} - if table.getn(arg) == 0 then - -- no argument - _current[name] = nil - elseif table.getn(arg) == 1 then - -- save only one argument - _current[name] = arg[1] - else - -- save all arguments - for i, v in ipairs(arg) do - _current[name][i] = v - end - end - end - end -end - --- init configures -function config._init() - - -- check - assert(option._MENU) - assert(option._MENU.config) - - -- enter new environment - local newenv = {} - local oldenv = getfenv() - setmetatable(newenv, {__index = _G}) - setfenv(1, newenv) - - -- get all configures name - local i = 1 - local configures = {} - for _, o in ipairs(option._MENU.config.options) do - local name = o[2] - if name and name ~= "target" and name ~= "file" and name ~= "project" and name ~= "verbose" then - configures[i] = name - i = i + 1 - end - end - - -- register all configures - config._register(newenv, configures) - - -- configure scope end - newenv["_end"] = function () - - -- check - assert(_current) - - -- leave the current scope - _current = _current._PARENT - end - - -- configure target - newenv["target"] = function (name) - - -- check - assert(name and _current) - - -- init targets - _current._TARGETS = _current._TARGETS or {} - - -- init target scope - _current._TARGETS[name] = {} - - -- enter target scope - local parent = _current - _current = _current._TARGETS[name] - _current._PARENT = parent - end - - -- the root configure - newenv["config"] = function () - - -- init the root scope, must be only one configs - if not config._CONFIGS then - config._CONFIGS = {} - else - -- error - utils.error("exists double configs!") - return - end - - -- init the current scope - _current = config._CONFIGS - _current._PARENT = nil - - end - - -- enter old environment - setfenv(1, oldenv) - return newenv -end - -- save object with the level function config._save_with_level(file, object, level) @@ -319,24 +203,26 @@ function config.loadxconf() -- the options local options = xmake._OPTIONS - assert(options) - - -- load and execute the xmake.xproj - local path = options.project .. "/xmake.xconf" - local script = preprocessor.loadx(path) - if script then + assert(options and options.project) - -- init the configs envirnoment - setfenv(script, config._init()) + -- check + assert(option._MENU) + assert(option._MENU.config) - -- execute it - local ok, err = pcall(script) - if not ok then - -- error - return err + -- get all configure names + local i = 1 + local configures = {} + for _, o in ipairs(option._MENU.config.options) do + local name = o[2] + if name and name ~= "target" and name ~= "file" and name ~= "project" and name ~= "verbose" then + configures[i] = name + i = i + 1 end end + -- load and execute the xmake.xproj + config._CONFIGS = preprocessor.loadfile(options.project .. "/xmake.xconf", "config", configures) + -- exists local configures? if config._CONFIGS then diff --git a/xmake/scripts/base/preprocessor.lua b/xmake/scripts/base/preprocessor.lua index d9c94d096..d2d9c1134 100644 --- a/xmake/scripts/base/preprocessor.lua +++ b/xmake/scripts/base/preprocessor.lua @@ -23,5 +23,149 @@ -- define module: preprocessor local preprocessor = preprocessor or {} +-- register configures +function preprocessor._register(env, names) + + -- check + assert(env and names and type(names) == "table") + + -- register all configures + for _, name in ipairs(names) do + + -- register the configure + env[name] = env[name] or function(...) + + -- check + local _current = env._current + assert(_current) + + -- init ldflags + _current[name] = _current[name] or {} + + -- get arguments + local arg = arg or {...} + if table.getn(arg) == 0 then + -- no argument + _current[name] = nil + elseif table.getn(arg) == 1 then + -- save only one argument + _current[name] = arg[1] + else + -- save all arguments + for i, v in ipairs(arg) do + _current[name][i] = v + end + end + end + end +end + +-- init configures +function preprocessor._init(root, configures) + + -- check + assert(root and configures) + + -- enter new environment + local newenv = {} + local oldenv = getfenv() + setmetatable(newenv, {__index = _G}) + setfenv(1, newenv) + + -- register all configures + preprocessor._register(newenv, configures) + + -- configure scope end + newenv["_end"] = function () + + -- check + assert(_current) + + -- leave the current scope + _current = _current._PARENT + end + + -- configure target + newenv["target"] = function (name) + + -- check + assert(name and _current) + + -- init targets + _current._TARGETS = _current._TARGETS or {} + + -- init target scope + _current._TARGETS[name] = {} + + -- enter target scope + local parent = _current + _current = _current._TARGETS[name] + _current._PARENT = parent + end + + -- the root configure + newenv[root] = function () + + -- init the root scope, must be only one configs + if not newenv._CONFIGS then + newenv._CONFIGS = {} + else + -- error + utils.error("exists double configs!") + return + end + + -- init the current scope + _current = newenv._CONFIGS + _current._PARENT = nil + + end + + -- enter old environment + setfenv(1, oldenv) + return newenv +end + +--!load the configure file +-- +-- supports: +-- xmake.xproj +-- xmake.xconf +-- +-- @code +-- local configs, errors = preprocessor.loadfile("xmake.xconf", "config", {"plat", "host", "arch", ...}) +-- local configs, errors = preprocessor.loadfile("xmake.xproj", "project", {"links", "files", "ldflags", ...}) +-- @endcode +function preprocessor.loadfile(path, root, configures) + + -- check + assert(path and root and configures) + + -- load and execute the configure file + local script = preprocessor.loadx(path) + if script then + + -- init a new envirnoment + local newenv = preprocessor._init(root, configures) + assert(newenv) + + -- bind this envirnoment + setfenv(script, newenv) + + -- execute it + local ok, err = pcall(script) + if not ok then + -- error + return nil, err + end + + -- ok? + return newenv._CONFIGS + else + -- error + return nil, string.format("load %s failed!", path) + end +end + -- return module: preprocessor return preprocessor |
