From ae7e10d189a3749d4220480dbbb1da907eb65f4c Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 10 Mar 2025 19:19:21 +0100 Subject: solver3: Fix detection of satisfied recommends for pkg variables This only worked for version literals lol --- apt-pkg/solver3.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/solver3.cc') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index c993c1096..721876906 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -819,7 +819,7 @@ APT::Solver::Clause APT::Solver::TranslateOrGroup(pkgCache::DepIterator start, p newOptional = false, wasImportant = policy.IsImportantDep(D); bool satisfied = std::any_of(clause.solutions.begin(), clause.solutions.end(), [this](auto var) - { return Var(var.CastPkg(cache).CurrentVer()) == var; }); + { return var.Pkg(cache) ? var.Pkg(cache)->CurrentVer != nullptr : Var(var.CastPkg(cache).CurrentVer()) == var; }); if (important && wasImportant && not newOptional && not satisfied) { -- cgit v1.2.3-70-g09d2 From de095b76b0562c4648b03406349e9914829e5590 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 10 Mar 2025 21:24:09 +0100 Subject: solver3: Print correct reason when registering dependency This is relevant when debugging common dependencies. --- apt-pkg/solver3.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'apt-pkg/solver3.cc') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index 721876906..fde1d192b 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -746,7 +746,6 @@ void APT::Solver::RegisterCommonDependencies(pkgCache::PkgIterator Pkg) APT::Solver::Clause APT::Solver::TranslateOrGroup(pkgCache::DepIterator start, pkgCache::DepIterator end, Var reason) { auto TgtPkg = start.TargetPkg(); - auto Ver = start.ParentVer(); // Non-important dependencies can only be installed if they are currently satisfied, see the check further // below once we have calculated all possible solutions. @@ -756,7 +755,7 @@ APT::Solver::Clause APT::Solver::TranslateOrGroup(pkgCache::DepIterator start, p if (start->Type == pkgCache::Dep::Replaces || start->Type == pkgCache::Dep::Enhances) return Clause{reason, Group::Satisfy, true}; if (unlikely(debug >= 3)) - std::cerr << "Found dependency critical " << Ver.ParentPkg().FullName() << "=" << Ver.VerStr() << " -> " << start.TargetPkg().FullName() << "\n"; + std::cerr << "Found dependency critical " << reason.toString(cache) << " -> " << start.TargetPkg().FullName() << "\n"; Clause clause{reason, Group::Satisfy, not start.IsCritical() /* optional */, start.IsNegative()}; -- cgit v1.2.3-70-g09d2 From 8a6b694108f41afd1e6cdba4c91481697f9b3004 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 10 Mar 2025 22:05:52 +0100 Subject: solver3: Correctly determine 'same' or groups We incorrectly used the DependencyData of the first or group member, however that only checked that the first or group member was the same and that both either had a next member or not. --- apt-pkg/solver3.cc | 38 ++++++++++++++++++++------- test/integration/test-solver3-similar-depends | 18 +++++++++++++ 2 files changed, 47 insertions(+), 9 deletions(-) create mode 100755 test/integration/test-solver3-similar-depends (limited to 'apt-pkg/solver3.cc') diff --git a/apt-pkg/solver3.cc b/apt-pkg/solver3.cc index fde1d192b..739309c59 100644 --- a/apt-pkg/solver3.cc +++ b/apt-pkg/solver3.cc @@ -634,6 +634,23 @@ bool APT::Solver::Propagate() return true; } +static bool SameOrGroup(pkgCache::DepIterator a, pkgCache::DepIterator b) +{ + while (1) + { + if (a->DependencyData != b->DependencyData) + return false; + + // At least one has reached the end, break + if (not(a->CompareOp & pkgCache::Dep::Or) || not(b->CompareOp & pkgCache::Dep::Or)) + break; + + ++a, ++b; + } + // Fully iterated over a and b + return not(a->CompareOp & pkgCache::Dep::Or) && not(b->CompareOp & pkgCache::Dep::Or); +} + const APT::Solver::Clause *APT::Solver::RegisterClause(Clause &&clause) { auto &clauses = (*this)[clause.reason].clauses; @@ -701,8 +718,8 @@ void APT::Solver::Discover(Var var) // This dependency is shared across all versions, skip it. if (auto &pkgClauses = (*this)[Ver.ParentPkg()].clauses; - std::any_of(pkgClauses.begin(), pkgClauses.end(), [start](auto &c) - { return c->dep && c->dep->DependencyData == start->DependencyData; })) + std::any_of(pkgClauses.begin(), pkgClauses.end(), [this, start](auto &c) + { return c->dep && SameOrGroup(start, pkgCache::DepIterator(cache, c->dep)); })) continue; auto clause = TranslateOrGroup(start, end, Var(Ver)); @@ -723,18 +740,21 @@ void APT::Solver::RegisterCommonDependencies(pkgCache::PkgIterator Pkg) { for (auto dep = Pkg.VersionList().DependsList(); not dep.end();) { - pkgCache::DepIterator start; - pkgCache::DepIterator end; + pkgCache::DepIterator start, end; dep.GlobOr(start, end); // advances dep bool allHaveDep = true; - for (auto ver = Pkg.VersionList()++; not ver.end(); ver++) + for (auto ver = Pkg.VersionList()++; allHaveDep && not ver.end(); ver++) { bool haveDep = false; - for (auto otherDep = ver.DependsList(); not haveDep && not otherDep.end(); otherDep++) - haveDep = otherDep->DependencyData == start->DependencyData; - if (!haveDep) - allHaveDep = haveDep; + for (auto otherDep = ver.DependsList(); not haveDep && not otherDep.end();) + { + pkgCache::DepIterator otherStart, otherEnd; + otherDep.GlobOr(otherStart, otherEnd); // advances other dep + haveDep = SameOrGroup(start, otherStart); + } + if (not haveDep) + allHaveDep = false; } if (not allHaveDep) continue; diff --git a/test/integration/test-solver3-similar-depends b/test/integration/test-solver3-similar-depends new file mode 100755 index 000000000..a301b9ac5 --- /dev/null +++ b/test/integration/test-solver3-similar-depends @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +TESTDIR="$(readlink -f "$(dirname "$0")")" +. "$TESTDIR/framework" +setupenvironment +configarchitecture 'amd64' + +insertpackage 'installed' 'a' 'all' '2' 'Depends: a|b' +insertpackage 'unstable' 'a' 'all' '3' 'Depends: a|c' + +setupaptarchive +testsuccess apt install -o debug::apt::solver=3 a -s --solver 3.0 +cp rootdir/tmp/testsuccess.output log +msgmsg "Test that æ|b and a|c are different or groups" +testsuccess grep "Found dependency critical a:amd64=2 -> a:amd64" log +testsuccess grep "Found dependency critical a:amd64=3 -> a:amd64" log + -- cgit v1.2.3-70-g09d2