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()