summaryrefslogtreecommitdiff
path: root/xmake/core/project/project.lua
diff options
context:
space:
mode:
authorruki <[email protected]>2026-08-14 23:28:20 +0800
committerruki <[email protected]>2026-08-14 23:28:20 +0800
commita79cf74f920c088528d66a67a59b3d8eaa1d4f7a (patch)
treedca4cb0ca1fd210e04e8c59ffd9ab8c410747c1f /xmake/core/project/project.lua
parent6c246c12a09524780e5bfdc53bc27a892e4793a9 (diff)
autofetch addons
Diffstat (limited to 'xmake/core/project/project.lua')
-rw-r--r--xmake/core/project/project.lua73
1 files changed, 73 insertions, 0 deletions
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 803bb5d9b..db269eda9 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -45,6 +45,8 @@ local option = require("project/option")
local policy = require("project/policy")
local project_package = require("project/package")
local deprecated_project = require("project/deprecated/project")
+local addon = require("package/addon")
+local addons = require("project/addons")
local package = require("package/package")
local platform = require("platform/platform")
local toolchain = require("tool/toolchain")
@@ -227,6 +229,69 @@ function project._api_add_toolchaindirs(interp, ...)
end
end
+-- install the addons which this project declares
+--
+-- @note we cannot install them here, we are loading the project, so we do it in a
+-- sub-process, @see xmake/modules/private/addons/main.lua
+--
+function project._install_addons()
+ -- @note we need to cache the result, the project may be loaded many times,
+ -- otherwise the failure would be ignored by the next load
+ if not project._ADDONS_CHECKED then
+ project._ADDONS_CHECKED = true
+ project._ADDONS_OK, project._ADDONS_ERRORS = project._do_install_addons()
+ end
+ return project._ADDONS_OK, project._ADDONS_ERRORS
+end
+
+-- do install the addons which this project declares
+function project._do_install_addons()
+ if os.getenv("XMAKE_SKIP_ADDONS") then
+ return true
+ end
+
+ -- this project declares nothing? or they have been installed already
+ local addonsinfo, errors = addons.load()
+ if errors then
+ return false, errors
+ end
+ if not addonsinfo or #addonsinfo.addons == 0 or addons.satisfied(addonsinfo) then
+ return true
+ end
+
+ -- @note we run it in a temporary directory, 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
+ --
+ local argv = {"lua"}
+ local flags = {["-y"] = "--yes", ["--yes"] = "--yes",
+ ["-v"] = "--verbose", ["--verbose"] = "--verbose",
+ ["-D"] = "--diagnosis", ["--diagnosis"] = "--diagnosis"}
+ local flags_added = {}
+ for _, arg in ipairs(xmake._COMMAND_ARGV or {}) do
+ local flag = flags[arg]
+ if flag and not flags_added[flag] then
+ table.insert(argv, flag)
+ flags_added[flag] = true
+ end
+ end
+ table.insert(argv, "private.addons")
+ table.insert(argv, os.projectdir())
+ local envs = os.getenvs()
+ envs.XMAKE_SKIP_ADDONS = "y"
+ local ok, errors = os.execv(os.programfile(), argv, {curdir = os.tmpdir(), envs = envs})
+ if ok ~= 0 then
+ return false, errors or "install the addons of this project failed!"
+ end
+
+ -- we have loaded the registry and its caches before installing them, so we need to reload it
+ addon.reload()
+ rule.clear()
+ task.clear()
+ return true
+end
+
-- load the project file
function project._load(force, disable_filter)
@@ -235,6 +300,14 @@ function project._load(force, disable_filter)
return true
end
+ -- install the addons which this project declares in `xmake-addons.lua` first,
+ -- it may use their rules, toolchains and includes files,
+ -- e.g. includes("@addon/esp32-devel/board")
+ local ok, errors = project._install_addons()
+ if not ok then
+ return false, errors
+ end
+
-- enter the project directory
local oldir, errors = os.cd(os.projectdir())
if not oldir then