]> git.saurik.com Git - apt.git/blobdiff - cmdline/apt-get.cc
fix some build-dep bugs; update changelog
[apt.git] / cmdline / apt-get.cc
index 857e8aa3f15816160233406250e2f1d8ecf2f32b..fdf06cbe09671c14a95e0748885b7297a7ba676d 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: apt-get.cc,v 1.123 2002/11/09 20:50:30 doogie Exp $
+// $Id: apt-get.cc,v 1.124 2003/02/01 20:18:46 tausq Exp $
 /* ######################################################################
    
    apt-get - Cover for dpkg
@@ -1920,32 +1920,56 @@ bool DoBuildDep(CommandLine &CmdL)
       pkgProblemResolver Fix(Cache);
       for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
       {
-        pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
-        if (Pkg.end() == true)
+         if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
+            (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
          {
-           /* for a build-conflict; ignore unknown packages */
-           if ((*D).Type == pkgSrcRecords::Parser::BuildConflict || 
-               (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
-               continue;
-
-           return _error->Error(_("%s dependency on %s cannot be satisfied because the package %s cannot be found"),
-                                Last->BuildDepType((*D).Type),Src.c_str(),(*D).Package.c_str());
+            pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
+            // Build-conflicts on unknown packages are silently ignored
+            if (Pkg.end() == true)
+               continue;
+
+            pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
+
+            /* 
+             * Remove if we have an installed version that satisfies the 
+             * version criteria
+             */
+            if (IV.end() == false && 
+                Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
+               TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
          }
-        pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
-        
-        if ((*D).Type == pkgSrcRecords::Parser::BuildConflict || 
-            (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
-        {
-           /* 
-            * conflict; need to remove if we have an installed version 
-            * that satisfies the version criterial 
-            */
-           if (IV.end() == false && 
-               Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
-              TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
-        } 
-        else 
-        {
+        else // BuildDep || BuildDepIndep
+         {
+           pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
+           if (Pkg.end() == true)
+            {
+               // Check if there are any alternatives
+               if (((*D).Op & pkgCache::Dep::Or) != pkgCache::Dep::Or)
+                 return _error->Error(_("%s dependency on %s cannot be satisfied "
+                                         "because the package %s cannot be found"),
+                                        Last->BuildDepType((*D).Type),Src.c_str(),
+                                         (*D).Package.c_str());
+               // Try the next alternative
+               continue;
+            }
+
+            /*
+             * if there are alternatives, we've already picked one, so skip
+             * the rest
+             *
+             * TODO: this means that if there's a build-dep on A|B and B is
+             * installed, we'll still try to install A; more importantly,
+             * if A is currently broken, we cannot go back and try B. To fix 
+             * this would require we do a Resolve cycle for each package we 
+             * add to the install list. Ugh
+             */
+            while (D != BuildDeps.end() && 
+                   (((*D).Op & pkgCache::Dep::Or) == pkgCache::Dep::Or))
+               D++;
+                       
+            // Get installed versions
+           pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
+
            /* 
             * If this is a virtual package, we need to check the list of
             * packages that provide it and see if any of those are
@@ -1956,21 +1980,18 @@ bool DoBuildDep(CommandLine &CmdL)
               if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
                  break;
 
-           if (Prv.end() == true)
-           {
-              /* 
-               * depends; need to install or upgrade if we don't have the
-               * package installed or if the version does not satisfy the
-               * build dep. This is complicated by the fact that if we
-               * depend on a version lower than what we already have 
-               * installed it is not clear what should be done; in practice
-               * this case should be rare though and right now nothing
-               * is done about it :-( 
-               */
-              if (IV.end() == true ||
-                 Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == false)
-                    TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst);
-           }
+            /*
+            * TODO: if we depend on a version lower than what we already have 
+            * installed it is not clear what should be done; in practice
+            * this case should be rare, and right now nothing is 
+             * done about it :-( 
+            */
+           if (Prv.end() == true && // Nothing provides it; and
+                (IV.end() == true || //  It is not installed, or
+                Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == false))
+                                     //  the version installed doesn't 
+                                     //  satisfy constraints 
+              TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst);
         }             
       }