diff options
| author | ruki <[email protected]> | 2017-02-04 09:01:00 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-02-04 09:01:00 +0800 |
| commit | c3e976d7c3c3a2883342413deab3511b8194f6e0 (patch) | |
| tree | 8e8d471fc675043bc84887dfe9bce9fbdfceb289 | |
| parent | d7b0f7012c71bb59fd45d4b58ea1556380157b8f (diff) | |
add builder to tool
| -rw-r--r-- | xmake/core/base/table.lua | 27 | ||||
| -rw-r--r-- | xmake/core/tool/archiver.lua | 181 | ||||
| -rw-r--r-- | xmake/core/tool/builder.lua | 219 | ||||
| -rw-r--r-- | xmake/core/tool/compiler.lua | 178 | ||||
| -rw-r--r-- | xmake/core/tool/linker.lua | 1 |
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 |
