On Tue, 30 Jan 2007 17:06:51 +0100
Marius Mauch <[EMAIL PROTECTED]> wrote:

> Sometimes a package has to depend on a specific version of a slotted
> package being the "active" one to build correctly, like in the
> current "tr1" discussion on -dev [1] or with packages that depend on
> the running kernel.

Just to note, since you mentioned both "build" and "running" in the same
sentence, that there can be various types of dependency here.

Some dependencies will be pure build-time dependencies (for example,
app-emulation/qemu needs gcc-3 to build) whereas others will be run-time
dependencies (availability of >gcc-4.1 tr1 library when executing the
emerged package, inclusion of a particular kernel configuration
switch on the target).  That gives you active BDEPENDs and active
RDEPENDs to consider.  Often there will be elements of both - the gcc-4
tr1 dependency may require the compiler to be gcc-4.1, and the target to
also contain the gcc-4.1 tr1 library for example.

> Currently this isn't really possible, however I while ago I got an
> idea how to solve this. Keep in mind this is just a rough idea and
> I'm pretty sure some people can/will point out why it is a stupid
> idea, but anyway:
> 
> The idea is to add a special category (let's call it "active" for
> now) that has the following properties:
> - this category doesn't exist in portdir or vdb (= no ebuilds)
> - when portage ($pkgmanager) encounters a "active/foo" atom in a
> dependency string it executes some special code (e.g.
> "$PORTDIR/scripts/active-check/foo =active/foo-1") to determine if
> that atom is satisfied

This could also be done as an entry point in the ebuild (e.g.
pkg_active()) - assuming you can source an ebuild when calculating
dependencies.  Not sure if that would be better or worse.

Either way, these scripts need to be able to deal with the
build-time/run-time difference I mentioned above.  This comes down to
defining the syntax of calling pkg_active() (or the script, for that
matter) - e.g. "pkg_active RDEPEND >4.1"

Also it's unclear what you intend 'foo' to be - it could be the name of
the package that is being checked for active-ness (e.g. 'gcc' -
returning true if the required version is active) or it could be
related to the package that needs various things active (e.g.
'qemu', returning true if gcc-3 is active), or it could be generic
(e.g. 'gcc-provides-tr1', returning true if the currently active gcc
provides the tr1 library).


Next, what do you do if the atom is not satisfied?

For normal depends, it would add the required package to the list of
stuff to be emerged.  That can't happen here, so I guess you'd handle
it somewhat like a blocker or mask error.  So the difference between
this idea, and the current way to handle it (script a build-time check
in pkg_setup() fex) is that you find out about the build problem
earlier.  This is nice, but I don't think it's a significant benefit.

Worth bearing in mind that you will be able to get conflicting active
dependencies - e.g. 'emerge world' trying to build both
app-emulation/qemu (which requires gcc-3 active) and one of these tr1
packages (requiring >gcc-4.1 active).


On a general note, introducing dynamic dependencies into the depgraph
worries me, although I'm not sure I can articulate why. Currently,
everything is static (you can parse the tree, and you get the exact
same depgraph on all systems for a given set of USE flags, no matter
what), and dynamic requirements must be dealt with at build time
(pkg_setup()).  Implementing dynamic dependencies means that the
depgraph now depends on the host and target systems, as well as the
tree.  This is a big conceptual change, so I would urge caution.


Hmm; one could get the same benefit by introducing a new interface
(e.g. pkg_env_check()) which is defined to return true if the
environment is ok, false otherwise (with some text to stdout, perhaps).
The package manager would then run this function, after building the
depgraph and finding the candidate packages to merge, for each
candidate package - if any package fails is env_check, none of the
packages get emerged.  Note this is then completely independent of
depgraph creation.

In the 'tr1' example, I'd imagine something like this:

use.local.desc: boost: Use boost library for tr1 rather than gcc's.

ebuild:

...
inherit ... toolchain-funcs versionator ...
...
DEPEND=... boost? ( dev-libs/boost ) ...
...
pkg_env_check() {
        use boost && return 0
        version_is_at_least "4.1" $(gcc-version) && return 0
        echo "Either USE boost, or switch to gcc later than 4.1"
}


(with a default definition, "pkg_env_check() { return 0; }" )
-- 
Kevin F. Quinn

Attachment: signature.asc
Description: PGP signature

Reply via email to