summaryrefslogtreecommitdiff
path: root/xmake/core/base/interpreter.lua
diff options
context:
space:
mode:
Diffstat (limited to 'xmake/core/base/interpreter.lua')
-rw-r--r--xmake/core/base/interpreter.lua82
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)