summaryrefslogtreecommitdiff
path: root/xmake/core/tool/toolchain.lua
diff options
context:
space:
mode:
Diffstat (limited to 'xmake/core/tool/toolchain.lua')
-rw-r--r--xmake/core/tool/toolchain.lua64
1 files changed, 53 insertions, 11 deletions
diff --git a/xmake/core/tool/toolchain.lua b/xmake/core/tool/toolchain.lua
index 3bca7e37a..7b841a018 100644
--- a/xmake/core/tool/toolchain.lua
+++ b/xmake/core/tool/toolchain.lua
@@ -33,6 +33,7 @@ local hashset = require("base/hashset")
local scopeinfo = require("base/scopeinfo")
local interpreter = require("base/interpreter")
local is_cross = require("base/private/is_cross")
+local addon = require("package/addon")
local config = require("project/config")
local memcache = require("cache/memcache")
local localcache = require("cache/localcache")
@@ -356,7 +357,7 @@ function _instance:check()
if checked == nil then
local on_check = self:_on_check()
if on_check then
- local ok, results_or_errors = sandbox.load(on_check, self)
+ local ok, results_or_errors = sandbox.call(on_check, self)
if ok then
checked = results_or_errors
else
@@ -449,7 +450,7 @@ function _instance:_load()
local on_load = self:_on_load()
if on_load then
info:set("__loading", true)
- local ok, errors = sandbox.load(on_load, self)
+ local ok, errors = sandbox.call(on_load, self)
info:set("__loading", false)
if not ok then
os.raise(errors)
@@ -670,6 +671,28 @@ end
-- e.g. "mingw[clang]@llvm-mingw", "msvc[vs=2025,..]"
--
function toolchain.parsename(name)
+
+ -- the toolchain of an addon?
+ -- e.g. set_toolchains("@addon/esp32/xtensa"), set_toolchains("@addon/esp32/clang@llvm"), set_toolchains("@self/xtensa")
+ --
+ -- @note we need to parse it first, because `@` is also used for the toolchain packages, e.g. "@zig"
+ --
+ -- @note we only strip the `@addon/<addon>/` prefix here, the rest is parsed as usual,
+ -- so the addon toolchains can also be bound to packages, e.g. "@addon/esp32/clang@llvm"
+ --
+ local addon_prefix
+ if name:startswith("@addon/") then
+ local rest = name:sub(#"@addon/" + 1)
+ local pos = rest:find("/", 1, true)
+ if pos then
+ addon_prefix = "@addon/" .. rest:sub(1, pos - 1) .. "/"
+ name = rest:sub(pos + 1)
+ end
+ elseif name:startswith("@self/") then
+ addon_prefix = "@self/"
+ name = name:sub(#"@self/" + 1)
+ end
+
local splitinfo = name:split('@', {plain = true, strict = true})
local toolchain_name = splitinfo[1]
if toolchain_name == "" then
@@ -707,7 +730,8 @@ function toolchain.parsename(name)
end
end
end
- return {name = toolchain_name or packages, packages = packages, requireconfs = requireconfs, requirestr = requirestr}
+ return {name = toolchain_name or packages, packages = packages, addon_prefix = addon_prefix,
+ requireconfs = requireconfs, requirestr = requirestr}
end
-- get toolchain apis
@@ -781,9 +805,27 @@ function toolchain.load(name, opt)
configs.plat = opt.plat or config.get("plat") or os.host()
configs.arch = opt.arch or config.get("arch") or os.arch()
+ -- find the toolchain script path
+ --
+ -- @note we need to resolve the addon reference before the cache, `@self/` depends on
+ -- the addon which owns the caller script, and the different addons may provide
+ -- the same toolchain name
+ --
+ local scriptpath, addon_prefix
+ if parseinfo.addon_prefix then
+ -- e.g. set_toolchains("@addon/esp32/xtensa"), set_toolchains("@self/xtensa")
+ local referenceinfo, errors = addon.resolve_reference(parseinfo.addon_prefix .. name, "/", "toolchains",
+ {scriptdir = opt.scriptdir})
+ if not referenceinfo then
+ return nil, errors
+ end
+ addon_prefix = "@addon/" .. referenceinfo.addon .. "/"
+ scriptpath = path.join(referenceinfo.dir, referenceinfo.name, "xmake.lua")
+ end
+
-- get cache
local cache = toolchain._memcache()
- local cachekey = toolchain._cachekey(name, configs)
+ local cachekey = toolchain._cachekey((addon_prefix or "") .. name, configs)
-- get it directly from cache dirst
local instance = cache:get(cachekey)
@@ -791,16 +833,16 @@ function toolchain.load(name, opt)
return instance
end
- -- find the toolchain script path
- local scriptpath = nil
- for _, dir in ipairs(toolchain.directories()) do
- scriptpath = path.join(dir, name, "xmake.lua")
- if os.isfile(scriptpath) then
- break
+ if not addon_prefix then
+ for _, dir in ipairs(toolchain.directories()) do
+ scriptpath = path.join(dir, name, "xmake.lua")
+ if os.isfile(scriptpath) then
+ break
+ end
end
end
if not scriptpath or not os.isfile(scriptpath) then
- return nil, string.format("the toolchain %s not found!", name)
+ return nil, string.format("the toolchain %s%s not found!", addon_prefix or "", name)
end
-- get interpreter