diff options
| author | ruki <[email protected]> | 2020-05-22 22:43:17 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2020-05-22 10:19:45 +0800 |
| commit | e649d1c2a8dab803bacbdd1551f629469ab5158f (patch) | |
| tree | 0830cc390f3080190dcf08f0984053a16547b4bb | |
| parent | e702326e0c1a25ad6e10ab31864b8a9f991606c7 (diff) | |
improve toolchain to support multi-arch
| -rw-r--r-- | xmake/core/base/scopeinfo.lua | 7 | ||||
| -rw-r--r-- | xmake/core/platform/platform.lua | 2 | ||||
| -rw-r--r-- | xmake/core/project/project.lua | 47 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/project/project.lua | 2 | ||||
| -rw-r--r-- | xmake/core/tool/toolchain.lua | 78 |
5 files changed, 102 insertions, 34 deletions
diff --git a/xmake/core/base/scopeinfo.lua b/xmake/core/base/scopeinfo.lua index 05337e4c8..c8bd2fec7 100644 --- a/xmake/core/base/scopeinfo.lua +++ b/xmake/core/base/scopeinfo.lua @@ -546,7 +546,12 @@ function _instance:extraconf(name, item, key) return value end --- new an scope instance +-- clone a new instance from the current +function _instance:clone() + return _instance.new(self:kind(), self:info(), {interpreter = self:interpreter(), remove_repeat = self._REMOVE_REPEAT, enable_filter = self._ENABLE_FILTER}) +end + +-- new a scope instance function scopeinfo.new(...) return _instance.new(...) end diff --git a/xmake/core/platform/platform.lua b/xmake/core/platform/platform.lua index 0131895ec..56491c927 100644 --- a/xmake/core/platform/platform.lua +++ b/xmake/core/platform/platform.lua @@ -135,7 +135,7 @@ function _instance:toolchains(opt) -- get the given toolchain local toolchain_given = config.get("toolchain") if toolchain_given then - local toolchain_inst, errors = toolchain.load(toolchain_given, self:name()) + local toolchain_inst, errors = toolchain.load(toolchain_given) if not toolchain_inst then os.raise(errors) end diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua index e900f394f..08f843d0e 100644 --- a/xmake/core/project/project.lua +++ b/xmake/core/project/project.lua @@ -42,6 +42,7 @@ local deprecated_project = require("project/deprecated/project") local package = require("package/package") local platform = require("platform/platform") local environment = require("platform/environment") +local toolchain = require("tool/toolchain") local language = require("language/language") local sandbox_os = require("sandbox/modules/os") local sandbox_module = require("sandbox/modules/import/core/sandbox/module") @@ -327,6 +328,29 @@ function project._load_rules() return rules end +-- load toolchains +function project._load_toolchains() + + -- load the project file first if has not been loaded? + local ok, errors = project._load() + if not ok then + return nil, errors + end + + -- load the toolchain from the the project file + local results, errors = project._load_scope("toolchain", true, true) + if not results then + return nil, errors + end + + -- make toolchain instances + local toolchains = {} + for toolchain_name, toolchain_info in pairs(results) do + toolchains[toolchain_name] = toolchain.new(toolchain_name, toolchain_info) + end + return toolchains +end + -- load targets function project._load_targets() @@ -680,6 +704,9 @@ function project.interpreter() -- define apis for language interp:api_define(language.apis()) + -- define apis for toolchain + interp:api_define(toolchain.apis()) + -- define apis for project interp:api_define(project.apis()) @@ -924,10 +951,7 @@ end -- get project rules function project.rules() - if not project._RULES then - - -- load rules local rules, errors = project._load_rules() if not rules then os.raise(errors) @@ -937,6 +961,23 @@ function project.rules() return project._RULES end +-- get the given toolchain +function project.toolchain(name) + return project.toolchains()[name] +end + +-- get project toolchains +function project.toolchains() + if not project._TOOLCHAINS then + local toolchains, errors = project._load_toolchains() + if not toolchains then + os.raise(errors) + end + project._TOOLCHAINS = toolchains + end + return project._TOOLCHAINS +end + -- get the given task function project.task(name) return project.tasks()[name] diff --git a/xmake/core/sandbox/modules/import/core/project/project.lua b/xmake/core/sandbox/modules/import/core/project/project.lua index c6796af36..cb7465fcd 100644 --- a/xmake/core/sandbox/modules/import/core/project/project.lua +++ b/xmake/core/sandbox/modules/import/core/project/project.lua @@ -39,6 +39,8 @@ local import = require("sandbox/modules/import") sandbox_core_project.get = project.get sandbox_core_project.rule = project.rule sandbox_core_project.rules = project.rules +sandbox_core_project.toolchain = project.toolchain +sandbox_core_project.toolchains = project.toolchains sandbox_core_project.target = project.target sandbox_core_project.targets = project.targets sandbox_core_project.option = project.option diff --git a/xmake/core/tool/toolchain.lua b/xmake/core/tool/toolchain.lua index 894dfb879..dddfb841a 100644 --- a/xmake/core/tool/toolchain.lua +++ b/xmake/core/tool/toolchain.lua @@ -49,21 +49,48 @@ function _instance:name() return self._NAME end +-- get toolchain platform +function _instance:plat() + return config.get("plat") or os.host() +end + +-- get toolchain architecture +function _instance:arch() + return config.get("arch") or os.arch() +end + +-- get toolchain info +function _instance:info() + local arch = self:arch() + local infos = self._INFOS + if not infos then + infos = {} + self._INFOS = infos + end + local info = infos[arch] + if not info then + -- we need multiple info objects for different architectures + info = self._INFO:clone() + infos[arch] = info + end + return info +end + -- set the value to the toolchain configuration function _instance:set(name, ...) - self._INFO:apival_set(name, ...) + self:info():apival_set(name, ...) end -- add the value to the toolchain configuration function _instance:add(name, ...) - self._INFO:apival_add(name, ...) + self:info():apival_add(name, ...) end -- get the toolchain configuration function _instance:get(name) -- attempt to get the static configure value - local value = self._INFO:get(name) + local value = self:info():get(name) if value ~= nil then return value end @@ -72,12 +99,12 @@ function _instance:get(name) self:_load() -- get other platform info - return self._INFO:get(name) + return self:info():get(name) end -- get toolchain kind function _instance:kind() - return self._INFO:get("kind") + return self:info():get("kind") end -- is standalone toolchain? @@ -100,7 +127,7 @@ end -- get the toolchain script function _instance:script(name) - return self._INFO:get(name) + return self:info():get(name) end -- get the bin directory @@ -115,25 +142,27 @@ end -- do load function _instance:_load() - if not self._LOADED and not self._LOADING then - local on_load = self._INFO:get("load") + local info = self:info() + if not info:get("__loaded") and not info:get("__loading") then + local on_load = info:get("load") if on_load then - self._LOADING = true + info:set("__loading", true) local ok, errors = sandbox.load(on_load, self) - self._LOADING = false + info:set("__loading", false) if not ok then os.raise(errors) end end - self._LOADED = true + info:set("__loaded", true) end end -- do check function _instance:check() local checkok = true - if not self._CHECKED then - local on_check = self._INFO:get("check") + local info = self:info() + if not info:get("__checked") then + local on_check = self:info():get("check") if on_check then local ok, results_or_errors = sandbox.load(on_check, self) if ok then @@ -142,7 +171,7 @@ function _instance:check() os.raise(results_or_errors) end end - self._CHECKED = true + info:set("__checked", true) end return checkok end @@ -246,7 +275,7 @@ function toolchain._interpreter() assert(interp) -- define apis - interp:api_define(toolchain._apis()) + interp:api_define(toolchain.apis()) -- define apis for language interp:api_define(language.apis()) @@ -259,7 +288,7 @@ function toolchain._interpreter() end -- get toolchain apis -function toolchain._apis() +function toolchain.apis() return { values = @@ -300,21 +329,12 @@ function toolchain.directories() end -- load the given toolchain -function toolchain.load(name, plat) - - -- get toolchain name - plat = plat or config.get("plat") or os.host() - if not plat then - return nil, string.format("unknown toolchain!") - end - - -- get cache key - local cachekey = name .. "_" .. plat .. "_" .. (config.get("arch") or os.arch()) +function toolchain.load(name) -- get it directly from cache dirst toolchain._TOOLCHAINS = toolchain._TOOLCHAINS or {} - if toolchain._TOOLCHAINS[cachekey] then - return toolchain._TOOLCHAINS[cachekey] + if toolchain._TOOLCHAINS[name] then + return toolchain._TOOLCHAINS[name] end -- find the toolchain script path @@ -357,7 +377,7 @@ function toolchain.load(name, plat) end -- save instance to the cache - toolchain._TOOLCHAINS[cachekey] = instance + toolchain._TOOLCHAINS[name] = instance return instance end |
