summaryrefslogtreecommitdiff
path: root/xmake/scripts/base
diff options
context:
space:
mode:
authorruki <[email protected]>2015-06-09 15:13:59 +0800
committerruki <[email protected]>2015-06-09 15:13:59 +0800
commitbf0040998da482cb640a3637fd91e36a0495b27b (patch)
treea793de42032147ebb2577fe9c38439ec2c36e800 /xmake/scripts/base
parentf6fec59106383347489ed77bb1896a9ccf5bbb2d (diff)
add archs interfaces
Diffstat (limited to 'xmake/scripts/base')
-rw-r--r--xmake/scripts/base/preprocessor.lua279
-rw-r--r--xmake/scripts/base/project.lua139
2 files changed, 136 insertions, 282 deletions
diff --git a/xmake/scripts/base/preprocessor.lua b/xmake/scripts/base/preprocessor.lua
deleted file mode 100644
index a8fd9fa39..000000000
--- a/xmake/scripts/base/preprocessor.lua
+++ /dev/null
@@ -1,279 +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 <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a>
---
--- Copyright (C) 2009 - 2015, ruki All rights reserved.
---
--- @author ruki
--- @file preprocessor.lua
---
-
--- define module: preprocessor
-local preprocessor = preprocessor or {}
-
--- load modules
-local utils = require("base/utils")
-
--- filter value
-function preprocessor._filter(env, value, filter)
-
- -- the value is string?
- if type(value) == "string" then
-
- -- init
- local _v = nil
- local _n = 0
-
- -- replace it for filter
- if filter then
- -- replace $(variable)
- _v, _n = value:gsub("%$%((.*)%)", function (v) return filter(env, v) end)
- end
-
- -- replace it for script
- if _n == 0 then
- _v, _n = value:gsub("%[(.*)%]", function (v)
-
- -- load the script
- local script = assert(loadstring("return " .. v))
-
- -- bind the envirnoment
- setfenv(script, env)
-
- -- done it
- local ok, result = pcall(script)
- if not ok then return end
-
- -- ok?
- return result or ""
- end)
- end
-
- -- update value
- value = _v
- end
-
- -- ok
- return value
-end
-
--- register configures
-function preprocessor._register(env, names, filter)
-
- -- check
- assert(env and names and type(names) == "table")
- assert(not filter or type(filter) == "function")
-
- -- 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 the configure entry
- _current[name] = _current[name] or {}
-
- -- get arguments
- local arg = arg or {...}
- if table.getn(arg) == 0 then
- -- no argument
- _current[name] = nil
- else
- -- save all arguments
- for _, v in ipairs(arg) do
- v = preprocessor._filter(env, v, filter)
- if v and type(v) == "string" and #v ~= 0 then
- table.insert(_current[name], v)
- end
- end
- end
- end
- end
-end
-
--- init configures
-function preprocessor._init(root, configures, scopes, filter, import)
-
- -- check
- assert(root and configures)
-
- -- enter new environment
- local newenv = {}
- local oldenv = getfenv()
- setmetatable(newenv, { __index = function(tbl, key)
- -- private configure entry? we can get it directly and need not register it
- if key and type(key) == "string" and key:startswith("__") then
-
- return function(...)
-
- -- check
- local _current = newenv._current
- assert(_current)
-
- -- init the configure entry
- _current[key] = _current[key] or {}
-
- -- get arguments
- local arg = arg or {...}
- if table.getn(arg) == 0 then
- -- no argument
- _current[key] = nil
- elseif table.getn(arg) == 1 then
- -- save only one argument
- _current[key] = arg[1]
- else
- -- save all arguments
- for i, v in ipairs(arg) do
- _current[key][i] = v
- end
- end
- end
- end
-
- -- get it from the global table
- return rawget(_G, key)
- end})
- setfenv(1, newenv)
-
- -- register all configures
- preprocessor._register(newenv, configures, filter)
-
- -- configure import
- if import then
- newenv["import"] = import
- end
-
- -- configure scope end
- newenv["_end"] = function ()
-
- -- check
- assert(_current)
-
- -- leave the current scope
- _current = _current._PARENT
- end
-
- -- configure scopes
- if scopes then
- for _, scope_name in ipairs(scopes) do
-
- newenv[scope_name] = function (...)
-
- -- check
- assert(_current)
-
- -- init config name
- local config_name = "_" .. scope_name:upper()
-
- -- init scope config
- _current[config_name] = _current[config_name] or {}
- local scope_config = _current[config_name]
-
- -- init scope
- local scope = {}
-
- -- configure all
- local arg = arg or {...}
- for _, name in ipairs(arg) do
-
- -- check
- if scope_config[name] then
- -- error
- utils.error("the %s: %s has been defined repeatly!", config_name, name)
- assert(false)
- end
-
- -- init the scope
- scope_config[name] = scope
-
- end
-
- -- enter scope
- local parent = _current
- _current = scope
- _current._PARENT = parent
- end
- end
- 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 %s!", root)
- 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", ...}, {"target"})
--- local configs, errors = preprocessor.loadfile("xmake.xproj", "project", {"links", "files", "ldflags", ...}, {"target", "platforms"}, filter, import)
--- @endcode
-function preprocessor.loadfile(path, root, configures, scopes, filter, import)
-
- -- 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, scopes, filter, import)
- 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
- else
- -- error
- return nil, string.format("load %s failed!", path)
- end
-end
-
--- return module: preprocessor
-return preprocessor
diff --git a/xmake/scripts/base/project.lua b/xmake/scripts/base/project.lua
index 70d31c061..09bdecd1b 100644
--- a/xmake/scripts/base/project.lua
+++ b/xmake/scripts/base/project.lua
@@ -45,7 +45,7 @@ function project._api_modes(env, ...)
end
-- the current platform is belong to the given platforms?
-function project._api_platforms(env, ...)
+function project._api_plats(env, ...)
-- get the current platform
local plat = config.get("plat")
@@ -59,6 +59,21 @@ function project._api_platforms(env, ...)
end
end
+-- the current platform is belong to the given architectures?
+function project._api_archs(env, ...)
+
+ -- get the current architecture
+ local arch = config.get("arch")
+ assert(arch)
+
+ -- exists this architecture?
+ for _, a in ipairs(utils.wrap(...)) do
+ if a and type(a) == "string" and a == arch then
+ return true
+ end
+ end
+end
+
-- load all subprojects from the given directories
function project._api_subdirs(env, ...)
@@ -194,7 +209,108 @@ function project._filter(values)
-- ok?
return newvals
end
-
+
+-- make configure for the given target_name
+function project._makeconf_for_target(target_name, target)
+
+ -- check
+ assert(target_name and target)
+
+ -- get the target configure file
+ local configfile = target.configfile
+ if not configfile then
+ return true
+ end
+
+ -- translate file path
+ if not path.is_absolute(configfile) then
+ configfile = path.absolute(configfile, xmake._PROJECT_DIR)
+ else
+ configfile = path.translate(configfile)
+ end
+
+ -- the prefix
+ local prefix = target_name:upper() .. "_CONFIG"
+
+ -- open the file
+ local file = io.open(configfile, "w")
+
+ -- make the head
+ file:write(string.format("#ifndef %s_H\n", prefix))
+ file:write(string.format("#define %s_H\n", prefix))
+ file:write("\n")
+
+ -- make version
+ if target.version then
+ file:write("// version\n")
+ file:write(string.format("#define %s_VERSION \"%s\"\n", prefix, target.version))
+ local i = 1
+ local m = {"MAJOR", "MINOR", "ALTER"}
+ for v in target.version:gmatch("%d+") do
+ file:write(string.format("#define %s_VERSION_%s %s\n", prefix, m[i], v))
+ i = i + 1
+ if i > 3 then break end
+ end
+ file:write(string.format("#define %s_VERSION_BUILD %d\n", prefix, os.date("%Y%m%d%H%M", os.time())))
+ file:write("\n")
+ end
+
+ -- make the undefines
+ if target.undefines then
+ file:write("// undefines\n")
+ for _, undefine in ipairs(utils.wrap(target.undefines)) do
+ file:write(string.format("#undef %s\n", undefine))
+ end
+ file:write("\n")
+ end
+
+ -- make the defines
+ if target.defines then
+ file:write("// defines\n")
+ for _, define in ipairs(utils.wrap(target.defines)) do
+ file:write(string.format("#define %s\n", define))
+ end
+ file:write("\n")
+ end
+
+ -- make the tail
+ file:write("#endif\n")
+
+ -- exit the file
+ file:close()
+
+ -- ok
+ return true
+end
+
+-- make the configure file for the given target and dependents
+function project._makeconf_for_target_and_deps(target_name)
+
+ -- the targets
+ local targets = project.targets()
+ assert(targets)
+
+ -- the target
+ local target = targets[target_name]
+ assert(target)
+
+ -- make configure for the target
+ if not project._makeconf_for_target(target_name, target) then
+ return false
+ end
+
+ -- exists the dependent targets?
+ if target.deps then
+ local deps = utils.wrap(target.deps)
+ for _, dep in ipairs(deps) do
+ if not project._makeconf_for_target_and_deps(dep) then return false end
+ end
+ end
+
+ -- ok
+ return true
+end
+
-- make the current project configure
function project._make(configs)
@@ -278,7 +394,8 @@ function project.load(file)
-- register interfaces for the condition
newenv.modes = function (...) return project._api_modes(newenv, ...) end
- newenv.platforms = function (...) return project._api_platforms(newenv, ...) end
+ newenv.plats = function (...) return project._api_plats(newenv, ...) end
+ newenv.archs = function (...) return project._api_archs(newenv, ...) end
-- register interfaces for the target
newenv.target = function (...) return project._api_target(newenv, ...) end
@@ -351,6 +468,22 @@ end
-- make the configure file for the given target
function project.makeconf(target_name)
+ -- the target name
+ if target_name and target_name ~= "all" then
+ -- make configure for the target and dependents
+ if not project._makeconf_for_target_and_deps(target_name) then return false end
+ else
+
+ -- the targets
+ local targets = project.targets()
+ assert(targets)
+
+ -- make configure for the targets
+ for target_name, target in pairs(targets) do
+ if not project._makeconf_for_target(target_name, target) then return false end
+ end
+ end
+
-- ok
return true
end