diff options
| author | ruki <[email protected]> | 2026-03-20 17:33:47 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-03-20 17:33:47 +0800 |
| commit | 8b1b87604943d055f854525e2a30e2b6741e061a (patch) | |
| tree | 798701263e044a714e0afd752d0a270600317980 | |
| parent | 5982d5110c74890122372c0ab6040ef0d0c9d9b5 (diff) | |
| parent | 9a6688113136d8e23c7f14f5611a06dcf885d2af (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.lua | 54 | ||||
| -rw-r--r-- | xmake/modules/package/manager/vcpkg/install_package.lua | 18 | ||||
| -rw-r--r-- | xmake/modules/package/manager/vcpkg/utils.lua | 32 |
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 |
