Blag

He's not dead, he's resting

EAPI 2: Use Dependencies

This is the second post in a series of posts describing EAPI 2.

Use dependencies have been needed for a very long time. They eliminate most of the built_with_use errors you see during pkg_setup, replacing them with an error that is seen at pretend-install time.

The first two real world trials of use dependencies were with Exherbo‘s exheres-0 and Gentoo‘s kdebuild-1. It became apparent that an awful lot of packages would end up with dependencies like:

blah? ( app-misc/foo[blah] ) !blah? ( app-misc/foo )
monkey? ( app-misc/foo[monkey] ) !monkey? ( app-misc/foo[-monkey] )
fnord? ( app-misc/foo ) !fnord? ( app-misc/foo[-fnord] )

Syntactically, that’s rather inconvenient. For exheres-0 and kdebuild-1, we added the following syntax:

[opt]
The flag must be enabled.
[opt=]
The flag must be enabled if the flag is enabled for the package with the dependency, or disabled otherwise.
[opt!=]
The flag must be disabled if the flag is enabled for the package with the dependency, or enabled otherwise.
[opt?]
The flag must be enabled if the flag is enabled for the package with the dependency.
[opt!?]
The flag must be enabled if the use flag is disabled for the package with the dependency.
[-opt]
The flag must be disabled.
[-opt?]
The flag must be disabled if the flag is enabled for the package with the dependency.
[-opt!?]
The flag must be disabled if the flag is disabled for the package with the dependency.

Dependencies could be combined by specifying multiple blocks, as in foo/bar[baz][monkey?].

For EAPI 2, Zac decided to go with an arbitrarily different syntax:

[opt]
The flag must be enabled.
[opt=]
The flag must be enabled if the flag is enabled for the package with the dependency, or disabled otherwise.
[!opt=]
The flag must be disabled if the flag is enabled for the package with the dependency, or enabled otherwise.
[opt?]
The flag must be enabled if the flag is enabled for the package with the dependency.
[!opt?]
The flag must be disabled if the use flag is disabled for the package with the dependency.
[-opt]
The flag must be disabled.

And to combine use dependencies, one uses a comma, as in foo/bar[baz,monkey?].

In both cases, the slot dependency must go before the dependency, so foo/bar:1[baz], not foo/bar[baz]:1. The use dependency goes after any version restrictions, so >=foo/bar-2.1:2[baz].

In both cases, it is illegal to reference a use flag that does not exist (including USE_EXPAND flags that are not explicitly listed in IUSE). So foo/bar[opt] when any version of foo/bar does not have opt in IUSE is illegal and has undefined behaviour, as is foo/baz[opt?] if either the owning package or foo/baz has no opt. For cases where only some versions of a package have a flag, use dependencies can be combined with version or slot restrictions.

From an implementation perspective: the package manager should not try to automatically solve unmet use dependencies. The package manager doesn’t know the impact of changing a use flag (changing some flags makes a system unbootable), so it can’t simply override the user’s choice. (Paludis will suggest an automatic reinstall if and only if the user has already modified their use.conf, so you don’t need to manually reinstall a dependency if you’re ok with altering the flags with which it is built.)

One response to “EAPI 2: Use Dependencies

  1. Pingback: What’s in EAPI 2? « Ciaran McCreesh’s Blag

Leave a comment