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

Re: build-dep fixes in cvs, please test



Hello,

I already fixed that (23 Jan 2003) and sent a patch to deity-digest and Jason.
I sent the result of a 'cvs diff' ready to be included in the source.
I think the solution (that I've explained bellow) works with more packages
(because of the little algorithm it uses).
I've tested it with several dozens of packages whose build-dep didn't work
and they work with (I use this to be able to build things with apt-build).
Maybe you can try and tell me what you think (you should checkout a
version before the Randolph commit, a 31 Jan 2003 whould be OK).

I'd like to obtain at least one-line-answer. Because I've only obtained once the
answer from Jason but no one has answered any of my messages/patches
after that (although the Spanish translation improvement has been commited). I can understand, maybe that you don't like to introduce it in an stable release.
(but I've not found an stable branch and different head branch on the CVS).

Thank you very much.
Asier Llano

The original message I sent was:

Jason Gunthorpe wrote:

On Wed, 15 Jan 2003, Asier Llano Palacios wrote:

If I understand the source code properly (maybe I am wrong) when we call:

apt-get build-dep whatever

It ignores the OR Build-Dependencies.
It treats these dependencies as being the same:

Build-Depends: a, b | c, d

and

Build-Depends: a, b, c, d

Might do, are you looking at CVS or the released source? I know some
fixing was done after the fact.

I don't think anyone else is trying to fix this.

Jason

Hi,

I've fixed it.
I atach you the result of a 'cvs diff'
(If you prefer any other format for the patch, just tell me)
I've tested it with a lot of packages and I think it works properly.

It now does the following:

foreach comma separated dependencies
{
  foreach | separated dependencies
  {
      check if it is unknown
      check if it should be installed (build dependency)
      check if it should be removed (build conflict)
  }

  if one of the dependencies is not already installed
  {
      if there is just one to install
          schedule it to install
      elseif there is no one to install and just on to remove
          schedule it to remove
      else
      {
          show the information to the user to let him/her decide
          which one to install or to remove.
          (this is the unusual case, because when there are several
          dependencies with OR are usually to let a package
          be in woody/sarge/sid/hurd and it usually only have
          a package to install, and the others are unknown)
          exit
      }
  }
}

install/remove every scheduled file

If you find this behaviour right, you could use the patch I've attached.
If you think this behaviour could be improved, just tell me (or do it yourself, whatever you prefer).

I think it changes the following bugs to pending:

#98640, #126938, #131265 , #145997
(I don't know if any other bug is fixed, because I haven't read all of them).

Cheers,
Asier Llano

? builddep.cvsdiff
Index: cmdline/apt-get.cc
===================================================================
RCS file: /cvs/deity/apt/cmdline/apt-get.cc,v
retrieving revision 1.123
diff -r1.123 apt-get.cc
1919a1920,1922
>       vector <string> notfound;
>       vector <pkgCache::PkgIterator> toinstall;
>       vector <pkgCache::PkgIterator> toremove;
1921c1924,1926
<       for (D = BuildDeps.begin(); D != BuildDeps.end(); D++)
---
> 
>       /* Foreach comma separated dependencies: AND */
>       for (D = BuildDeps.begin(); D != BuildDeps.end(); )
1923,1924c1928,1933
< 	 pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
< 	 if (Pkg.end() == true)
---
>          vector < pkgSrcRecords::Parser::BuildDepRec >::iterator startor = D;
>          bool lastor = true;
>          bool doneor = false;
>          
>          /* Foreach | separated dependencies: OR */
>          for(; D != BuildDeps.end(  ) && lastor; D++ )
1926c1935,1960
< 	    /* for a build-conflict; ignore unknown packages */
---
>             /* Update if the element is inside an OR operation */
>             lastor = ((*D).Op & pkgCache::Dep::Or) != 0;
>             /* If the or depencies are already met, then we just skip every or element */
>             if( doneor )
>                continue;
> 
>             /* Get the package of the build dependency */
>             pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
> 
>             /* Check if the package is an unknown one */
>             if (Pkg.end() == true)
>             {
>   	       /* for a build-conflict; ignore unknown packages */
> 	       if ((*D).Type == pkgSrcRecords::Parser::BuildConflict || 
> 	           (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
> 		   continue;
> 
>                /* Add the package to the vector of not found packages */
>                notfound.push_back( ( *D ).Package );
>                continue;
>             }
> 
>             /* Get the installed version */
> 	    pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
> 	 
>             /* If the dependency is a build conflict schedule it to be removed */
1929c1963,1971
< 		continue;
---
> 	    {
> 	       /* 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)
>                   toremove.push_back( Pkg );
>                else
>                   doneor = true;
> 	    } 
1931,1934c1973,2006
< 	    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::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
---
>             /* If the dependency is a build dependency check if it is installed
>              * or schedule it to be installed */
> 	    else 
> 	    {
> 	       /* If this is a virtual package, we need to check the list of
> 	        * packages that provide it and see if any of those are
> 	        * installed */
>                pkgCache::PrvIterator Prv = Pkg.ProvidesList();
>                for (; Prv.end() != true; Prv++)
> 	          if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
> 	             break;
> 
>                /* If it was not found */
> 	       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)
> 	                toinstall.push_back( Pkg );
>                   else
>                      doneor = true;
> 	       }
>                
>                /* If the dependencies are properly installed */
>                else
>                   doneor = true;
>             }
> 	 }
1936,1957c2008,2013
< 	 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 
< 	 {
< 	    /* 
< 	     * If this is a virtual package, we need to check the list of
< 	     * packages that provide it and see if any of those are
< 	     * installed
< 	     */
<             pkgCache::PrvIterator Prv = Pkg.ProvidesList();
<             for (; Prv.end() != true; Prv++)
< 	       if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
< 	          break;
---
>          // If the or group was not fit
>          if( ! doneor )
>          {
>             // If there is just one package to install ...
>             if( toinstall.size() == 1 )
>                TryToInstall( *toinstall.begin(), Cache, Fix, false, false, ExpectedInst );
1959,1974c2015,2053
< 	    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);
< 	    }
< 	 }	       
---
>             // If there is no pacakge to install and one to remove
>             else if( toinstall.size() == 0 && toremove.size() == 1 )
>                TryToInstall( *toremove.begin(), Cache, Fix, true, false, ExpectedInst );
> 
>             // If there is more than one package to install show them to the user
>             else
>             {
>                if( toinstall.size() > 0 )
>                {
>                   string List;
>                   for( unsigned showindex=0; showindex<toinstall.size(); showindex++ )
>                      List += string( toinstall[showindex].Name() ) + " ";
>                   ShowList( c1out, _( "One of the following packages should be installed:\n"), List );
>                }
>                if( toremove.size() > 0 )
>                {
>                   string List;
>                   for( unsigned showindex=0; showindex<toremove.size(); showindex++ )
>                      List += string( toremove[showindex].Name() ) + " ";
>                   if( toinstall.size() > 0 )
>                      ShowList( c1out, _( "or one of the following packages should be removed:\n"), List );
>                   else
>                      ShowList( c1out, _( "One of the following packages should be removed:\n"), List );
>                }
>                if( notfound.size() > 0 )
>                {
>                   string List;
>                   for( unsigned showindex=0; showindex<notfound.size(); showindex++ )
>                      List += notfound[showindex] + " ";
>                   ShowList( c1out, _( "No one of the following packages was found:\n"), List );
>                }
>                return _error->Error( _( "The building dependencies cannot be automatically filled,\nso the user should fix them by hand and retry the build-dep command\n" ) );
>             }
>          }
>          
>          /* Clear the OR data */
>          notfound.clear();
>          toinstall.clear();
>          toremove.clear();

Reply to: