summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-02-04 09:01:00 +0800
committerruki <[email protected]>2017-02-04 09:01:00 +0800
commitc3e976d7c3c3a2883342413deab3511b8194f6e0 (patch)
tree8e8d471fc675043bc84887dfe9bce9fbdfceb289
parentd7b0f7012c71bb59fd45d4b58ea1556380157b8f (diff)
add builder to tool
-rw-r--r--xmake/core/base/table.lua27
-rw-r--r--xmake/core/tool/archiver.lua181
-rw-r--r--xmake/core/tool/builder.lua219
-rw-r--r--xmake/core/tool/compiler.lua178
-rw-r--r--xmake/core/tool/linker.lua1
5 files changed, 243 insertions, 363 deletions
diff --git a/xmake/core/base/table.lua b/xmake/core/base/table.lua
index af1e36fc8..6c37ae219 100644
--- a/xmake/core/base/table.lua
+++ b/xmake/core/base/table.lua
@@ -322,16 +322,16 @@ function table.unique(array)
end
-- inherit interfaces and create a new instance
-function table.inherit(self)
-
- -- check
- assert(self)
+function table.inherit(...)
-- init instance
+ local classes = {...}
local instance = {}
- for k, v in pairs(self) do
- if type(v) == "function" then
- instance[k] = v
+ for _, clasz in ipairs(classes) do
+ for k, v in pairs(clasz) do
+ if type(v) == "function" then
+ instance[k] = v
+ end
end
end
@@ -340,15 +340,18 @@ function table.inherit(self)
end
-- inherit interfaces from the given class
-function table.inherit2(self, clasz)
+function table.inherit2(self, ...)
-- check
- assert(self and clasz)
+ assert(self)
-- init instance
- for k, v in pairs(clasz) do
- if type(v) == "function" and self[k] == nil then
- self[k] = v
+ local classes = {...}
+ for _, clasz in ipairs(classes) do
+ for k, v in pairs(clasz) do
+ if type(v) == "function" and self[k] == nil then
+ self[k] = v
+ end
end
end
diff --git a/xmake/core/tool/archiver.lua b/xmake/core/tool/archiver.lua
index bfeebf87e..3bc45d5d3 100644
--- a/xmake/core/tool/archiver.lua
+++ b/xmake/core/tool/archiver.lua
@@ -37,20 +37,7 @@ local sandbox = require("sandbox/sandbox")
local language = require("language/language")
local platform = require("platform/platform")
local tool = require("tool/tool")
-
--- get the current tool
-function archiver:_tool()
-
- -- get it
- return self._TOOL
-end
-
--- get the named flags
-function archiver:_namedflags()
-
- -- get it
- return self._NAMEDFLAGS
-end
+local builder = require("tool/builder")
-- get the current flag name
function archiver:_flagname()
@@ -100,63 +87,6 @@ function archiver:_flags(target)
return flags
end
--- map gcc flag to the given archiver flag
-function archiver:_mapflag(flag, mapflags)
-
- -- attempt to map it directly
- local flag_mapped = mapflags[flag]
- if flag_mapped then
- return flag_mapped
- end
-
- -- find and replace it using pattern
- for k, v in pairs(mapflags) do
- local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w) return v end)
- if flag_mapped and count ~= 0 then
- return utils.ifelse(#flag_mapped ~= 0, flag_mapped, nil)
- end
- end
-
- -- check it
- if self:check(flag) then
- return flag
- end
-end
-
--- map gcc flags to the given archiver flags
-function archiver:_mapflags(flags)
-
- -- wrap flags first
- flags = table.wrap(flags)
-
- -- done
- local results = {}
- local mapflags = self:get("mapflags")
- if mapflags then
-
- -- map flags
- for _, flag in pairs(flags) do
- local flag_mapped = self:_mapflag(flag, mapflags)
- if flag_mapped then
- table.insert(results, flag_mapped)
- end
- end
-
- else
-
- -- check flags
- for _, flag in pairs(flags) do
- if self:check(flag) then
- table.insert(results, flag)
- end
- end
-
- end
-
- -- ok?
- return results
-end
-
-- add flags from the configure
function archiver:_addflags_from_config(flags)
@@ -185,71 +115,6 @@ function archiver:_addflags_from_archiver(flags)
table.join2(flags, self:get(self:_flagname()))
end
--- add flags (named) from the language
-function archiver:_addflags_from_language(flags, target)
-
- -- init getters
- local getters =
- {
- config = config.get
- , platform = platform.get
- , target = function (name) return target:get(name) end
- , option = function (name)
-
- -- only for target (exclude option)
- if target.options then
- local results = {}
- for _, opt in ipairs(target:options()) do
- table.join2(results, table.wrap(opt:get(name)))
- end
- return results
- end
- end
- }
-
- -- get named flags for archiver
- for _, flaginfo in ipairs(self:_namedflags()) do
-
- -- get flag info
- local flagscope = flaginfo[1]
- local flagname = flaginfo[2]
- local checkstate = flaginfo[3]
-
- -- get getter
- local getter = getters[flagscope]
- assert(getter)
-
- -- get api name of tool
- --
- -- .e.g
- --
- -- defines => define
- -- defines_if_ok => define
- -- ...
- --
- local apiname = flagname:split('_')[1]
- if apiname:endswith("s") then
- apiname = apiname:sub(1, #apiname - 1)
- end
-
- -- map named flag to real flag
- local mapper = self:_tool()[apiname]
- if mapper then
-
- -- add the flags
- for _, flagvalue in ipairs(table.wrap(getter(flagname))) do
-
- -- map and check flag
- local flag = mapper(flagvalue, target)
- if flag and flag ~= "" and (not checkstate or self:check(flag)) then
- table.join2(flags, flag)
- end
- end
- end
- end
-end
-
-
-- load the archiver
function archiver.load(sourcekinds)
@@ -259,7 +124,7 @@ function archiver.load(sourcekinds)
end
-- new instance
- local instance = table.inherit(archiver)
+ local instance = table.inherit(archiver, builder)
-- load the archiver tool from the source file type
local result, errors = tool.load("ar")
@@ -300,13 +165,6 @@ function archiver.load(sourcekinds)
return instance
end
--- get properties of the tool
-function archiver:get(name)
-
- -- get it
- return self:_tool().get(name)
-end
-
-- archive the library file
function archiver:archive(objectfiles, targetfile, target)
@@ -333,40 +191,5 @@ function archiver:archivecmd(objectfiles, targetfile, target)
return self:_tool().archivecmd(table.concat(table.wrap(objectfiles), " "), targetfile, flags or "")
end
--- check the given flags
-function archiver:check(flags)
-
- -- the archiver tool
- local ltool = self:_tool()
-
- -- no check?
- if not ltool.check then
- return true
- end
-
- -- have been checked? return it directly
- self._CHECKED = self._CHECKED or {}
- if self._CHECKED[flags] ~= nil then
- return self._CHECKED[flags]
- end
-
- -- check it
- local ok, errors = sandbox.load(ltool.check, flags)
-
- -- trace
- if option.get("verbose") then
- utils.cprint("checking for the flags %s ... %s", flags, utils.ifelse(ok, "${green}ok", "${red}no"))
- if not ok then
- utils.cprint("${red}" .. errors or "")
- end
- end
-
- -- save the checked result
- self._CHECKED[flags] = ok
-
- -- ok?
- return ok
-end
-
-- return module
return archiver
diff --git a/xmake/core/tool/builder.lua b/xmake/core/tool/builder.lua
new file mode 100644
index 000000000..e3955756b
--- /dev/null
+++ b/xmake/core/tool/builder.lua
@@ -0,0 +1,219 @@
+--!The Make-like Build Utility based on Lua
+--
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015 - 2017, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file builder.lua
+--
+
+-- define module
+local builder = builder or {}
+
+-- load modules
+local io = require("base/io")
+local path = require("base/path")
+local utils = require("base/utils")
+local table = require("base/table")
+local string = require("base/string")
+local option = require("base/option")
+local tool = require("tool/tool")
+local config = require("project/config")
+local sandbox = require("sandbox/sandbox")
+local language = require("language/language")
+local platform = require("platform/platform")
+
+-- get the tool of builder
+function builder:_tool()
+
+ -- get it
+ return self._TOOL
+end
+
+-- get the named flags
+function builder:_namedflags()
+
+ -- get it
+ return self._NAMEDFLAGS
+end
+
+-- map gcc flag to the given builder flag
+function builder:_mapflag(flag, mapflags)
+
+ -- attempt to map it directly
+ local flag_mapped = mapflags[flag]
+ if flag_mapped then
+ return flag_mapped
+ end
+
+ -- find and replace it using pattern
+ for k, v in pairs(mapflags) do
+ local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w) return v end)
+ if flag_mapped and count ~= 0 then
+ return utils.ifelse(#flag_mapped ~= 0, flag_mapped, nil)
+ end
+ end
+
+ -- check it
+ if self:check(flag) then
+ return flag
+ end
+end
+
+-- map gcc flags to the given builder flags
+function builder:_mapflags(flags)
+
+ -- wrap flags first
+ flags = table.wrap(flags)
+
+ -- done
+ local results = {}
+ local mapflags = self:get("mapflags")
+ if mapflags then
+
+ -- map flags
+ for _, flag in pairs(flags) do
+ local flag_mapped = self:_mapflag(flag, mapflags)
+ if flag_mapped then
+ table.insert(results, flag_mapped)
+ end
+ end
+
+ else
+
+ -- check flags
+ for _, flag in pairs(flags) do
+ if self:check(flag) then
+ table.insert(results, flag)
+ end
+ end
+
+ end
+
+ -- ok?
+ return results
+end
+
+-- add flags (named) from the language
+function builder:_addflags_from_language(flags, target)
+
+ -- init getters
+ local getters =
+ {
+ config = config.get
+ , platform = platform.get
+ , target = function (name) return target:get(name) end
+ , option = function (name)
+
+ -- only for target (exclude option)
+ if target.options then
+ local results = {}
+ for _, opt in ipairs(target:options()) do
+ table.join2(results, table.wrap(opt:get(name)))
+ end
+ return results
+ end
+ end
+ }
+
+ -- get named flags for builder
+ for _, flaginfo in ipairs(self:_namedflags()) do
+
+ -- get flag info
+ local flagscope = flaginfo[1]
+ local flagname = flaginfo[2]
+ local checkstate = flaginfo[3]
+
+ -- get getter
+ local getter = getters[flagscope]
+ assert(getter)
+
+ -- get api name of tool
+ --
+ -- .e.g
+ --
+ -- defines => define
+ -- defines_if_ok => define
+ -- ...
+ --
+ local apiname = flagname:split('_')[1]
+ if apiname:endswith("s") then
+ apiname = apiname:sub(1, #apiname - 1)
+ end
+
+ -- map named flag to real flag
+ local mapper = self:_tool()[apiname]
+ if mapper then
+
+ -- add the flags
+ for _, flagvalue in ipairs(table.wrap(getter(flagname))) do
+
+ -- map and check flag
+ local flag = mapper(flagvalue, target)
+ if flag and flag ~= "" and (not checkstate or self:check(flag)) then
+ table.join2(flags, flag)
+ end
+ end
+ end
+ end
+end
+
+-- get properties of the tool
+function builder:get(name)
+
+ -- get it
+ return self:_tool().get(name)
+end
+
+-- check the given flags
+function builder:check(flags)
+
+ -- the builder tool
+ local ctool = self:_tool()
+
+ -- no check?
+ if not ctool.check then
+ return true
+ end
+
+ -- have been checked? return it directly
+ self._CHECKED = self._CHECKED or {}
+ if self._CHECKED[flags] ~= nil then
+ return self._CHECKED[flags]
+ end
+
+ -- check it
+ local ok, errors = sandbox.load(ctool.check, flags)
+
+ -- trace
+ if option.get("verbose") then
+ utils.cprint("checking for the flags %s ... %s", flags, utils.ifelse(ok, "${green}ok", "${red}no"))
+ if not ok then
+ utils.cprint("${red}" .. errors or "")
+ end
+ end
+
+ -- save the checked result
+ self._CHECKED[flags] = ok
+
+ -- ok?
+ return ok
+end
+
+-- return module
+return builder
diff --git a/xmake/core/tool/compiler.lua b/xmake/core/tool/compiler.lua
index e28509384..6e7e5d8e6 100644
--- a/xmake/core/tool/compiler.lua
+++ b/xmake/core/tool/compiler.lua
@@ -33,18 +33,12 @@ local table = require("base/table")
local string = require("base/string")
local option = require("base/option")
local tool = require("tool/tool")
+local builder = require("tool/builder")
local config = require("project/config")
local sandbox = require("sandbox/sandbox")
local language = require("language/language")
local platform = require("platform/platform")
--- get the tool of compiler
-function compiler:_tool()
-
- -- get it
- return self._TOOL
-end
-
-- get the language of compiler
function compiler:_language()
@@ -59,63 +53,6 @@ function compiler:_sourceflags()
return self._SOURCEFLAGS
end
--- map gcc flag to the given compiler flag
-function compiler:_mapflag(flag, mapflags)
-
- -- attempt to map it directly
- local flag_mapped = mapflags[flag]
- if flag_mapped then
- return flag_mapped
- end
-
- -- find and replace it using pattern
- for k, v in pairs(mapflags) do
- local flag_mapped, count = flag:gsub("^" .. k .. "$", function (w) return v end)
- if flag_mapped and count ~= 0 then
- return utils.ifelse(#flag_mapped ~= 0, flag_mapped, nil)
- end
- end
-
- -- check it
- if self:check(flag) then
- return flag
- end
-end
-
--- map gcc flags to the given compiler flags
-function compiler:_mapflags(flags)
-
- -- wrap flags first
- flags = table.wrap(flags)
-
- -- done
- local results = {}
- local mapflags = self:get("mapflags")
- if mapflags then
-
- -- map flags
- for _, flag in pairs(flags) do
- local flag_mapped = self:_mapflag(flag, mapflags)
- if flag_mapped then
- table.insert(results, flag_mapped)
- end
- end
-
- else
-
- -- check flags
- for _, flag in pairs(flags) do
- if self:check(flag) then
- table.insert(results, flag)
- end
- end
-
- end
-
- -- ok?
- return results
-end
-
-- add flags from the configure
function compiler:_addflags_from_config(flags)
@@ -170,70 +107,6 @@ function compiler:_addflags_from_compiler(flags, kind)
end
end
--- add flags (named) from the language
-function compiler:_addflags_from_language(flags, target)
-
- -- init getters
- local getters =
- {
- config = config.get
- , platform = platform.get
- , target = function (name) return target:get(name) end
- , option = function (name)
-
- -- only for target (exclude option)
- if target.options then
- local results = {}
- for _, opt in ipairs(target:options()) do
- table.join2(results, table.wrap(opt:get(name)))
- end
- return results
- end
- end
- }
-
- -- get named flags for compiler
- for _, flaginfo in ipairs(self:_language():namedflags()["compiler"]) do
-
- -- get flag info
- local flagscope = flaginfo[1]
- local flagname = flaginfo[2]
- local checkstate = flaginfo[3]
-
- -- get getter
- local getter = getters[flagscope]
- assert(getter)
-
- -- get api name of tool
- --
- -- .e.g
- --
- -- defines => define
- -- defines_if_ok => define
- -- ...
- --
- local apiname = flagname:split('_')[1]
- if apiname:endswith("s") then
- apiname = apiname:sub(1, #apiname - 1)
- end
-
- -- map named flag to real flag
- local mapper = self:_tool()[apiname]
- if mapper then
-
- -- add the flags
- for _, flagvalue in ipairs(table.wrap(getter(flagname))) do
-
- -- map and check flag
- local flag = mapper(flagvalue, target)
- if flag and flag ~= "" and (not checkstate or self:check(flag)) then
- table.join2(flags, flag)
- end
- end
- end
- end
-end
-
-- load the compiler from the given source kind
function compiler.load(sourcekind)
@@ -247,7 +120,7 @@ function compiler.load(sourcekind)
end
-- new instance
- local instance = table.inherit(compiler)
+ local instance = table.inherit(compiler, builder)
-- load the compiler tool from the source kind
local result, errors = tool.load(sourcekind)
@@ -263,7 +136,10 @@ function compiler.load(sourcekind)
end
instance._LANGUAGE = result
- -- get source flags
+ -- init named flags
+ instance._NAMEDFLAGS = result:namedflags()["compiler"]
+
+ -- init source flags
instance._SOURCEFLAGS = table.wrap(result:sourceflags()[sourcekind])
-- save this instance
@@ -273,13 +149,6 @@ function compiler.load(sourcekind)
return instance
end
--- get properties of the tool
-function compiler:get(name)
-
- -- get it
- return self:_tool().get(name)
-end
-
-- compile the source file
function compiler:compile(sourcefile, objectfile, incdepfile, target)
@@ -341,40 +210,5 @@ function compiler:compflags(target)
return flags_str, flags
end
--- check the given flags
-function compiler:check(flags)
-
- -- the compiler tool
- local ctool = self:_tool()
-
- -- no check?
- if not ctool.check then
- return true
- end
-
- -- have been checked? return it directly
- self._CHECKED = self._CHECKED or {}
- if self._CHECKED[flags] ~= nil then
- return self._CHECKED[flags]
- end
-
- -- check it
- local ok, errors = sandbox.load(ctool.check, flags)
-
- -- trace
- if option.get("verbose") then
- utils.cprint("checking for the flags %s ... %s", flags, utils.ifelse(ok, "${green}ok", "${red}no"))
- if not ok then
- utils.cprint("${red}" .. errors or "")
- end
- end
-
- -- save the checked result
- self._CHECKED[flags] = ok
-
- -- ok?
- return ok
-end
-
-- return module
return compiler
diff --git a/xmake/core/tool/linker.lua b/xmake/core/tool/linker.lua
index 674e5345a..50876e613 100644
--- a/xmake/core/tool/linker.lua
+++ b/xmake/core/tool/linker.lua
@@ -36,6 +36,7 @@ local config = require("project/config")
local sandbox = require("sandbox/sandbox")
local platform = require("platform/platform")
local tool = require("tool/tool")
+local builder = require("tool/builder")
local compiler = require("tool/compiler")
-- get the current tool