diff options
| author | kanren3 <[email protected]> | 2026-03-19 20:22:11 +0800 |
|---|---|---|
| committer | kanren3 <[email protected]> | 2026-03-20 14:41:33 +0800 |
| commit | 101c700f7b5339ea4850a928e354471e9e9c0d8f (patch) | |
| tree | 231b347020b9e3dff151ae7a83812fd1dfd05347 | |
| parent | 5982d5110c74890122372c0ab6040ef0d0c9d9b5 (diff) | |
add manifest mode support for vcpkg package depend-info
| -rw-r--r-- | xmake/modules/package/manager/vcpkg/find_package.lua | 66 | ||||
| -rw-r--r-- | xmake/modules/package/manager/vcpkg/utils.lua | 16 |
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 |
