diff options
| author | Saikari <[email protected]> | 2026-07-10 23:59:07 +0300 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-07-30 10:17:31 +0800 |
| commit | 6e1cb54894a5aa4dbbb75318a9927f56533e4b36 (patch) | |
| tree | 805abdf47b2508b8ab532f36a40e2168ed958acc | |
| parent | dc0f11050075a727c68546b656e57c1d98a71022 (diff) | |
fix: optimize package directory lookup by caching plugin presence
| -rw-r--r-- | xmake/core/package/package.lua | 4 | ||||
| -rw-r--r-- | xmake/modules/private/action/require/impl/repository.lua | 29 |
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) |
