summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2026-03-13 22:42:49 +0800
committerGitHub <[email protected]>2026-03-13 22:42:49 +0800
commit78d9621895056a0163a3a481d52f049c59f6ef2f (patch)
treefdd0559faebf8cb2569f6f3d1f3984c578fa1a23
parentf9d6d506bae007c99ddc1747aa5520d28e301b06 (diff)
parent737959ac2cb795665ccae272997cd0c85d9d5199 (diff)
Merge pull request #7396 from xmake-io/vcpkg
Improve vcpkg
-rw-r--r--xmake/modules/package/manager/vcpkg/find_package.lua17
-rw-r--r--xmake/modules/package/manager/vcpkg/install_package.lua19
-rw-r--r--xmake/modules/package/manager/vcpkg/utils.lua55
3 files changed, 74 insertions, 17 deletions
diff --git a/xmake/modules/package/manager/vcpkg/find_package.lua b/xmake/modules/package/manager/vcpkg/find_package.lua
index 563521889..7cc6af548 100644
--- a/xmake/modules/package/manager/vcpkg/find_package.lua
+++ b/xmake/modules/package/manager/vcpkg/find_package.lua
@@ -26,6 +26,7 @@ import("core.project.config")
import("core.project.target")
import("detect.sdks.find_vcpkgdir")
import("package.manager.vcpkg.configurations")
+import("package.manager.vcpkg.utils", {alias = "vcpkg_utils"})
import("package.manager.pkgconfig.find_package", {alias = "find_package_from_pkgconfig"})
-- we iterate over each pkgconfig file to extract the required data
@@ -131,20 +132,6 @@ function _get_package_info(name, triplet, infodirs, arch, plat, mode)
return result
end
--- check if the required features are installed via `vcpkg list`
--- @see https://github.com/xmake-io/xmake/issues/7388
-function _has_installed_features(vcpkg, name, triplet, required_features)
- for _, feature in ipairs(required_features) do
- local listinfo = try { function ()
- return os.iorunv(vcpkg, {"list", name .. "[" .. feature .. "]:" .. triplet})
- end}
- if not listinfo or listinfo:trim() == "" then
- return false
- end
- end
- return true
-end
-
function _find_package(vcpkg, vcpkgdir, name, opt)
-- get configs
@@ -184,7 +171,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 _has_installed_features(vcpkg, name, triplet, required_features) then
+ if required_features and not vcpkg_utils.has_installed_features(vcpkg, name, triplet, required_features) then
return
end
diff --git a/xmake/modules/package/manager/vcpkg/install_package.lua b/xmake/modules/package/manager/vcpkg/install_package.lua
index e7c0fa930..2c2c520f3 100644
--- a/xmake/modules/package/manager/vcpkg/install_package.lua
+++ b/xmake/modules/package/manager/vcpkg/install_package.lua
@@ -24,6 +24,7 @@ import("core.base.json")
import("core.base.semver")
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)
@@ -56,9 +57,23 @@ function _install_for_classic(vcpkg, name, opt)
table.insert(argv, "--debug")
end
- -- allow rebuilding packages when features change
+ -- check if the base package is already installed with different features,
+ -- if so, prompt user before rebuilding with --recurse
-- @see https://github.com/xmake-io/xmake/issues/7388
- table.insert(argv, "--recurse")
+ 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
+ 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
+ table.insert(argv, "--recurse")
+ else
+ raise("install %s:%s cancelled!", name, triplet)
+ end
+ end
+ end
+ end
-- install package
os.vrunv(vcpkg, argv)
diff --git a/xmake/modules/package/manager/vcpkg/utils.lua b/xmake/modules/package/manager/vcpkg/utils.lua
new file mode 100644
index 000000000..da321cda0
--- /dev/null
+++ b/xmake/modules/package/manager/vcpkg/utils.lua
@@ -0,0 +1,55 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-present, Xmake Open Source Community.
+--
+-- @author ruki
+-- @file utils.lua
+--
+
+-- 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")
+--
+-- @see https://github.com/xmake-io/xmake/issues/7388
+--
+function is_installed(vcpkg, name, triplet)
+ local listinfo = try { function ()
+ return os.iorunv(vcpkg, {"list", name .. ":" .. triplet, "--x-full-desc"})
+ end}
+ if listinfo then
+ local exact_prefix = name .. ":" .. triplet
+ for _, line in ipairs(listinfo:split("\n", {plain = true})) do
+ local first = line:split("%s")[1]
+ if first == exact_prefix then
+ return true
+ end
+ end
+ end
+ return false
+end
+
+-- check if all required features are installed
+-- e.g. has_installed_features(vcpkg, "curl", "x64-windows-static-md", {"openssl", "mbedtls"})
+--
+-- @see https://github.com/xmake-io/xmake/issues/7388
+--
+function has_installed_features(vcpkg, name, triplet, required_features)
+ for _, feature in ipairs(required_features) do
+ if not is_installed(vcpkg, name .. "[" .. feature .. "]", triplet) then
+ return false
+ end
+ end
+ return true
+end