From 331eea386e2bb57af6dbb9f1c86f176b2d55c6a1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 23 Jul 2011 11:50:49 +0200 Subject: =?UTF-8?q?you=20want=20to=20be=20nice=20and=20quote=20a=20filenam?= =?UTF-8?q?e=20just=20to=20be=20reminded=20by=20gpg=20that=20it=20doesn't?= =?UTF-8?q?=20like=20that=E2=80=A6=20remove=20superficial=20quoting=20to?= =?UTF-8?q?=20fix=20apt-key?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmdline/apt-key | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmdline/apt-key b/cmdline/apt-key index 8a995dadd..e632be706 100755 --- a/cmdline/apt-key +++ b/cmdline/apt-key @@ -7,7 +7,7 @@ unset GREP_OPTIONS # implodes if there isn't one available SECRETKEYRING="$(mktemp)" 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 # we could use a tmpfile here too, but creation of this tends to be time-consuming -- cgit v1.2.3 From e3a86238d2fac37c5573079d70dbf3d31a638cfd Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 24 Jul 2011 19:03:15 +0200 Subject: buildconflicts effect all architectures --- cmdline/apt-get.cc | 24 +++++++++++++----------- debian/changelog | 3 ++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 748ebe6ab..1df3b520e 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2733,20 +2733,22 @@ bool DoBuildDep(CommandLine &CmdL) if ((*D).Type == pkgSrcRecords::Parser::BuildConflict || (*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 - if (Pkg.end() == true) + if (Grp.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) - 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 { diff --git a/debian/changelog b/debian/changelog index 607f7c64a..c9659395f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -18,6 +18,7 @@ apt (0.8.15.3) UNRELEASED; urgency=low * cmdline/apt-get.cc: - restore all important dependencies for garbage packages (LP: #806274) - do not require unused partial dirs in 'source' (Closes: #633510) + - buildconflicts effect all architectures * apt-pkg/init.cc: - use CndSet in pkgInitConfig (Closes: #629617) * apt-pkg/depcache.cc: @@ -31,7 +32,7 @@ apt (0.8.15.3) UNRELEASED; urgency=low * apt-pkg/policy.cc: - emit an error on unknown APT::Default-Release value (Closes: #407511) - -- David Kalnischkies Sat, 16 Jul 2011 16:43:37 +0200 + -- David Kalnischkies Sun, 24 Jul 2011 18:41:43 +0200 apt (0.8.15.2) unstable; urgency=high -- cgit v1.2.3 From 3fdb6f8315de03819a82bcf9fc5ac5d15389fcb0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 24 Jul 2011 19:04:18 +0200 Subject: first round of reorder code without changing result --- cmdline/apt-get.cc | 56 ++++++++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 1df3b520e..721ce9dc7 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2725,6 +2725,16 @@ bool DoBuildDep(CommandLine &CmdL) 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) skipAlternatives = false; // end of or group continue; @@ -2752,10 +2762,10 @@ bool DoBuildDep(CommandLine &CmdL) } else // BuildDep || BuildDepIndep { - pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package); if (_config->FindB("Debug::BuildDeps",false) == true) cout << "Looking for " << (*D).Package << "...\n"; + pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package); if (Pkg.end() == true) { if (_config->FindB("Debug::BuildDeps",false) == true) @@ -2770,34 +2780,6 @@ bool DoBuildDep(CommandLine &CmdL) (*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); if ((*D).Version[0] != '\0') { // Versioned dependency @@ -2827,6 +2809,21 @@ bool DoBuildDep(CommandLine &CmdL) } 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 (_config->FindB("Debug::BuildDeps",false) == true) + cout << " Checking provider " << Prv.OwnerPkg().FullName() << endl; + + if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false) + break; + } + // Only consider virtual packages if there is no versioned dependency if (Prv.end() == false) { @@ -2837,6 +2834,7 @@ bool DoBuildDep(CommandLine &CmdL) } } + pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache); if (IV.end() == false) { if (_config->FindB("Debug::BuildDeps",false) == true) -- cgit v1.2.3 From 91bee655abd9091eee0687dc3689744217c6cdb4 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 24 Jul 2011 19:06:01 +0200 Subject: move the detection for installed versions up as it is the easiest case --- cmdline/apt-get.cc | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 721ce9dc7..9f9a9e589 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2780,6 +2780,26 @@ bool DoBuildDep(CommandLine &CmdL) (*D).Package.c_str()); } + 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.empty() == true || + Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) + { + skipAlternatives = hasAlternatives; + continue; + } + + 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()); + } if ((*D).Version[0] != '\0') { // Versioned dependency @@ -2834,31 +2854,6 @@ bool DoBuildDep(CommandLine &CmdL) } } - pkgCache::VerIterator IV = (*Cache)[Pkg].InstVerIter(*Cache); - if (IV.end() == false) - { - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Is installed\n"; - - if (Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true) - { - skipAlternatives = hasAlternatives; - continue; - } - - 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()); - } - } - - if (_config->FindB("Debug::BuildDeps",false) == true) cout << " Trying to install " << (*D).Package << endl; -- cgit v1.2.3 From fe0278799cb7bd1c9039a053da178f54d120248c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 24 Jul 2011 19:15:20 +0200 Subject: after this consider providing packages (if it is not a versioned dep) --- cmdline/apt-get.cc | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 9f9a9e589..b37ced5cb 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2801,6 +2801,33 @@ bool DoBuildDep(CommandLine &CmdL) 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 (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[0] != '\0') { // Versioned dependency @@ -2827,32 +2854,6 @@ bool DoBuildDep(CommandLine &CmdL) } } } - 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 (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Checking provider " << Prv.OwnerPkg().FullName() << endl; - - if ((*Cache)[Prv.OwnerPkg()].InstVerIter(*Cache).end() == false) - break; - } - - // 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 (_config->FindB("Debug::BuildDeps",false) == true) cout << " Trying to install " << (*D).Package << endl; -- cgit v1.2.3 From 2baf02ca838e9d7df0a0e9923ffbbb706978ffa4 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 24 Jul 2011 19:26:38 +0200 Subject: alternatively check in a versioned depends if the candidate is good The old code used to do move on to versions behind the candidate in cases the candidate wasn't a match, but as the Install request later always installs the candidate (witch wasn't switched) this could have never worked - and shouldn't in most cases anyway as: a) it could only work for <, <=, != depends which are unusal b) doesn't respect pinning, so it could install -1 versions --- cmdline/apt-get.cc | 48 +++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index b37ced5cb..80037ae66 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2827,33 +2827,27 @@ bool DoBuildDep(CommandLine &CmdL) continue; } } - - 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 // 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 (_config->FindB("Debug::BuildDeps",false) == true) cout << " Trying to install " << (*D).Package << endl; -- cgit v1.2.3 From ac32148639b3a35bc359275b9265f41f81e29296 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 24 Jul 2011 19:37:49 +0200 Subject: move debug message about attempt install/remove to the responsible method --- cmdline/apt-get.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index 80037ae66..b3ce54bb7 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -1388,6 +1388,14 @@ bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache, 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) { TryToRemove RemoveAction(Cache, &Fix); @@ -2849,9 +2857,6 @@ bool DoBuildDep(CommandLine &CmdL) } } - if (_config->FindB("Debug::BuildDeps",false) == true) - cout << " Trying to install " << (*D).Package << endl; - if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true) { // We successfully installed something; skip remaining alternatives -- cgit v1.2.3 From bd9d81e3d793b9fb5c94fd5ad0b00245205b8cbc Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 25 Jul 2011 12:37:06 +0200 Subject: * apt-pkg/aptconfiguration.cc: - ensure that native architecture is if not specified otherwise the first architecture in the Architectures vector --- apt-pkg/aptconfiguration.cc | 2 +- debian/changelog | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index e8c8e73d0..9ccbeecf1 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -352,7 +352,7 @@ std::vector const Configuration::getArchitectures(bool const &Cache if (archs.empty() == true || std::find(archs.begin(), archs.end(), arch) == archs.end()) - archs.push_back(arch); + archs.insert(archs.begin(), arch); // erase duplicates and empty strings for (std::vector::reverse_iterator a = archs.rbegin(); diff --git a/debian/changelog b/debian/changelog index c9659395f..76d5a2183 100644 --- a/debian/changelog +++ b/debian/changelog @@ -31,8 +31,11 @@ apt (0.8.15.3) UNRELEASED; urgency=low - apply madison typofix from John Feuerstein, thanks! (Closes: #633455) * apt-pkg/policy.cc: - 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 - -- David Kalnischkies Sun, 24 Jul 2011 18:41:43 +0200 + -- David Kalnischkies Mon, 25 Jul 2011 12:36:07 +0200 apt (0.8.15.2) unstable; urgency=high -- cgit v1.2.3 From 550f6493654e921a8af860694efdb268c9b2a47c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 25 Jul 2011 12:52:50 +0200 Subject: * 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 --- apt-pkg/deb/deblistparser.cc | 9 ++++++--- debian/changelog | 6 +++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 9ae1065a4..651fa2a81 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -461,7 +461,7 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op) * * The complete architecture, consisting of -. */ -static string CompleteArch(std::string& arch) { +static string CompleteArch(std::string const &arch) { if (arch == "armel") return "linux-arm"; if (arch == "armhf") return "linux-arm"; 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); // We don't want to confuse library users which can't handle MultiArch + string const arch = _config->Find("APT::Architecture"); if (StripMultiArch == true) { 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); } @@ -543,7 +547,6 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, if (ParseArchFlags == true) { - string arch = _config->Find("APT::Architecture"); string completeArch = CompleteArch(arch); // Parse an architecture diff --git a/debian/changelog b/debian/changelog index 76d5a2183..fe4b233a4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -34,8 +34,12 @@ apt (0.8.15.3) UNRELEASED; urgency=low * 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 Mon, 25 Jul 2011 12:36:07 +0200 + -- David Kalnischkies Mon, 25 Jul 2011 12:46:19 +0200 apt (0.8.15.2) unstable; urgency=high -- cgit v1.2.3 From c3182c823bdba037e7f1daaffde8b44155ff4f48 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 25 Jul 2011 13:40:50 +0200 Subject: update the testcase to reflect that native is always on top if it is not in the config provided list of Architectures --- test/libapt/getarchitectures_test.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/libapt/getarchitectures_test.cc b/test/libapt/getarchitectures_test.cc index 1500caeed..e3ca7bbc2 100644 --- a/test/libapt/getarchitectures_test.cc +++ b/test/libapt/getarchitectures_test.cc @@ -39,6 +39,12 @@ int main(int argc,char *argv[]) _config->Set("APT::Architecture", "armel"); vec = APT::Configuration::getArchitectures(false); 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[1], "armel"); -- cgit v1.2.3 From fce1153321e432ed4a64e9742a8fc1c5558124e4 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 25 Jul 2011 13:55:23 +0200 Subject: the order of languages after "none" is not important, so ignore it in tests --- test/libapt/assert.h | 42 ++++++++++++++++++++++++++++++++++++---- test/libapt/getlanguages_test.cc | 4 ++-- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/test/libapt/assert.h b/test/libapt/assert.h index 5da76ae0a..92b662dfa 100644 --- a/test/libapt/assert.h +++ b/test/libapt/assert.h @@ -1,9 +1,9 @@ #include -#define equals(x,y) assertEquals(x, y, __LINE__) +#define equals(x,y) assertEquals(y, x, __LINE__) 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; } @@ -11,11 +11,45 @@ template < typename X, typename Y > void assertEquals(X expect, Y get, unsigned long const &line) { if (expect == get) return; - OutputAssert(expect, "==", get, line); + OutputAssertEqual(expect, "==", get, line); } void assertEquals(unsigned int const &expect, int const &get, unsigned long const &line) { if (get < 0) - OutputAssert(expect, "==", get, line); + OutputAssertEqual(expect, "==", get, line); assertEquals(expect, get, line); } + +void assertEquals(int const &expect, unsigned int const &get, unsigned long const &line) { + if (expect < 0) + OutputAssertEqual(expect, "==", get, line); + assertEquals(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(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(expect1, expect2, get, line); +} + diff --git a/test/libapt/getlanguages_test.cc b/test/libapt/getlanguages_test.cc index 707142aef..3d63e0e74 100644 --- a/test/libapt/getlanguages_test.cc +++ b/test/libapt/getlanguages_test.cc @@ -138,8 +138,8 @@ int main(int argc,char *argv[]) equals(vec[1], "de"); equals(vec[2], "en"); 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("Acquire::Languages::1", "none"); -- cgit v1.2.3 From 234675b71a2caab5c7cc0dc3b32a241683d3b3d2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 25 Jul 2011 14:40:22 +0200 Subject: implement MultiarchCross for build-dep and source (Closes: #632221) --- cmdline/apt-get.cc | 113 ++++++++++++- debian/changelog | 3 +- doc/apt-get.8.xml | 27 ++- doc/examples/configure-index | 1 + test/integration/framework | 22 +++ .../test-bug-632221-cross-dependency-satisfaction | 183 +++++++++++++++++++++ 6 files changed, 341 insertions(+), 8 deletions(-) create mode 100755 test/integration/test-bug-632221-cross-dependency-satisfaction diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc index b3ce54bb7..8eda29362 100644 --- a/cmdline/apt-get.cc +++ b/cmdline/apt-get.cc @@ -2620,12 +2620,17 @@ bool DoSource(CommandLine &CmdL) // Try to compile it with dpkg-buildpackage 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 char S[500]; snprintf(S,sizeof(S),"cd %s && %s %s", Dir.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) { @@ -2687,8 +2692,19 @@ bool DoBuildDep(CommandLine &CmdL) if (Fetcher.Setup(&Stat) == false) return false; + bool StripMultiArch; + string hostArch = _config->Find("APT::Get::Host-Architecture"); + if (hostArch.empty() == false) + { + std::vector 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; - bool const StripMultiArch = APT::Configuration::getArchitectures().size() <= 1; for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) { string Src; @@ -2722,7 +2738,7 @@ bool DoBuildDep(CommandLine &CmdL) ioprintf(c1out,_("%s has no build depends.\n"),Src.c_str()); continue; } - + // Install the requested packages vector ::iterator D; pkgProblemResolver Fix(Cache); @@ -2773,7 +2789,95 @@ bool DoBuildDep(CommandLine &CmdL) if (_config->FindB("Debug::BuildDeps",false) == true) cout << "Looking for " << (*D).Package << "...\n"; - pkgCache::PkgIterator Pkg = Cache->FindPkg((*D).Package); + 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 (_config->FindB("Debug::BuildDeps",false) == true) @@ -3241,6 +3345,7 @@ int main(int argc,const char *argv[]) /*{{{*/ {'m',"ignore-missing","APT::Get::Fix-Missing",0}, {'t',"target-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,"fix-missing","APT::Get::Fix-Missing",0}, {0,"ignore-hold","APT::Ignore-Hold",0}, diff --git a/debian/changelog b/debian/changelog index fe4b233a4..c32edc4ad 100644 --- a/debian/changelog +++ b/debian/changelog @@ -19,6 +19,7 @@ apt (0.8.15.3) UNRELEASED; urgency=low - restore all important dependencies for garbage packages (LP: #806274) - 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: - use CndSet in pkgInitConfig (Closes: #629617) * apt-pkg/depcache.cc: @@ -39,7 +40,7 @@ apt (0.8.15.3) UNRELEASED; urgency=low 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 Mon, 25 Jul 2011 12:46:19 +0200 + -- David Kalnischkies Mon, 25 Jul 2011 14:40:00 +0200 apt (0.8.15.2) unstable; urgency=high diff --git a/doc/apt-get.8.xml b/doc/apt-get.8.xml index 11b53e5e7..9d901b492 100644 --- a/doc/apt-get.8.xml +++ b/doc/apt-get.8.xml @@ -54,6 +54,13 @@ target_release + + + + default_architecture + + + update @@ -254,8 +261,10 @@ If the option is specified then the package will be compiled to a binary .deb using - dpkg-buildpackage, if - is specified then the source package will not be unpacked. + dpkg-buildpackage for the architecture as + defined by the --host-architecture option. + If is specified then the source package + will not be unpacked. 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 @@ -270,7 +279,9 @@ build-dep build-dep causes apt-get to install/remove packages in an - attempt to satisfy the build dependencies for a source package. + 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 instead. check @@ -433,6 +444,16 @@ Configuration Item: APT::Get::Show-Versions. + + + This option controls the architecture packages are built for + by apt-get source --compile 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 APT::Architecture) + Configuration Item: APT::Get::Host-Architecture + + + Compile source packages after downloading them. diff --git a/doc/examples/configure-index b/doc/examples/configure-index index 27232d40b..49e803f91 100644 --- a/doc/examples/configure-index +++ b/doc/examples/configure-index @@ -32,6 +32,7 @@ APT // Options for apt-get Get { + Host-Architecture "armel"; Arch-Only "false"; AllowUnauthenticated "false"; AutomaticRemove "false"; diff --git a/test/integration/framework b/test/integration/framework index 702e352a3..fa451cf4f 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -151,6 +151,7 @@ setupenvironment() { configarchitecture() { local CONFFILE=rootdir/etc/apt/apt.conf.d/01multiarch.conf + rm -f $CONFFILE echo "APT::Architecture \"$1\";" > $CONFFILE shift while [ -n "$1" ]; do @@ -429,6 +430,27 @@ Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb" >> $FILE 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 +Architecture: $ARCH" >> $FILE + test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE + echo "Files: + d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.dsc + d41d8cd98f00b204e9800998ecf8427e 0 ${NAME}_${VERSION}.tar.gz" >> $FILE +} + insertinstalledpackage() { local NAME="$1" local ARCH="$2" diff --git a/test/integration/test-bug-632221-cross-dependency-satisfaction b/test/integration/test-bug-632221-cross-dependency-satisfaction new file mode 100755 index 000000000..58de44843 --- /dev/null +++ b/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 + + -- cgit v1.2.3