summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-05-22 22:43:17 +0800
committerruki <[email protected]>2020-05-22 10:19:45 +0800
commite649d1c2a8dab803bacbdd1551f629469ab5158f (patch)
tree0830cc390f3080190dcf08f0984053a16547b4bb
parente702326e0c1a25ad6e10ab31864b8a9f991606c7 (diff)
improve toolchain to support multi-arch
-rw-r--r--xmake/core/base/scopeinfo.lua7
-rw-r--r--xmake/core/platform/platform.lua2
-rw-r--r--xmake/core/project/project.lua47
-rw-r--r--xmake/core/sandbox/modules/import/core/project/project.lua2
-rw-r--r--xmake/core/tool/toolchain.lua78
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