summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2018-12-20 23:46:03 +0800
committerruki <[email protected]>2018-12-20 16:36:22 +0800
commit38315771588ae29bacc20cae6a16fa0d4d8a2be5 (patch)
tree063f662f1e8c22b39864e3b0d3c94355c3b633c8
parenta9f3eac5faf29e1a60b68ec2ac7ec791ef7549ee (diff)
improve compiler and linker
-rw-r--r--xmake/core/tool/compiler.lua43
-rw-r--r--xmake/core/tool/linker.lua83
-rw-r--r--xmake/core/tool/tool.lua4
-rw-r--r--xmake/modules/lib/detect/has_flags.lua7
4 files changed, 88 insertions, 49 deletions
diff --git a/xmake/core/tool/compiler.lua b/xmake/core/tool/compiler.lua
index 9c622ba33..b12b59d6d 100644
--- a/xmake/core/tool/compiler.lua
+++ b/xmake/core/tool/compiler.lua
@@ -77,8 +77,8 @@ function compiler:_addflags_from_compiler(flags, targetkind)
end
end
--- load the compiler from the given source kind
-function compiler.load(sourcekind, target)
+-- load compiler tool
+function compiler._load_tool(sourcekind, target)
-- get program from target
local program = nil
@@ -89,27 +89,42 @@ function compiler.load(sourcekind, target)
end
end
- -- init key
- local key = sourcekind .. (program or "")
+ -- load the compiler tool from the source kind
+ local result, errors = tool.load(sourcekind, program)
+ if not result then
+ return nil, errors
+ end
+
+ -- done
+ return result, program
+end
+
+-- load the compiler from the given source kind
+function compiler.load(sourcekind, target)
+
+ -- load compiler tool first (with cache)
+ local compiler_tool, program_or_errors = compiler._load_tool(sourcekind, target)
+ if not compiler_tool then
+ return nil, program_or_errors
+ end
+
+ -- init cache key
+ local cachekey = sourcekind .. (program_or_errors or "")
-- get it directly from cache dirst
compiler._INSTANCES = compiler._INSTANCES or {}
- if compiler._INSTANCES[key] then
- return compiler._INSTANCES[key]
+ if compiler._INSTANCES[cachekey] then
+ return compiler._INSTANCES[cachekey]
end
-- new instance
local instance = table.inherit(compiler, builder)
- -- load the compiler tool from the source kind
- local result, errors = tool.load(sourcekind, program)
- if not result then
- return nil, errors
- end
- instance._TOOL = result
+ -- save the compiler tool
+ instance._TOOL = compiler_tool
-- load the compiler language from the source kind
- result, errors = language.load_sk(sourcekind)
+ local result, errors = language.load_sk(sourcekind)
if not result then
return nil, errors
end
@@ -125,7 +140,7 @@ function compiler.load(sourcekind, target)
instance._FLAGKINDS = table.wrap(result:sourceflags()[sourcekind])
-- save this instance
- compiler._INSTANCES[key] = instance
+ compiler._INSTANCES[cachekey] = instance
-- ok
return instance
diff --git a/xmake/core/tool/linker.lua b/xmake/core/tool/linker.lua
index ec177aa20..423dce0e0 100644
--- a/xmake/core/tool/linker.lua
+++ b/xmake/core/tool/linker.lua
@@ -100,23 +100,8 @@ function linker:_addflags_from_linker(flags)
end
end
--- load the linker from the given target kind
-function linker.load(targetkind, sourcekinds, target)
-
- -- check
- assert(sourcekinds)
-
- -- wrap sourcekinds first
- sourcekinds = table.wrap(sourcekinds)
- if #sourcekinds == 0 then
- -- we need detect the sourcekinds of all deps if the current target has not any source files
- for _, dep in ipairs(target:orderdeps()) do
- table.join2(sourcekinds, dep:sourcekinds())
- end
- if #sourcekinds > 0 then
- sourcekinds = table.unique(sourcekinds)
- end
- end
+-- load tool
+function linker._load_tool(targetkind, sourcekinds, target)
-- get the linker infos
local linkerinfos, errors = language.linkerinfos_of(targetkind, sourcekinds)
@@ -124,24 +109,26 @@ function linker.load(targetkind, sourcekinds, target)
return nil, errors
end
- -- get program from target
- local program = nil
- if target then
- local tools = target:get("tools")
- if tools then
- program = tools[sourcekind]
- end
- end
-
-- select the linker
local linkerinfo = nil
local linkertool = nil
local firsterror = nil
for _, _linkerinfo in ipairs(linkerinfos) do
- -- load the linker tool from the linker kind
+
+ -- get program from target
+ local program = nil
+ if target then
+ local tools = target:get("tools")
+ if tools then
+ program = tools[_linkerinfo.linkerkind]
+ end
+ end
+
+ -- load the linker tool from the linker kind (with cache)
linkertool, errors = tool.load(_linkerinfo.linkerkind, program)
if linkertool then
linkerinfo = _linkerinfo
+ linkerinfo.program = program
break
else
firsterror = firsterror or errors
@@ -151,10 +138,44 @@ function linker.load(targetkind, sourcekinds, target)
return nil, firsterror
end
+ -- done
+ return linkertool, linkerinfo
+end
+
+-- load the linker from the given target kind
+function linker.load(targetkind, sourcekinds, target)
+
+ -- check
+ assert(sourcekinds)
+
+ -- wrap sourcekinds first
+ sourcekinds = table.wrap(sourcekinds)
+ if #sourcekinds == 0 then
+ -- we need detect the sourcekinds of all deps if the current target has not any source files
+ for _, dep in ipairs(target:orderdeps()) do
+ table.join2(sourcekinds, dep:sourcekinds())
+ end
+ if #sourcekinds > 0 then
+ sourcekinds = table.unique(sourcekinds)
+ end
+ end
+
+ -- load linker tool first (with cache)
+ local linkertool, linkerinfo_or_errors = linker._load_tool(targetkind, sourcekinds, target)
+ if not linkertool then
+ return nil, linkerinfo_or_errors
+ end
+
+ -- get linker info
+ local linkerinfo = linkerinfo_or_errors
+
+ -- init cache key
+ local cachekey = linkerinfo.linkerkind .. (linkerinfo.program or "")
+
-- get it directly from cache dirst
builder._INSTANCES = builder._INSTANCES or {}
- if builder._INSTANCES[linkerinfo.linkerkind] then
- return builder._INSTANCES[linkerinfo.linkerkind]
+ if builder._INSTANCES[cachekey] then
+ return builder._INSTANCES[cachekey]
end
-- new instance
@@ -169,7 +190,7 @@ function linker.load(targetkind, sourcekinds, target)
for _, sourcekind in ipairs(sourcekinds) do
-- load language
- result, errors = language.load_sk(sourcekind)
+ local result, errors = language.load_sk(sourcekind)
if not result then
return nil, errors
end
@@ -195,7 +216,7 @@ function linker.load(targetkind, sourcekinds, target)
instance._FLAGKINDS = {linkerinfo.linkerflag}
-- save this instance
- builder._INSTANCES[linkerinfo.linkerkind] = instance
+ builder._INSTANCES[cachekey] = instance
-- ok
return instance
diff --git a/xmake/core/tool/tool.lua b/xmake/core/tool/tool.lua
index d4380bec9..7b1bcaed3 100644
--- a/xmake/core/tool/tool.lua
+++ b/xmake/core/tool/tool.lua
@@ -109,13 +109,13 @@ function _instance:get(name)
end
-- has the given flag?
-function _instance:has_flags(flag)
+function _instance:has_flags(flags)
-- import has_flags()
self._has_flags = self._has_flags or import("lib.detect.has_flags")
-- has flags?
- return self._has_flags(self:name(), flag, {program = self:program(), toolkind = self:kind()})
+ return self._has_flags(self:name(), flags, {program = self:program(), toolkind = self:kind()})
end
-- load the given tool from the given kind
diff --git a/xmake/modules/lib/detect/has_flags.lua b/xmake/modules/lib/detect/has_flags.lua
index 66bdcfece..4f3d42eab 100644
--- a/xmake/modules/lib/detect/has_flags.lua
+++ b/xmake/modules/lib/detect/has_flags.lua
@@ -76,7 +76,10 @@ function main(name, flags, opt)
opt.program = tool.program
opt.programver = tool.version
- -- get tool arch
+ -- get tool platform
+ local plat = config.get("plat") or os.host()
+
+ -- get tool architecture
--
-- some tools select arch by path environment, not be flags, .e.g cl.exe of msvc)
-- so, it will affect the cache result
@@ -84,7 +87,7 @@ function main(name, flags, opt)
local arch = config.get("arch") or os.arch()
-- init cache key
- local key = tool.program .. "_" .. (tool.version or "") .. "_" .. (opt.toolkind or "") .. "_" .. table.concat(flags, " ") .. "_" .. arch
+ local key = plat .. "_" .. arch .. "_" .. tool.program .. "_" .. (tool.version or "") .. "_" .. (opt.toolkind or "") .. "_" .. table.concat(flags, " ")
-- @note avoid detect the same program in the same time if running in the coroutine (.e.g ccache)
local coroutine_running = coroutine.running()