diff options
| author | ruki <[email protected]> | 2026-08-16 22:28:05 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-08-16 22:28:05 +0800 |
| commit | d7fc1e30a747c0457b4f45194946fcff747c76db (patch) | |
| tree | beb7b01b9f2f04e54169689023e8ad5e8fe3eff6 | |
| parent | 1678e141d274309ab56917f585a8fb036571541b (diff) | |
improve find addon includes
| -rw-r--r-- | xmake/core/base/interpreter.lua | 61 | ||||
| -rw-r--r-- | xmake/core/package/addon.lua | 30 | ||||
| -rw-r--r-- | xmake/core/project/project.lua | 4 |
3 files changed, 65 insertions, 30 deletions
diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua index ad62168fb..8dc0e4880 100644 --- a/xmake/core/base/interpreter.lua +++ b/xmake/core/base/interpreter.lua @@ -30,7 +30,6 @@ local string = require("base/string") local hashset = require("base/hashset") local scopeinfo = require("base/scopeinfo") local deprecated = require("base/deprecated") -local addon = require("package/addon") local sandbox = require("sandbox/sandbox") -- the rules to reword the raw lua error messages into friendly ones, {pattern, replacement} @@ -880,6 +879,19 @@ function interpreter:scriptdir() return path.directory(self._PRIVATE._CURFILE) end +-- add a resolver for the references of includes(), e.g. includes("@addon/esp32/check") +-- +-- @param resolver function (interp, reference), it returns the files, or nil and errors +-- +-- @note the interpreter knows nothing about the references, the callers register the +-- resolvers which they support, e.g. @see project._interpreter() +-- +function interpreter:includes_resolver_add(resolver) + local resolvers = self._PRIVATE._INCLUDES_RESOLVERS or {} + table.insert(resolvers, resolver) + self._PRIVATE._INCLUDES_RESOLVERS = resolvers +end + -- do we ignore the unresolvable references of includes()? e.g. includes("@addon/esp32/board") function interpreter:includes_unresolved() return self._PRIVATE._INCLUDES_UNRESOLVED @@ -1810,30 +1822,6 @@ function interpreter:_find_builtin_includes(subpath) return os.files(path.join(os.programdir(), "includes", builtin_path, "xmake.lua")) end --- find the include files of the addons, e.g. includes("@addon/esp32/check"), includes("@self/check") -function interpreter:_find_addon_includes(subpath) - local referenceinfo, errors = addon.resolve_reference(subpath, "/", "includes", {scriptdir = self:scriptdir()}) - if not referenceinfo then - -- it has not been installed yet? the caller may install it and load this file again - if self:includes_unresolved() then - return {} - end - os.raise(errors) - end - local addon_path = referenceinfo.name - local files - if addon_path:endswith(".lua") then - files = os.files(path.join(referenceinfo.dir, addon_path)) - else - files = os.files(path.join(referenceinfo.dir, addon_path, "xmake.lua")) - end - -- the addon is installed, but it does not provide this file, we cannot ignore it - if not files or #files == 0 then - os.raise("includes(%s) not found!", subpath) - end - return files -end - function interpreter:api_builtin_includes(...) assert(self and self._PRIVATE and self._PRIVATE._ROOTDIR and self._PRIVATE._MTIMES) local curfile = self._PRIVATE._CURFILE @@ -1853,11 +1841,24 @@ function interpreter:api_builtin_includes(...) found = true end end - -- attempt to find files from the includes of the addons - -- e.g. includes("@addon/esp32/check"), includes("@self/check") - if not found and addon.is_reference(subpath, "/") then - table.join2(subpaths_matched, self:_find_addon_includes(subpath)) - found = true + -- attempt to find files from the registered resolvers of the references + -- e.g. includes("@addon/esp32/check"), @see interpreter:includes_resolver_add() + if not found and subpath:startswith("@") then + for _, resolver in ipairs(self._PRIVATE._INCLUDES_RESOLVERS or {}) do + local files, errors = resolver(self, subpath) + if files then + table.join2(subpaths_matched, files) + found = true + break + elseif errors then + -- it has not been resolved yet? the caller may load this file again + if self:includes_unresolved() then + found = true + break + end + os.raise(errors) + end + end end -- find the given files from the project directory if not found then diff --git a/xmake/core/package/addon.lua b/xmake/core/package/addon.lua index 6e7d62eb4..e35a58317 100644 --- a/xmake/core/package/addon.lua +++ b/xmake/core/package/addon.lua @@ -566,6 +566,36 @@ function addon.globalmodules() return globalmodules end +-- find the include files of the given addon reference, e.g. includes("@addon/esp32/board") +-- +-- @param interp the interpreter which is loading the file, @see interpreter:includes_resolver_add +-- @param reference the reference, e.g. "@addon/esp32/board", "@self/board" +-- +-- @return the files, or nil and errors +-- +function addon.find_includes(interp, reference) + if not addon.is_reference(reference, "/") then + return + end + local referenceinfo, errors = addon.resolve_reference(reference, "/", "includes", {scriptdir = interp:scriptdir()}) + if not referenceinfo then + return nil, errors + end + local name = referenceinfo.name + local files + if name:endswith(".lua") then + files = os.files(path.join(referenceinfo.dir, name)) + else + files = os.files(path.join(referenceinfo.dir, name, "xmake.lua")) + end + + -- the addon is installed, but it does not provide this file, we cannot ignore it + if not files or #files == 0 then + os.raise("includes(%s) not found!", reference) + end + return files +end + -- get the payload directories of the given kind from all installed addons -- -- @param kind the payload kind, e.g. "plugins", "rules" diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua index f67ac9a67..b92c5cfab 100644 --- a/xmake/core/project/project.lua +++ b/xmake/core/project/project.lua @@ -860,6 +860,10 @@ function project.interpreter() -- set root scope interp:rootscope_set("target") + -- the project file can reference the includes files of the addons, + -- e.g. includes("@addon/esp32-devel/board") + interp:includes_resolver_add(addon.find_includes) + -- define apis for rule interp:api_define(rule.apis()) |
