summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-03-20 17:33:47 +0800
committerGitHub <[email protected]>2026-03-20 17:33:47 +0800
commit8b1b87604943d055f854525e2a30e2b6741e061a (patch)
tree798701263e044a714e0afd752d0a270600317980
parent5982d5110c74890122372c0ab6040ef0d0c9d9b5 (diff)
parent9a6688113136d8e23c7f14f5611a06dcf885d2af (diff)
Merge pull request #7411 from kanren3/dev
add manifest mode support for vcpkg package depend-info
-rw-r--r--xmake/modules/package/manager/vcpkg/find_package.lua54
-rw-r--r--xmake/modules/package/manager/vcpkg/install_package.lua18
-rw-r--r--xmake/modules/package/manager/vcpkg/utils.lua32
3 files changed, 74 insertions, 30 deletions
diff --git a/xmake/modules/package/manager/vcpkg/find_package.lua b/xmake/modules/package/manager/vcpkg/find_package.lua
index 7cc6af548..f3dc740bd 100644
--- a/xmake/modules/package/manager/vcpkg/find_package.lua
+++ b/xmake/modules/package/manager/vcpkg/find_package.lua
@@ -29,6 +29,30 @@ import("package.manager.vcpkg.configurations")
import("package.manager.vcpkg.utils", {alias = "vcpkg_utils"})
import("package.manager.pkgconfig.find_package", {alias = "find_package_from_pkgconfig"})
+-- extract required features from both package name and configs.features.
+function _required_features(name, configs)
+ local features = {}
+ local features_str = name:match("%[(.-)%]")
+ if features_str then
+ for _, feature in ipairs(features_str:split(",", {plain = true})) do
+ feature = feature:trim()
+ if #feature > 0 then
+ table.insert(features, feature)
+ end
+ end
+ end
+ for _, feature in ipairs(table.wrap(configs and configs.features)) do
+ feature = tostring(feature):trim()
+ if #feature > 0 then
+ table.insert(features, feature)
+ end
+ end
+ features = table.unique(features)
+ if #features > 0 then
+ return features
+ end
+end
+
-- we iterate over each pkgconfig file to extract the required data
function _find_package_from_pkgconfig(pkgconfig_files, opt)
opt = opt or {}
@@ -137,13 +161,17 @@ function _find_package(vcpkg, vcpkgdir, name, opt)
-- get configs
local configs = opt.configs or {}
- -- extract required features before stripping, e.g. curl[openssl,mbedtls] -> {"openssl", "mbedtls"}
- local required_features
- local features_str = name:match("%[(.-)%]")
- if features_str then
- required_features = features_str:split(",", {plain = true})
+ -- is need manifest mode?
+ local manifest_mode = vcpkg_utils.need_manifest(opt)
+
+ -- manifest mode requires installdir to run vcpkg commands in the context of the manifest
+ if manifest_mode and not opt.installdir then
+ raise("installdir is required for manifest mode!")
end
+ -- extract required features from both package name and configs.features.
+ local required_features = _required_features(name, configs)
+
-- fix name, e.g. ffmpeg[x264] as ffmpeg
-- @see https://github.com/xmake-io/xmake/issues/925
name = name:gsub("%[.-%]", "")
@@ -158,10 +186,11 @@ function _find_package(vcpkg, vcpkgdir, name, opt)
-- get the vcpkg info directories
local infodirs = {}
- if opt.installdir then
+ if manifest_mode then
table.join2(infodirs, path.join(opt.installdir, "vcpkg_installed", "vcpkg", "info"))
+ else
+ table.join2(infodirs, path.join(vcpkgdir, "installed", "vcpkg", "info"))
end
- table.join2(infodirs, path.join(vcpkgdir, "installed", "vcpkg", "info"))
-- find the package info file, e.g. zlib_1.2.11-3_x86-windows[-static].list
local infofile = find_file(format("%s_*_%s.list", name, triplet), infodirs)
@@ -171,7 +200,7 @@ function _find_package(vcpkg, vcpkgdir, name, opt)
-- check that required features are installed
-- @see https://github.com/xmake-io/xmake/issues/7388
- if required_features and not vcpkg_utils.has_installed_features(vcpkg, name, triplet, required_features) then
+ if required_features and not vcpkg_utils.has_installed_features(vcpkg, name, triplet, required_features, opt) then
return
end
@@ -184,7 +213,14 @@ function _find_package(vcpkg, vcpkgdir, name, opt)
depend_name = name .. "[" .. table.concat(required_features, ",") .. "]"
end
local result = nil
- local _, dependinfo = try { function () return os.iorunv(vcpkg, {"depend-info", depend_name, "--sort=reverse", "--triplet=" .. triplet}) end }
+ 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
+ if manifest_mode then
+ 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 }
if dependinfo then
for _, line in ipairs(dependinfo:split("\n", {plain = true})) do
if not line:startswith("vcpkg-") then
diff --git a/xmake/modules/package/manager/vcpkg/install_package.lua b/xmake/modules/package/manager/vcpkg/install_package.lua
index 2c2c520f3..a8546e5d0 100644
--- a/xmake/modules/package/manager/vcpkg/install_package.lua
+++ b/xmake/modules/package/manager/vcpkg/install_package.lua
@@ -26,18 +26,6 @@ import("lib.detect.find_tool")
import("package.manager.vcpkg.configurations")
import("package.manager.vcpkg.utils", {alias = "vcpkg_utils"})
--- need manifest mode?
-function _need_manifest(opt)
- local require_version = opt.require_version
- if require_version ~= nil and require_version ~= "latest" then
- return true
- end
- local configs = opt.configs
- if configs and (configs.features or configs.default_features == false or configs.baseline) then
- return true
- end
-end
-
-- install for classic mode
function _install_for_classic(vcpkg, name, opt)
@@ -62,8 +50,8 @@ function _install_for_classic(vcpkg, name, opt)
-- @see https://github.com/xmake-io/xmake/issues/7388
local basename = name:gsub("%[.-%]", "")
if basename ~= name then
- if not vcpkg_utils.is_installed(vcpkg, name, triplet) then
- if vcpkg_utils.is_installed(vcpkg, basename, triplet) then
+ if not vcpkg_utils.is_installed(vcpkg, name, triplet, opt) then
+ if vcpkg_utils.is_installed(vcpkg, basename, triplet, opt) then
local confirm = utils.confirm({default = true,
description = format("%s:%s is already installed (possibly with different features). Installing %s will require a rebuild of it and its dependencies. Continue?", basename, triplet, name)})
if confirm then
@@ -168,7 +156,7 @@ function main(name, opt)
-- do install
opt = opt or {}
- if _need_manifest(opt) then
+ if vcpkg_utils.need_manifest(opt) then
_install_for_manifest(vcpkg.program, name, opt)
else
_install_for_classic(vcpkg.program, name, opt)
diff --git a/xmake/modules/package/manager/vcpkg/utils.lua b/xmake/modules/package/manager/vcpkg/utils.lua
index da321cda0..fdd85d501 100644
--- a/xmake/modules/package/manager/vcpkg/utils.lua
+++ b/xmake/modules/package/manager/vcpkg/utils.lua
@@ -19,14 +19,34 @@
--
-- check if a package (with optional features) is installed for the given triplet
--- e.g. is_installed(vcpkg, "curl", "x64-windows-static-md")
--- is_installed(vcpkg, "curl[mbedtls]", "x64-windows-static-md")
+-- e.g. is_installed(vcpkg, "curl", "x64-windows-static-md", opt)
+-- is_installed(vcpkg, "curl[mbedtls]", "x64-windows-static-md", opt)
--
-- @see https://github.com/xmake-io/xmake/issues/7388
--
-function is_installed(vcpkg, name, triplet)
+
+function need_manifest(opt)
+ local require_version = opt.require_version
+ if require_version ~= nil and require_version ~= "latest" then
+ return true
+ end
+ local configs = opt.configs
+ if configs and (configs.features or configs.default_features == false or configs.baseline) then
+ return true
+ end
+end
+
+function is_installed(vcpkg, name, triplet, opt)
+ local argv = {"list", name .. ":" .. triplet, "--x-full-desc"}
+ local manifest_mode = need_manifest(opt)
+
+ -- pass feature flags to depend-info when in manifest mode, otherwise depend-info will not show the complete dependency tree with features
+ if manifest_mode then
+ table.insert(argv, 1, "--feature-flags=versions")
+ end
+
local listinfo = try { function ()
- return os.iorunv(vcpkg, {"list", name .. ":" .. triplet, "--x-full-desc"})
+ return os.iorunv(vcpkg, argv, manifest_mode and {curdir = opt.installdir} or nil)
end}
if listinfo then
local exact_prefix = name .. ":" .. triplet
@@ -45,9 +65,9 @@ end
--
-- @see https://github.com/xmake-io/xmake/issues/7388
--
-function has_installed_features(vcpkg, name, triplet, required_features)
+function has_installed_features(vcpkg, name, triplet, required_features, opt)
for _, feature in ipairs(required_features) do
- if not is_installed(vcpkg, name .. "[" .. feature .. "]", triplet) then
+ if not is_installed(vcpkg, name .. "[" .. feature .. "]", triplet, opt) then
return false
end
end