Просмотр исходного кода

merged from lp:~donkult/apt/sid

Michael Vogt лет назад: 15
Родитель
Сommit
35b55cbc1c

+ 1 - 1
apt-pkg/aptconfiguration.cc

@@ -352,7 +352,7 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
 
 
 	if (archs.empty() == true ||
 	if (archs.empty() == true ||
 	    std::find(archs.begin(), archs.end(), arch) == archs.end())
 	    std::find(archs.begin(), archs.end(), arch) == archs.end())
-		archs.push_back(arch);
+		archs.insert(archs.begin(), arch);
 
 
 	// erase duplicates and empty strings
 	// erase duplicates and empty strings
 	for (std::vector<string>::reverse_iterator a = archs.rbegin();
 	for (std::vector<string>::reverse_iterator a = archs.rbegin();

+ 6 - 3
apt-pkg/deb/deblistparser.cc

@@ -461,7 +461,7 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op)
  *
  *
  * The complete architecture, consisting of <kernel>-<cpu>.
  * The complete architecture, consisting of <kernel>-<cpu>.
  */
  */
-static string CompleteArch(std::string& arch) {
+static string CompleteArch(std::string const &arch) {
     if (arch == "armel")              return "linux-arm";
     if (arch == "armel")              return "linux-arm";
     if (arch == "armhf")              return "linux-arm";
     if (arch == "armhf")              return "linux-arm";
     if (arch == "lpia")               return "linux-i386";
     if (arch == "lpia")               return "linux-i386";
@@ -500,9 +500,13 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
    Package.assign(Start,I - Start);
    Package.assign(Start,I - Start);
 
 
    // We don't want to confuse library users which can't handle MultiArch
    // We don't want to confuse library users which can't handle MultiArch
+   string const arch = _config->Find("APT::Architecture");
    if (StripMultiArch == true) {
    if (StripMultiArch == true) {
       size_t const found = Package.rfind(':');
       size_t const found = Package.rfind(':');
-      if (found != string::npos)
+      if (found != string::npos &&
+	  (strcmp(Package.c_str() + found, ":any") == 0 ||
+	   strcmp(Package.c_str() + found, ":native") == 0 ||
+	   strcmp(Package.c_str() + found + 1, arch.c_str()) == 0))
 	 Package = Package.substr(0,found);
 	 Package = Package.substr(0,found);
    }
    }
 
 
@@ -543,7 +547,6 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
 
 
    if (ParseArchFlags == true)
    if (ParseArchFlags == true)
    {
    {
-      string arch = _config->Find("APT::Architecture");
       string completeArch = CompleteArch(arch);
       string completeArch = CompleteArch(arch);
 
 
       // Parse an architecture
       // Parse an architecture

+ 201 - 101
cmdline/apt-get.cc

@@ -1388,6 +1388,14 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache,
 	 return AllowFail;
 	 return AllowFail;
    }
    }
 
 
+   if (_config->FindB("Debug::BuildDeps",false) == true)
+   {
+      if (Remove == true)
+	 cout << "  Trying to remove " << Pkg << endl;
+      else
+	 cout << "  Trying to install " << Pkg << endl;
+   }
+
    if (Remove == true)
    if (Remove == true)
    {
    {
       TryToRemove RemoveAction(Cache, &Fix);
       TryToRemove RemoveAction(Cache, &Fix);
@@ -2612,12 +2620,17 @@ bool DoSource(CommandLine &CmdL)
 	 // Try to compile it with dpkg-buildpackage
 	 // Try to compile it with dpkg-buildpackage
 	 if (_config->FindB("APT::Get::Compile",false) == true)
 	 if (_config->FindB("APT::Get::Compile",false) == true)
 	 {
 	 {
+	    string buildopts = _config->Find("APT::Get::Host-Architecture");
+	    if (buildopts.empty() == false)
+	       buildopts = "-a " + buildopts + " ";
+	    buildopts.append(_config->Find("DPkg::Build-Options","-b -uc"));
+
 	    // Call dpkg-buildpackage
 	    // Call dpkg-buildpackage
 	    char S[500];
 	    char S[500];
 	    snprintf(S,sizeof(S),"cd %s && %s %s",
 	    snprintf(S,sizeof(S),"cd %s && %s %s",
 		     Dir.c_str(),
 		     Dir.c_str(),
 		     _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
 		     _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
-		     _config->Find("DPkg::Build-Options","-b -uc").c_str());
+		     buildopts.c_str());
 	    
 	    
 	    if (system(S) != 0)
 	    if (system(S) != 0)
 	    {
 	    {
@@ -2679,8 +2692,19 @@ bool DoBuildDep(CommandLine &CmdL)
    if (Fetcher.Setup(&Stat) == false)
    if (Fetcher.Setup(&Stat) == false)
       return false;
       return false;
 
 
+   bool StripMultiArch;
+   string hostArch = _config->Find("APT::Get::Host-Architecture");
+   if (hostArch.empty() == false)
+   {
+      std::vector<std::string> archs = APT::Configuration::getArchitectures();
+      if (std::find(archs.begin(), archs.end(), hostArch) == archs.end())
+	 return _error->Error(_("No architecture information available for %s. See apt.conf(5) APT::Architectures for setup"), hostArch.c_str());
+      StripMultiArch = false;
+   }
+   else
+      StripMultiArch = true;
+
    unsigned J = 0;
    unsigned J = 0;
-   bool const StripMultiArch = APT::Configuration::getArchitectures().size() <= 1;
    for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
    for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++)
    {
    {
       string Src;
       string Src;
@@ -2714,7 +2738,7 @@ bool DoBuildDep(CommandLine &CmdL)
 	 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
 	 ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str());
 	 continue;
 	 continue;
       }
       }
-      
+
       // Install the requested packages
       // Install the requested packages
       vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
       vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
       pkgProblemResolver Fix(Cache);
       pkgProblemResolver Fix(Cache);
@@ -2725,6 +2749,16 @@ bool DoBuildDep(CommandLine &CmdL)
 
 
          if (skipAlternatives == true)
          if (skipAlternatives == true)
          {
          {
+            /*
+             * 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
+             */
             if (!hasAlternatives)
             if (!hasAlternatives)
                skipAlternatives = false; // end of or group
                skipAlternatives = false; // end of or group
             continue;
             continue;
@@ -2733,27 +2767,117 @@ bool DoBuildDep(CommandLine &CmdL)
          if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
          if ((*D).Type == pkgSrcRecords::Parser::BuildConflict ||
 	     (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
 	     (*D).Type == pkgSrcRecords::Parser::BuildConflictIndep)
          {
          {
-            pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
+            pkgCache::GrpIterator Grp = Cache->FindGrp((*D).Package);
             // Build-conflicts on unknown packages are silently ignored
             // Build-conflicts on unknown packages are silently ignored
-            if (Pkg.end() == true)
+            if (Grp.end() == true)
                continue;
                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)
-               TryToInstallBuildDep(Pkg,Cache,Fix,true,false);
+	    for (pkgCache::PkgIterator Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg))
+	    {
+	       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)
+		  TryToInstallBuildDep(Pkg,Cache,Fix,true,false);
+	    }
          }
          }
 	 else // BuildDep || BuildDepIndep
 	 else // BuildDep || BuildDepIndep
          {
          {
-	    pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package);
             if (_config->FindB("Debug::BuildDeps",false) == true)
             if (_config->FindB("Debug::BuildDeps",false) == true)
                  cout << "Looking for " << (*D).Package << "...\n";
                  cout << "Looking for " << (*D).Package << "...\n";
 
 
+	    pkgCache::PkgIterator Pkg;
+
+	    // Cross-Building?
+	    if (StripMultiArch == false)
+	    {
+	       size_t const colon = D->Package.find(":");
+	       if (colon != string::npos &&
+		   (strcmp(D->Package.c_str() + colon, ":any") == 0 || strcmp(D->Package.c_str() + colon, ":native") == 0))
+		  Pkg = Cache->FindPkg(D->Package.substr(0,colon));
+	       else
+		  Pkg = Cache->FindPkg(D->Package);
+
+	       // We need to decide if host or build arch, so find a version we can look at
+	       pkgCache::VerIterator Ver;
+
+	       // a bad version either is invalid or doesn't satify dependency
+	       #define BADVER(Ver) Ver.end() == true || \
+				   (Ver.end() == false && D->Version.empty() == false && \
+				    Cache->VS().CheckDep(Ver.VerStr(),D->Op,D->Version.c_str()) == false)
+
+	       if (Pkg.end() == false)
+	       {
+		  Ver = (*Cache)[Pkg].InstVerIter(*Cache);
+		  if (BADVER(Ver))
+		     Ver = (*Cache)[Pkg].CandidateVerIter(*Cache);
+	       }
+	       if (BADVER(Ver))
+	       {
+		  pkgCache::PkgIterator HostPkg = Cache->FindPkg(D->Package, hostArch);
+		  if (HostPkg.end() == false)
+		  {
+		     Ver = (*Cache)[HostPkg].InstVerIter(*Cache);
+		     if (BADVER(Ver))
+		        Ver = (*Cache)[HostPkg].CandidateVerIter(*Cache);
+		  }
+	       }
+	       if ((BADVER(Ver)) == false)
+	       {
+		  string forbidden;
+		  if (Ver->MultiArch == pkgCache::Version::None || Ver->MultiArch == pkgCache::Version::All);
+		  else if (Ver->MultiArch == pkgCache::Version::Same)
+		  {
+		     if (colon != string::npos)
+			Pkg = Ver.ParentPkg().Group().FindPkg(hostArch);
+		     else if (strcmp(D->Package.c_str() + colon, ":any") == 0)
+			forbidden = "Multi-Arch: same";
+		     // :native gets the buildArch
+		  }
+		  else if (Ver->MultiArch == pkgCache::Version::Foreign || Ver->MultiArch == pkgCache::Version::AllForeign)
+		  {
+		     if (colon != string::npos)
+			forbidden = "Multi-Arch: foreign";
+		  }
+		  else if (Ver->MultiArch == pkgCache::Version::Allowed || Ver->MultiArch == pkgCache::Version::AllAllowed)
+		  {
+		     if (colon == string::npos)
+			Pkg = Ver.ParentPkg().Group().FindPkg(hostArch);
+		     else if (strcmp(D->Package.c_str() + colon, ":any") == 0)
+		     {
+			// prefer any installed over preferred non-installed architectures
+			pkgCache::GrpIterator Grp = Ver.ParentPkg().Group();
+			// we don't check for version here as we are better of with upgrading than remove and install
+			for (Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg))
+			   if (Pkg.CurrentVer().end() == false)
+			      break;
+			if (Pkg.end() == true)
+			   Pkg = Grp.FindPreferredPkg(true);
+		     }
+		     // native gets buildArch
+		  }
+		  if (forbidden.empty() == false)
+		  {
+		     if (_config->FindB("Debug::BuildDeps",false) == true)
+			cout << " :any is not allowed from M-A: same package " << (*D).Package << endl;
+		     if (hasAlternatives)
+			continue;
+		     return _error->Error(_("%s dependency for %s can't be satisfied "
+					    "because %s is not allowed on '%s' packages"),
+					  Last->BuildDepType(D->Type), Src.c_str(),
+					  D->Package.c_str(), "Multi-Arch: same");
+		  }
+	       }
+	       else if (_config->FindB("Debug::BuildDeps",false) == true)
+		  cout << " No multiarch info as we have no satisfying installed nor candidate for " << D->Package << " on build or host arch" << endl;
+	       #undef BADVER
+	    }
+	    else
+	       Pkg = Cache->FindPkg(D->Package);
+
 	    if (Pkg.end() == true)
 	    if (Pkg.end() == true)
             {
             {
                if (_config->FindB("Debug::BuildDeps",false) == true)
                if (_config->FindB("Debug::BuildDeps",false) == true)
@@ -2768,99 +2892,74 @@ bool DoBuildDep(CommandLine &CmdL)
                                     (*D).Package.c_str());
                                     (*D).Package.c_str());
             }
             }
 
 
-            /*
-             * 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
-             */
-                       
-	    /* 
-	     * 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 (_config->FindB("Debug::BuildDeps",false) == true)
-                    cout << "  Checking provider " << Prv.OwnerPkg().FullName() << endl;
-
-	       if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
-	          break;
-            }
-            
-            // Get installed version and version we are going to install
 	    pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
 	    pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache);
+	    if (IV.end() == false)
+	    {
+	       if (_config->FindB("Debug::BuildDeps",false) == true)
+		  cout << "  Is installed\n";
 
 
-            if ((*D).Version[0] != '\0') {
-                 // Versioned dependency
-
-                 pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
-
-                 for (; CV.end() != true; CV++)
-                 {
-                      if (Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
-                           break;
-                 }
-                 if (CV.end() == true)
-		 {
-		   if (hasAlternatives)
-		   {
-		      continue;
-		   }
-		   else
-		   {
-                      return _error->Error(_("%s dependency for %s cannot be satisfied "
-                                             "because no available versions of package %s "
-                                             "can satisfy version requirements"),
-                                           Last->BuildDepType((*D).Type),Src.c_str(),
-                                           (*D).Package.c_str());
-		   }
-		 }
-            }
-            else
-            {
-               // Only consider virtual packages if there is no versioned dependency
-               if (Prv.end() == false)
-               {
-                  if (_config->FindB("Debug::BuildDeps",false) == true)
-                     cout << "  Is provided by installed package " << Prv.OwnerPkg().FullName() << endl;
-                  skipAlternatives = hasAlternatives;
-                  continue;
-               }
-            }
+	       if (D->Version.empty() == true ||
+		   Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
+	       {
+		  skipAlternatives = hasAlternatives;
+		  continue;
+	       }
 
 
-            if (IV.end() == false)
-            {
-               if (_config->FindB("Debug::BuildDeps",false) == true)
-                  cout << "  Is installed\n";
+	       if (_config->FindB("Debug::BuildDeps",false) == true)
+		  cout << "    ...but the installed version doesn't meet the version requirement\n";
 
 
-               if (Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
-               {
-                  skipAlternatives = hasAlternatives;
-                  continue;
-               }
+	       if (((*D).Op & pkgCache::Dep::LessEq) == pkgCache::Dep::LessEq)
+		  return _error->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"),
+					Last->BuildDepType((*D).Type), Src.c_str(), Pkg.FullName(true).c_str());
+	    }
 
 
-               if (_config->FindB("Debug::BuildDeps",false) == true)
-                  cout << "    ...but the installed version doesn't meet the version requirement\n";
-
-               if (((*D).Op & pkgCache::Dep::LessEq) == pkgCache::Dep::LessEq)
-               {
-                  return _error->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"),
-                                       Last->BuildDepType((*D).Type),
-                                       Src.c_str(),
-                                       Pkg.FullName(true).c_str());
-               }
-            }
+	    // Only consider virtual packages if there is no versioned dependency
+	    if ((*D).Version.empty() == true)
+	    {
+	       /*
+		* 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 (_config->FindB("Debug::BuildDeps",false) == true)
+		     cout << "  Checking provider " << Prv.OwnerPkg().FullName() << endl;
 
 
+		  if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false)
+		     break;
+	       }
 
 
-            if (_config->FindB("Debug::BuildDeps",false) == true)
-               cout << "  Trying to install " << (*D).Package << endl;
+	       if (Prv.end() == false)
+	       {
+		  if (_config->FindB("Debug::BuildDeps",false) == true)
+		     cout << "  Is provided by installed package " << Prv.OwnerPkg().FullName() << endl;
+		  skipAlternatives = hasAlternatives;
+		  continue;
+	       }
+	    }
+	    else // versioned dependency
+	    {
+	       pkgCache::VerIterator CV = (*Cache)[Pkg].CandidateVerIter(*Cache);
+	       if (CV.end() == true ||
+		   Cache->VS().CheckDep(CV.VerStr(),(*D).Op,(*D).Version.c_str()) == false)
+	       {
+		  if (hasAlternatives)
+		     continue;
+		  else if (CV.end() == false)
+		     return _error->Error(_("%s dependency for %s cannot be satisfied "
+					    "because candidate version of package %s "
+					    "can't satisfy version requirements"),
+					  Last->BuildDepType(D->Type), Src.c_str(),
+					  D->Package.c_str());
+		  else
+		     return _error->Error(_("%s dependency for %s cannot be satisfied "
+					    "because package %s has no candidate version"),
+					  Last->BuildDepType(D->Type), Src.c_str(),
+					  D->Package.c_str());
+	       }
+	    }
 
 
             if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true)
             if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true)
             {
             {
@@ -3246,6 +3345,7 @@ int main(int argc,const char *argv[])					/*{{{*/
       {'m',"ignore-missing","APT::Get::Fix-Missing",0},
       {'m',"ignore-missing","APT::Get::Fix-Missing",0},
       {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
       {'t',"target-release","APT::Default-Release",CommandLine::HasArg},
       {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
       {'t',"default-release","APT::Default-Release",CommandLine::HasArg},
+      {'a',"host-architecture","APT::Get::Host-Architecture",CommandLine::HasArg},
       {0,"download","APT::Get::Download",0},
       {0,"download","APT::Get::Download",0},
       {0,"fix-missing","APT::Get::Fix-Missing",0},
       {0,"fix-missing","APT::Get::Fix-Missing",0},
       {0,"ignore-hold","APT::Ignore-Hold",0},      
       {0,"ignore-hold","APT::Ignore-Hold",0},      

+ 1 - 1
cmdline/apt-key

@@ -7,7 +7,7 @@ unset GREP_OPTIONS
 # implodes if there isn't one available
 # implodes if there isn't one available
 SECRETKEYRING="$(mktemp)"
 SECRETKEYRING="$(mktemp)"
 trap "rm -f '${SECRETKEYRING}'" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
 trap "rm -f '${SECRETKEYRING}'" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
-GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring '${SECRETKEYRING}'"
+GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring ${SECRETKEYRING}"
 
 
 if [ "$(id -u)" -eq 0 ]; then
 if [ "$(id -u)" -eq 0 ]; then
 	# we could use a tmpfile here too, but creation of this tends to be time-consuming
 	# we could use a tmpfile here too, but creation of this tends to be time-consuming

+ 11 - 2
debian/changelog

@@ -1,4 +1,4 @@
-apt (0.8.15.3) UNRELEASED; urgency=low
+apt (0.8.15.3) unstable; urgency=low
 
 
   [ Michael Vogt ]
   [ Michael Vogt ]
   * apt-pkg/acquire-item.cc:
   * apt-pkg/acquire-item.cc:
@@ -20,6 +20,8 @@ apt (0.8.15.3) UNRELEASED; urgency=low
   * cmdline/apt-get.cc:
   * cmdline/apt-get.cc:
     - restore all important dependencies for garbage packages (LP: #806274)
     - restore all important dependencies for garbage packages (LP: #806274)
     - do not require unused partial dirs in 'source' (Closes: #633510)
     - do not require unused partial dirs in 'source' (Closes: #633510)
+    - buildconflicts effect all architectures
+    - implement MultiarchCross for build-dep and source (Closes: #632221)
   * apt-pkg/init.cc:
   * apt-pkg/init.cc:
     - use CndSet in pkgInitConfig (Closes: #629617)
     - use CndSet in pkgInitConfig (Closes: #629617)
   * apt-pkg/depcache.cc:
   * apt-pkg/depcache.cc:
@@ -32,8 +34,15 @@ apt (0.8.15.3) UNRELEASED; urgency=low
     - apply madison typofix from John Feuerstein, thanks! (Closes: #633455)
     - apply madison typofix from John Feuerstein, thanks! (Closes: #633455)
   * apt-pkg/policy.cc:
   * apt-pkg/policy.cc:
     - emit an error on unknown APT::Default-Release value (Closes: #407511)
     - emit an error on unknown APT::Default-Release value (Closes: #407511)
+  * apt-pkg/aptconfiguration.cc:
+    - ensure that native architecture is if not specified otherwise the
+      first architecture in the Architectures vector
+  * apt-pkg/deb/deblistparser.cc:
+    - Strip only :any and :native if MultiArch should be stripped as it is
+      save to ignore them in non-MultiArch contexts but if the dependency
+      is a specific architecture (and not the native) do not strip
 
 
- -- David Kalnischkies <kalnischkies@gmail.com>  Sat, 16 Jul 2011 16:43:37 +0200
+ -- Michael Vogt <mvo@debian.org>  Mon, 25 Jul 2011 15:04:43 +0200
 
 
 apt (0.8.15.2) unstable; urgency=high
 apt (0.8.15.2) unstable; urgency=high
 
 

+ 24 - 3
doc/apt-get.8.xml

@@ -54,6 +54,13 @@
 			<replaceable>target_release</replaceable>
 			<replaceable>target_release</replaceable>
 		</arg>
 		</arg>
       </arg>
       </arg>
+      <arg>
+		<option>-a=</option>
+		<arg choice='plain'>
+			<replaceable>default_architecture</replaceable>
+		</arg>
+      </arg>
+
 
 
       <group choice="req">
       <group choice="req">
          <arg choice='plain'>update</arg>
          <arg choice='plain'>update</arg>
@@ -254,8 +261,10 @@
 
 
      <para>If the <option>--compile</option> option is specified
      <para>If the <option>--compile</option> option is specified
      then the package will be compiled to a binary .deb using
      then the package will be compiled to a binary .deb using
-     <command>dpkg-buildpackage</command>, if <option>--download-only</option>
-     is specified then the source package will not be unpacked.</para>
+     <command>dpkg-buildpackage</command> for the architecture as
+     defined by the <command>--host-architecture</command> option.
+     If <option>--download-only</option> is specified then the source package
+     will not be unpacked.</para>
 
 
      <para>A specific source version can be retrieved by postfixing the source name
      <para>A specific source version can be retrieved by postfixing the source name
      with an equals and then the version to fetch, similar to the mechanism
      with an equals and then the version to fetch, similar to the mechanism
@@ -270,7 +279,9 @@
 
 
      <varlistentry><term>build-dep</term>
      <varlistentry><term>build-dep</term>
      <listitem><para><literal>build-dep</literal> causes apt-get to install/remove packages in an 
      <listitem><para><literal>build-dep</literal> causes apt-get to install/remove packages in an 
-     attempt to satisfy the build dependencies for a source package.</para></listitem>
+     attempt to satisfy the build dependencies for a source package. By default the dependencies are
+     satisfied to build the package nativly. If desired a host-architecture can be specified
+     with the <option>--host-architecture</option> option instead.</para></listitem>
      </varlistentry>
      </varlistentry>
 
 
      <varlistentry><term>check</term>
      <varlistentry><term>check</term>
@@ -433,6 +444,16 @@
      Configuration Item: <literal>APT::Get::Show-Versions</literal>.</para></listitem>
      Configuration Item: <literal>APT::Get::Show-Versions</literal>.</para></listitem>
      </varlistentry>
      </varlistentry>
 
 
+     <varlistentry><term><option>-a</option></term>
+                   <term><option>--host-architecture</option></term>
+     <listitem><para>This option controls the architecture packages are built for
+     by <command>apt-get source --compile</command> and how cross-builddependencies
+     are satisfied. By default is not set which means that the host architecture
+     is the same as the build architecture (which is defined by <literal>APT::Architecture</literal>)
+     Configuration Item: <literal>APT::Get::Host-Architecture</literal>
+     </para></listitem>
+     </varlistentry>
+
      <varlistentry><term><option>-b</option></term><term><option>--compile</option></term>
      <varlistentry><term><option>-b</option></term><term><option>--compile</option></term>
                    <term><option>--build</option></term>
                    <term><option>--build</option></term>
      <listitem><para>Compile source packages after downloading them.
      <listitem><para>Compile source packages after downloading them.

+ 1 - 0
doc/examples/configure-index

@@ -32,6 +32,7 @@ APT
   // Options for apt-get
   // Options for apt-get
   Get 
   Get 
   {
   {
+     Host-Architecture "armel";
      Arch-Only "false";
      Arch-Only "false";
      AllowUnauthenticated "false";
      AllowUnauthenticated "false";
      AutomaticRemove "false";       
      AutomaticRemove "false";       

+ 22 - 0
test/integration/framework

@@ -151,6 +151,7 @@ setupenvironment() {
 
 
 configarchitecture() {
 configarchitecture() {
 	local CONFFILE=rootdir/etc/apt/apt.conf.d/01multiarch.conf
 	local CONFFILE=rootdir/etc/apt/apt.conf.d/01multiarch.conf
+	rm -f $CONFFILE
 	echo "APT::Architecture \"$1\";" > $CONFFILE
 	echo "APT::Architecture \"$1\";" > $CONFFILE
 	shift
 	shift
 	while [ -n "$1" ]; do
 	while [ -n "$1" ]; do
@@ -429,6 +430,27 @@ Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb" >> $FILE
 	done
 	done
 }
 }
 
 
+insertsource() {
+	local RELEASE="$1"
+	local NAME="$2"
+	local ARCH="$3"
+	local VERSION="$4"
+	local DEPENDENCIES="$5"
+	local ARCHS=""
+	local SPATH="aptarchive/dists/${RELEASE}/main/source"
+	mkdir -p $SPATH
+	local FILE="${SPATH}/Sources"
+	echo "Package: $NAME
+Binary: $NAME
+Version: $VERSION
+Maintainer: Joe Sixpack <joe@example.org>
+Architecture: $ARCH" >> $FILE
+	test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE
+	echo "Files:
+ d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.dsc
+ d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.tar.gz" >> $FILE
+}
+
 insertinstalledpackage() {
 insertinstalledpackage() {
 	local NAME="$1"
 	local NAME="$1"
 	local ARCH="$2"
 	local ARCH="$2"

+ 183 - 0
test/integration/test-bug-632221-cross-dependency-satisfaction

@@ -0,0 +1,183 @@
+#!/bin/sh
+set -e
+
+TESTDIR=$(readlink -f $(dirname $0))
+. $TESTDIR/framework
+setupenvironment
+configarchitecture 'amd64' 'armel'
+
+insertinstalledpackage 'build-essential' 'all' '11.5'
+
+insertpackage 'unstable' 'doxygen' 'amd64,armel' '1.0'
+insertpackage 'unstable' 'libc6' 'amd64,armel' '1.0' 'Multi-Arch: same'
+insertpackage 'unstable' 'libc6-dev' 'amd64,armel' '1.0' 'Depends: libc6
+Multi-Arch: same'
+insertpackage 'unstable' 'cool' 'amd64,armel' '1.0' 'Multi-Arch: allowed'
+insertpackage 'unstable' 'amdboot' 'amd64' '1.0'
+insertpackage 'unstable' 'foreigner' 'amd64,armel' '1.0' 'Multi-Arch: foreign'
+
+insertsource 'unstable' 'apt' 'any' '0.8.15' 'Build-Depends: doxygen, libc6-dev, libc6-dev:native, cool:any, amdboot:amd64, foreigner'
+
+setupaptarchive
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot cool doxygen foreigner libc6 libc6-dev
+0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
+Inst amdboot (1.0 unstable [amd64])
+Inst cool (1.0 unstable [amd64])
+Inst doxygen (1.0 unstable [amd64])
+Inst foreigner (1.0 unstable [amd64])
+Inst libc6 (1.0 unstable [amd64])
+Inst libc6-dev (1.0 unstable [amd64])
+Conf amdboot (1.0 unstable [amd64])
+Conf cool (1.0 unstable [amd64])
+Conf doxygen (1.0 unstable [amd64])
+Conf foreigner (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [amd64])
+Conf libc6-dev (1.0 unstable [amd64])' aptget build-dep apt -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot cool doxygen foreigner libc6 libc6:armel libc6-dev libc6-dev:armel
+0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded.
+Inst amdboot (1.0 unstable [amd64])
+Inst cool (1.0 unstable [amd64])
+Inst doxygen (1.0 unstable [amd64])
+Inst foreigner (1.0 unstable [amd64])
+Inst libc6:armel (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [amd64])
+Inst libc6-dev:armel (1.0 unstable [armel])
+Inst libc6-dev (1.0 unstable [amd64])
+Conf amdboot (1.0 unstable [amd64])
+Conf cool (1.0 unstable [amd64])
+Conf doxygen (1.0 unstable [amd64])
+Conf foreigner (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [amd64])
+Conf libc6:armel (1.0 unstable [armel])
+Conf libc6-dev (1.0 unstable [amd64])
+Conf libc6-dev:armel (1.0 unstable [armel])' aptget build-dep apt -s -a armel
+
+configarchitecture 'armel' 'amd64'
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot:amd64 cool doxygen foreigner libc6 libc6-dev
+0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
+Inst amdboot:amd64 (1.0 unstable [amd64])
+Inst cool (1.0 unstable [armel])
+Inst doxygen (1.0 unstable [armel])
+Inst foreigner (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [armel])
+Inst libc6-dev (1.0 unstable [armel])
+Conf amdboot:amd64 (1.0 unstable [amd64])
+Conf cool (1.0 unstable [armel])
+Conf doxygen (1.0 unstable [armel])
+Conf foreigner (1.0 unstable [armel])
+Conf libc6 (1.0 unstable [armel])
+Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot:amd64 cool doxygen foreigner libc6:amd64 libc6 libc6-dev:amd64
+  libc6-dev
+0 upgraded, 8 newly installed, 0 to remove and 0 not upgraded.
+Inst amdboot:amd64 (1.0 unstable [amd64])
+Inst cool (1.0 unstable [armel])
+Inst doxygen (1.0 unstable [armel])
+Inst foreigner (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [armel])
+Inst libc6:amd64 (1.0 unstable [amd64])
+Inst libc6-dev (1.0 unstable [armel])
+Inst libc6-dev:amd64 (1.0 unstable [amd64])
+Conf amdboot:amd64 (1.0 unstable [amd64])
+Conf cool (1.0 unstable [armel])
+Conf doxygen (1.0 unstable [armel])
+Conf foreigner (1.0 unstable [armel])
+Conf libc6:amd64 (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [armel])
+Conf libc6-dev:amd64 (1.0 unstable [amd64])
+Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s -a amd64
+
+configarchitecture 'amd64' 'armel'
+
+insertinstalledpackage 'cool' 'amd64' '0.5'
+insertinstalledpackage 'foreigner' 'armel' '0.5'
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot doxygen libc6 libc6-dev
+0 upgraded, 4 newly installed, 0 to remove and 2 not upgraded.
+Inst amdboot (1.0 unstable [amd64])
+Inst doxygen (1.0 unstable [amd64])
+Inst libc6 (1.0 unstable [amd64])
+Inst libc6-dev (1.0 unstable [amd64])
+Conf amdboot (1.0 unstable [amd64])
+Conf doxygen (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [amd64])
+Conf libc6-dev (1.0 unstable [amd64])' aptget build-dep apt -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot doxygen libc6 libc6:armel libc6-dev libc6-dev:armel
+0 upgraded, 6 newly installed, 0 to remove and 2 not upgraded.
+Inst amdboot (1.0 unstable [amd64])
+Inst doxygen (1.0 unstable [amd64])
+Inst libc6:armel (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [amd64])
+Inst libc6-dev:armel (1.0 unstable [armel])
+Inst libc6-dev (1.0 unstable [amd64])
+Conf amdboot (1.0 unstable [amd64])
+Conf doxygen (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [amd64])
+Conf libc6:armel (1.0 unstable [armel])
+Conf libc6-dev (1.0 unstable [amd64])
+Conf libc6-dev:armel (1.0 unstable [armel])' aptget build-dep apt -s -a armel
+
+configarchitecture 'armel' 'amd64'
+
+# cool 0.5 is not M-A: allowed, so amd64 is not acceptable
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be REMOVED:
+  cool:amd64
+The following NEW packages will be installed:
+  amdboot:amd64 cool doxygen libc6 libc6-dev
+0 upgraded, 5 newly installed, 1 to remove and 1 not upgraded.
+Remv cool:amd64 [0.5]
+Inst amdboot:amd64 (1.0 unstable [amd64])
+Inst cool (1.0 unstable [armel])
+Inst doxygen (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [armel])
+Inst libc6-dev (1.0 unstable [armel])
+Conf amdboot:amd64 (1.0 unstable [amd64])
+Conf cool (1.0 unstable [armel])
+Conf doxygen (1.0 unstable [armel])
+Conf libc6 (1.0 unstable [armel])
+Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s
+
+testequal 'Reading package lists...
+Building dependency tree...
+The following NEW packages will be installed:
+  amdboot:amd64 doxygen libc6:amd64 libc6 libc6-dev:amd64 libc6-dev
+0 upgraded, 6 newly installed, 0 to remove and 2 not upgraded.
+Inst amdboot:amd64 (1.0 unstable [amd64])
+Inst doxygen (1.0 unstable [armel])
+Inst libc6 (1.0 unstable [armel])
+Inst libc6:amd64 (1.0 unstable [amd64])
+Inst libc6-dev (1.0 unstable [armel])
+Inst libc6-dev:amd64 (1.0 unstable [amd64])
+Conf amdboot:amd64 (1.0 unstable [amd64])
+Conf doxygen (1.0 unstable [armel])
+Conf libc6:amd64 (1.0 unstable [amd64])
+Conf libc6 (1.0 unstable [armel])
+Conf libc6-dev:amd64 (1.0 unstable [amd64])
+Conf libc6-dev (1.0 unstable [armel])' aptget build-dep apt -s -a amd64
+
+

+ 38 - 4
test/libapt/assert.h

@@ -1,9 +1,9 @@
 #include <iostream>
 #include <iostream>
 
 
-#define equals(x,y) assertEquals(x, y, __LINE__)
+#define equals(x,y) assertEquals(y, x, __LINE__)
 
 
 template < typename X, typename Y >
 template < typename X, typename Y >
-void OutputAssert(X expect, char const* compare, Y get, unsigned long const &line) {
+void OutputAssertEqual(X expect, char const* compare, Y get, unsigned long const &line) {
 	std::cerr << "Test FAILED: »" << expect << "« " << compare << " »" << get << "« at line " << line << std::endl;
 	std::cerr << "Test FAILED: »" << expect << "« " << compare << " »" << get << "« at line " << line << std::endl;
 }
 }
 
 
@@ -11,11 +11,45 @@ template < typename X, typename Y >
 void assertEquals(X expect, Y get, unsigned long const &line) {
 void assertEquals(X expect, Y get, unsigned long const &line) {
 	if (expect == get)
 	if (expect == get)
 		return;
 		return;
-	OutputAssert(expect, "==", get, line);
+	OutputAssertEqual(expect, "==", get, line);
 }
 }
 
 
 void assertEquals(unsigned int const &expect, int const &get, unsigned long const &line) {
 void assertEquals(unsigned int const &expect, int const &get, unsigned long const &line) {
 	if (get < 0)
 	if (get < 0)
-		OutputAssert(expect, "==", get, line);
+		OutputAssertEqual(expect, "==", get, line);
 	assertEquals<unsigned int const&, unsigned int const&>(expect, get, line);
 	assertEquals<unsigned int const&, unsigned int const&>(expect, get, line);
 }
 }
+
+void assertEquals(int const &expect, unsigned int const &get, unsigned long const &line) {
+	if (expect < 0)
+		OutputAssertEqual(expect, "==", get, line);
+	assertEquals<unsigned int const&, unsigned int const&>(expect, get, line);
+}
+
+
+#define equalsOr2(x,y,z) assertEqualsOr2(y, z, x, __LINE__)
+
+template < typename X, typename Y >
+void OutputAssertEqualOr2(X expect1, X expect2, char const* compare, Y get, unsigned long const &line) {
+	std::cerr << "Test FAILED: »" << expect1 << "« or »" << expect2 << "« " << compare << " »" << get << "« at line " << line << std::endl;
+}
+
+template < typename X, typename Y >
+void assertEqualsOr2(X expect1, X expect2, Y get, unsigned long const &line) {
+	if (expect1 == get || expect2 == get)
+		return;
+	OutputAssertEqualOr2(expect1, expect2, "==", get, line);
+}
+
+void assertEqualsOr2(unsigned int const &expect1, unsigned int const &expect2, int const &get, unsigned long const &line) {
+	if (get < 0)
+		OutputAssertEqualOr2(expect1, expect2, "==", get, line);
+	assertEqualsOr2<unsigned int const&, unsigned int const&>(expect1, expect2, get, line);
+}
+
+void assertEqualsOr2(int const &expect1, int const &expect2, unsigned int const &get, unsigned long const &line) {
+	if (expect1 < 0 && expect2 < 0)
+		OutputAssertEqualOr2(expect1, expect2, "==", get, line);
+	assertEqualsOr2<unsigned int const&, unsigned int const&>(expect1, expect2, get, line);
+}
+

+ 6 - 0
test/libapt/getarchitectures_test.cc

@@ -39,6 +39,12 @@ int main(int argc,char *argv[])
 	_config->Set("APT::Architecture", "armel");
 	_config->Set("APT::Architecture", "armel");
 	vec = APT::Configuration::getArchitectures(false);
 	vec = APT::Configuration::getArchitectures(false);
 	equals(vec.size(), 2);
 	equals(vec.size(), 2);
+	equals(vec[0], "armel");
+	equals(vec[1], "i386");
+
+	_config->Set("APT::Architectures::2", "armel");
+	vec = APT::Configuration::getArchitectures(false);
+	equals(vec.size(), 2);
 	equals(vec[0], "i386");
 	equals(vec[0], "i386");
 	equals(vec[1], "armel");
 	equals(vec[1], "armel");
 
 

+ 2 - 2
test/libapt/getlanguages_test.cc

@@ -138,8 +138,8 @@ int main(int argc,char *argv[])
 	equals(vec[1], "de");
 	equals(vec[1], "de");
 	equals(vec[2], "en");
 	equals(vec[2], "en");
 	equals(vec[3], "none");
 	equals(vec[3], "none");
-	equals(vec[4], "pt");
-	equals(vec[5], "tr");
+	equalsOr2(vec[4], "pt", "tr");
+	equalsOr2(vec[5], "tr", "pt");
 
 
 	_config->Set("Dir::State::lists", "/non-existing-dir");
 	_config->Set("Dir::State::lists", "/non-existing-dir");
 	_config->Set("Acquire::Languages::1", "none");
 	_config->Set("Acquire::Languages::1", "none");