diff options
| author | ruki <[email protected]> | 2018-12-20 23:46:03 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2018-12-20 16:36:22 +0800 |
| commit | 38315771588ae29bacc20cae6a16fa0d4d8a2be5 (patch) | |
| tree | 063f662f1e8c22b39864e3b0d3c94355c3b633c8 | |
| parent | a9f3eac5faf29e1a60b68ec2ac7ec791ef7549ee (diff) | |
improve compiler and linker
| -rw-r--r-- | xmake/core/tool/compiler.lua | 43 | ||||
| -rw-r--r-- | xmake/core/tool/linker.lua | 83 | ||||
| -rw-r--r-- | xmake/core/tool/tool.lua | 4 | ||||
| -rw-r--r-- | xmake/modules/lib/detect/has_flags.lua | 7 |
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() |
