summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-07-27 15:58:21 +0800
committerGitHub <[email protected]>2026-07-27 15:58:21 +0800
commite440a9168b0d2c3151daa8ab0db4bf4e44ff70ba (patch)
tree2f0dec9766b10408050d5262a4071305c1b0b851
parentddfd397d81a4283a74425f2418e1337cc2e04037 (diff)
parent451a46e86a2651ffb326870b07cc27952fbe6505 (diff)
Merge pull request #7666 from xmake-io/vcpkg3
improve to find vcpkg packages
-rw-r--r--xmake/modules/package/manager/vcpkg/find_package.lua36
-rw-r--r--xmake/modules/package/manager/vcpkg/install_package.lua5
-rw-r--r--xmake/modules/package/manager/vcpkg/utils.lua18
3 files changed, 45 insertions, 14 deletions
diff --git a/xmake/modules/package/manager/vcpkg/find_package.lua b/xmake/modules/package/manager/vcpkg/find_package.lua
index 5b515d8a2..0504070a3 100644
--- a/xmake/modules/package/manager/vcpkg/find_package.lua
+++ b/xmake/modules/package/manager/vcpkg/find_package.lua
@@ -212,7 +212,6 @@ function _find_package(vcpkg, vcpkgdir, name, opt)
if required_features then
depend_name = name .. "[" .. table.concat(required_features, ",") .. "]"
end
- local result = nil
local argv = {"depend-info", depend_name, "--sort=reverse", "--triplet=" .. triplet}
-- pass feature flags to depend-info when in manifest mode, otherwise depend-info will not show the complete dependency tree with features
@@ -220,31 +219,44 @@ function _find_package(vcpkg, vcpkgdir, name, opt)
table.insert(argv, 1, "--feature-flags=versions")
end
- local _, dependinfo = try { function () return os.iorunv(vcpkg, argv, manifest_mode and {curdir = opt.installdir} or nil) end }
+ local _, dependinfo = try { function () return os.iorunv(vcpkg, argv, {curdir = manifest_mode and opt.installdir or vcpkg_utils.classic_curdir()}) end }
if manifest_mode and not dependinfo then
- -- fallback: newer vcpkg-tool no longer accepts the package name as a positional argument,
- -- drop it and retry. see https://github.com/microsoft/vcpkg-tool/pull/1909
+ -- fallback: in manifest mode vcpkg rejects the package name as a positional argument, so
+ -- drop it and query the manifest's dependency tree instead.
+ -- see https://github.com/microsoft/vcpkg-tool/pull/1909
table.remove(argv, 3)
_, dependinfo = try { function () return os.iorunv(vcpkg, argv, {curdir = opt.installdir}) end }
end
+
+ -- collect the packages to read info from: always the main package (its .list file was found
+ -- above, so it is known-installed), plus any transitive dependencies reported by depend-info.
+ -- this keeps resolution working even when depend-info fails, e.g. a project-owned vcpkg.json
+ -- puts vcpkg in manifest mode and it rejects arguments; only transitive deps are then missing.
+ -- @see https://github.com/xmake-io/xmake/issues/7660
+ local packagenames = {name}
if dependinfo then
for _, line in ipairs(dependinfo:split("\n", {plain = true})) do
if not line:startswith("vcpkg-") then
local packagename = line:match("^([^%[:]+)[^:]*:")
if packagename then
- local dependencyresult = _get_package_info(packagename, triplet, infodirs, arch, plat, mode)
- if dependencyresult then
- result = result or {}
- for key, dependencylist in pairs(dependencyresult) do
- result[key] = result[key] or {}
- table.join2(result[key], dependencylist)
- end
- end
+ table.insert(packagenames, packagename)
end
end
end
end
+ local result = nil
+ for _, packagename in ipairs(table.unique(packagenames)) do
+ local dependencyresult = _get_package_info(packagename, triplet, infodirs, arch, plat, mode)
+ if dependencyresult then
+ result = result or {}
+ for key, dependencylist in pairs(dependencyresult) do
+ result[key] = result[key] or {}
+ table.join2(result[key], dependencylist)
+ end
+ end
+ end
+
-- save version
if result then
local infoname = path.basename(infofile)
diff --git a/xmake/modules/package/manager/vcpkg/install_package.lua b/xmake/modules/package/manager/vcpkg/install_package.lua
index a8546e5d0..909374e61 100644
--- a/xmake/modules/package/manager/vcpkg/install_package.lua
+++ b/xmake/modules/package/manager/vcpkg/install_package.lua
@@ -64,7 +64,10 @@ function _install_for_classic(vcpkg, name, opt)
end
-- install package
- os.vrunv(vcpkg, argv)
+ -- run in a neutral directory so that a project-owned vcpkg.json in the current working
+ -- directory does not switch vcpkg into manifest mode (which rejects package arguments).
+ -- @see https://github.com/xmake-io/xmake/issues/7660
+ os.vrunv(vcpkg, argv, {curdir = vcpkg_utils.classic_curdir()})
end
-- install for manifest mode
diff --git a/xmake/modules/package/manager/vcpkg/utils.lua b/xmake/modules/package/manager/vcpkg/utils.lua
index fdd85d501..1c83323b4 100644
--- a/xmake/modules/package/manager/vcpkg/utils.lua
+++ b/xmake/modules/package/manager/vcpkg/utils.lua
@@ -36,6 +36,22 @@ function need_manifest(opt)
end
end
+-- get a neutral empty directory to run classic-mode vcpkg commands in.
+--
+-- vcpkg switches to manifest mode when a vcpkg.json exists in the current working directory, and
+-- in manifest mode it rejects individual package arguments ("In manifest mode, `vcpkg install`
+-- does not support individual package arguments"). so classic-mode commands (install/list/
+-- depend-info, which pass `<pkg>:<triplet>`) must not run from a project directory that ships its
+-- own vcpkg.json.
+-- @see https://github.com/xmake-io/xmake/issues/7660
+function classic_curdir()
+ local dir = path.join(os.tmpdir(), "vcpkg", "classic")
+ if not os.isdir(dir) then
+ os.mkdir(dir)
+ end
+ return dir
+end
+
function is_installed(vcpkg, name, triplet, opt)
local argv = {"list", name .. ":" .. triplet, "--x-full-desc"}
local manifest_mode = need_manifest(opt)
@@ -46,7 +62,7 @@ function is_installed(vcpkg, name, triplet, opt)
end
local listinfo = try { function ()
- return os.iorunv(vcpkg, argv, manifest_mode and {curdir = opt.installdir} or nil)
+ return os.iorunv(vcpkg, argv, {curdir = manifest_mode and opt.installdir or classic_curdir()})
end}
if listinfo then
local exact_prefix = name .. ":" .. triplet