diff options
Diffstat (limited to 'xmake/core/base/interpreter.lua')
| -rw-r--r-- | xmake/core/base/interpreter.lua | 82 |
1 files changed, 74 insertions, 8 deletions
diff --git a/xmake/core/base/interpreter.lua b/xmake/core/base/interpreter.lua index 83bbdf593..01b689fe6 100644 --- a/xmake/core/base/interpreter.lua +++ b/xmake/core/base/interpreter.lua @@ -30,6 +30,7 @@ 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} @@ -883,6 +884,36 @@ end -- -- the root api will affect these scopes -- +-- get the root file name of the included directories, e.g. includes("subdir") -> subdir/xmake.lua +function interpreter:includes_rootfilename() + return self._PRIVATE._INCLUDES_ROOTFILENAME or "xmake.lua" +end + +-- set the root file name of the included directories +-- +-- e.g. interp:includes_rootfilename_set("xmake-addons.lua") -> includes("subdir") -> subdir/xmake-addons.lua +-- +function interpreter:includes_rootfilename_set(filename) + self._PRIVATE._INCLUDES_ROOTFILENAME = filename +end + +-- can we include the referenced files? e.g. includes("@builtin/check"), includes("@addon/esp32/board") +function interpreter:includes_references() + return self._PRIVATE._INCLUDES_REFERENCES ~= false +end + +-- enable/disable the referenced files of includes() +-- +-- @param enabled enable them or not +-- @param hint the extra hint of the error message +-- +-- @note the addons file is loaded before the addons are installed, so it cannot reference them +-- +function interpreter:includes_references_set(enabled, hint) + self._PRIVATE._INCLUDES_REFERENCES = enabled + self._PRIVATE._INCLUDES_REFERENCES_HINT = hint +end + function interpreter:rootscope_set(scope_kind) assert(self and self._PRIVATE) self._PRIVATE._ROOTSCOPE = scope_kind @@ -1786,6 +1817,35 @@ 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 + +-- 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 + 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 @@ -1796,21 +1856,27 @@ function interpreter:api_builtin_includes(...) local subpaths_matched = {} for _, subpath in ipairs(subpaths) do local found = false + -- the referenced files are not always available, e.g. the addons file + if subpath:startswith("@") and not self:includes_references() then + local hint = self._PRIVATE._INCLUDES_REFERENCES_HINT + os.raise("includes(%s): the referenced files are not supported in %s!%s", + subpath, path.filename(curfile), hint and ("\n" .. hint) or "") + end -- 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 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 + end -- find the given files from the project directory if not found then local files @@ -1818,7 +1884,7 @@ function interpreter:api_builtin_includes(...) files = os.files(subpath) else -- @see https://github.com/xmake-io/xmake/issues/6026 - files = os.files(path.join(subpath, "xmake.lua")) + files = os.files(path.join(subpath, self:includes_rootfilename())) end if files and #files > 0 then table.join2(subpaths_matched, files) |
