Fink:Major New Feature Plans:InheritedBuildDepends

From the Fink Wiki
Jump to navigation Jump to search

Inherited Build Depends

The idea

Often a package needs not just another package as a BuildDepends, but also a bunch of associated packages. For example, every package that BuildDepends on gtk+2-dev also wants atk1. The solution is for gtk+2-dev to have InheritedBuildDepends:atk1, which will then automagically become a BuildDepends for every package that BDeps on gtk+2-dev.

  • I think we're gonna uncover a huge dependency mess when we implement this (in whatever form). We have cases where foo:Depends:libbiff,libboff, with libbiff:Depends:libbar1 libboff:Depends:libbar2. Formally, that means to compile foo, we may need both libbar1 and libbar2 header packages concurrently, even though that's an impossible situation. Practically, we now install either libbar1 or libbar2 headers and pray that if foo accesses a libbar* symbol as a result of it being exposed by libbiff or libboff and passed back to that lib, the symbol is compatible between the libbar* (or we happen to BuildDepends on the "right" one). That is, we wind up linking foo with -lbar and hoping for the best. It usually works out so far with at most a linker warning, thanks to two-level namespaces and "most" symbols not chaning "that much" between ABIs of a lib. dmacks

The rule

The basic rule for expanding BuildDepends is: If X bdep Y, then X bdep y for all y in IBD(Y). This is applied recursively!


Package: foo
BuildDepends: foo-bdep
InheritedBuildDepends: foo-ibd
Package: bar
BuildDepends: bar-bdep
InheritedBuildDepends: foo, bar-ibd
Package: iggy
BuildDepends: bar

When asked to resolve the build depends, Fink should yeild the following results:

  • foo: foo-bdep, foo-ibd
  • bar: bar-bdep, foo, foo-ibd, bar-ibd
  • iggy: bar, foo, foo-ibd, bar-ibd

Stumbling blocks

  • If IBD applies to the package that lists it (foo:IBD:foo-ibd propagates as foo:BD:foo-ibd) we have to make sure to exclude pkgs from the current build set ("this .info") when doing IBD->BD for building that file. BUG: current BD processor in the engine does this but buildlock does not.
  • I think that duplicate listings of a package with different versions are OK for now, as Fink will always pick the highest version of a package. But this is something to keep in mind!
  • At what level do we want to insert the IBDs? In pkglist*? In get_depends? In resolve_depends?
  • While we're at it, maybe we should rewrite resolve_depends to use the lol model?
  • Are there situations where a pkg that one might use as a Depends would want IBD functionality? Recursing down Depends looking for IBD is a giant mess, so one would have to know this in advance in order to list it as a BuildDepends also. Or we could enforce that IBD is only for BDO:true packages, which would never be a Depends so no problem.
    • I see IBD as a tool only for BDO packages. If it turns out later that it's useful for non-BDO stuff as well, we can deal with that when we get there. (drm's input would be useful here though.)
    • (drm's input) If we also implement the proposed RunTimeDepends, we will have three kinds of depends fields: BD which is only enforced at build time, D which is enforced both at build time and at runtime, and RTD which is enforced only at runtime. At build time, we are relying on dependencies which are specificed in .info files, whereas at runtime we are relying on dependencies which have been written out to .deb files. Now we already recurse on the Depends field at buildtime (and dpkg/apt-get do so at "runtime", i.e., install time for the pkg). The RTD field will be irrelevant at build time. So the only one we need to worry about recursion on is BD. That is the point of IBD, and I don't see how it would ever be applied to entries in the Depends field.
    • (more drm input) So I guess the short answer is: package authors should put into IBD any of the buildtime dependencies which should be inherited but which can't be "Depends". This essentially means BDO packages.
  • Have to store IBD in the .deb and make sure to read IBD of the actual version installed, since the .info present may be for a different revision that has different IBD.
  • Pkgs with IBD will have to Depends:fink (>= wherever it gets implemented) and that fink will have to Depends on dpkg that supports the new field.

Potential extensions

  • After phase_install, parse .pc and .la in each %d and automatically add items to IBD lists:
    • .pc: add pkgs containing .pc for libs listed in Requires field and also "pkgconfig" itself.
    • .la: add pkgs containing .la files listed in dependency_libs field
    • (vasi ponders) NOTE: This could be very annoying for large builds, if we can't know what the actual BDeps are until we've built a whole bunch of stuff.
    • (drm again) I would much rather see this be done by the validator. To make sure we have determinacy in this process, our IBD processing should be limited to stuff which is actually in the .info database at the time of buliding.
    • (dmacks clarifies) This is actually the opposite approach to the current IBD thought...instead of a package declaring IBD ("what does some other package need to link against me?") it would declare BD ("what I need to get built") and then fink would decide what is needed to link against me. Essentially upgrade some BD to IBD.Can't do it both ways in a single pkg magic, gotta list something...that means this is still deterministic at the start of a large build set.

Alternate solution

  • Weaken the "nothing may Depends on a BDO package" policy to "only BDO packages may Depends on a BDO package". Then we can use normal Depends so that a -dev automatically drags along anything else needed to compile against it.
  • Arguments:
    • pro: useful for people using Fink to install -dev for their own (!fink) uses. BDO only works for things compiled within Fink.
    • pro: don't gotta mess with a whole new type of dependency check in the engine.
    • con: creates a hole in the swappy code? Engine may not realize these other things got removed, then tries to install things that depend on them.
  • Implementation plan (CVS tag "bdo_depends", which is only the changed files; all others are the versions that existed at the same time):
    • adjust phase_activate so that when installing a BDO package that conflicts/replaces some other package, do a recursive removal of that other package first. done
    • adjust BDO violation check. done
    • move messages noting recursive-removal into main engine planning stage instead of phase_activate so no secondary confirmation question needed during each install.
    • If we recursive-remove some BDO stuff, then we also have to be able to recursive-install it if it's needed later, no? Vasi
    • Sure. Something that Depends on a thing that got removed (either explicitly or via recursion) would cause the thing that got removed (along with all its dependencies) to get installed. No, I don't have a clever way in mind to automatically reinstall stuff later that got removed automatically (recursively) in the manner of the swappy-code. I really hate our recursive "and forget once we've handled it" dep engine! dmacks