From 62456790b7c23a4f471d45d69f65bf4dbdc5aab2 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 15 May 2015 11:57:59 +0800 Subject: modify xconf format --- core/src/xmake/machine.c | 4 +- core/src/xmake/makefile | 2 +- core/src/xmake/preprocessor/load_xproj.c | 251 ----------------------- core/src/xmake/preprocessor/loadx.c | 251 +++++++++++++++++++++++ xmake/scripts/_xmake_main.lua | 1 - xmake/scripts/action/_config.lua | 3 - xmake/scripts/base/config.lua | 335 ++++++++++++++++++++++++++----- xmake/scripts/base/main.lua | 17 +- xmake/scripts/base/project.lua | 180 +++++++++-------- xmake/scripts/base/utils.lua | 12 +- 10 files changed, 652 insertions(+), 404 deletions(-) delete mode 100755 core/src/xmake/preprocessor/load_xproj.c create mode 100755 core/src/xmake/preprocessor/loadx.c diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c index 50b8984a4..375f12bd8 100755 --- a/core/src/xmake/machine.c +++ b/core/src/xmake/machine.c @@ -58,7 +58,7 @@ tb_int_t xm_path_is_absolute(lua_State* lua); tb_int_t xm_string_startswith(lua_State* lua); // the preprocessor functions -tb_int_t xm_preprocessor_load_xproj(lua_State* lua); +tb_int_t xm_preprocessor_loadx(lua_State* lua); /* ////////////////////////////////////////////////////////////////////////////////////// * globals @@ -83,7 +83,7 @@ static luaL_Reg const g_string_functions[] = // the preprocessor functions static luaL_Reg const g_preprocessor_functions[] = { - { "load_xproj", xm_preprocessor_load_xproj } + { "loadx", xm_preprocessor_loadx } , { tb_null, tb_null } }; diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile index 20b4706e3..e0b530bb1 100755 --- a/core/src/xmake/makefile +++ b/core/src/xmake/makefile @@ -18,7 +18,7 @@ xmake_C_FILES += \ path/translate \ path/is_absolute \ string/startswith \ - preprocessor/load_xproj + preprocessor/loadx # flags diff --git a/core/src/xmake/preprocessor/load_xproj.c b/core/src/xmake/preprocessor/load_xproj.c deleted file mode 100755 index a13fb0dc6..000000000 --- a/core/src/xmake/preprocessor/load_xproj.c +++ /dev/null @@ -1,251 +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 load_xproj.c - * - */ - -/* ////////////////////////////////////////////////////////////////////////////////////// - * trace - */ -#define TB_TRACE_MODULE_NAME "load_xproj" -#define TB_TRACE_MODULE_DEBUG (0) - -/* ////////////////////////////////////////////////////////////////////////////////////// - * includes - */ -#include "prefix.h" - -/* ////////////////////////////////////////////////////////////////////////////////////// - * private implementation - */ -static tb_char_t const* xm_preprocessor_load_xproj_to_string(tb_stream_ref_t stream, tb_string_ref_t string) -{ - // check - tb_assert_and_check_return_val(stream && string, tb_null); - - // init value - tb_string_t value; - if (!tb_string_init(&value)) return tb_null; - - // init temporary value - tb_string_t value_temp; - if (!tb_string_init(&value_temp)) return tb_null; - - // done - tb_bool_t is_value = tb_false; - tb_bool_t is_values = tb_false; - while (!tb_stream_beof(stream)) - { - // read character - tb_char_t ch = (tb_char_t)tb_stream_bread_u8(stream); - if (ch) - { - // is values? - if (is_values) - { - // is value? - if (is_value && ch != ',' && ch != ':' && ch != '{' && ch != '}' && ch != '\r' && ch != '\n') - { - // append to value - tb_string_chrcat(&value, ch); - } - // ',' or ':' or '{' or newline? - else if (ch == ',' || ch == ':' || ch == '{' || ch == '}' || ch == '\r' || ch == '\n') - { - // has value? - if (is_value) - { - // values end? append ')' and newline first - if (ch == ':') tb_string_cstrcat(string, ")\n"); - else - { - // trim the left spaces - tb_string_ltrim(&value); - - // trim the right spaces - tb_string_rtrim(&value); - - // wrap "xxx" - if (tb_string_size(&value)) - { - // it has been "xxx"? only copy it - if (tb_string_charat(&value, 0) == '\"') - tb_string_strcpy(&value_temp, &value); - // wrap it - else - { - tb_string_clear(&value_temp); - tb_string_chrcat(&value_temp, '\"'); - tb_string_strcat(&value_temp, &value); - tb_string_chrcat(&value_temp, '\"'); - } - - // clear value first - tb_string_clear(&value); - - // copy and replace '\"' to "\\"" - tb_char_t const* s = tb_string_cstr(&value_temp); - tb_size_t n = tb_string_size(&value_temp); - tb_size_t i = 0; - for (i = 0; i < n; i++) - { - // replace '\"' to "\\"" - if (i && i != n - 1 && s[i] == '\"') tb_string_cstrcat(&value, "\\\""); - // only copy iy - else tb_string_chrcat(&value, s[i]); - } - } - } - - // append value to string - if (tb_string_size(&value)) tb_string_strcat(string, &value); - - // clear value - tb_string_clear(&value); - - // not value now - is_value = tb_false; - } - - // continue to enter values? onyl replace ':' to '(' - if (ch == ':') tb_string_chrcat(string, '('); - // '{' ? - else if (ch == '{') - { - // not values now - is_values = tb_false; - - // append ')' and newline - tb_string_cstrcat(string, ")\n"); - } - // '}' ? - else if (ch == '}') - { - // not values now - is_values = tb_false; - - // append ')' and replace '}' to scopend - tb_string_cstrcat(string, ")\nscopend()"); - } - // skip newline - else if (ch == '\r' || ch == '\n') ; - // append to string - else tb_string_chrcat(string, ch); - } - else - { - // value now - is_value = tb_true; - - // append to value - tb_string_chrcat(&value, ch); - } - } - // enter values? - else if (ch == ':') - { - // values now - is_values = tb_true; - - // replace ':' to '(' - tb_string_chrcat(string, '('); - } - // replace '}' and newline to scopend - else if (ch == '}') tb_string_cstrcat(string, "\nscopend()"); - // append it - else tb_string_chrcat(string, ch); - } - else - { - // end - break; - } - } - - // exit value - tb_string_exit(&value); - - // exit temporary value - tb_string_exit(&value_temp); - - // ok? - return tb_string_size(string)? tb_string_cstr(string) : tb_null; -} - -/* ////////////////////////////////////////////////////////////////////////////////////// - * implementation - */ -tb_int_t xm_preprocessor_load_xproj(lua_State* lua) -{ - // check - tb_assert_and_check_return_val(lua, 0); - - // get the xmake.xproj path - tb_char_t const* path = luaL_checkstring(lua, 1); - tb_check_return_val(path, 0); - - // done - tb_int_t ok = 0; - tb_stream_ref_t stream = tb_null; - tb_string_t string; - do - { - // init string - if (!tb_string_init(&string)) break; - - // init stream - stream = tb_stream_init_from_file(path, TB_FILE_MODE_RO); - tb_assert_and_check_break(stream); - - // open stream - if (!tb_stream_open(stream)) break; - - // load xmake.xproj to the string and preprocess it - tb_char_t const* xproj = xm_preprocessor_load_xproj_to_string(stream, &string); - tb_assert_and_check_break(xproj); - - // trace - tb_trace_d("%s", xproj); - - // load xmake.xproj string to script - if (luaL_loadstring(lua, xproj)) - { - // error - tb_printf("error: %s\n", lua_tostring(lua, -1)); - - // failed - break; - } - - // ok - ok = 1; - - } while (0); - - // exit stream - if (stream) tb_stream_exit(stream); - stream = tb_null; - - // exit string - tb_string_exit(&string); - - // ok? - return ok; -} diff --git a/core/src/xmake/preprocessor/loadx.c b/core/src/xmake/preprocessor/loadx.c new file mode 100755 index 000000000..81763aa4c --- /dev/null +++ b/core/src/xmake/preprocessor/loadx.c @@ -0,0 +1,251 @@ +/*!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 loadx.c + * + */ + +/* ////////////////////////////////////////////////////////////////////////////////////// + * trace + */ +#define TB_TRACE_MODULE_NAME "loadx" +#define TB_TRACE_MODULE_DEBUG (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// + * includes + */ +#include "prefix.h" + +/* ////////////////////////////////////////////////////////////////////////////////////// + * private implementation + */ +static tb_char_t const* xm_preprocessor_loadx_to_string(tb_stream_ref_t stream, tb_string_ref_t string) +{ + // check + tb_assert_and_check_return_val(stream && string, tb_null); + + // init value + tb_string_t value; + if (!tb_string_init(&value)) return tb_null; + + // init temporary value + tb_string_t value_temp; + if (!tb_string_init(&value_temp)) return tb_null; + + // done + tb_bool_t is_value = tb_false; + tb_bool_t is_values = tb_false; + while (!tb_stream_beof(stream)) + { + // read character + tb_char_t ch = (tb_char_t)tb_stream_bread_u8(stream); + if (ch) + { + // is values? + if (is_values) + { + // is value? + if (is_value && ch != ',' && ch != ':' && ch != '{' && ch != '}' && ch != '\r' && ch != '\n') + { + // append to value + tb_string_chrcat(&value, ch); + } + // ',' or ':' or '{' or newline? + else if (ch == ',' || ch == ':' || ch == '{' || ch == '}' || ch == '\r' || ch == '\n') + { + // has value? + if (is_value) + { + // values end? append ')' and newline first + if (ch == ':') tb_string_cstrcat(string, ")\n"); + else + { + // trim the left spaces + tb_string_ltrim(&value); + + // trim the right spaces + tb_string_rtrim(&value); + + // wrap "xxx" + if (tb_string_size(&value)) + { + // it has been "xxx"? only copy it + if (tb_string_charat(&value, 0) == '\"') + tb_string_strcpy(&value_temp, &value); + // wrap it + else + { + tb_string_clear(&value_temp); + tb_string_chrcat(&value_temp, '\"'); + tb_string_strcat(&value_temp, &value); + tb_string_chrcat(&value_temp, '\"'); + } + + // clear value first + tb_string_clear(&value); + + // copy and replace '\"' to "\\"" + tb_char_t const* s = tb_string_cstr(&value_temp); + tb_size_t n = tb_string_size(&value_temp); + tb_size_t i = 0; + for (i = 0; i < n; i++) + { + // replace '\"' to "\\"" + if (i && i != n - 1 && s[i] == '\"') tb_string_cstrcat(&value, "\\\""); + // only copy iy + else tb_string_chrcat(&value, s[i]); + } + } + } + + // append value to string + if (tb_string_size(&value)) tb_string_strcat(string, &value); + + // clear value + tb_string_clear(&value); + + // not value now + is_value = tb_false; + } + + // continue to enter values? onyl replace ':' to '(' + if (ch == ':') tb_string_chrcat(string, '('); + // '{' ? + else if (ch == '{') + { + // not values now + is_values = tb_false; + + // append ')' and newline + tb_string_cstrcat(string, ")\n"); + } + // '}' ? + else if (ch == '}') + { + // not values now + is_values = tb_false; + + // append ')' and replace '}' to _end + tb_string_cstrcat(string, ")\n_end()"); + } + // skip newline + else if (ch == '\r' || ch == '\n') ; + // append to string + else tb_string_chrcat(string, ch); + } + else + { + // value now + is_value = tb_true; + + // append to value + tb_string_chrcat(&value, ch); + } + } + // enter values? + else if (ch == ':') + { + // values now + is_values = tb_true; + + // replace ':' to '(' + tb_string_chrcat(string, '('); + } + // replace '}' and newline to _end + else if (ch == '}') tb_string_cstrcat(string, "\n_end()"); + // append it + else tb_string_chrcat(string, ch); + } + else + { + // end + break; + } + } + + // exit value + tb_string_exit(&value); + + // exit temporary value + tb_string_exit(&value_temp); + + // ok? + return tb_string_size(string)? tb_string_cstr(string) : tb_null; +} + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation + */ +tb_int_t xm_preprocessor_loadx(lua_State* lua) +{ + // check + tb_assert_and_check_return_val(lua, 0); + + // get the xmake.xproj path + tb_char_t const* path = luaL_checkstring(lua, 1); + tb_check_return_val(path, 0); + + // done + tb_int_t ok = 0; + tb_stream_ref_t stream = tb_null; + tb_string_t string; + do + { + // init string + if (!tb_string_init(&string)) break; + + // init stream + stream = tb_stream_init_from_file(path, TB_FILE_MODE_RO); + tb_assert_and_check_break(stream); + + // open stream + if (!tb_stream_open(stream)) break; + + // load xmake.xproj to the string and preprocess it + tb_char_t const* xproj = xm_preprocessor_loadx_to_string(stream, &string); + tb_assert_and_check_break(xproj); + + // trace + tb_trace_d("%s", xproj); + + // load xmake.xproj string to script + if (luaL_loadstring(lua, xproj)) + { + // error + tb_printf("error: %s\n", lua_tostring(lua, -1)); + + // failed + break; + } + + // ok + ok = 1; + + } while (0); + + // exit stream + if (stream) tb_stream_exit(stream); + stream = tb_null; + + // exit string + tb_string_exit(&string); + + // ok? + return ok; +} diff --git a/xmake/scripts/_xmake_main.lua b/xmake/scripts/_xmake_main.lua index 44272d99b..41977a6b3 100644 --- a/xmake/scripts/_xmake_main.lua +++ b/xmake/scripts/_xmake_main.lua @@ -30,7 +30,6 @@ xmake._PROGRAM_DIR = _PROGRAM_DIR xmake._SCRIPTS_DIR = _PROGRAM_DIR .. "/scripts/" xmake._OPTIONS = {} xmake._CONFIGS = {} -xmake._PROJECT = nil -- init package path package.path = xmake._SCRIPTS_DIR .. "?.lua;" .. package.path diff --git a/xmake/scripts/action/_config.lua b/xmake/scripts/action/_config.lua index a627c61d9..ee730a718 100644 --- a/xmake/scripts/action/_config.lua +++ b/xmake/scripts/action/_config.lua @@ -31,9 +31,6 @@ local config = require("base/config") -- done the given config function _config.done() - -- dump configs - config.dump() - -- save configs if not config.savexconf() then return false diff --git a/xmake/scripts/base/config.lua b/xmake/scripts/base/config.lua index ae73b61d8..45ec33494 100644 --- a/xmake/scripts/base/config.lua +++ b/xmake/scripts/base/config.lua @@ -20,15 +20,32 @@ -- @file config.lua -- --- define module: config -local config = config or {} - -- load modules -local io = require("base/io") -local utils = require("base/utils") +local io = require("base/io") +local utils = require("base/utils") +local option = require("base/option") + +-- enter config +local _CONFIG = _CONFIG or {} +local _MAINENV = getfenv() +setmetatable(_CONFIG, {__index = _G}) +setfenv(1, _CONFIG) + +-- init the current scope +local current = nil + +-- configure scope end +function _end() + + -- check + assert(current) + + -- leave the current scope + current = current._PARENT +end -- auto configs -function config._auto(name) +function _auto(name) -- get platform or host if name == "plat" or name == "host" then @@ -43,8 +60,229 @@ function config._auto(name) return "unknown" end +-- register configures +function _register(names) + + -- check + assert(_CONFIG) + assert(names and type(names) == "table") + + -- register all configures + for _, name in ipairs(names) do + + -- register the configure + _CONFIG[name] = _CONFIG[name] or function(...) + + -- check + 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 _init() + + -- check + assert(option._MENU) + assert(option._MENU.config) + + -- 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 + _register(configures) + +end + +-- save object with the level +function _save_with_level(file, object, level) + + -- check + assert(object) + + -- save string + if type(object) == "string" then + file:write(object) + -- save boolean + elseif type(object) == "boolean" then + file:write(tostring(object)) + -- save number + elseif type(object) == "number" then + file:write(object) + -- save function + elseif type(object) == "function" then + file:write("") + -- save table + elseif type(object) == "table" then + + -- save head + file:write(utils.ifelse(level == 0, "config:\n", "\n")) + for l = 1, level do + file:write(" ") + end + file:write("{\n") + + -- save body + for k, v in pairs(object) do + + -- save _TARGETS + if type(k) == "string" and k == "_TARGETS" then + + for _k, _v in pairs(v) do + + -- save spaces + for l = 0, level do + file:write(" ") + end + + -- save key + file:write("target: ", _k) + + -- save value + if not _save_with_level(file, _v, level + 1) then + return false + end + + -- save newline + file:write("\n") + end + + -- exclude _PARENT + elseif type(k) ~= "string" or k ~= "_PARENT" then + + -- save spaces + for l = 0, level do + file:write(" ") + end + + -- save key + if type(k) == "string" then + file:write(k, ": ") + end + + -- save value + if not _save_with_level(file, v, level + 1) then + return false + end + + -- save newline + file:write("\n") + end + end + + -- save tail + for l = 1, level do + file:write(" ") + end + file:write("}\n") + else + -- error + utils.error("invalid object type: %s", type(object)) + return false + end + + -- ok + return true +end + +-- save object +function _save(file, object) + + -- save it + return _save_with_level(file, object, 0) +end + +-- configure target +function target(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 +function config() + + -- init the root scope, must be only one configs + if not _CONFIGS then + _CONFIGS = {} + else + -- error + utils.error("exists double configs!") + return + end + + -- init the current scope + current = _CONFIGS + current._PARENT = nil + +end + +-- get the current target scope +function getarget() + + -- check + assert(_CONFIGS) + + -- the options + local options = xmake._OPTIONS + assert(options) + + -- the target name + local name = options.target or options._DEFAULTS.target + assert(name and type(name) == "string") + + -- for all targets? + if name == "all" then + return _CONFIGS + else + -- init it if not exists + _CONFIGS._TARGETS = _CONFIGS._TARGETS or {} + _CONFIGS._TARGETS[name] = _CONFIGS._TARGETS[name] or {} + + -- get it + return _CONFIGS._TARGETS[name] + end +end + -- save xmake.xconf -function config.savexconf() +function savexconf() -- the options local options = xmake._OPTIONS @@ -60,7 +298,7 @@ function config.savexconf() end -- save configs to file - if not io.save(file, xmake._CONFIGS, "return") then + if not _save(file, _CONFIGS) then -- error utils.error("save %s failed!", path) file:close() @@ -75,52 +313,51 @@ function config.savexconf() end -- load xmake.xconf -function config.loadxconf() +function loadxconf() -- the options local options = xmake._OPTIONS assert(options) - -- the target - local target = options.target or options._DEFAULTS.target - assert(target) - - -- open the configure file + -- load and execute the xmake.xproj local path = options.project .. "/xmake.xconf" - local file = loadfile(path) - if file then + local script = preprocessor.loadx(path) + if script then + + -- init the configs envirnoment + _CONFIG._init() + setfenv(script, _CONFIG) + -- execute it - local ok, cfg = pcall(file) + local ok, err = pcall(script) if not ok then -- error - utils.error("load %s failed!", path) - utils.error(cfg) - return + return err end + end - -- check - assert(cfg and type(cfg) == "table") + -- exists local configures? + if _CONFIGS then -- clear configs if the host environment has been changed - if cfg[target] and cfg[target].host ~= xmake._HOST then - cfg = {} - end - if cfg.all and cfg.all.host ~= xmake._HOST then - cfg = {} + local target = getarget() + if target and target.host ~= xmake._HOST then + _CONFIGS = {} end - - -- merges configs to xmake._CONFIGS - xmake._CONFIGS = cfg end - -- the configs - xmake._CONFIGS = xmake._CONFIGS or {} - local configs = xmake._CONFIGS + -- the target name + local name = options.target or options._DEFAULTS.target + assert(name and type(name) == "string") + + -- ensures the configs + _CONFIGS = _CONFIGS or {} - -- init the configs for the target - configs[target] = configs[target] or {} + -- get the current target scope + local target = getarget() + assert(target and type(target) == "table") - -- merge xmake._OPTIONS to xmake._CONFIGS[target] + -- merge xmake._OPTIONS to target for k, v in pairs(options) do -- check @@ -130,11 +367,11 @@ function config.loadxconf() if not k:startswith("_") and k ~= "project" and k ~= "file" and k ~= "verbose" and k ~= "target" then -- save the option to the target - configs[target][k] = v + target[k] = v end end - -- merge xmake._OPTIONS._DEFAULTS to xmake._CONFIGS[target] + -- merge xmake._OPTIONS._DEFAULTS to target for k, v in pairs(options._DEFAULTS) do -- check @@ -144,26 +381,34 @@ function config.loadxconf() if k ~= "project" and k ~= "file" and k ~= "verbose" and k ~= "target" then -- save the default option to the target - if not configs[target][k] then + if not target[k] then + if v == "auto" then - configs[target][k] = config._auto(k) + target[k] = _auto(k) else - configs[target][k] = v + target[k] = v end end end end + + -- ok + return nil end -- dump configs -function config.dump() +function dump() + -- check + assert(_CONFIGS) + -- dump if xmake._OPTIONS.verbose then - utils.dump(xmake._CONFIGS, "configs = ") + utils.dump(_CONFIGS, "_PARENT") end end --- return module: config -return config +-- leave configs +setfenv(1, _MAINENV) +return _CONFIG diff --git a/xmake/scripts/base/main.lua b/xmake/scripts/base/main.lua index 3b9f3d57a..4b404a73e 100644 --- a/xmake/scripts/base/main.lua +++ b/xmake/scripts/base/main.lua @@ -277,11 +277,12 @@ function main._done_option() end assert(options.file) - -- load xmake.xconf file - config.loadxconf() - - -- load xmake.xproj file - local _, errors = project.loadxproj(options.file) + -- load xmake.xconf file first + local errors = config.loadxconf() + if not errors then + -- load xmake.xproj file + errors = project.loadxproj(options.file) + end -- done help if options.help then @@ -313,12 +314,12 @@ function main._done_option() return false end - -- save project - xmake._PROJECT = project - -- dump project project.dump() + -- dump config + config.dump() + -- done action return action.done(options._ACTION or "build") end diff --git a/xmake/scripts/base/project.lua b/xmake/scripts/base/project.lua index 16ac087c4..a36b71af1 100644 --- a/xmake/scripts/base/project.lua +++ b/xmake/scripts/base/project.lua @@ -24,7 +24,7 @@ local utils = require("base/utils") -- enter project -local _PROJECT = {} +local _PROJECT = _PROJECT or {} local _MAINENV = getfenv() setmetatable(_PROJECT, {__index = _G}) setfenv(1, _PROJECT) @@ -33,7 +33,7 @@ setfenv(1, _PROJECT) local current = nil -- configure scope end -function scopend() +function _end() -- check assert(current) @@ -42,6 +42,88 @@ function scopend() current = current._PARENT end +-- preprocess value +function _preprocess(value) + + -- the value is string? + if type(value) == "string" then + + -- replace $(variable) + value = value:gsub("%$%((.*)%)", function (v) + if v == "buildir" then + -- TODO + return v + --return xmake._CONFIGS.all.output + elseif v == "projectdir" then + return xmake._OPTIONS.project + end + return v + end) + end + + -- ok + return value +end + +-- register configures +function _register(names) + + -- check + assert(_PROJECT) + assert(names and type(names) == "table") + + -- register all configures + for _, name in ipairs(names) do + + -- register the configure + _PROJECT[name] = _PROJECT[name] or function(...) + + -- check + 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] = _preprocess(arg[1]) + else + -- save all arguments + for i, v in ipairs(arg) do + current[name][i] = _preprocess(v) + end + end + end + end +end + +-- init project +function _init() + + -- register all configures + _register { "kind" + , "deps" + , "files" + , "links" + , "mflags" + , "headers" + , "headerdir" + , "targetdir" + , "objectdir" + , "linkdirs" + , "includedirs" + , "cflags" + , "cxxflags" + , "ldflags" + , "mxflags" + , "defines"} +end + -- configure platforms function plarforms(...) @@ -118,65 +200,6 @@ function project(name) end --- preprocess value -function _preprocess(value) - - -- the value is string? - if type(value) == "string" then - - -- replace $(variable) - value = value:gsub("%$%((.*)%)", function (v) - if v == "buildir" then - -- TODO - return xmake._CONFIGS.all.output - elseif v == "projectdir" then - return xmake._OPTIONS.project - end - return v - end) - end - - -- ok - return value -end - --- register configures -function _register(names) - - -- check - assert(_PROJECT) - assert(names and type(names) == "table") - - -- register all configures - for _, name in ipairs(names) do - - -- register the configure - _PROJECT[name] = _PROJECT[name] or function(...) - - -- check - 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] = _preprocess(arg[1]) - else - -- save all arguments - for i, v in ipairs(arg) do - current[name][i] = _preprocess(v) - end - end - end - end -end - -- load xproj function loadxproj(file) @@ -184,56 +207,41 @@ function loadxproj(file) assert(file) -- load and execute the xmake.xproj - local script = preprocessor.load_xproj(file) + local script = preprocessor.loadx(file) if script then -- init the project envirnoment + _PROJECT._init() setfenv(script, _PROJECT) -- execute it local ok, err = pcall(script) if not ok then -- error - return false, err + return err end else -- error - return false, string.format("load %s failed!", file) + return string.format("load %s failed!", file) end -- ok - return true + return nil end -- dump all configures function dump() - + + -- check + assert(_CONFIGS) + -- dump if xmake._OPTIONS.verbose then - utils.dump(xmake._PROJECT._CONFIGS, "", "_PARENT") + utils.dump(_CONFIGS, "_PARENT") end end --- register all configures -_register { "kind" - , "deps" - , "files" - , "links" - , "mflags" - , "headers" - , "headerdir" - , "targetdir" - , "objectdir" - , "linkdirs" - , "includedirs" - , "cflags" - , "cxxflags" - , "ldflags" - , "mxflags" - , "defines"} - - -- leave project setfenv(1, _MAINENV) return _PROJECT diff --git a/xmake/scripts/base/utils.lua b/xmake/scripts/base/utils.lua index c3b4cc38b..8def2a7e6 100644 --- a/xmake/scripts/base/utils.lua +++ b/xmake/scripts/base/utils.lua @@ -65,6 +65,9 @@ function utils._dump_with_level(object, exclude, level) -- dump number elseif type(object) == "number" then io.write(object) + -- dump function + elseif type(object) == "function" then + io.write("") -- dump table elseif type(object) == "table" then @@ -122,13 +125,8 @@ function utils._dump_with_level(object, exclude, level) end -- dump object -function utils.dump(object, prefix, exclude) - - -- dump prefix - if prefix and type(prefix) == "string" then - io.write(prefix) - end - +function utils.dump(object, exclude) + -- dump it utils._dump_with_level(object, exclude, 0) -- cgit v1.3.1