diff options
| author | ruki <[email protected]> | 2026-07-27 15:58:21 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-07-27 15:58:21 +0800 |
| commit | e440a9168b0d2c3151daa8ab0db4bf4e44ff70ba (patch) | |
| tree | 2f0dec9766b10408050d5262a4071305c1b0b851 | |
| parent | ddfd397d81a4283a74425f2418e1337cc2e04037 (diff) | |
| parent | 451a46e86a2651ffb326870b07cc27952fbe6505 (diff) | |
Merge pull request #7666 from xmake-io/vcpkg3
improve to find vcpkg packages
| -rw-r--r-- | xmake/modules/package/manager/vcpkg/find_package.lua | 36 | ||||
| -rw-r--r-- | xmake/modules/package/manager/vcpkg/install_package.lua | 5 | ||||
| -rw-r--r-- | xmake/modules/package/manager/vcpkg/utils.lua | 18 |
3 files changed, 45 insertions, 14 deletions
diff --git a/xmake/modules/package/manager/vcpkg/find_package.lua b/xmake/modules/package/manager/vcpkg/find_package.lua index 5b515d8a2..0504070a3 100644 --- a/xmake/modules/package/manager/vcpkg/find_package.lua +++ b/xmake/modules/package/manager/vcpkg/find_package.lua @@ -212,7 +212,6 @@ function _find_package(vcpkg, vcpkgdir, name, opt) if required_features then depend_name = name .. "[" .. table.concat(required_features, ",") .. "]" end - local result = nil 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 @@ -220,31 +219,44 @@ function _find_package(vcpkg, vcpkgdir, name, opt) 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 } + local _, dependinfo = try { function () return os.iorunv(vcpkg, argv, {curdir = manifest_mode and opt.installdir or vcpkg_utils.classic_curdir()}) end } if manifest_mode and not dependinfo then - -- fallback: newer vcpkg-tool no longer accepts the package name as a positional argument, - -- drop it and retry. see https://github.com/microsoft/vcpkg-tool/pull/1909 + -- fallback: in manifest mode vcpkg rejects the package name as a positional argument, so + -- drop it and query the manifest's dependency tree instead. + -- see https://github.com/microsoft/vcpkg-tool/pull/1909 table.remove(argv, 3) _, dependinfo = try { function () return os.iorunv(vcpkg, argv, {curdir = opt.installdir}) end } end + + -- collect the packages to read info from: always the main package (its .list file was found + -- above, so it is known-installed), plus any transitive dependencies reported by depend-info. + -- this keeps resolution working even when depend-info fails, e.g. a project-owned vcpkg.json + -- puts vcpkg in manifest mode and it rejects arguments; only transitive deps are then missing. + -- @see https://github.com/xmake-io/xmake/issues/7660 + local packagenames = {name} if dependinfo then for _, line in ipairs(dependinfo:split("\n", {plain = true})) do if not line:startswith("vcpkg-") then local packagename = line:match("^([^%[:]+)[^:]*:") if packagename then - local dependencyresult = _get_package_info(packagename, triplet, infodirs, arch, plat, mode) - if dependencyresult then - result = result or {} - for key, dependencylist in pairs(dependencyresult) do - result[key] = result[key] or {} - table.join2(result[key], dependencylist) - end - end + table.insert(packagenames, packagename) end end end end + local result = nil + for _, packagename in ipairs(table.unique(packagenames)) do + local dependencyresult = _get_package_info(packagename, triplet, infodirs, arch, plat, mode) + if dependencyresult then + result = result or {} + for key, dependencylist in pairs(dependencyresult) do + result[key] = result[key] or {} + table.join2(result[key], dependencylist) + end + end + end + -- save version if result then local infoname = path.basename(infofile) diff --git a/xmake/modules/package/manager/vcpkg/install_package.lua b/xmake/modules/package/manager/vcpkg/install_package.lua index a8546e5d0..909374e61 100644 --- a/xmake/modules/package/manager/vcpkg/install_package.lua +++ b/xmake/modules/package/manager/vcpkg/install_package.lua @@ -64,7 +64,10 @@ function _install_for_classic(vcpkg, name, opt) end -- install package - os.vrunv(vcpkg, argv) + -- run in a neutral directory so that a project-owned vcpkg.json in the current working + -- directory does not switch vcpkg into manifest mode (which rejects package arguments). + -- @see https://github.com/xmake-io/xmake/issues/7660 + os.vrunv(vcpkg, argv, {curdir = vcpkg_utils.classic_curdir()}) end -- install for manifest mode diff --git a/xmake/modules/package/manager/vcpkg/utils.lua b/xmake/modules/package/manager/vcpkg/utils.lua index fdd85d501..1c83323b4 100644 --- a/xmake/modules/package/manager/vcpkg/utils.lua +++ b/xmake/modules/package/manager/vcpkg/utils.lua @@ -36,6 +36,22 @@ function need_manifest(opt) end end +-- get a neutral empty directory to run classic-mode vcpkg commands in. +-- +-- vcpkg switches to manifest mode when a vcpkg.json exists in the current working directory, and +-- in manifest mode it rejects individual package arguments ("In manifest mode, `vcpkg install` +-- does not support individual package arguments"). so classic-mode commands (install/list/ +-- depend-info, which pass `<pkg>:<triplet>`) must not run from a project directory that ships its +-- own vcpkg.json. +-- @see https://github.com/xmake-io/xmake/issues/7660 +function classic_curdir() + local dir = path.join(os.tmpdir(), "vcpkg", "classic") + if not os.isdir(dir) then + os.mkdir(dir) + end + return dir +end + function is_installed(vcpkg, name, triplet, opt) local argv = {"list", name .. ":" .. triplet, "--x-full-desc"} local manifest_mode = need_manifest(opt) @@ -46,7 +62,7 @@ function is_installed(vcpkg, name, triplet, opt) end local listinfo = try { function () - return os.iorunv(vcpkg, argv, manifest_mode and {curdir = opt.installdir} or nil) + return os.iorunv(vcpkg, argv, {curdir = manifest_mode and opt.installdir or classic_curdir()}) end} if listinfo then local exact_prefix = name .. ":" .. triplet |
