diff options
| author | ruki <[email protected]> | 2017-02-04 10:24:21 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-02-04 10:24:21 +0800 |
| commit | 6162f24b4c7a443e78ea68e5e0407ac60eb561fe (patch) | |
| tree | d122b322b4f7715b06deee523db5c654caa3fe42 | |
| parent | c3e976d7c3c3a2883342413deab3511b8194f6e0 (diff) | |
add linkerkind_of for language
| -rwxr-xr-x | xmake/actions/config/scanner.lua | 2 | ||||
| -rw-r--r-- | xmake/core/language/language.lua | 114 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/language/language.lua | 4 | ||||
| -rw-r--r-- | xmake/core/tool/linker.lua | 152 | ||||
| -rwxr-xr-x | xmake/languages/asm/xmake.lua | 5 | ||||
| -rwxr-xr-x | xmake/languages/c++/xmake.lua | 5 | ||||
| -rwxr-xr-x | xmake/languages/golang/xmake.lua | 5 | ||||
| -rwxr-xr-x | xmake/languages/objc++/xmake.lua | 5 | ||||
| -rwxr-xr-x | xmake/languages/swift/xmake.lua | 5 |
9 files changed, 57 insertions, 240 deletions
diff --git a/xmake/actions/config/scanner.lua b/xmake/actions/config/scanner.lua index 049bf1b41..fd363c8df 100755 --- a/xmake/actions/config/scanner.lua +++ b/xmake/actions/config/scanner.lua @@ -58,7 +58,7 @@ function make() -- add targetkinds if filecount > 0 then - for _, targetkind in ipairs(instance:targetkinds()) do + for targetkind, _ in pairs(instance:targetkinds()) do targetkinds[targetkind] = true end end diff --git a/xmake/core/language/language.lua b/xmake/core/language/language.lua index 7b3dfc93e..42bedf09e 100644 --- a/xmake/core/language/language.lua +++ b/xmake/core/language/language.lua @@ -131,30 +131,11 @@ function _instance:sourceflags() return self._INFO.sourceflags end --- get the linker kinds -function _instance:linkerkinds() - - -- attempt to get it from cache first - if self._LINKERKINDS then - return self._LINKERKINDS - end - - -- merge all for each language - local linkerkinds = {} - for linkerkind, sourcekinds in pairs(table.wrap(self._INFO.linkerkinds)) do - for _, sourcekind in ipairs(sourcekinds) do - linkerkinds[sourcekind] = table.join(linkerkinds[sourcekind] or {}, linkerkind) - end - end - - -- cache this results - self._LINKERKINDS = linkerkinds - - -- ok? - return linkerkinds -end - --- get the target kinds +-- get the target kinds (targetkind => linkerkind) +-- +-- .e.g +-- {binary = "ld", static = "ar", shared = "sh"} +-- function _instance:targetkinds() -- get it @@ -239,7 +220,6 @@ function language._interpreter() { -- language.set_xxx "language.set_menu" - , "language.set_targetkinds" } , script = { @@ -253,7 +233,7 @@ function language._interpreter() "language.set_namedflags" , "language.set_sourcekinds" , "language.set_sourceflags" - , "language.set_linkerkinds" + , "language.set_targetkinds" } } @@ -540,47 +520,6 @@ function language.sourceflags() return sourceflags end --- get language linker kinds (sourcekind => linkerkinds) --- --- .e.g --- --- { --- cc = {"ld", "go"} --- , mm = {"ld"} --- , go = {"go"} --- , sc = {"ld"} --- , cxx = {"ld", "go"} --- , as = {"ld", "go"} --- } --- -function language.linkerkinds() - - -- attempt to get it from cache - if language._LINKERKINDS then - return language._LINKERKINDS - end - - -- load all languages - local languages, errors = language.load() - if not languages then - os.raise(errors) - end - - -- merge all for each language - local results = {} - for name, instance in pairs(languages) do - for sourcekind, linkerkinds in pairs(instance:linkerkinds()) do - results[sourcekind] = table.unique(table.join(results[sourcekind] or {}, linkerkinds)) - end - end - - -- cache it - language._LINKERKINDS = results - - -- ok - return results -end - -- get source kind of the source file name function language.sourcekind_of(sourcefile) @@ -603,29 +542,52 @@ function language.sourcekind_of(sourcefile) return sourcekind end --- get linker kind of the source kinds -function language.linkerkind_of(sourcekinds) +-- get linker kind of the target kind and the source kinds +function language.linkerkind_of(targetkind, sourcekinds) + + -- load linkerkinds + local linkerkinds = language._LINKERKINDS + if not linkerkinds then - -- get linkerkinds - local linkerkinds = language.linkerkinds() + -- load all languages + local languages, errors = language.load() + if not languages then + return nil, errors + end - -- compute the scores of linker kinds + -- make linker kinds + linkerkinds = {} + for name, instance in pairs(languages) do + for sourcekind, _ in pairs(instance:sourcekinds()) do + for _targetkind, linkerkind in pairs(instance:targetkinds()) do + linkerkinds[_targetkind] = linkerkinds[_targetkind] or {} + linkerkinds[_targetkind][sourcekind] = linkerkind + end + end + end + + -- cache it + language._LINKERKINDS = linkerkinds + end + + -- compute the scores of the linker kinds local linkerscores = {} for _, sourcekind in ipairs(sourcekinds) do - for _, linkerkind in ipairs(table.wrap(linkerkinds[sourcekind])) do + local linkerkind = linkerkinds[targetkind][sourcekind] + if linkerkind then linkerscores[linkerkind] = (linkerscores[linkerkind] or 0) + 1 end end - -- get the linker kind with max score + -- select the suitable linker kind for linkerkind, linkerscore in pairs(linkerscores) do if #sourcekinds == linkerscore then return linkerkind end end - -- ok - return nil, string.format("no suitable linker for '%s'", table.concat(sourcekinds, " ")) + -- not suitable linker + return nil, string.format("no suitable linker for %s.{%s}", targetkind, table.concat(sourcekinds, ' ')) end -- return module diff --git a/xmake/core/sandbox/modules/import/core/language/language.lua b/xmake/core/sandbox/modules/import/core/language/language.lua index 6b50f8830..05ec75f46 100644 --- a/xmake/core/sandbox/modules/import/core/language/language.lua +++ b/xmake/core/sandbox/modules/import/core/language/language.lua @@ -110,10 +110,10 @@ function sandbox_core_language.sourcekind_of(sourcefile) end -- get linker kind of the source kinds -function sandbox_core_language.linkerkind_of(sourcekinds) +function sandbox_core_language.linkerkind_of(targetkind, sourcekinds) -- get it - local linkerkind, errors = language.linkerkind_of(sourcekinds) + local linkerkind, errors = language.linkerkind_of(targetkind, sourcekinds) if not linkerkind then raise(errors) end diff --git a/xmake/core/tool/linker.lua b/xmake/core/tool/linker.lua index 50876e613..b7d1d48f3 100644 --- a/xmake/core/tool/linker.lua +++ b/xmake/core/tool/linker.lua @@ -34,18 +34,12 @@ local string = require("base/string") local option = require("base/option") local config = require("project/config") local sandbox = require("sandbox/sandbox") +local language = require("language/language") local platform = require("platform/platform") local tool = require("tool/tool") local builder = require("tool/builder") local compiler = require("tool/compiler") --- get the current tool -function linker:_tool() - - -- get it - return self._TOOL -end - -- get the current flag name function linker:_flagname() @@ -53,86 +47,6 @@ function linker:_flagname() return self._FLAGNAME end --- get the link kind of the target kind -function linker._kind_of_target(targetkind, sourcekinds) - - -- link the target of golang objects - if sourcekinds then - for _, sourcekind in ipairs(sourcekinds) do - if sourcekind == "go" then - return "go" - end - end - end - - -- the kinds - local kinds = - { - ["binary"] = "ld" - , ["shared"] = "sh" - } - - -- get kind - return kinds[targetkind] -end - --- map gcc flag to the given linker flag -function linker:_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 linker flags -function linker:_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 linker:_addflags_from_config(flags) @@ -267,27 +181,25 @@ end function linker.load(targetkind, sourcekinds) -- get the linker kind - local kind = linker._kind_of_target(targetkind, sourcekinds) - if not kind then - return nil, string.format("unknown target kind: %s", targetkind) + local linkerkind, errors = language.linkerkind_of(targetkind, sourcekinds) + if not linkerkind then + return nil, errors end -- get it directly from cache dirst linker._INSTANCES = linker._INSTANCES or {} - if linker._INSTANCES[kind] then - return linker._INSTANCES[kind] + if linker._INSTANCES[linkerkind] then + return linker._INSTANCES[linkerkind] end -- new instance - local instance = table.inherit(linker) + local instance = table.inherit(linker, builder) -- load the linker tool from the source file type - local result, errors = tool.load(kind) + local result, errors = tool.load(linkerkind) if not result then return nil, errors end - - -- save tool instance._TOOL = result -- save flagname @@ -297,27 +209,20 @@ function linker.load(targetkind, sourcekinds) , sh = "shflags" , go = "goflags" } - instance._FLAGNAME = flagname[kind] + instance._FLAGNAME = flagname[linkerkind] -- check if not instance._FLAGNAME then - return nil, string.format("unknown linker for kind: %s", kind) + return nil, string.format("unknown linker for kind: %s", linkerkind) end -- save this instance - linker._INSTANCES[kind] = instance + linker._INSTANCES[linkerkind] = instance -- ok return instance end --- get properties of the tool -function linker:get(name) - - -- get it - return self:_tool().get(name) -end - -- link the target file function linker:link(objectfiles, targetfile, target) @@ -416,40 +321,5 @@ function linker:linkdir(dir) return self:_tool().linkdir(dir) end --- check the given flags -function linker:check(flags) - - -- the linker 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 linker diff --git a/xmake/languages/asm/xmake.lua b/xmake/languages/asm/xmake.lua index c614b2d55..36a54c271 100755 --- a/xmake/languages/asm/xmake.lua +++ b/xmake/languages/asm/xmake.lua @@ -31,11 +31,8 @@ language("asm") -- set source file flags set_sourceflags {as = "asflags"} - -- set linker kinds (linker => source kinds) - set_linkerkinds {ld = {"as"}} - -- set target kinds - set_targetkinds("binary", "static", "shared") + set_targetkinds {binary = "ld", static = "ar", shared = "sh"} -- on load on_load("load") diff --git a/xmake/languages/c++/xmake.lua b/xmake/languages/c++/xmake.lua index 3680d5c65..d31fc1bc2 100755 --- a/xmake/languages/c++/xmake.lua +++ b/xmake/languages/c++/xmake.lua @@ -31,11 +31,8 @@ language("c++") -- set source file flags set_sourceflags {cc = {"cflags", "cxflags"}, cxx = {"cxxflags", "cxflags"}} - -- set linker kinds (linker => source kinds) - set_linkerkinds {ld = {"cc", "cxx"}} - -- set target kinds - set_targetkinds("binary", "static", "shared") + set_targetkinds {binary = "ld", static = "ar", shared = "sh"} -- on load on_load("load") diff --git a/xmake/languages/golang/xmake.lua b/xmake/languages/golang/xmake.lua index be74d6c11..706ad2df0 100755 --- a/xmake/languages/golang/xmake.lua +++ b/xmake/languages/golang/xmake.lua @@ -31,11 +31,8 @@ language("golang") -- set source file flags set_sourceflags {go = "goflags"} - -- set linker kinds (linker => source kinds) - set_linkerkinds {go = {"go", "cc", "cxx", "as"}} - -- set target kinds - set_targetkinds("binary", "static", "shared") + set_targetkinds {binary = "go", static = "go", shared = "go"} -- on load on_load("load") diff --git a/xmake/languages/objc++/xmake.lua b/xmake/languages/objc++/xmake.lua index 6fd6a1144..ab1e2f80e 100755 --- a/xmake/languages/objc++/xmake.lua +++ b/xmake/languages/objc++/xmake.lua @@ -31,11 +31,8 @@ language("objc++") -- set source file flags set_sourceflags {mm = {"mflags", "mxflags"}, mxx = {"mxxflags", "mxflags"}} - -- set linker kinds (linker => source kinds) - set_linkerkinds {ld = {"mm", "mxx"}} - -- set target kinds - set_targetkinds("binary", "static", "shared") + set_targetkinds {binary = "ld", static = "ar", shared = "sh"} -- on load on_load("load") diff --git a/xmake/languages/swift/xmake.lua b/xmake/languages/swift/xmake.lua index 85ff05f46..484bb46f2 100755 --- a/xmake/languages/swift/xmake.lua +++ b/xmake/languages/swift/xmake.lua @@ -31,11 +31,8 @@ language("swift") -- set source file flags set_sourceflags {sc = "scflags"} - -- set linker kinds (linker => source kinds) - set_linkerkinds {ld = {"sc"}} - -- set target kinds - set_targetkinds("binary") + set_targetkinds {binary = "ld", static = "ar", shared = "sh"} -- on load on_load("load") |
