<feed xmlns='http://www.w3.org/2005/Atom'>
<title>apt/apt-pkg/solver3.cc, branch 3.1.5</title>
<subtitle>Debians commandline package manager</subtitle>
<id>https://git.kalnischkies.de/apt/atom?h=3.1.5</id>
<link rel='self' href='https://git.kalnischkies.de/apt/atom?h=3.1.5'/>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/'/>
<updated>2025-08-26T11:41:35Z</updated>
<entry>
<title>solver3: Allow any downloadable version to mark a package as not obsolete</title>
<updated>2025-08-26T11:41:35Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-07-22T18:34:34Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=539a3dfcfdf30e552a6374ee478a98e16ab7fa7d'/>
<id>urn:sha1:539a3dfcfdf30e552a6374ee478a98e16ab7fa7d</id>
<content type='text'>
Lots of people have pinned an older version that is no longer
installable, or more common yesterday, we saw a lot of people
who seemingly manually installed a newer version of a deb than
in the repositories, causing the package to be considered obsolete,
which does not make much sense.

Oops: 4c39d922-410f-11f0-bbf9-fa163ec44ecd
Oops: a64054f6-4140-11f0-bbfd-fa163ec44ecd
Oops: a32196c1-661d-11f0-a97c-fa163ec8ca8c
</content>
</entry>
<entry>
<title>solver3: Sort dependency targets against current alternative</title>
<updated>2025-08-26T11:41:35Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-07-22T17:58:14Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=db78e2f8eafb1009bd47e488fc39d8b420f4c749'/>
<id>urn:sha1:db78e2f8eafb1009bd47e488fc39d8b420f4c749</id>
<content type='text'>
Instead of inadvertently sorting dependency targets against
the first alternative in an or group, sort them against the
current alternative as we should.

Otherwise we ended up sorting

    gnome-shell | notification-daemon

With

    Package: notification-daemon

    Package: awesome
    Provides: notification-daemon

into

    gnome-shell | awesome | notification-daemon
                &lt;-we sorted this part wrongly-&gt;

This fixes a minor difference in test-release-candidate-switching
in one case, but not the other where the difference was actually
caused by the loss of install argument ordering information in
the new solver, so just flip the arguments so both solvers produce
the same outcome.
</content>
</entry>
<entry>
<title>solver3: Filter installed Recommends</title>
<updated>2025-06-10T14:27:36Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-10T14:09:19Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=b99ec5f1d80962e39e9debb05f1a7c7840e7d97c'/>
<id>urn:sha1:b99ec5f1d80962e39e9debb05f1a7c7840e7d97c</id>
<content type='text'>
When inspecting Recommends of installed packages, filter
them to the installed packages only, as we want to avoid
switching between alternatives of recommended packages.
</content>
</entry>
<entry>
<title>solver3: Explicitly declare and define ~Solver</title>
<updated>2025-06-10T14:27:36Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-10T11:44:18Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=060f4e274f08ea338158606fc81b451924a293d0'/>
<id>urn:sha1:060f4e274f08ea338158606fc81b451924a293d0</id>
<content type='text'>
On recent armfhf and s390x builds in the PPA, the compiler seems to have
generated the destructor at the wrong point where the definitions where
not yet complete, and it does seem ill-advised to rely on a
default-constructed destructor in the solver for future ABI sake.

In file included from /usr/include/c++/14/vector:66,
                 from /&lt;&lt;PKGBUILDDIR&gt;&gt;/obj-arm-linux-gnueabihf/include/apt-pkg/cachefilter.h:14:
/usr/include/c++/14/bits/stl_vector.h: In instantiation of ‘constexpr std::_Vector_base&lt;_Tp, _Alloc&gt;::~_Vector_base() [with _Tp = APT::Solver::Work; _Alloc = std::allocator&lt;APT::Solver::Work&gt;]’:
/usr/include/c++/14/bits/stl_vector.h:531:7:   required from here
  531 |       vector() = default;
      |       ^~~~~~
/usr/include/c++/14/bits/stl_vector.h:369:49: error: invalid use of incomplete type ‘struct APT::Solver::Work’
  369 |                       _M_impl._M_end_of_storage - _M_impl._M_start);
      |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
In file included from /&lt;&lt;PKGBUILDDIR&gt;&gt;/apt-pkg/edsp.cc:22:
/&lt;&lt;PKGBUILDDIR&gt;&gt;/obj-arm-linux-gnueabihf/include/apt-pkg/solver3.h:87:11: note: forward declaration of ‘struct APT::Solver::Work’
   87 |    struct Work;
      |           ^~~~
/usr/include/c++/14/bits/stl_vector.h: In instantiation of ‘constexpr std::_Vector_base&lt;_Tp, _Alloc&gt;::~_Vector_base() [with _Tp = APT::Solver::Solved; _Alloc = std::allocator&lt;APT::Solver::Solved&gt;]’:
/usr/include/c++/14/bits/stl_vector.h:531:7:   required from here
  531 |       vector() = default;
      |       ^~~~~~
/usr/include/c++/14/bits/stl_vector.h:369:49: error: invalid use of incomplete type ‘struct APT::Solver::Solved’
  369 |                       _M_impl._M_end_of_storage - _M_impl._M_start);
      |                       ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
/&lt;&lt;PKGBUILDDIR&gt;&gt;/obj-arm-linux-gnueabihf/include/apt-pkg/solver3.h:88:11: note: forward declaration of ‘struct APT::Solver::Solved’
   88 |    struct Solved;
      |           ^~~~~~
