summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-02-04 10:24:21 +0800
committerruki <[email protected]>2017-02-04 10:24:21 +0800
commit6162f24b4c7a443e78ea68e5e0407ac60eb561fe (patch)
treed122b322b4f7715b06deee523db5c654caa3fe42
parentc3e976d7c3c3a2883342413deab3511b8194f6e0 (diff)
add linkerkind_of for language
-rwxr-xr-xxmake/actions/config/scanner.lua2
-rw-r--r--xmake/core/language/language.lua114
-rw-r--r--xmake/core/sandbox/modules/import/core/language/language.lua4
-rw-r--r--xmake/core/tool/linker.lua152
-rwxr-xr-xxmake/languages/asm/xmake.lua5
-rwxr-xr-xxmake/languages/c++/xmake.lua5
-rwxr-xr-xxmake/languages/golang/xmake.lua5
-rwxr-xr-xxmake/languages/objc++/xmake.lua5
-rwxr-xr-xxmake/languages/swift/xmake.lua5
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")