summaryrefslogtreecommitdiff
path: root/xmake/core/language/language.lua
diff options
context:
space:
mode:
authorruki <[email protected]>2017-02-27 10:48:13 +0800
committerruki <[email protected]>2017-02-27 10:48:13 +0800
commit92c6f33e0d4a9c4e657f2f30ef277795062e2fc4 (patch)
treef552a523ec46e02318c5897d667d5335d727a70f /xmake/core/language/language.lua
parentb468766f9a45ffb721dd82363f44539644d3d08d (diff)
fix mix linking
Diffstat (limited to 'xmake/core/language/language.lua')
-rw-r--r--xmake/core/language/language.lua63
1 files changed, 34 insertions, 29 deletions
diff --git a/xmake/core/language/language.lua b/xmake/core/language/language.lua
index 4b0ee358c..97c7d555f 100644
--- a/xmake/core/language/language.lua
+++ b/xmake/core/language/language.lua
@@ -554,12 +554,12 @@ function language.sourcekind_of(sourcefile)
return sourcekind
end
--- get linker info(kind and flag) of the target kind and the source kinds
-function language.linkerinfo_of(targetkind, sourcekinds)
+-- get linker infos(kind and flag) of the target kind and the source kinds
+function language.linkerinfos_of(targetkind, sourcekinds)
- -- load linkerkinds
- local linkerkinds = language._LINKERKINDS
- if not linkerkinds then
+ -- load linkerinfos
+ local linkerinfos = language._LINKERINFOS
+ if not linkerinfos then
-- load all languages
local languages, errors = language.load()
@@ -567,48 +567,53 @@ function language.linkerinfo_of(targetkind, sourcekinds)
return nil, errors
end
- -- make linker kinds
- linkerkinds = {}
+ -- make linker infos
+ linkerinfos = {}
for name, instance in pairs(languages) do
for sourcekind, _ in pairs(instance:sourcekinds()) do
local targetflags = instance:targetflags()
for _targetkind, linkerkind in pairs(instance:targetkinds()) do
- -- make linker info
- local linkerinfo = {kind = linkerkind}
+ -- init linker info
+ linkerinfos[_targetkind] = linkerinfos[_targetkind] or {}
+ linkerinfos[_targetkind][linkerkind] = linkerinfos[_targetkind][linkerkind] or {}
+ local linkerinfo = linkerinfos[_targetkind][linkerkind]
+
+ -- sve linker info
local linkerflag = targetflags[_targetkind]
+ linkerinfo.linkerkind = linkerkind
if linkerflag then
- linkerinfo.flag = linkerflag
+ linkerinfo.linkerflag = linkerflag
end
-
- -- save linker info
- linkerkinds[_targetkind] = linkerkinds[_targetkind] or {}
- linkerkinds[_targetkind][sourcekind] = linkerinfo
+ linkerinfo.sourcekinds = linkerinfo.sourcekinds or {}
+ linkerinfo.sourcekinds[sourcekind] = 1
+ linkerinfo.sourcecount = (linkerinfo.sourcecount or 0) + 1
end
end
end
-- cache it
- language._LINKERKINDS = linkerkinds
+ language._LINKERINFOS = linkerinfos
end
- -- compute the scores of the linker kinds
- local linkerscores = {}
- for _, sourcekind in ipairs(sourcekinds) do
- local linkerinfo = linkerkinds[targetkind][sourcekind]
- if linkerinfo then
- local key = linkerinfo.kind .. (linkerinfo.flag or "")
- linkerscores[key] = linkerscores[key] or {score = 0, info = linkerinfo}
- linkerscores[key].score = linkerscores[key].score + 1
- end
- end
+ -- find suitable linkers
+ local results = {}
+ for _, linkerinfo in pairs(linkerinfos[targetkind]) do
- -- select the suitable linker kind
- for _, linkerscore in pairs(linkerscores) do
- if #sourcekinds == linkerscore.score then
- return linkerscore.info
+ -- match all source kinds?
+ local count = 0
+ for _, sourcekind in ipairs(sourcekinds) do
+ count = count + (linkerinfo.sourcekinds[sourcekind] or 0)
+ end
+ if count == #sourcekinds then
+ table.insert(results, linkerinfo)
end
end
+ if #results > 0 then
+ -- sort it by most matches
+ table.sort(results, function(a, b) return a.sourcecount > b.sourcecount end)
+ return results
+ end
-- not suitable linker
return nil, string.format("no suitable linker for %s.{%s}", targetkind, table.concat(sourcekinds, ' '))