diff options
| author | ruki <[email protected]> | 2026-08-11 23:45:05 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-08-11 23:45:05 +0800 |
| commit | 7ffcc9f8e2a98d63f7f6880b9a3e4553439583c6 (patch) | |
| tree | f2bf7c4e0e9806fd157cc3243a45f691fd282988 /xmake | |
| parent | 9e6abef8b0a26d7098d79749dd68b5a2590512c4 (diff) | |
add global modules and rewrite addon tests
Diffstat (limited to 'xmake')
| -rw-r--r-- | xmake/actions/addon/main.lua | 9 | ||||
| -rw-r--r-- | xmake/core/package/addon.lua | 41 | ||||
| -rw-r--r-- | xmake/core/sandbox/modules/import/core/sandbox/module.lua | 37 | ||||
| -rw-r--r-- | xmake/modules/private/action/require/impl/actions/install.lua | 3 |
4 files changed, 62 insertions, 28 deletions
diff --git a/xmake/actions/addon/main.lua b/xmake/actions/addon/main.lua index 878b1712d..481b9334b 100644 --- a/xmake/actions/addon/main.lua +++ b/xmake/actions/addon/main.lua @@ -118,12 +118,19 @@ function _install_from_local(dir, name) { function () addon.register(name, LOCALVERSION, manifest and { - description = manifest.description, deps = #manifest.deps > 0 and manifest.deps or nil}) + description = manifest.description, + deps = #manifest.deps > 0 and manifest.deps or nil, + globalmodules = #manifest.globalmodules > 0 and manifest.globalmodules or nil}) end, catch { function (errors) os.tryrm(dstdir) + -- we need to remove the addon directory too if no other version is installed + local addondir = path.directory(dstdir) + if #os.filedirs(path.join(addondir, "*")) == 0 then + os.tryrm(addondir) + end raise(errors) end } diff --git a/xmake/core/package/addon.lua b/xmake/core/package/addon.lua index e5b03b959..1f116bcd4 100644 --- a/xmake/core/package/addon.lua +++ b/xmake/core/package/addon.lua @@ -154,16 +154,25 @@ end -- @return the errors if there are some conflicts -- function addon._check_conflicts(dirname, addoninfo) - for _, kind in ipairs({"plugins", "templates"}) do + local kindnames = {plugins = "plugin", templates = "template", globalmodules = "global module"} + for _, kind in ipairs({"plugins", "templates", "globalmodules"}) do for _, name in ipairs(addoninfo[kind] or {}) do for otherdirname, otheraddoninfo in pairs(addon.addons()) do if otherdirname ~= dirname and table.contains(otheraddoninfo[kind] or {}, name) then return string.format("%s(%s) conflicts, it has been provided by the addon(%s)!\nplease remove one of them, e.g. xmake addon --remove %s", - kind == "plugins" and "plugin" or "template", name, otherdirname, otherdirname) + kindnames[kind], name, otherdirname, otherdirname) end end end end + + -- the global modules can also conflict with the builtin ones + for _, name in ipairs(addoninfo.globalmodules or {}) do + local modulefile = path.join(os.programdir(), "modules", (name:gsub("%.", "/")) .. ".lua") + if os.isfile(modulefile) then + return string.format("global module(%s) conflicts, it has been provided by xmake!\nplease rename it in the addon manifest.", name) + end + end end -- get the addons which depend on the given addon @@ -203,6 +212,7 @@ function addon.apis() , "addon.set_sourcedir" -- addon.add_xxx , "addon.add_deps" + , "addon.add_globalmodules" } } end @@ -252,7 +262,8 @@ function addon.manifest(sourcedir) homepage = addoninfo:get("homepage"), license = addoninfo:get("license"), sourcedir = addoninfo:get("sourcedir"), - deps = table.wrap(addoninfo:get("deps"))} + deps = table.wrap(addoninfo:get("deps")), + globalmodules = table.wrap(addoninfo:get("globalmodules"))} end if not manifest then return nil, string.format("%s: no addon() scope found!", manifestfile) @@ -422,6 +433,28 @@ function addon.addondir(name, version) return path.join(addon.installdir(), dirname, version) end +-- get the modules which the installed addons export as the global modules +-- +-- they are declared in the addon manifest, e.g. add_globalmodules("core.tools.esptool"), +-- so that they can be imported with their plain names by the internal calls, +-- e.g. import("core.tools.esptool"), find_tool("esptool") +-- +-- @return the modules table, e.g. {["core.tools.esptool"] = "~/.xmake/addons/esp32/v1.0.0/modules"} +-- +function addon.globalmodules() + local globalmodules = addon._GLOBALMODULES + if globalmodules == nil then + globalmodules = {} + for dirname, addoninfo in pairs(addon.addons()) do + for _, name in ipairs(addoninfo.globalmodules or {}) do + globalmodules[name] = path.join(addon.installdir(), dirname, addoninfo.version, "modules") + end + end + addon._GLOBALMODULES = globalmodules + end + return globalmodules +end + -- get the payload directories of the given kind from all installed addons -- -- @param kind the payload kind, e.g. "plugins", "rules" @@ -560,6 +593,7 @@ function addon.register(name, version, opt) -- recorded whenever this addon has one, so that the repositories can -- check that the manifest and the package recipe are kept in sync manifest_deps = opt.manifest_deps, + globalmodules = opt.globalmodules, payloads = addon.payloads_of(addondir), plugins = addon._plugins_of(addondir), templates = addon._templates_of(addondir)} @@ -665,6 +699,7 @@ function addon.clear() end addon._ADDONS = {} addon._MANIFESTS = nil + addon._GLOBALMODULES = nil end -- return module diff --git a/xmake/core/sandbox/modules/import/core/sandbox/module.lua b/xmake/core/sandbox/modules/import/core/sandbox/module.lua index 3fd2d0fe6..4cf419b44 100644 --- a/xmake/core/sandbox/modules/import/core/sandbox/module.lua +++ b/xmake/core/sandbox/modules/import/core/sandbox/module.lua @@ -441,28 +441,6 @@ function core_sandbox_module.coredir() return path.join(os.programdir(), "core/sandbox/modules/import") end --- get the module directories for the given addon reference --- --- they are only used for the addon modules, --- e.g. import("@addon.esp32.sdkconfig"), import("@self.sdkconfig") --- -function core_sandbox_module.addon_directories(modulesdir) - local moduledirs = {modulesdir} - - -- add the modules of the addon toolchains, e.g. <addondir>/toolchains/<name>/modules - -- so that a custom toolchain can bundle its tool modules together - local toolchainsdir = path.join(path.directory(modulesdir), "toolchains") - if os.isdir(toolchainsdir) then - for _, toolchaindir in ipairs(os.dirs(path.join(toolchainsdir, "*"))) do - local dir = path.join(toolchaindir, "modules") - if os.isdir(dir) then - table.insert(moduledirs, dir) - end - end - end - return moduledirs -end - -- add module directories function core_sandbox_module.add_directories(...) local moduledirs = core_sandbox_module.directories() @@ -567,9 +545,22 @@ function core_sandbox_module.import(name, opt) -- init module directories (disable local packages?) local modules_directories if addon_modulesdir then - modules_directories = core_sandbox_module.addon_directories(addon_modulesdir) + -- the addon modules are always resolved from the addon `modules` directory only, + -- e.g. import("@addon.esp32.sdkconfig"), import("@self.sdkconfig") + modules_directories = {addon_modulesdir} else modules_directories = (opt.nolocal or not rootdir) and core_sandbox_module.directories() or table.join(rootdir, core_sandbox_module.directories()) + + -- an addon can export some modules as the global modules, e.g. add_globalmodules("core.tools.esptool"), + -- so that the internal calls can import them with their plain names, e.g. import("core.tools.esptool") + -- + -- @note we only accept the declared names, the other modules of this addon are + -- still private and can only be imported with `@addon.`/`@self.` + -- + local globalmodulesdir = addon.globalmodules()[name] + if globalmodulesdir then + table.insert(modules_directories, rootdir and 2 or 1, globalmodulesdir) + end end -- load module diff --git a/xmake/modules/private/action/require/impl/actions/install.lua b/xmake/modules/private/action/require/impl/actions/install.lua index 8bc51f4b3..c9e09763e 100644 --- a/xmake/modules/private/action/require/impl/actions/install.lua +++ b/xmake/modules/private/action/require/impl/actions/install.lua @@ -529,7 +529,8 @@ function main(package) end addon.register(package:name(), package:version_str() or "latest", {description = description, deps = deps, - manifest_deps = manifest and manifest.deps or nil}) + manifest_deps = manifest and manifest.deps or nil, + globalmodules = manifest and #manifest.globalmodules > 0 and manifest.globalmodules or nil}) end installed_now = true end |
