diff options
Diffstat (limited to 'xmake/core/base/interpreter.lua')
| -rw-r--r-- | xmake/core/base/interpreter.lua | 63 |
1 files changed, 56 insertions, 7 deletions
diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua index 83bbdf593..8dc0e4880 100644 --- a/xmake/core/base/interpreter.lua +++ b/xmake/core/base/interpreter.lua @@ -879,6 +879,33 @@ 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 +end + +-- ignore the unresolvable references of includes() instead of raising errors +-- +-- @note the project file may reference the resources which have not been installed yet, +-- so the caller can load it, install them and load it again, @see project._load() +-- +function interpreter:includes_unresolved_set(enabled) + self._PRIVATE._INCLUDES_UNRESOLVED = enabled +end + -- set root scope kind -- -- the root api will affect these scopes @@ -1786,6 +1813,15 @@ function interpreter:api_builtin_set_xmakever(minver) end -- the builtin api: includes() +-- find the include files of the builtin includes, e.g. includes("@builtin/check") +function interpreter:_find_builtin_includes(subpath) + local builtin_path = subpath:sub(#"@builtin/" + 1) + if builtin_path:endswith(".lua") then + return os.files(path.join(os.programdir(), "includes", builtin_path)) + end + return os.files(path.join(os.programdir(), "includes", builtin_path, "xmake.lua")) +end + function interpreter:api_builtin_includes(...) assert(self and self._PRIVATE and self._PRIVATE._ROOTDIR and self._PRIVATE._MTIMES) local curfile = self._PRIVATE._CURFILE @@ -1799,18 +1835,31 @@ function interpreter:api_builtin_includes(...) -- attempt to find files from programdir/includes/*.lua -- e.g. includes("@builtin/check") if subpath:startswith("@builtin/") then - local builtin_path = subpath:sub(10) - local files - if builtin_path:endswith(".lua") then - files = os.files(path.join(os.programdir(), "includes", builtin_path)) - else - files = os.files(path.join(os.programdir(), "includes", builtin_path, "xmake.lua")) - end + local files = self:_find_builtin_includes(subpath) if files and #files > 0 then table.join2(subpaths_matched, files) found = true end end + -- 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 local files |
