summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaikari <[email protected]>2026-07-10 23:59:07 +0300
committerruki <[email protected]>2026-07-30 10:17:31 +0800
commit6e1cb54894a5aa4dbbb75318a9927f56533e4b36 (patch)
tree805abdf47b2508b8ab532f36a40e2168ed958acc
parentdc0f11050075a727c68546b656e57c1d98a71022 (diff)
fix: optimize package directory lookup by caching plugin presence
-rw-r--r--xmake/core/package/package.lua4
-rw-r--r--xmake/modules/private/action/require/impl/repository.lua29
2 files changed, 23 insertions, 10 deletions
diff --git a/xmake/core/package/package.lua b/xmake/core/package/package.lua
index 3537740e3..af11ec649 100644
--- a/xmake/core/package/package.lua
+++ b/xmake/core/package/package.lua
@@ -760,7 +760,9 @@ function _instance:is_host()
if requireinfo and requireinfo.host then
return true
end
- return self:is_binary() or self:is_plugin()
+ -- we only get the kind once, because this function will be called frequently. e.g. in plat()/arch()
+ local kind = self:kind()
+ return kind == "binary" or kind == "toolchain" or kind == "plugin"
end
-- is cross-compilation?
diff --git a/xmake/modules/private/action/require/impl/repository.lua b/xmake/modules/private/action/require/impl/repository.lua
index 9d150cb06..4a546e091 100644
--- a/xmake/modules/private/action/require/impl/repository.lua
+++ b/xmake/modules/private/action/require/impl/repository.lua
@@ -37,15 +37,26 @@ import("net.proxy")
--
function _find_packagedir(repodir, packagename, opt)
opt = opt or {}
- local packagedirs = {path.join("packages", packagename:sub(1, 1), packagename)}
- local plugindirs = {path.join("plugins", packagename),
- path.join("plugins", packagename:sub(1, 1), packagename)}
- local dirs
- if opt.kind == "plugin" then
- -- find it from the plugin directories first
- dirs = table.join(plugindirs, packagedirs)
- else
- dirs = table.join(packagedirs, plugindirs)
+ local dirs = {path.join("packages", packagename:sub(1, 1), packagename)}
+ -- we only find the plugin directories if this repository has plugins,
+ -- it can avoid unnecessary filesystem access, because most repositories only have packages
+ local has_plugins = _g._HAS_PLUGINS
+ if has_plugins == nil then
+ has_plugins = {}
+ _g._HAS_PLUGINS = has_plugins
+ end
+ if has_plugins[repodir] == nil then
+ has_plugins[repodir] = os.isdir(path.join(repodir, "plugins"))
+ end
+ if has_plugins[repodir] then
+ local plugindirs = {path.join("plugins", packagename),
+ path.join("plugins", packagename:sub(1, 1), packagename)}
+ if opt.kind == "plugin" then
+ -- find it from the plugin directories first
+ dirs = table.join(plugindirs, dirs)
+ else
+ table.join2(dirs, plugindirs)
+ end
end
for _, dir in ipairs(dirs) do
dir = path.join(repodir, dir)