summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/pkgcachegen.cc181
-rw-r--r--apt-pkg/pkgcachegen.h7
-rw-r--r--debian/changelog4
3 files changed, 109 insertions, 83 deletions
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 47441d65c..9f999c41b 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -392,6 +392,31 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator
return _error->Error(_("Error occurred while processing %s (%s%d)"),
Pkg.Name(), "NewFileVer", 2);
+ pkgCache::GrpIterator Grp = Pkg.Group();
+ Dynamic<pkgCache::GrpIterator> DynGrp(Grp);
+
+ /* If it is the first version of this package we need to add implicit
+ Multi-Arch dependencies to all other package versions in the group now -
+ otherwise we just add them for this new version */
+ if (Pkg.VersionList()->NextVer == 0)
+ {
+ pkgCache::PkgIterator P = Grp.PackageList();
+ Dynamic<pkgCache::PkgIterator> DynP(P);
+ for (; P.end() != true; P = Grp.NextPkg(P))
+ {
+ if (P->ID == Pkg->ID)
+ continue;
+ pkgCache::VerIterator V = P.VersionList();
+ Dynamic<pkgCache::VerIterator> DynV(V);
+ for (; V.end() != true; ++V)
+ if (unlikely(AddImplicitDepends(V, Pkg) == false))
+ return _error->Error(_("Error occurred while processing %s (%s%d)"),
+ Pkg.Name(), "AddImplicitDepends", 1);
+ }
+ }
+ if (unlikely(AddImplicitDepends(Grp, Pkg, Ver) == false))
+ return _error->Error(_("Error occurred while processing %s (%s%d)"),
+ Pkg.Name(), "AddImplicitDepends", 2);
// Read only a single record and return
if (OutVer != 0)
@@ -409,7 +434,6 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator
/* Before we add a new description we first search in the group for
a version with a description of the same MD5 - if so we reuse this
description group instead of creating our own for this version */
- pkgCache::GrpIterator Grp = Pkg.Group();
for (pkgCache::PkgIterator P = Grp.PackageList();
P.end() == false; P = Grp.NextPkg(P))
{
@@ -574,6 +598,75 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
return true;
}
/*}}}*/
+// CacheGenerator::AddImplicitDepends /*{{{*/
+bool pkgCacheGenerator::AddImplicitDepends(pkgCache::GrpIterator &G,
+ pkgCache::PkgIterator &P,
+ pkgCache::VerIterator &V)
+{
+ // copy P.Arch() into a string here as a cache remap
+ // in NewDepends() later may alter the pointer location
+ string Arch = P.Arch() == NULL ? "" : P.Arch();
+ map_ptrloc *OldDepLast = NULL;
+ /* MultiArch handling introduces a lot of implicit Dependencies:
+ - MultiArch: same → Co-Installable if they have the same version
+ - All others conflict with all other group members */
+ bool const coInstall = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same);
+ pkgCache::PkgIterator D = G.PackageList();
+ Dynamic<pkgCache::PkgIterator> DynD(D);
+ for (; D.end() != true; D = G.NextPkg(D))
+ {
+ if (Arch == D.Arch() || D->VersionList == 0)
+ continue;
+ /* We allow only one installed arch at the time
+ per group, therefore each group member conflicts
+ with all other group members */
+ if (coInstall == true)
+ {
+ // Replaces: ${self}:other ( << ${binary:Version})
+ NewDepends(D, V, V.VerStr(),
+ pkgCache::Dep::Less, pkgCache::Dep::Replaces,
+ OldDepLast);
+ // Breaks: ${self}:other (!= ${binary:Version})
+ NewDepends(D, V, V.VerStr(),
+ pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks,
+ OldDepLast);
+ } else {
+ // Conflicts: ${self}:other
+ NewDepends(D, V, "",
+ pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts,
+ OldDepLast);
+ }
+ }
+ return true;
+}
+bool pkgCacheGenerator::AddImplicitDepends(pkgCache::VerIterator &V,
+ pkgCache::PkgIterator &D)
+{
+ /* MultiArch handling introduces a lot of implicit Dependencies:
+ - MultiArch: same → Co-Installable if they have the same version
+ - All others conflict with all other group members */
+ map_ptrloc *OldDepLast = NULL;
+ bool const coInstall = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same);
+ if (coInstall == true)
+ {
+ // Replaces: ${self}:other ( << ${binary:Version})
+ NewDepends(D, V, V.VerStr(),
+ pkgCache::Dep::Less, pkgCache::Dep::Replaces,
+ OldDepLast);
+ // Breaks: ${self}:other (!= ${binary:Version})
+ NewDepends(D, V, V.VerStr(),
+ pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks,
+ OldDepLast);
+ } else {
+ // Conflicts: ${self}:other
+ NewDepends(D, V, "",
+ pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts,
+ OldDepLast);
+ }
+ return true;
+}
+
+ /*}}}*/
// CacheGenerator::NewFileVer - Create a new File<->Version association /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -692,76 +785,6 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
return Description;
}
/*}}}*/
-// CacheGenerator::FinishCache - do various finish operations /*{{{*/
-// ---------------------------------------------------------------------
-/* This prepares the Cache for delivery */
-bool pkgCacheGenerator::FinishCache(OpProgress *Progress)
-{
- // FIXME: add progress reporting for this operation
- // Do we have different architectures in your groups ?
- vector<string> archs = APT::Configuration::getArchitectures();
- if (archs.size() > 1)
- {
- // Create Conflicts in between the group
- pkgCache::GrpIterator G = GetCache().GrpBegin();
- Dynamic<pkgCache::GrpIterator> DynG(G);
- for (; G.end() != true; ++G)
- {
- string const PkgName = G.Name();
- pkgCache::PkgIterator P = G.PackageList();
- Dynamic<pkgCache::PkgIterator> DynP(P);
- for (; P.end() != true; P = G.NextPkg(P))
- {
- pkgCache::PkgIterator allPkg;
- Dynamic<pkgCache::PkgIterator> DynallPkg(allPkg);
- pkgCache::VerIterator V = P.VersionList();
- Dynamic<pkgCache::VerIterator> DynV(V);
- for (; V.end() != true; ++V)
- {
- // copy P.Arch() into a string here as a cache remap
- // in NewDepends() later may alter the pointer location
- string Arch = P.Arch() == NULL ? "" : P.Arch();
- map_ptrloc *OldDepLast = NULL;
- /* MultiArch handling introduces a lot of implicit Dependencies:
- - MultiArch: same → Co-Installable if they have the same version
- - Architecture: all → Need to be Co-Installable for internal reasons
- - All others conflict with all other group members */
- bool const coInstall = ((V->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same);
- for (vector<string>::const_iterator A = archs.begin(); A != archs.end(); ++A)
- {
- if (*A == Arch)
- continue;
- /* We allow only one installed arch at the time
- per group, therefore each group member conflicts
- with all other group members */
- pkgCache::PkgIterator D = G.FindPkg(*A);
- Dynamic<pkgCache::PkgIterator> DynD(D);
- if (D.end() == true)
- continue;
- if (coInstall == true)
- {
- // Replaces: ${self}:other ( << ${binary:Version})
- NewDepends(D, V, V.VerStr(),
- pkgCache::Dep::Less, pkgCache::Dep::Replaces,
- OldDepLast);
- // Breaks: ${self}:other (!= ${binary:Version})
- NewDepends(D, V, V.VerStr(),
- pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks,
- OldDepLast);
- } else {
- // Conflicts: ${self}:other
- NewDepends(D, V, "",
- pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts,
- OldDepLast);
- }
- }
- }
- }
- }
- }
- return true;
-}
- /*}}}*/
// CacheGenerator::NewDepends - Create a dependency element /*{{{*/
// ---------------------------------------------------------------------
/* This creates a dependency element in the tree. It is linked to the
@@ -1324,9 +1347,6 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
if (BuildCache(Gen,Progress,CurrentSize,TotalSize,
Files.begin()+EndOfSource,Files.end()) == false)
return false;
-
- // FIXME: move me to a better place
- Gen.FinishCache(Progress);
}
else
{
@@ -1369,9 +1389,6 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
if (BuildCache(Gen,Progress,CurrentSize,TotalSize,
Files.begin()+EndOfSource,Files.end()) == false)
return false;
-
- // FIXME: move me to a better place
- Gen.FinishCache(Progress);
}
if (Debug == true)
std::clog << "Caches are ready for shipping" << std::endl;
@@ -1422,9 +1439,6 @@ bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **O
Files.begin()+EndOfSource,Files.end()) == false)
return false;
- // FIXME: move me to a better place
- Gen.FinishCache(Progress);
-
if (_error->PendingError() == true)
return false;
*OutMap = Map.UnGuard();
@@ -1445,4 +1459,9 @@ bool IsDuplicateDescription(pkgCache::DescIterator Desc,
return false;
}
/*}}}*/
-
+// CacheGenerator::FinishCache /*{{{*/
+bool pkgCacheGenerator::FinishCache(OpProgress *Progress)
+{
+ return true;
+}
+ /*}}}*/
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index 99795bb1c..b6259b433 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -22,6 +22,7 @@
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/md5.h>
+#include <apt-pkg/macros.h>
#include <vector>
@@ -94,7 +95,7 @@ class pkgCacheGenerator /*{{{*/
bool HasFileDeps() {return FoundFileDeps;};
bool MergeFileProvides(ListParser &List);
- bool FinishCache(OpProgress *Progress);
+ __deprecated bool FinishCache(OpProgress *Progress);
static bool MakeStatusCache(pkgSourceList &List,OpProgress *Progress,
MMap **OutMap = 0,bool AllowMem = false);
@@ -111,6 +112,10 @@ class pkgCacheGenerator /*{{{*/
bool MergeListPackage(ListParser &List, pkgCache::PkgIterator &Pkg);
bool MergeListVersion(ListParser &List, pkgCache::PkgIterator &Pkg,
std::string const &Version, pkgCache::VerIterator* &OutVer);
+
+ bool AddImplicitDepends(pkgCache::GrpIterator &G, pkgCache::PkgIterator &P,
+ pkgCache::VerIterator &V);
+ bool AddImplicitDepends(pkgCache::VerIterator &V, pkgCache::PkgIterator &D);
};
/*}}}*/
// This is the abstract package list parser class. /*{{{*/
diff --git a/debian/changelog b/debian/changelog
index 62f32d8de..52396e84c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -26,6 +26,8 @@ apt (0.8.16~exp7) UNRELEASEDexperimental; urgency=low
- refactor MergeList by creating -Group, -Package and -Version specialist
- share description list between "same" versions (LP: #868977)
This also means that descriptions are shared across archives now.
+ - add implicit dependencies needed for Multi-Arch at the time a Version
+ struct is created and not at the end of the cache generation
[ Michael Vogt ]
* apt-pkg/contrib/configuration.cc:
@@ -40,7 +42,7 @@ apt (0.8.16~exp7) UNRELEASEDexperimental; urgency=low
* ftparchive/cachedb.cc:
- fix buffersize in bytes2hex
- -- David Kalnischkies <kalnischkies@gmail.com> Wed, 12 Oct 2011 15:47:43 +0200
+ -- David Kalnischkies <kalnischkies@gmail.com> Wed, 12 Oct 2011 20:02:25 +0200
apt (0.8.16~exp6) experimental; urgency=low