summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-08-15 00:25:51 +0800
committerruki <[email protected]>2026-08-15 00:25:51 +0800
commitea1af59107ffd962ad8e063577e7546908d5a731 (patch)
tree3701cf47d747065271d4ca0747b2853dbdcfe313
parentca9239022e1cba0faf054e8fe2f178a466149b04 (diff)
add addon workdir
-rw-r--r--xmake/actions/addon/main.lua8
-rw-r--r--xmake/core/package/addon.lua20
-rw-r--r--xmake/core/project/project.lua5
-rw-r--r--xmake/core/sandbox/modules/import/core/package/addon.lua1
-rw-r--r--xmake/modules/private/action/addon/impl/xrepo.lua7
5 files changed, 31 insertions, 10 deletions
diff --git a/xmake/actions/addon/main.lua b/xmake/actions/addon/main.lua
index 37923e589..29df38b0a 100644
--- a/xmake/actions/addon/main.lua
+++ b/xmake/actions/addon/main.lua
@@ -54,11 +54,7 @@ end
-- install an addon from the given repository or the first repository containing it
function _install_from_repo(name, reponame)
_check_addon_name(name)
- xrepo_addon("install", {reponame and (reponame .. "@" .. name) or name},
- {force = option.get("force"),
- -- @note we run it in a temporary directory, this action manages the global addons,
- -- so we need not load the project of the current directory again
- curdir = os.tmpdir()})
+ xrepo_addon("install", {reponame and (reponame .. "@" .. name) or name}, {force = option.get("force")})
end
-- install a single addon from a source directory (as the given name, default to the directory name)
@@ -245,7 +241,7 @@ end
-- search the addons from the repositories
function _search()
local patterns = assert(option.get("addons"), "please specify the addon name pattern to be searched!")
- xrepo_addon("search", patterns, {curdir = os.tmpdir()})
+ xrepo_addon("search", patterns)
end
-- collect the installed addons from the addons registry
diff --git a/xmake/core/package/addon.lua b/xmake/core/package/addon.lua
index 731c673ab..4a4c8f50a 100644
--- a/xmake/core/package/addon.lua
+++ b/xmake/core/package/addon.lua
@@ -294,6 +294,26 @@ function addon.manifest(sourcedir)
return manifest
end
+-- get a working directory which has no project
+--
+-- we need it to run the sub-processes of the addons, e.g. `xrepo install --addon`,
+-- otherwise they would load the project of the current directory again
+--
+-- @note we cannot use `os.tmpdir()` directly, it is shared by all the commands,
+-- e.g. a stray `xmake.lua` in it would break the isolation
+--
+-- @note we can share it between the processes, we only use it as the working directory
+-- and never write anything into it, @see private/action/addon/impl/xrepo.lua
+--
+function addon.workdir()
+ local workdir = path.join(os.tmpdir(), "addons", "working")
+ if not os.isdir(workdir) then
+ -- it may be created by the other processes at the same time, we can ignore it
+ os.mkdir(workdir)
+ end
+ return workdir
+end
+
-- the install directory of addons, e.g. ~/.xmake/addons
function addon.installdir()
return path.join(global.directory(), "addons")
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 5c2a12e00..2c68976dd 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -275,7 +275,8 @@ function project._do_install_addons()
return true
end
- -- @note we run it in a temporary directory, otherwise it would load this project again
+ -- @note we run it in a working directory which has no project, @see addon.workdir(),
+ -- otherwise it would load this project again
--
-- @note we may be called when building the option menu, the command line has not
-- been parsed yet, so we can only get the common flags from the raw arguments
@@ -294,7 +295,7 @@ function project._do_install_addons()
end
table.insert(argv, "private.action.addon.impl.install_addons")
table.insert(argv, os.projectdir())
- local ok, errors = os.execv(os.programfile(), argv, {curdir = os.tmpdir()})
+ local ok, errors = os.execv(os.programfile(), argv, {curdir = addon.workdir()})
if ok ~= 0 then
return false, errors or "install the addons of this project failed!"
end
diff --git a/xmake/core/sandbox/modules/import/core/package/addon.lua b/xmake/core/sandbox/modules/import/core/package/addon.lua
index dc4740c2e..74610c693 100644
--- a/xmake/core/sandbox/modules/import/core/package/addon.lua
+++ b/xmake/core/sandbox/modules/import/core/package/addon.lua
@@ -27,6 +27,7 @@ local raise = require("sandbox/modules/raise")
-- inherit some builtin interfaces
sandbox_core_package_addon.installdir = addon.installdir
+sandbox_core_package_addon.workdir = addon.workdir
sandbox_core_package_addon.dirname = addon.dirname
sandbox_core_package_addon.owner = addon.owner
sandbox_core_package_addon.is_reference = addon.is_reference
diff --git a/xmake/modules/private/action/addon/impl/xrepo.lua b/xmake/modules/private/action/addon/impl/xrepo.lua
index 34c1d2632..46ada2d01 100644
--- a/xmake/modules/private/action/addon/impl/xrepo.lua
+++ b/xmake/modules/private/action/addon/impl/xrepo.lua
@@ -20,6 +20,7 @@
-- imports
import("core.base.option")
+import("core.package.addon")
-- run the given xrepo action for the addons
--
@@ -28,7 +29,9 @@ import("core.base.option")
--
-- @param action the action name, e.g. "install", "search"
-- @param names the addon names, urls or require strings, e.g. {"esp32-devel 1.0.x"}
--- @param opt the options, e.g. {force = true, includes = "/tmp/xxx.lua", curdir = "/tmp"}
+-- @param opt the options, e.g. {force = true, includes = "/tmp/xxx.lua"}
+--
+-- @note we always run it in a working directory which has no project, @see addon.workdir()
--
function main(action, names, opt)
opt = opt or {}
@@ -50,5 +53,5 @@ function main(action, names, opt)
end
table.join2(argv, names)
- os.execv(os.programfile(), argv, {curdir = opt.curdir})
+ os.execv(os.programfile(), argv, {curdir = opt.curdir or addon.workdir()})
end