From 5b6ccc1740802dda446cd4d95a748047bd66f80a Mon Sep 17 00:00:00 2001 From: ruki Date: Thu, 28 Nov 2024 23:55:27 +0800 Subject: add deps version test --- .../package/compatibility/deps_with_version/src/main.c | 7 +++++++ .../package/compatibility/deps_with_version/test.lua | 10 ++++++++++ .../package/compatibility/deps_with_version/xmake.lua | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100755 tests/projects/package/compatibility/deps_with_version/src/main.c create mode 100644 tests/projects/package/compatibility/deps_with_version/test.lua create mode 100644 tests/projects/package/compatibility/deps_with_version/xmake.lua diff --git a/tests/projects/package/compatibility/deps_with_version/src/main.c b/tests/projects/package/compatibility/deps_with_version/src/main.c new file mode 100755 index 000000000..9ae580511 --- /dev/null +++ b/tests/projects/package/compatibility/deps_with_version/src/main.c @@ -0,0 +1,7 @@ +#include + +int main(int argc, char** argv) +{ + printf("hello world!\n"); + return 0; +} diff --git a/tests/projects/package/compatibility/deps_with_version/test.lua b/tests/projects/package/compatibility/deps_with_version/test.lua new file mode 100644 index 000000000..a6690754b --- /dev/null +++ b/tests/projects/package/compatibility/deps_with_version/test.lua @@ -0,0 +1,10 @@ +function main(t) + -- freebsd ci is slower + if is_host("bsd") then + return + end + -- only for x86/x64, because it will take too long time on ci with arm/mips + if os.subarch():startswith("x") or os.subarch() == "i386" then + t:build() + end +end diff --git a/tests/projects/package/compatibility/deps_with_version/xmake.lua b/tests/projects/package/compatibility/deps_with_version/xmake.lua new file mode 100644 index 000000000..f0cc809b9 --- /dev/null +++ b/tests/projects/package/compatibility/deps_with_version/xmake.lua @@ -0,0 +1,18 @@ +package("foo") + add_deps("zlib >=v1.2.13") +package_end() + +package("bar") + add_deps("zlib") +package_end() + +package("test") + add_deps("foo", "bar") +package_end() + +add_requires("test") + +target("test") + set_kind("binary") + add_files("src/*.c") + add_packages("test") -- cgit v1.3.1 From 36953ccf16f9765746471b47aca5b2611270b274 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 29 Nov 2024 00:00:39 +0800 Subject: improve tests --- tests/projects/package/compatibility/deps_with_version/xmake.lua | 5 ++++- xmake/modules/private/action/require/impl/package.lua | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/projects/package/compatibility/deps_with_version/xmake.lua b/tests/projects/package/compatibility/deps_with_version/xmake.lua index f0cc809b9..895b57d3b 100644 --- a/tests/projects/package/compatibility/deps_with_version/xmake.lua +++ b/tests/projects/package/compatibility/deps_with_version/xmake.lua @@ -1,13 +1,16 @@ package("foo") - add_deps("zlib >=v1.2.13") + add_deps("zlib >=1.2.13") + on_install(function () end) package_end() package("bar") add_deps("zlib") + on_install(function () end) package_end() package("test") add_deps("foo", "bar") + on_install(function () end) package_end() add_requires("test") diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index 5c0d1bf3d..cea24ba10 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -1191,6 +1191,8 @@ end -- cannot be detected at present and can only be resolved by the user -- function _check_package_depconflicts(package) + print("_check_package_depconflicts ..") + --[[ local packagekeys = {} for _, dep in ipairs(package:librarydeps()) do local key = _get_packagekey(dep:name(), dep:requireinfo()) @@ -1200,7 +1202,7 @@ function _check_package_depconflicts(package) else packagekeys[dep:name()] = key end - end + end]] end -- must depend on the given package? -- cgit v1.3.1 From 202fb01a8cae37a4168e75c1abbe1ae9b6cdd688 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 29 Nov 2024 00:53:22 +0800 Subject: get conflict packages --- .../compatibility/deps_with_version/xmake.lua | 2 +- .../private/action/require/impl/package.lua | 32 +++++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/tests/projects/package/compatibility/deps_with_version/xmake.lua b/tests/projects/package/compatibility/deps_with_version/xmake.lua index 895b57d3b..e937c1384 100644 --- a/tests/projects/package/compatibility/deps_with_version/xmake.lua +++ b/tests/projects/package/compatibility/deps_with_version/xmake.lua @@ -4,7 +4,7 @@ package("foo") package_end() package("bar") - add_deps("zlib") + add_deps("zlib 1.2.x") on_install(function () end) package_end() diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index cea24ba10..0e4513a98 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -1176,7 +1176,13 @@ function _get_parents_str(package) end end --- check dependencies conflicts +-- check and resolve package conflicts +function _check_and_resolve_package_conflicts(package1, package2) + print(package1:version_str(), package2:version_str()) + print(package1:requireinfo(), package2:requireinfo()) +end + +-- check and resolve dependencies conflicts -- -- It exists conflict for dependent packages for each root packages? resolve it first -- e.g. @@ -1190,8 +1196,8 @@ end -- Of course, conflicts caused by `add_packages("foo", "ddd")` -- cannot be detected at present and can only be resolved by the user -- -function _check_package_depconflicts(package) - print("_check_package_depconflicts ..") +function _check_and_resolve_package_depconflicts(package) + print("_check_and_resole_package_depconflicts ..") --[[ local packagekeys = {} for _, dep in ipairs(package:librarydeps()) do @@ -1203,6 +1209,24 @@ function _check_package_depconflicts(package) packagekeys[dep:name()] = key end end]] + local same_packages = {} + for _, dep in ipairs(package:librarydeps()) do + local packages = same_packages[dep:name()] + if packages == nil then + packages = {} + same_packages[dep:name()] = packages + end + table.insert(packages, dep) + end + for name, packages in pairs(same_packages) do + if #packages > 1 then + for i = 1, #packages do + for j = i + 1, #packages do + _check_and_resolve_package_conflicts(packages[i], packages[j]) + end + end + end + end end -- must depend on the given package? @@ -1449,7 +1473,7 @@ function load_packages(requires, opt) local packages = {} for _, package in ipairs((_load_packages(requires, opt))) do if package:is_toplevel() then - _check_package_depconflicts(package) + _check_and_resolve_package_depconflicts(package) end local key = _get_packagekey(package:name(), package:requireinfo()) if not unique[key] then -- cgit v1.3.1 From 603de8819bbc4234a12035f7b9d5748362ec9aa0 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 29 Nov 2024 00:53:51 +0800 Subject: format code --- tests/projects/package/depconfigs/src/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/projects/package/depconfigs/src/main.c b/tests/projects/package/depconfigs/src/main.c index 9ae580511..113930e1a 100755 --- a/tests/projects/package/depconfigs/src/main.c +++ b/tests/projects/package/depconfigs/src/main.c @@ -1,7 +1,6 @@ #include -int main(int argc, char** argv) -{ +int main(int argc, char** argv) { printf("hello world!\n"); return 0; } -- cgit v1.3.1 From 78f2f9b858a5acede19b35608a193364bda1f738 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 29 Nov 2024 23:50:04 +0800 Subject: check verison conflicts --- .../compatibility/deps_with_version/xmake.lua | 8 +- .../private/action/require/impl/package.lua | 102 +++++++++++++++------ 2 files changed, 80 insertions(+), 30 deletions(-) diff --git a/tests/projects/package/compatibility/deps_with_version/xmake.lua b/tests/projects/package/compatibility/deps_with_version/xmake.lua index e937c1384..b6ba830c3 100644 --- a/tests/projects/package/compatibility/deps_with_version/xmake.lua +++ b/tests/projects/package/compatibility/deps_with_version/xmake.lua @@ -5,11 +5,17 @@ package_end() package("bar") add_deps("zlib 1.2.x") +-- add_deps("libpng dev") + on_install(function () end) +package_end() + +package("zoo") + add_deps("libpng master") on_install(function () end) package_end() package("test") - add_deps("foo", "bar") + add_deps("foo", "bar", "zoo") on_install(function () end) package_end() diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index 0e4513a98..b3cc69e87 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -1011,6 +1011,7 @@ function _load_package(packagename, requireinfo, opt) local version, source = _select_package_version(package, requireinfo, locked_requireinfo) if version then package:version_set(version, source) + package:data_set("__locked_requireinfo", locked_requireinfo) end -- get package key @@ -1176,10 +1177,69 @@ function _get_parents_str(package) end end +-- get package compatibility info +function _get_package_compatinfo(package) + local compatinfo = {name = package:name()} + if package:data("__locked_requireinfo") then + compatinfo.locked = true + compatinfo.versions = hashset.from(table.wrap(package:version_str())) + return compatinfo + end + + -- get compatible version range + local requireinfo = package:requireinfo() + local require_version = requireinfo.version + if require_version then + compatinfo.require_version = require_version + if semver.is_valid(require_version) or semver.is_valid_range(require_version) then + local versions = hashset.new() + for _, version in ipairs(package:versions()) do + if semver.satisfies(version, require_version) then + versions:insert(version) + end + end + compatinfo.versions = versions + elseif require_version == "latest" then + compatinfo.versions = hashset.from(table.wrap(package:versions())) + else + compatinfo.versions = hashset.from(table.wrap(require_version)) + end + else + compatinfo.versions = hashset.from(table.wrap(package:versions())) + end + return compatinfo +end + -- check and resolve package conflicts -function _check_and_resolve_package_conflicts(package1, package2) - print(package1:version_str(), package2:version_str()) - print(package1:requireinfo(), package2:requireinfo()) +function _check_and_resolve_package_depconflicts_impl(package, name, deps) + + -- compute versions intersection + local versions + for _, dep in ipairs(deps) do + local compatinfo = _get_package_compatinfo(dep) + assert(compatinfo.versions) + + if versions then + for version in versions:items() do + if not compatinfo.versions:has(version) then + versions:remove(version) + end + end + else + versions = compatinfo.versions + end + end + + if not versions or versions:empty() then + print("package(%s): add_deps(%s, ...)", package:name(), name) + for idx, dep in ipairs(deps) do + local key = _get_packagekey(dep:name(), dep:requireinfo()) + cprint(" ${color.warning}->${clear} %s %s ${dim}%s", + dep:displayname(), dep:version_str() or "", get_configs_str(dep)) + end + raise("package(%s): conflict version dependencies!", name) + end + print(name, versions) end -- check and resolve dependencies conflicts @@ -1197,34 +1257,18 @@ end -- cannot be detected at present and can only be resolved by the user -- function _check_and_resolve_package_depconflicts(package) - print("_check_and_resole_package_depconflicts ..") - --[[ - local packagekeys = {} + local some_packagedeps = {} for _, dep in ipairs(package:librarydeps()) do - local key = _get_packagekey(dep:name(), dep:requireinfo()) - local prevkey = packagekeys[dep:name()] - if prevkey then - assert(key == prevkey, "package(%s): conflict dependencies with package(%s) in %s!", key, prevkey, package:name()) - else - packagekeys[dep:name()] = key + local deps = some_packagedeps[dep:name()] + if deps == nil then + deps = {} + some_packagedeps[dep:name()] = deps end - end]] - local same_packages = {} - for _, dep in ipairs(package:librarydeps()) do - local packages = same_packages[dep:name()] - if packages == nil then - packages = {} - same_packages[dep:name()] = packages - end - table.insert(packages, dep) - end - for name, packages in pairs(same_packages) do - if #packages > 1 then - for i = 1, #packages do - for j = i + 1, #packages do - _check_and_resolve_package_conflicts(packages[i], packages[j]) - end - end + table.insert(deps, dep) + end + for name, deps in pairs(some_packagedeps) do + if #deps > 1 then + _check_and_resolve_package_depconflicts_impl(package, name, deps) end end end -- cgit v1.3.1 From 42098468650fba086e24acb137fa1edce4c4d0ee Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 29 Nov 2024 23:52:51 +0800 Subject: check configs conflict --- .../private/action/require/impl/package.lua | 28 +++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index b3cc69e87..2ba278f37 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -1213,7 +1213,7 @@ end -- check and resolve package conflicts function _check_and_resolve_package_depconflicts_impl(package, name, deps) - -- compute versions intersection + -- check version compatibility local versions for _, dep in ipairs(deps) do local compatinfo = _get_package_compatinfo(dep) @@ -1233,13 +1233,35 @@ function _check_and_resolve_package_depconflicts_impl(package, name, deps) if not versions or versions:empty() then print("package(%s): add_deps(%s, ...)", package:name(), name) for idx, dep in ipairs(deps) do - local key = _get_packagekey(dep:name(), dep:requireinfo()) cprint(" ${color.warning}->${clear} %s %s ${dim}%s", dep:displayname(), dep:version_str() or "", get_configs_str(dep)) end raise("package(%s): conflict version dependencies!", name) + else + -- TODO switch to compatible version + end + + -- check configs compatibility + local prevkey + local configs_conflict = false + for _, dep in ipairs(deps) do + local key = _get_packagekey(dep:name(), dep:requireinfo()) + if prevkey then + if prevkey ~= key then + configs_conflict = true + end + else + prevkey = key + end + end + if configs_conflict then + print("package(%s): add_deps(%s, ...)", package:name(), name) + for idx, dep in ipairs(deps) do + cprint(" ${color.warning}->${clear} %s %s ${dim}%s", + dep:displayname(), dep:version_str() or "", get_configs_str(dep)) + end + raise("package(%s): conflict configs dependencies!", name) end - print(name, versions) end -- check and resolve dependencies conflicts -- cgit v1.3.1 From cea762c1a9cf6ae35081097cfe1b1adcf1bc19b2 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 29 Nov 2024 23:57:24 +0800 Subject: improve compatkey --- .../private/action/require/impl/package.lua | 72 +++++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index 2ba278f37..ea4d4dd76 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -1177,6 +1177,51 @@ function _get_parents_str(package) end end +-- get configs key for compatibility +function _get_package_compatkey(requireinfo, opt) + opt = opt or {} + local key = "" + if opt.name then + key = key .. "/" .. opt.name + end + if opt.plat then + key = key .. "/" .. opt.plat + end + if opt.arch then + key = key .. "/" .. opt.arch + end + if opt.kind then + key = key .. "/" .. opt.kind + end + if requireinfo.host then + if is_subhost(core_package.targetplat()) and os.subarch() == core_package.targetarch() then + -- we need to pass plat/arch to avoid repeat installation + -- @see https://github.com/xmake-io/xmake/issues/1579 + else + key = key .. "/host" + end + end + if requireinfo.system then + key = key .. "/system" + end + if key:startswith("/") then + key = key:sub(2) + end + local configs = requireinfo.configs + if configs then + local configs_order = {} + for k, v in pairs(configs) do + if type(v) == "table" then + v = string.serialize(v, {strip = true, indent = false, orderkeys = true}) + end + table.insert(configs_order, k .. "=" .. tostring(v)) + end + table.sort(configs_order) + key = key .. ":" .. string.serialize(configs_order, true) + end + return key +end + -- get package compatibility info function _get_package_compatinfo(package) local compatinfo = {name = package:name()} @@ -1238,14 +1283,37 @@ function _check_and_resolve_package_depconflicts_impl(package, name, deps) end raise("package(%s): conflict version dependencies!", name) else - -- TODO switch to compatible version + -- resolve to compatible version for all deps + local version_best + for version in versions:items() do + if version_best == nil or semver.compare(version, version_best) > 0 then + version_best = version + end + end + if version_best then + for _, dep in ipairs(deps) do + local source = "version" + if dep:branch() then + source = "branch" + elseif dep:tag() then + source = "tag" + elseif dep:commit() then + source = "commit" + end + dep:version_set(version_best, source) + end + end end -- check configs compatibility local prevkey local configs_conflict = false for _, dep in ipairs(deps) do - local key = _get_packagekey(dep:name(), dep:requireinfo()) + local key = _get_package_compatkey(dep:requireinfo(), { + name = dep:name(), + plat = dep:plat(), + arch = dep:arch(), + kind = dep:kind()}) if prevkey then if prevkey ~= key then configs_conflict = true -- cgit v1.3.1 From c665218691e6655c0feee4f0a30f92af91392b62 Mon Sep 17 00:00:00 2001 From: ruki Date: Fri, 29 Nov 2024 23:58:22 +0800 Subject: add todo --- xmake/modules/private/action/require/impl/package.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index ea4d4dd76..8b222e224 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -1301,6 +1301,9 @@ function _check_and_resolve_package_depconflicts_impl(package, name, deps) source = "commit" end dep:version_set(version_best, source) + + -- TODO reset buildhash and cache + -- ... end end end -- cgit v1.3.1 From bc5af31be35359999af8f7907f48f3d7f7f3089a Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 30 Nov 2024 00:23:53 +0800 Subject: add tips --- xmake/modules/private/action/require/impl/package.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index 8b222e224..6d897968d 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -1281,6 +1281,7 @@ function _check_and_resolve_package_depconflicts_impl(package, name, deps) cprint(" ${color.warning}->${clear} %s %s ${dim}%s", dep:displayname(), dep:version_str() or "", get_configs_str(dep)) end + print("we can use add_requireconfs(\"**.%s\", {override = true, configs = {version = \"x.x.x\"}}) to override version.", name) raise("package(%s): conflict version dependencies!", name) else -- resolve to compatible version for all deps @@ -1331,6 +1332,7 @@ function _check_and_resolve_package_depconflicts_impl(package, name, deps) cprint(" ${color.warning}->${clear} %s %s ${dim}%s", dep:displayname(), dep:version_str() or "", get_configs_str(dep)) end + print("we can use add_requireconfs(\"**.%s\", {override = true, configs = {}}) to override configs.", name) raise("package(%s): conflict configs dependencies!", name) end end -- cgit v1.3.1 From fc0b268bd8bc991f7e04ccaa4179709abafb0b78 Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 30 Nov 2024 00:41:47 +0800 Subject: improve to resolve package version --- .../private/action/require/impl/package.lua | 108 +++++++++++++++------ 1 file changed, 76 insertions(+), 32 deletions(-) diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index 6d897968d..90e34fcef 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -139,7 +139,8 @@ function _parse_require(require_str) end -- load require info -function _load_require(require_str, requires_extra, parentinfo) +function _load_require(require_str, requires_extra, opt) + opt = opt or {} -- parse require local packagename, version, reponame = _parse_require(require_str) @@ -215,8 +216,25 @@ function _load_require(require_str, requires_extra, parentinfo) require_extra.system = false end + -- resolve require info + local resolvedinfo = opt.resolvedinfo + local requirepath = opt.requirepath + if requirepath then + requirepath = requirepath .. "." .. packagename + else + requirepath = packagename + end + resolvedinfo = resolvedinfo and resolvedinfo[requirepath] + if resolvedinfo then + -- resolve the conflict package version + if resolvedinfo.version then + version = resolvedinfo.version + end + end + -- init required item local required = {} + local parentinfo = opt.parentinfo parentinfo = parentinfo or {} required.packagename = packagename required.requireinfo = @@ -1121,7 +1139,7 @@ function _load_packages(requires, opt) -- load package local requireinfo = requireitem.info local requirepath = opt.requirepath and (opt.requirepath .. "." .. requireitem.name) or requireitem.name - local package = _load_package(requireitem.name, requireinfo, table.join(opt, {requirepath = requirepath})) + local package = _load_package(requireitem.name, requireinfo, table.join(opt, {requirepath = requirepath})) -- maybe package not found and optional if package then @@ -1135,6 +1153,7 @@ function _load_packages(requires, opt) requires_extra = package:extraconf("deps") or {}, parentinfo = requireinfo, nodeps = opt.nodeps, + resolvedinfo = opt.resolvedinfo, system = false}) for _, dep in ipairs(plaindeps) do dep:parents_add(package) @@ -1177,6 +1196,22 @@ function _get_parents_str(package) end end +-- get require paths +function _get_requirepaths(package) + local requirepaths = {} + local parents = package:parents() + if parents and #parents > 0 then + for _, parent in ipairs(parents) do + for _, requirepath in ipairs(_get_requirepaths(parent)) do + table.insert(requirepaths, requirepath .. "." .. package:name()) + end + end + else + table.insert(requirepaths, package:name()) + end + return requirepaths +end + -- get configs key for compatibility function _get_package_compatkey(requireinfo, opt) opt = opt or {} @@ -1256,7 +1291,7 @@ function _get_package_compatinfo(package) end -- check and resolve package conflicts -function _check_and_resolve_package_depconflicts_impl(package, name, deps) +function _check_and_resolve_package_depconflicts_impl(package, name, deps, resolvedinfo) -- check version compatibility local versions @@ -1283,30 +1318,6 @@ function _check_and_resolve_package_depconflicts_impl(package, name, deps) end print("we can use add_requireconfs(\"**.%s\", {override = true, configs = {version = \"x.x.x\"}}) to override version.", name) raise("package(%s): conflict version dependencies!", name) - else - -- resolve to compatible version for all deps - local version_best - for version in versions:items() do - if version_best == nil or semver.compare(version, version_best) > 0 then - version_best = version - end - end - if version_best then - for _, dep in ipairs(deps) do - local source = "version" - if dep:branch() then - source = "branch" - elseif dep:tag() then - source = "tag" - elseif dep:commit() then - source = "commit" - end - dep:version_set(version_best, source) - - -- TODO reset buildhash and cache - -- ... - end - end end -- check configs compatibility @@ -1335,6 +1346,23 @@ function _check_and_resolve_package_depconflicts_impl(package, name, deps) print("we can use add_requireconfs(\"**.%s\", {override = true, configs = {}}) to override configs.", name) raise("package(%s): conflict configs dependencies!", name) end + + -- resolve compatible version for all deps + if versions and not versions:empty() then + local version_best + for version in versions:items() do + if version_best == nil or semver.compare(version, version_best) > 0 then + version_best = version + end + end + if version_best then + for _, dep in ipairs(deps) do + for _, requirepath in ipairs(_get_requirepaths(dep)) do + resolvedinfo[requirepath] = {version = version_best} + end + end + end + end end -- check and resolve dependencies conflicts @@ -1351,7 +1379,7 @@ end -- Of course, conflicts caused by `add_packages("foo", "ddd")` -- cannot be detected at present and can only be resolved by the user -- -function _check_and_resolve_package_depconflicts(package) +function _check_and_resolve_package_depconflicts(package, resolvedinfo) local some_packagedeps = {} for _, dep in ipairs(package:librarydeps()) do local deps = some_packagedeps[dep:name()] @@ -1363,7 +1391,7 @@ function _check_and_resolve_package_depconflicts(package) end for name, deps in pairs(some_packagedeps) do if #deps > 1 then - _check_and_resolve_package_depconflicts_impl(package, name, deps) + _check_and_resolve_package_depconflicts_impl(package, name, deps, resolvedinfo) end end end @@ -1599,7 +1627,7 @@ function load_requires(requires, requires_extra, opt) opt = opt or {} local requireitems = {} for _, require_str in ipairs(requires) do - local packagename, requireinfo = _load_require(require_str, requires_extra, opt.parentinfo) + local packagename, requireinfo = _load_require(require_str, requires_extra, opt) table.insert(requireitems, {name = packagename, info = requireinfo}) end return requireitems @@ -1610,9 +1638,10 @@ function load_packages(requires, opt) opt = opt or {} local unique = {} local packages = {} - for _, package in ipairs((_load_packages(requires, opt))) do + local resolvedinfo = {} + for _, package in ipairs((_load_packages(requires, table.clone(opt)))) do if package:is_toplevel() then - _check_and_resolve_package_depconflicts(package) + _check_and_resolve_package_depconflicts(package, resolvedinfo) end local key = _get_packagekey(package:name(), package:requireinfo()) if not unique[key] then @@ -1620,6 +1649,21 @@ function load_packages(requires, opt) unique[key] = true end end + + -- we need to reload packages with new resolved deps if there are some dep conflicts + if not table.empty(resolvedinfo) then + unique = {} + packages = {} + _memcache():clear() + opt = table.join(opt, {resolvedinfo = resolvedinfo}) + for _, package in ipairs((_load_packages(requires, opt))) do + local key = _get_packagekey(package:name(), package:requireinfo()) + if not unique[key] then + table.insert(packages, package) + unique[key] = true + end + end + end return packages end -- cgit v1.3.1 From d5cfb02a82a02455e0af1d9f9e5d3f49cb991b4e Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 30 Nov 2024 00:42:58 +0800 Subject: clean empty dirs --- xmake/modules/private/action/require/impl/package.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index 90e34fcef..8e11b7c73 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -1652,6 +1652,12 @@ function load_packages(requires, opt) -- we need to reload packages with new resolved deps if there are some dep conflicts if not table.empty(resolvedinfo) then + for _, package in ipairs(packages) do + local installdir = package:installdir({readonly = true}) + if os.isdir(installdir) and os.emptydir(installdir) then + os.tryrm(installdir, {emptydirs = true}) + end + end unique = {} packages = {} _memcache():clear() -- cgit v1.3.1 From 156e09f96486ef8c5f5517aae6f432954816b209 Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 30 Nov 2024 00:46:15 +0800 Subject: improve compatkey --- .../private/action/require/impl/package.lua | 38 +++------------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/xmake/modules/private/action/require/impl/package.lua b/xmake/modules/private/action/require/impl/package.lua index 8e11b7c73..19b05f51d 100644 --- a/xmake/modules/private/action/require/impl/package.lua +++ b/xmake/modules/private/action/require/impl/package.lua @@ -1213,36 +1213,12 @@ function _get_requirepaths(package) end -- get configs key for compatibility -function _get_package_compatkey(requireinfo, opt) - opt = opt or {} - local key = "" - if opt.name then - key = key .. "/" .. opt.name - end - if opt.plat then - key = key .. "/" .. opt.plat - end - if opt.arch then - key = key .. "/" .. opt.arch - end - if opt.kind then - key = key .. "/" .. opt.kind - end - if requireinfo.host then - if is_subhost(core_package.targetplat()) and os.subarch() == core_package.targetarch() then - -- we need to pass plat/arch to avoid repeat installation - -- @see https://github.com/xmake-io/xmake/issues/1579 - else - key = key .. "/host" - end - end - if requireinfo.system then +function _get_package_compatkey(dep) + local key = dep:plat() .. "/" .. dep:arch() .. "/" .. (dep:kind() or "") + if dep:is_system() then key = key .. "/system" end - if key:startswith("/") then - key = key:sub(2) - end - local configs = requireinfo.configs + local configs = dep:requireinfo().configs if configs then local configs_order = {} for k, v in pairs(configs) do @@ -1324,11 +1300,7 @@ function _check_and_resolve_package_depconflicts_impl(package, name, deps, resol local prevkey local configs_conflict = false for _, dep in ipairs(deps) do - local key = _get_package_compatkey(dep:requireinfo(), { - name = dep:name(), - plat = dep:plat(), - arch = dep:arch(), - kind = dep:kind()}) + local key = _get_package_compatkey(dep) if prevkey then if prevkey ~= key then configs_conflict = true -- cgit v1.3.1 From d9220fbb1cad4e025094c52c3ee5deaf6dbb9d8f Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 30 Nov 2024 00:49:20 +0800 Subject: fix test --- tests/projects/package/compatibility/deps_with_version/src/main.c | 3 +-- tests/projects/package/compatibility/deps_with_version/xmake.lua | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/projects/package/compatibility/deps_with_version/src/main.c b/tests/projects/package/compatibility/deps_with_version/src/main.c index 9ae580511..113930e1a 100755 --- a/tests/projects/package/compatibility/deps_with_version/src/main.c +++ b/tests/projects/package/compatibility/deps_with_version/src/main.c @@ -1,7 +1,6 @@ #include -int main(int argc, char** argv) -{ +int main(int argc, char** argv) { printf("hello world!\n"); return 0; } diff --git a/tests/projects/package/compatibility/deps_with_version/xmake.lua b/tests/projects/package/compatibility/deps_with_version/xmake.lua index b6ba830c3..28adf5e7e 100644 --- a/tests/projects/package/compatibility/deps_with_version/xmake.lua +++ b/tests/projects/package/compatibility/deps_with_version/xmake.lua @@ -1,21 +1,25 @@ package("foo") add_deps("zlib >=1.2.13") + set_policy("package.install_locally", true) on_install(function () end) package_end() package("bar") add_deps("zlib 1.2.x") + set_policy("package.install_locally", true) -- add_deps("libpng dev") on_install(function () end) package_end() package("zoo") add_deps("libpng master") + set_policy("package.install_locally", true) on_install(function () end) package_end() package("test") add_deps("foo", "bar", "zoo") + set_policy("package.install_locally", true) on_install(function () end) package_end() -- cgit v1.3.1