</content>
</entry>
<entry>
<title>solver3: Ignore Architecture: all for obsoleted-by</title>
<updated>2025-06-10T14:27:36Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-06-10T09:47:41Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=15f48dcd65fb17a4cb4cd1f93b872b3bb810c3b2'/>
<id>urn:sha1:15f48dcd65fb17a4cb4cd1f93b872b3bb810c3b2</id>
<content type='text'>
In case a new version of the source package is published, we
check that if there's a newer binary for the same architecture
and then consider the binary obsoleted.

This logic did not properly account for Architecture: all packages
which are considered as native architecture package with an "All"
multi-arch flag set, and hence a native architecture package may
inadvertently be considered obsoleted by a package that only built
on Architecture: all.
</content>
</entry>
<entry>
<title>solver3: Only merge dependencies on the same package</title>
<updated>2025-05-28T11:58:04Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-28T11:57:17Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=3f8162ea008b8a3330a1113a94bc654f05000660'/>
<id>urn:sha1:3f8162ea008b8a3330a1113a94bc654f05000660</id>
<content type='text'>
Avoid or groups and dependencies on different (virtual) packages,
to avoid some common pitfalls like the added xorg test case.
</content>
</entry>
<entry>
<title>solver3: Merge Depends into Recommends</title>
<updated>2025-05-27T14:06:06Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-27T12:24:09Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=86c44166b470ecee5a192ffb434fb7931b7c0afd'/>
<id>urn:sha1:86c44166b470ecee5a192ffb434fb7931b7c0afd</id>
<content type='text'>
Merge any hard clauses into optional clauses, such that
optional clauses don't end up with more choices.

For example if you have

    Depends: a | b
    Recommends: a | c

This becomes:

    Depends: a | b
    Recommends: a

We have simulated this with the chaos-actor in the test case
and a

    Depends: git (not satisfied by chaos provider)
    Recommends: git (satisfied by chaos provider)

and the latter constraint is limited to the former.
</content>
</entry>
<entry>
<title>solver3: Merge intersecting dependencies</title>
<updated>2025-05-27T13:56:55Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-27T12:24:09Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=eafc52e942d4daec30fb80e70c035ed935f31afb'/>
<id>urn:sha1:eafc52e942d4daec30fb80e70c035ed935f31afb</id>
<content type='text'>
If a package declares multiple dependencies that can be solved by
the same packages we should use the common set of packages to
solve them.

A common example is requiring the same Debian source version, or the
same upstream version as in our test case:

    git-ng Depends: git (&gt;&gt; 1:2.26.2), git (&lt;&lt; 1:2.26.2-.)

The solver expands this to the concrete objects:

    git-ng Depends: "real git" (= 1:2.26.2-1) | chaos-actor, "real git" (= 1:2.26.2-1) | "real git" (= 1:2.25.1-1)

When given an upgrade request, the solver would now choose

    chaos-actor               to satisfy git (&gt;&gt; 1:2.26.2)
    "real git" (= 1:2.25.1-1) to satisfy git (&lt;&lt; 1:2.26.2-.)

To satisfy the two constraints, which is not the intended outcome.

Address this problem by introducing a concept of merged clauses:
If two dependencies of a package have overlapping solutions, replace
the dependency by the intersection, and record the merged clause
instead, this leads to a single clause:

    Depends: git (&gt;&gt; 1:2.26.2) and git (&lt;&lt; 1:2.26.2-.)

which expands to just the real git binary.

The implementation is a bit finicky in that it removes the variables
from the original clause which may not be helpful for debugging, but
it records the clauses merged with, as seen in the test case, so the
reasoning is clear.

LP: #2111792
</content>
</entry>
<entry>
<title>solver3: Assume manual packages</title>
<updated>2025-05-26T10:45:12Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-26T09:19:11Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=717ca7922be8a025b8034dc840b2ad9befc3b171'/>
<id>urn:sha1:717ca7922be8a025b8034dc840b2ad9befc3b171</id>
<content type='text'>
If we have allowed the removal of manual packages, assume them
all before starting the solver. This should ensure that as long
as there is a solution that does not remove a manually installed
package, it is found.

This requires a sweeping set of changes in the test suite, but
ensures that we get "safe" behavior from the solver. We have
in particular seen that without asserting the installed packages,
several people ended up with ubuntu-minimal and perl removed in
a situation where that was not warranted, that is, they install
winehq, and then pull in some new perl packages in a newer version
than the installed one, and the solver chose to create a mismatched
version set, which then caused the main perl package to not be
installable.

Oops: 1b55173a-3526-11f0-b7ac-fa163e171f02
Oops: dbd5149e-36b9-11f0-bb74-fa163ec44ecd
</content>
</entry>
<entry>
<title>solver3: Initialize startTime if not set in Pop()</title>
<updated>2025-05-26T10:43:24Z</updated>
<author>
<name>Julian Andres Klode</name>
<email>jak@debian.org</email>
</author>
<published>2025-05-26T10:42:58Z</published>
<link rel='alternate' type='text/html' href='https://git.kalnischkies.de/apt/commit/?id=6c3196950acb6a1351c221c74edd9c3ba691b7e5'/>
<id>urn:sha1:6c3196950acb6a1351c221c74edd9c3ba691b7e5</id>
<content type='text'>
If the user pushes Assumptions that fail, we could inadvertently
timeout during the Pop() as the variable was not initialized.

Always initialize it to 0, and if we haven't set an actual time
by the time we Pop() set it there.
</content>
</entry>
</feed>
