1 // Include Files /*{{{*/
4 #include <apt-pkg/acquire-item.h>
5 #include <apt-pkg/acquire.h>
6 #include <apt-pkg/algorithms.h>
7 #include <apt-pkg/aptconfiguration.h>
8 #include <apt-pkg/cachefile.h>
9 #include <apt-pkg/cacheiterators.h>
10 #include <apt-pkg/cacheset.h>
11 #include <apt-pkg/cmndline.h>
12 #include <apt-pkg/configuration.h>
13 #include <apt-pkg/depcache.h>
14 #include <apt-pkg/error.h>
15 #include <apt-pkg/fileutl.h>
16 #include <apt-pkg/hashes.h>
17 #include <apt-pkg/indexfile.h>
18 #include <apt-pkg/metaindex.h>
19 #include <apt-pkg/pkgcache.h>
20 #include <apt-pkg/sourcelist.h>
21 #include <apt-pkg/srcrecords.h>
22 #include <apt-pkg/strutl.h>
23 #include <apt-pkg/version.h>
25 #include <apt-private/private-cachefile.h>
26 #include <apt-private/private-cacheset.h>
27 #include <apt-private/private-download.h>
28 #include <apt-private/private-install.h>
29 #include <apt-private/private-source.h>
46 // TryToInstallBuildDep - Try to install a single package /*{{{*/
47 // ---------------------------------------------------------------------
48 /* This used to be inlined in DoInstall, but with the advent of regex package
49 name matching it was split out.. */
50 static bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg
,pkgCacheFile
&Cache
,
51 pkgProblemResolver
&Fix
,bool Remove
,bool BrokenFix
,
52 bool AllowFail
= true)
54 if (Cache
[Pkg
].CandidateVer
== 0 && Pkg
->ProvidesList
!= 0)
56 CacheSetHelperAPTGet
helper(c1out
);
57 helper
.showErrors(false);
58 pkgCache::VerIterator Ver
= helper
.canNotFindNewestVer(Cache
, Pkg
);
59 if (Ver
.end() == false)
60 Pkg
= Ver
.ParentPkg();
61 else if (helper
.showVirtualPackageErrors(Cache
) == false)
65 if (_config
->FindB("Debug::BuildDeps",false) == true)
68 std::cout
<< " Trying to remove " << Pkg
<< std::endl
;
70 std::cout
<< " Trying to install " << Pkg
<< std::endl
;
75 TryToRemove
RemoveAction(Cache
, &Fix
);
76 RemoveAction(Pkg
.VersionList());
77 } else if (Cache
[Pkg
].CandidateVer
!= 0) {
78 TryToInstall
InstallAction(Cache
, &Fix
, BrokenFix
);
79 InstallAction(Cache
[Pkg
].CandidateVerIter(Cache
));
80 InstallAction
.doAutoInstall();
87 // GetReleaseFileForSourceRecord - Return Suite for the given srcrecord /*{{{*/
88 static pkgCache::RlsFileIterator
GetReleaseFileForSourceRecord(CacheFile
&CacheFile
,
89 pkgSourceList
*SrcList
, pkgSrcRecords::Parser
*Parse
)
91 // try to find release
92 const pkgIndexFile
& CurrentIndexFile
= Parse
->Index();
94 for (pkgSourceList::const_iterator S
= SrcList
->begin();
95 S
!= SrcList
->end(); ++S
)
97 std::vector
<pkgIndexFile
*> *Indexes
= (*S
)->GetIndexFiles();
98 for (std::vector
<pkgIndexFile
*>::const_iterator IF
= Indexes
->begin();
99 IF
!= Indexes
->end(); ++IF
)
101 if (&CurrentIndexFile
== (*IF
))
102 return (*S
)->FindInCache(CacheFile
, false);
105 return pkgCache::RlsFileIterator(CacheFile
);
108 // FindSrc - Find a source record /*{{{*/
109 static pkgSrcRecords::Parser
*FindSrc(const char *Name
,
110 pkgSrcRecords
&SrcRecs
,std::string
&Src
,
111 CacheFile
&CacheFile
)
113 std::string VerTag
, UserRequestedVerTag
;
114 std::string ArchTag
= "";
115 std::string RelTag
= _config
->Find("APT::Default-Release");
116 std::string TmpSrc
= Name
;
117 pkgDepCache
*Cache
= CacheFile
.GetDepCache();
120 size_t found
= TmpSrc
.find_last_of("/");
121 if (found
!= std::string::npos
)
123 RelTag
= TmpSrc
.substr(found
+1);
124 TmpSrc
= TmpSrc
.substr(0,found
);
126 // extract the version
127 found
= TmpSrc
.find_last_of("=");
128 if (found
!= std::string::npos
)
130 VerTag
= UserRequestedVerTag
= TmpSrc
.substr(found
+1);
131 TmpSrc
= TmpSrc
.substr(0,found
);
134 found
= TmpSrc
.find_last_of(":");
135 if (found
!= std::string::npos
)
137 ArchTag
= TmpSrc
.substr(found
+1);
138 TmpSrc
= TmpSrc
.substr(0,found
);
141 /* Lookup the version of the package we would install if we were to
142 install a version and determine the source package name, then look
143 in the archive for a source package of the same name. */
144 bool MatchSrcOnly
= _config
->FindB("APT::Get::Only-Source");
145 pkgCache::PkgIterator Pkg
;
147 Pkg
= Cache
->FindPkg(TmpSrc
, ArchTag
);
149 Pkg
= Cache
->FindPkg(TmpSrc
);
151 // if we can't find a package but the user qualified with a arch,
153 if (Pkg
.end() && ArchTag
!= "")
156 _error
->Error(_("Can not find a package for architecture '%s'"),
161 if (MatchSrcOnly
== false && Pkg
.end() == false)
163 if(VerTag
!= "" || RelTag
!= "" || ArchTag
!= "")
166 // we have a default release, try to locate the pkg. we do it like
167 // this because GetCandidateVer() will not "downgrade", that means
168 // "apt-get source -t stable apt" won't work on a unstable system
169 for (pkgCache::VerIterator Ver
= Pkg
.VersionList();; ++Ver
)
171 // try first only exact matches, later fuzzy matches
172 if (Ver
.end() == true)
177 Ver
= Pkg
.VersionList();
178 // exit right away from the Pkg.VersionList() loop if we
179 // don't have any versions
180 if (Ver
.end() == true)
184 // ignore arches that are not for us
185 if (ArchTag
!= "" && Ver
.Arch() != ArchTag
)
188 // pick highest version for the arch unless the user wants
190 if (ArchTag
!= "" && VerTag
== "" && RelTag
== "")
191 if(Cache
->VS().CmpVersion(VerTag
, Ver
.VerStr()) < 0)
192 VerTag
= Ver
.VerStr();
194 // We match against a concrete version (or a part of this version)
195 if (VerTag
.empty() == false &&
196 (fuzzy
== true || Cache
->VS().CmpVersion(VerTag
, Ver
.VerStr()) != 0) && // exact match
197 (fuzzy
== false || strncmp(VerTag
.c_str(), Ver
.VerStr(), VerTag
.size()) != 0)) // fuzzy match
200 for (pkgCache::VerFileIterator VF
= Ver
.FileList();
201 VF
.end() == false; ++VF
)
203 /* If this is the status file, and the current version is not the
204 version in the status file (ie it is not installed, or somesuch)
205 then it is not a candidate for installation, ever. This weeds
206 out bogus entries that may be due to config-file states, or
208 if ((VF
.File()->Flags
& pkgCache::Flag::NotSource
) ==
209 pkgCache::Flag::NotSource
&& Pkg
.CurrentVer() != Ver
)
212 // or we match against a release
213 if(VerTag
.empty() == false ||
214 (VF
.File().Archive() != 0 && VF
.File().Archive() == RelTag
) ||
215 (VF
.File().Codename() != 0 && VF
.File().Codename() == RelTag
))
217 // the Version we have is possibly fuzzy or includes binUploads,
218 // so we use the Version of the SourcePkg (empty if same as package)
219 Src
= Ver
.SourcePkgName();
220 VerTag
= Ver
.SourceVerStr();
224 if (Src
.empty() == false)
229 if (Src
== "" && ArchTag
!= "")
232 _error
->Error(_("Can not find a package '%s' with version '%s'"),
233 Pkg
.FullName().c_str(), VerTag
.c_str());
235 _error
->Error(_("Can not find a package '%s' with release '%s'"),
236 Pkg
.FullName().c_str(), RelTag
.c_str());
242 if (Src
.empty() == true)
244 // if we don't have found a fitting package yet so we will
245 // choose a good candidate and proceed with that.
246 // Maybe we will find a source later on with the right VerTag
248 pkgCache::VerIterator
const Ver
= Cache
->GetCandidateVersion(Pkg
);
249 if (Ver
.end() == false)
251 if (strcmp(Ver
.SourcePkgName(),Ver
.ParentPkg().Name()) != 0)
252 Src
= Ver
.SourcePkgName();
253 if (VerTag
.empty() == true && strcmp(Ver
.SourceVerStr(),Ver
.VerStr()) != 0)
254 VerTag
= Ver
.SourceVerStr();
259 if (Src
.empty() == true)
265 /* if we have a source pkg name, make sure to only search
266 for srcpkg names, otherwise apt gets confused if there
267 is a binary package "pkg1" and a source package "pkg1"
268 with the same name but that comes from different packages */
272 ioprintf(c1out
, _("Picking '%s' as source package instead of '%s'\n"), Src
.c_str(), TmpSrc
.c_str());
277 pkgSrcRecords::Parser
*Last
= 0;
278 unsigned long Offset
= 0;
280 pkgSourceList
*SrcList
= CacheFile
.GetSourceList();
282 /* Iterate over all of the hits, which includes the resulting
283 binary packages in the search */
284 pkgSrcRecords::Parser
*Parse
;
288 while ((Parse
= SrcRecs
.Find(Src
.c_str(), MatchSrcOnly
)) != 0)
290 const std::string Ver
= Parse
->Version();
291 bool CorrectRelTag
= false;
293 // See if we need to look for a specific release tag
294 if (RelTag
!= "" && UserRequestedVerTag
== "")
296 pkgCache::RlsFileIterator
const Rls
= GetReleaseFileForSourceRecord(CacheFile
, SrcList
, Parse
);
297 if (Rls
.end() == false)
299 if ((Rls
->Archive
!= 0 && RelTag
== Rls
.Archive()) ||
300 (Rls
->Codename
!= 0 && RelTag
== Rls
.Codename()))
301 CorrectRelTag
= true;
304 CorrectRelTag
= true;
306 // Ignore all versions which doesn't fit
307 if (VerTag
.empty() == false &&
308 Cache
->VS().CmpVersion(VerTag
, Ver
) != 0) // exact match
311 // Newer version or an exact match? Save the hit
312 if (CorrectRelTag
&& (Last
== 0 || Cache
->VS().CmpVersion(Version
,Ver
) < 0)) {
314 Offset
= Parse
->Offset();
318 // was the version check above an exact match?
319 // If so, we don't need to look further
320 if (VerTag
.empty() == false && (VerTag
== Ver
))
323 if (UserRequestedVerTag
== "" && Version
!= "" && RelTag
!= "")
324 ioprintf(c1out
, "Selected version '%s' (%s) for %s\n",
325 Version
.c_str(), RelTag
.c_str(), Src
.c_str());
327 if (Last
!= 0 || VerTag
.empty() == true)
329 _error
->Error(_("Can not find version '%s' of package '%s'"), VerTag
.c_str(), TmpSrc
.c_str());
333 if (Last
== 0 || Last
->Jump(Offset
) == false)
339 // DoSource - Fetch a source archive /*{{{*/
340 // ---------------------------------------------------------------------
341 /* Fetch souce packages */
348 bool DoSource(CommandLine
&CmdL
)
351 if (Cache
.Open(false) == false)
354 if (CmdL
.FileSize() <= 1)
355 return _error
->Error(_("Must specify at least one package to fetch source for"));
357 // Read the source list
358 if (Cache
.BuildSourceList() == false)
360 pkgSourceList
*List
= Cache
.GetSourceList();
362 // Create the text record parsers
363 pkgSrcRecords
SrcRecs(*List
);
364 if (_error
->PendingError() == true)
367 std::unique_ptr
<DscFile
[]> Dsc(new DscFile
[CmdL
.FileSize()]);
369 // insert all downloaded uris into this set to avoid downloading them
371 std::set
<std::string
> queued
;
373 // Diff only mode only fetches .diff files
374 bool const diffOnly
= _config
->FindB("APT::Get::Diff-Only", false);
375 // Tar only mode only fetches .tar files
376 bool const tarOnly
= _config
->FindB("APT::Get::Tar-Only", false);
377 // Dsc only mode only fetches .dsc files
378 bool const dscOnly
= _config
->FindB("APT::Get::Dsc-Only", false);
380 // Load the requestd sources into the fetcher
381 aptAcquireWithTextStatus Fetcher
;
383 std::vector
<std::string
> UntrustedList
;
384 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; I
++, J
++)
387 pkgSrcRecords::Parser
*Last
= FindSrc(*I
,SrcRecs
,Src
,Cache
);
389 return _error
->Error(_("Unable to find a source package for %s"),Src
.c_str());
392 if (Last
->Index().IsTrusted() == false)
393 UntrustedList
.push_back(Src
);
395 std::string srec
= Last
->AsStr();
396 std::string::size_type pos
= srec
.find("\nVcs-");
397 while (pos
!= std::string::npos
)
399 pos
+= strlen("\nVcs-");
400 std::string vcs
= srec
.substr(pos
,srec
.find(":",pos
)-pos
);
403 pos
= srec
.find("\nVcs-", pos
);
406 pos
+= vcs
.length()+2;
407 std::string::size_type epos
= srec
.find("\n", pos
);
408 std::string
const uri
= srec
.substr(pos
,epos
-pos
);
409 ioprintf(c1out
, _("NOTICE: '%s' packaging is maintained in "
410 "the '%s' version control system at:\n"
412 Src
.c_str(), vcs
.c_str(), uri
.c_str());
415 vcscmd
= "bzr branch " + uri
;
416 else if (vcs
== "Git")
417 vcscmd
= "git clone " + uri
;
419 if (vcscmd
.empty() == false)
420 ioprintf(c1out
,_("Please use:\n%s\n"
421 "to retrieve the latest (possibly unreleased) "
422 "updates to the package.\n"),
428 std::vector
<pkgSrcRecords::File2
> Lst
;
429 if (Last
->Files2(Lst
) == false) {
433 // Load them into the fetcher
434 for (std::vector
<pkgSrcRecords::File2
>::const_iterator I
= Lst
.begin();
437 // Try to guess what sort of file it is we are getting.
438 if (I
->Type
== "dsc")
440 Dsc
[J
].Package
= Last
->Package();
441 Dsc
[J
].Version
= Last
->Version();
442 Dsc
[J
].Dsc
= flNotDir(I
->Path
);
445 // Handle the only options so that multiple can be used at once
446 if (diffOnly
== true || tarOnly
== true || dscOnly
== true)
448 if ((diffOnly
== true && I
->Type
== "diff") ||
449 (tarOnly
== true && I
->Type
== "tar") ||
450 (dscOnly
== true && I
->Type
== "dsc"))
451 ; // Fine, we want this file downloaded
456 // don't download the same uri twice (should this be moved to
457 // the fetcher interface itself?)
458 if(queued
.find(Last
->Index().ArchiveURI(I
->Path
)) != queued
.end())
460 queued
.insert(Last
->Index().ArchiveURI(I
->Path
));
462 // check if we have a file with that md5 sum already localy
463 std::string localFile
= flNotDir(I
->Path
);
464 if (FileExists(localFile
) == true)
465 if(I
->Hashes
.VerifyFile(localFile
) == true)
467 ioprintf(c1out
,_("Skipping already downloaded file '%s'\n"),
472 // see if we have a hash (Acquire::ForceHash is the only way to have none)
473 if (I
->Hashes
.usable() == false && _config
->FindB("APT::Get::AllowUnauthenticated",false) == false)
475 ioprintf(c1out
, "Skipping download of file '%s' as requested hashsum is not available for authentication\n",
480 new pkgAcqFile(&Fetcher
,Last
->Index().ArchiveURI(I
->Path
),
481 I
->Hashes
, I
->FileSize
, Last
->Index().SourceInfo(*Last
,*I
), Src
);
485 // Display statistics
486 unsigned long long FetchBytes
= Fetcher
.FetchNeeded();
487 unsigned long long FetchPBytes
= Fetcher
.PartialPresent();
488 unsigned long long DebBytes
= Fetcher
.TotalNeeded();
490 if (CheckFreeSpaceBeforeDownload(".", (FetchBytes
- FetchPBytes
)) == false)
494 if (DebBytes
!= FetchBytes
)
495 //TRANSLATOR: The required space between number and unit is already included
496 // in the replacement strings, so %sB will be correctly translate in e.g. 1,5 MB
497 ioprintf(c1out
,_("Need to get %sB/%sB of source archives.\n"),
498 SizeToStr(FetchBytes
).c_str(),SizeToStr(DebBytes
).c_str());
500 //TRANSLATOR: The required space between number and unit is already included
501 // in the replacement string, so %sB will be correctly translate in e.g. 1,5 MB
502 ioprintf(c1out
,_("Need to get %sB of source archives.\n"),
503 SizeToStr(DebBytes
).c_str());
505 if (_config
->FindB("APT::Get::Simulate",false) == true)
507 for (unsigned I
= 0; I
!= J
; I
++)
508 ioprintf(std::cout
,_("Fetch source %s\n"),Dsc
[I
].Package
.c_str());
512 // Just print out the uris an exit if the --print-uris flag was used
513 if (_config
->FindB("APT::Get::Print-URIs") == true)
515 pkgAcquire::UriIterator I
= Fetcher
.UriBegin();
516 for (; I
!= Fetcher
.UriEnd(); ++I
)
517 std::cout
<< '\'' << I
->URI
<< "' " << flNotDir(I
->Owner
->DestFile
) << ' ' <<
518 I
->Owner
->FileSize
<< ' ' << I
->Owner
->HashSum() << std::endl
;
522 // check authentication status of the source as well
523 if (UntrustedList
.empty() == false && AuthPrompt(UntrustedList
, false) == false)
528 if (AcquireRun(Fetcher
, 0, &Failed
, NULL
) == false || Failed
== true)
530 return _error
->Error(_("Failed to fetch some archives."));
533 if (_config
->FindB("APT::Get::Download-only",false) == true)
535 c1out
<< _("Download complete and in download only mode") << std::endl
;
539 // Unpack the sources
540 pid_t Process
= ExecFork();
544 bool const fixBroken
= _config
->FindB("APT::Get::Fix-Broken", false);
545 for (unsigned I
= 0; I
!= J
; ++I
)
547 std::string Dir
= Dsc
[I
].Package
+ '-' + Cache
->VS().UpstreamVersion(Dsc
[I
].Version
.c_str());
549 // Diff only mode only fetches .diff files
550 if (_config
->FindB("APT::Get::Diff-Only",false) == true ||
551 _config
->FindB("APT::Get::Tar-Only",false) == true ||
552 Dsc
[I
].Dsc
.empty() == true)
555 // See if the package is already unpacked
557 if (fixBroken
== false && stat(Dir
.c_str(),&Stat
) == 0 &&
558 S_ISDIR(Stat
.st_mode
) != 0)
560 ioprintf(c0out
,_("Skipping unpack of already unpacked source in %s\n"),
566 std::string
const sourceopts
= _config
->Find("DPkg::Source-Options", "-x");
568 strprintf(S
, "%s %s %s",
569 _config
->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(),
570 sourceopts
.c_str(), Dsc
[I
].Dsc
.c_str());
571 if (system(S
.c_str()) != 0)
573 fprintf(stderr
, _("Unpack command '%s' failed.\n"), S
.c_str());
574 fprintf(stderr
, _("Check if the 'dpkg-dev' package is installed.\n"));
579 // Try to compile it with dpkg-buildpackage
580 if (_config
->FindB("APT::Get::Compile",false) == true)
582 std::string buildopts
= _config
->Find("APT::Get::Host-Architecture");
583 if (buildopts
.empty() == false)
584 buildopts
= "-a" + buildopts
+ " ";
586 // get all active build profiles
587 std::string
const profiles
= APT::Configuration::getBuildProfilesString();
588 if (profiles
.empty() == false)
589 buildopts
.append(" -P").append(profiles
).append(" ");
591 buildopts
.append(_config
->Find("DPkg::Build-Options","-b -uc"));
593 // Call dpkg-buildpackage
595 strprintf(S
, "cd %s && %s %s",
597 _config
->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(),
600 if (system(S
.c_str()) != 0)
602 fprintf(stderr
, _("Build command '%s' failed.\n"), S
.c_str());
611 return ExecWait(Process
, "dpkg-source");
614 // InstallBuildDepsLoop /*{{{*/
615 static bool InstallBuildDepsLoop(CacheFile
&Cache
, std::string
const &Src
,
616 std::vector
<pkgSrcRecords::Parser::BuildDepRec
> const &BuildDeps
,
617 bool const StripMultiArch
, std::string
const &hostArch
)
619 // Install the requested packages
620 std::vector
<pkgSrcRecords::Parser::BuildDepRec
>::const_iterator D
;
621 pkgProblemResolver
Fix(Cache
);
622 bool skipAlternatives
= false; // skip remaining alternatives in an or group
623 for (D
= BuildDeps
.begin(); D
!= BuildDeps
.end(); ++D
)
625 bool hasAlternatives
= (((*D
).Op
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
);
627 if (skipAlternatives
== true)
630 * if there are alternatives, we've already picked one, so skip
633 * TODO: this means that if there's a build-dep on A|B and B is
634 * installed, we'll still try to install A; more importantly,
635 * if A is currently broken, we cannot go back and try B. To fix
636 * this would require we do a Resolve cycle for each package we
637 * add to the install list. Ugh
639 if (!hasAlternatives
)
640 skipAlternatives
= false; // end of or group
644 if ((*D
).Type
== pkgSrcRecords::Parser::BuildConflict
||
645 (*D
).Type
== pkgSrcRecords::Parser::BuildConflictIndep
)
647 pkgCache::GrpIterator Grp
= Cache
->FindGrp((*D
).Package
);
648 // Build-conflicts on unknown packages are silently ignored
649 if (Grp
.end() == true)
652 for (pkgCache::PkgIterator Pkg
= Grp
.PackageList(); Pkg
.end() == false; Pkg
= Grp
.NextPkg(Pkg
))
654 pkgCache::VerIterator IV
= (*Cache
)[Pkg
].InstVerIter(*Cache
);
656 * Remove if we have an installed version that satisfies the
659 if (IV
.end() == false &&
660 Cache
->VS().CheckDep(IV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == true)
661 TryToInstallBuildDep(Pkg
,Cache
,Fix
,true,false);
664 else // BuildDep || BuildDepIndep
666 if (_config
->FindB("Debug::BuildDeps",false) == true)
667 std::cout
<< "Looking for " << (*D
).Package
<< "...\n";
669 pkgCache::PkgIterator Pkg
;
672 if (StripMultiArch
== false && D
->Type
!= pkgSrcRecords::Parser::BuildDependIndep
)
674 size_t const colon
= D
->Package
.find(":");
675 if (colon
!= std::string::npos
)
677 if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0 || strcmp(D
->Package
.c_str() + colon
, ":native") == 0)
678 Pkg
= Cache
->FindPkg(D
->Package
.substr(0,colon
));
680 Pkg
= Cache
->FindPkg(D
->Package
);
683 Pkg
= Cache
->FindPkg(D
->Package
, hostArch
);
685 // a bad version either is invalid or doesn't satify dependency
686 #define BADVER(Ver) (Ver.end() == true || \
687 (D->Version.empty() == false && \
688 Cache->VS().CheckDep(Ver.VerStr(),D->Op,D->Version.c_str()) == false))
690 APT::VersionList verlist
;
691 if (Pkg
.end() == false)
693 pkgCache::VerIterator Ver
= (*Cache
)[Pkg
].InstVerIter(*Cache
);
694 if (BADVER(Ver
) == false)
696 Ver
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
697 if (BADVER(Ver
) == false)
700 if (verlist
.empty() == true)
702 pkgCache::PkgIterator BuildPkg
= Cache
->FindPkg(D
->Package
, "native");
703 if (BuildPkg
.end() == false && Pkg
!= BuildPkg
)
705 pkgCache::VerIterator Ver
= (*Cache
)[BuildPkg
].InstVerIter(*Cache
);
706 if (BADVER(Ver
) == false)
708 Ver
= (*Cache
)[BuildPkg
].CandidateVerIter(*Cache
);
709 if (BADVER(Ver
) == false)
715 std::string forbidden
;
716 // We need to decide if host or build arch, so find a version we can look at
717 APT::VersionList::const_iterator Ver
= verlist
.begin();
718 for (; Ver
!= verlist
.end(); ++Ver
)
721 if (Ver
->MultiArch
== pkgCache::Version::No
|| Ver
->MultiArch
== pkgCache::Version::All
)
723 if (colon
== std::string::npos
)
724 Pkg
= Ver
.ParentPkg().Group().FindPkg(hostArch
);
725 else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0)
726 forbidden
= "Multi-Arch: no";
727 else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0)
728 Pkg
= Ver
.ParentPkg().Group().FindPkg("native");
730 else if (Ver
->MultiArch
== pkgCache::Version::Same
)
732 if (colon
== std::string::npos
)
733 Pkg
= Ver
.ParentPkg().Group().FindPkg(hostArch
);
734 else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0)
735 forbidden
= "Multi-Arch: same";
736 else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0)
737 Pkg
= Ver
.ParentPkg().Group().FindPkg("native");
739 else if ((Ver
->MultiArch
& pkgCache::Version::Foreign
) == pkgCache::Version::Foreign
)
741 if (colon
== std::string::npos
)
742 Pkg
= Ver
.ParentPkg().Group().FindPkg("native");
743 else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0 ||
744 strcmp(D
->Package
.c_str() + colon
, ":native") == 0)
745 forbidden
= "Multi-Arch: foreign";
747 else if ((Ver
->MultiArch
& pkgCache::Version::Allowed
) == pkgCache::Version::Allowed
)
749 if (colon
== std::string::npos
)
750 Pkg
= Ver
.ParentPkg().Group().FindPkg(hostArch
);
751 else if (strcmp(D
->Package
.c_str() + colon
, ":any") == 0)
753 // prefer any installed over preferred non-installed architectures
754 pkgCache::GrpIterator Grp
= Ver
.ParentPkg().Group();
755 // we don't check for version here as we are better of with upgrading than remove and install
756 for (Pkg
= Grp
.PackageList(); Pkg
.end() == false; Pkg
= Grp
.NextPkg(Pkg
))
757 if (Pkg
.CurrentVer().end() == false)
759 if (Pkg
.end() == true)
760 Pkg
= Grp
.FindPreferredPkg(true);
762 else if (strcmp(D
->Package
.c_str() + colon
, ":native") == 0)
763 Pkg
= Ver
.ParentPkg().Group().FindPkg("native");
766 if (forbidden
.empty() == false)
768 if (_config
->FindB("Debug::BuildDeps",false) == true)
769 std::cout
<< D
->Package
.substr(colon
, std::string::npos
) << " is not allowed from " << forbidden
<< " package " << (*D
).Package
<< " (" << Ver
.VerStr() << ")" << std::endl
;
773 //we found a good version
776 if (Ver
== verlist
.end())
778 if (_config
->FindB("Debug::BuildDeps",false) == true)
779 std::cout
<< " No multiarch info as we have no satisfying installed nor candidate for " << D
->Package
<< " on build or host arch" << std::endl
;
781 if (forbidden
.empty() == false)
785 return _error
->Error(_("%s dependency for %s can't be satisfied "
786 "because %s is not allowed on '%s' packages"),
787 pkgSrcRecords::Parser::BuildDepType(D
->Type
), Src
.c_str(),
788 D
->Package
.c_str(), forbidden
.c_str());
793 Pkg
= Cache
->FindPkg(D
->Package
);
795 if (Pkg
.end() == true || (Pkg
->VersionList
== 0 && Pkg
->ProvidesList
== 0))
797 if (_config
->FindB("Debug::BuildDeps",false) == true)
798 std::cout
<< " (not found)" << (*D
).Package
<< std::endl
;
803 return _error
->Error(_("%s dependency for %s cannot be satisfied "
804 "because the package %s cannot be found"),
805 pkgSrcRecords::Parser::BuildDepType(D
->Type
), Src
.c_str(),
806 (*D
).Package
.c_str());
809 pkgCache::VerIterator IV
= (*Cache
)[Pkg
].InstVerIter(*Cache
);
810 if (IV
.end() == false)
812 if (_config
->FindB("Debug::BuildDeps",false) == true)
813 std::cout
<< " Is installed\n";
815 if (D
->Version
.empty() == true ||
816 Cache
->VS().CheckDep(IV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == true)
818 skipAlternatives
= hasAlternatives
;
822 if (_config
->FindB("Debug::BuildDeps",false) == true)
823 std::cout
<< " ...but the installed version doesn't meet the version requirement\n";
825 if (((*D
).Op
& pkgCache::Dep::LessEq
) == pkgCache::Dep::LessEq
)
826 return _error
->Error(_("Failed to satisfy %s dependency for %s: Installed package %s is too new"),
827 pkgSrcRecords::Parser::BuildDepType(D
->Type
), Src
.c_str(), Pkg
.FullName(true).c_str());
830 // Only consider virtual packages if there is no versioned dependency
831 if ((*D
).Version
.empty() == true)
834 * If this is a virtual package, we need to check the list of
835 * packages that provide it and see if any of those are
838 pkgCache::PrvIterator Prv
= Pkg
.ProvidesList();
839 for (; Prv
.end() != true; ++Prv
)
841 if (_config
->FindB("Debug::BuildDeps",false) == true)
842 std::cout
<< " Checking provider " << Prv
.OwnerPkg().FullName() << std::endl
;
844 if ((*Cache
)[Prv
.OwnerPkg()].InstVerIter(*Cache
).end() == false)
848 if (Prv
.end() == false)
850 if (_config
->FindB("Debug::BuildDeps",false) == true)
851 std::cout
<< " Is provided by installed package " << Prv
.OwnerPkg().FullName() << std::endl
;
852 skipAlternatives
= hasAlternatives
;
856 else // versioned dependency
858 pkgCache::VerIterator CV
= (*Cache
)[Pkg
].CandidateVerIter(*Cache
);
859 if (CV
.end() == true ||
860 Cache
->VS().CheckDep(CV
.VerStr(),(*D
).Op
,(*D
).Version
.c_str()) == false)
864 else if (CV
.end() == false)
865 return _error
->Error(_("%s dependency for %s cannot be satisfied "
866 "because candidate version of package %s "
867 "can't satisfy version requirements"),
868 pkgSrcRecords::Parser::BuildDepType(D
->Type
), Src
.c_str(),
871 return _error
->Error(_("%s dependency for %s cannot be satisfied "
872 "because package %s has no candidate version"),
873 pkgSrcRecords::Parser::BuildDepType(D
->Type
), Src
.c_str(),
878 if (TryToInstallBuildDep(Pkg
,Cache
,Fix
,false,false,false) == true)
880 // We successfully installed something; skip remaining alternatives
881 skipAlternatives
= hasAlternatives
;
882 if(_config
->FindB("APT::Get::Build-Dep-Automatic", false) == true)
883 Cache
->MarkAuto(Pkg
, true);
886 else if (hasAlternatives
)
888 if (_config
->FindB("Debug::BuildDeps",false) == true)
889 std::cout
<< " Unsatisfiable, trying alternatives\n";
894 return _error
->Error(_("Failed to satisfy %s dependency for %s: %s"),
895 pkgSrcRecords::Parser::BuildDepType(D
->Type
),
897 (*D
).Package
.c_str());
902 if (Fix
.Resolve(true) == false)
905 // Now we check the state of the packages,
906 if (Cache
->BrokenCount() != 0)
908 ShowBroken(std::cout
, Cache
, false);
909 return _error
->Error(_("Build-dependencies for %s could not be satisfied."), Src
.c_str());
914 // DoBuildDep - Install/removes packages to satisfy build dependencies /*{{{*/
915 // ---------------------------------------------------------------------
916 /* This function will look at the build depends list of the given source
917 package and install the necessary packages to make it true, or fail. */
918 static std::vector
<pkgSrcRecords::Parser::BuildDepRec
> GetBuildDeps(pkgSrcRecords::Parser
* const Last
,
919 char const * const Src
, bool const StripMultiArch
, std::string
const &hostArch
)
921 std::vector
<pkgSrcRecords::Parser::BuildDepRec
> BuildDeps
;
922 // FIXME: Can't specify architecture to use for [wildcard] matching, so switch default arch temporary
923 if (hostArch
.empty() == false)
925 std::string nativeArch
= _config
->Find("APT::Architecture");
926 _config
->Set("APT::Architecture", hostArch
);
927 bool Success
= Last
->BuildDepends(BuildDeps
, _config
->FindB("APT::Get::Arch-Only", false), StripMultiArch
);
928 _config
->Set("APT::Architecture", nativeArch
);
929 if (Success
== false)
931 _error
->Error(_("Unable to get build-dependency information for %s"), Src
);
935 else if (Last
->BuildDepends(BuildDeps
, _config
->FindB("APT::Get::Arch-Only", false), StripMultiArch
) == false)
937 _error
->Error(_("Unable to get build-dependency information for %s"), Src
);
941 if (BuildDeps
.empty() == true)
942 ioprintf(c1out
,_("%s has no build depends.\n"), Src
);
946 bool DoBuildDep(CommandLine
&CmdL
)
949 std::vector
<char const *> VolatileCmdL
;
950 Cache
.GetSourceList()->AddVolatileFiles(CmdL
, &VolatileCmdL
);
952 _config
->Set("APT::Install-Recommends", false);
954 bool WantLock
= _config
->FindB("APT::Get::Print-URIs", false) == false;
956 if (Cache
.Open(WantLock
) == false)
959 if (CmdL
.FileSize() <= 1 && VolatileCmdL
.empty())
960 return _error
->Error(_("Must specify at least one package to check builddeps for"));
963 std::string hostArch
= _config
->Find("APT::Get::Host-Architecture");
964 if (hostArch
.empty() == false)
966 std::vector
<std::string
> archs
= APT::Configuration::getArchitectures();
967 if (std::find(archs
.begin(), archs
.end(), hostArch
) == archs
.end())
968 return _error
->Error(_("No architecture information available for %s. See apt.conf(5) APT::Architectures for setup"), hostArch
.c_str());
969 StripMultiArch
= false;
972 StripMultiArch
= true;
974 // deal with the build essentials first
976 std::vector
<pkgSrcRecords::Parser::BuildDepRec
> BuildDeps
;
978 Configuration::Item
const *Opts
= _config
->Tree("APT::Build-Essential");
981 for (; Opts
; Opts
= Opts
->Next
)
983 if (Opts
->Value
.empty() == true)
986 pkgSrcRecords::Parser::BuildDepRec rec
;
987 rec
.Package
= Opts
->Value
;
988 rec
.Type
= pkgSrcRecords::Parser::BuildDependIndep
;
990 BuildDeps
.push_back(rec
);
993 if (InstallBuildDepsLoop(Cache
, "APT::Build-Essential", BuildDeps
, StripMultiArch
, hostArch
) == false)
997 // Read the source list
998 if (Cache
.BuildSourceList() == false)
1000 pkgSourceList
*List
= Cache
.GetSourceList();
1002 // FIXME: Avoid volatile sources == cmdline assumption
1004 auto const VolatileSources
= List
->GetVolatileFiles();
1005 if (VolatileSources
.size() == VolatileCmdL
.size())
1007 for (size_t i
= 0; i
< VolatileSources
.size(); ++i
)
1009 char const * const Src
= VolatileCmdL
[i
];
1010 if (DirectoryExists(Src
))
1011 ioprintf(c1out
, _("Note, using directory '%s' to get the build dependencies\n"), Src
);
1013 ioprintf(c1out
, _("Note, using file '%s' to get the build dependencies\n"), Src
);
1014 std::unique_ptr
<pkgSrcRecords::Parser
> Last(VolatileSources
[i
]->CreateSrcParser());
1015 if (Last
== nullptr)
1016 return _error
->Error(_("Unable to find a source package for %s"), Src
);
1018 auto const BuildDeps
= GetBuildDeps(Last
.get(), Src
, StripMultiArch
, hostArch
);
1019 if (InstallBuildDepsLoop(Cache
, Src
, BuildDeps
, StripMultiArch
, hostArch
) == false)
1024 _error
->Error("Implementation error: Volatile sources (%lu) and commandline elements (%lu) do not match!", VolatileSources
.size(), VolatileCmdL
.size());
1027 if (CmdL
.FileList
[1] != 0)
1029 // Create the text record parsers
1030 pkgSrcRecords
SrcRecs(*List
);
1031 if (_error
->PendingError() == true)
1033 for (const char **I
= CmdL
.FileList
+ 1; *I
!= 0; ++I
)
1036 pkgSrcRecords::Parser
* const Last
= FindSrc(*I
,SrcRecs
,Src
,Cache
);
1037 if (Last
== nullptr)
1038 return _error
->Error(_("Unable to find a source package for %s"), *I
);
1040 auto const BuildDeps
= GetBuildDeps(Last
, Src
.c_str(), StripMultiArch
, hostArch
);
1041 if (InstallBuildDepsLoop(Cache
, Src
, BuildDeps
, StripMultiArch
, hostArch
) == false)
1046 if (_error
->PendingError() || InstallPackages(Cache
, false, true) == false)
1047 return _error
->Error(_("Failed to process build dependencies"));