[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#471771: apt should prefer packages with the least new packages being pulled in for dependency resolution



Package: apt
Version: 0.7.11
Severity: wishlist
Tags: patch

When installing a package A, which depends on a virtual package V, apt
uses the first package, which provides "V".

Imagine that "V" gets provided by M and N, where M depends on M1 and N
on N1. N1 is already installed, but M1 isn't.

Now, installing A will also install M and M1, while it would be better
to install N only.

At least that was what I was expecting and this seems to be the reason
for a bug in Ubuntu, where installing virtualbox-ose on a system with
"generic" kernel pulls in the 386 kernel.
See https://launchpad.net/bugs/188579 for more details.

I've looked at the source and started hacking around (without much C++
knowledge at hand).

What I came up with, was the following:
In pkgDepCache::MarkInstall, instead of using the first candidate (in
case of provides), run MarkInstall on all of them (recursively) and use
the version where iInstCount changes the least.
The missing part in my patch is to really revert the pkgCache; I have no
idea how to do this properly and since this whole approach might be
wrong, I'd like to only propose this.

Please consider adding this feature/functionality/idea.


btw: do you have any suggestion about fixing the particular
virtualbox-ose issue mentioned above?
Apart from moving the modules into the general "kernel modules" package, I
only see the fallback of making the "Depends" and "Recommends" again.


I hope that the feature suggestion makes any sense and that you can help
me to work around/fix it for apt currents behavior.

Thank you.
diff -Nur apt-0.7.11.orig/apt-pkg/depcache.cc apt-0.7.11/apt-pkg/depcache.cc
--- apt-0.7.11.orig/apt-pkg/depcache.cc	2007-07-28 17:24:10.000000000 +0200
+++ apt-0.7.11/apt-pkg/depcache.cc	2008-03-20 02:06:04.976191209 +0100
@@ -958,18 +958,34 @@
 	 if (InstPkg.end() == true)
 	 {
 	    pkgPrioSortList(*Cache,Cur);
+	    std::clog << "Searching for best resolution of " << Pkg.Name() << "..." << std::endl;
+	    int iBestInstCount = -1;
+
 	    for (; *Cur != 0; Cur++)
 	    {
 	       PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg);
 	       if (PkgState[Pkg->ID].CandidateVer != *Cur)
 		  continue;
+
+	       std::clog << "DEBUG: Temp install of " << Pkg.Name() << ", depth " << Depth << std::endl;
+
+	       int iInstCountBefore = iInstCount;
+	       MarkInstall(Pkg,true,0,false);
+	       int iInstCountNew = iInstCount - iInstCountBefore;
+
+	       std::clog << "DEBUG: Number of new packages for " << Pkg.Name() << ": " << iInstCountNew << std::endl;
+	       if (iInstCountNew > iBestInstCount)
+	       {
 	       InstPkg = Pkg;
-	       break;
+		  iBestInstCount = iInstCountNew;
+	       }
+	       MarkDelete(Pkg); // FIXME: does not remove "depends of depend"!
 	    }
 	 }
 	 
 	 if (InstPkg.end() == false) 
 	 {
+	    std::clog << "InstPkg: " << InstPkg.Name() << std::endl;
 	    if(_config->FindB("Debug::pkgDepCache::AutoInstall",false) == true)
 	       std::clog << "Installing " << InstPkg.Name() 
 			 << " as dep of " << Pkg.Name() 

Reply to: