summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkanren3 <[email protected]>2026-03-19 20:22:11 +0800
committerkanren3 <[email protected]>2026-03-20 14:41:33 +0800
commit101c700f7b5339ea4850a928e354471e9e9c0d8f (patch)
tree231b347020b9e3dff151ae7a83812fd1dfd05347
parent5982d5110c74890122372c0ab6040ef0d0c9d9b5 (diff)
add manifest mode support for vcpkg package depend-info
-rw-r--r--xmake/modules/package/manager/vcpkg/find_package.lua66
-rw-r--r--xmake/modules/package/manager/vcpkg/utils.lua16
2 files changed, 69 insertions, 13 deletions
diff --git a/xmake/modules/package/manager/vcpkg/find_package.lua b/xmake/modules/package/manager/vcpkg/find_package.lua
index 7cc6af548..ab65cf21d 100644
--- a/xmake/modules/package/manager/vcpkg/find_package.lua
+++ b/xmake/modules/package/manager/vcpkg/find_package.lua
@@ -29,6 +29,42 @@ import("package.manager.vcpkg.configurations")
import("package.manager.vcpkg.utils", {alias = "vcpkg_utils"})
import("package.manager.pkgconfig.find_package", {alias = "find_package_from_pkgconfig"})
+-- 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
+
+-- extract required features from both package name and configs.features.
+local 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 +173,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 = _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 +198,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 +212,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, manifest_mode, opt) then
return
end
@@ -184,7 +225,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/utils.lua b/xmake/modules/package/manager/vcpkg/utils.lua
index da321cda0..7829a311e 100644
--- a/xmake/modules/package/manager/vcpkg/utils.lua
+++ b/xmake/modules/package/manager/vcpkg/utils.lua
@@ -24,9 +24,17 @@
--
-- @see https://github.com/xmake-io/xmake/issues/7388
--
-function is_installed(vcpkg, name, triplet)
+
+function is_installed(vcpkg, name, triplet, manifest_mode, opt)
+ local argv = {"list", name .. ":" .. triplet, "--x-full-desc"}
+
+ -- 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 +53,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, manifest_mode, 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, manifest_mode, opt) then
return false
end
end