1 |
On Tue, 30 Jan 2007 17:06:51 +0100 |
2 |
Marius Mauch <genone@g.o> wrote: |
3 |
|
4 |
> Sometimes a package has to depend on a specific version of a slotted |
5 |
> package being the "active" one to build correctly, like in the |
6 |
> current "tr1" discussion on -dev [1] or with packages that depend on |
7 |
> the running kernel. |
8 |
|
9 |
Just to note, since you mentioned both "build" and "running" in the same |
10 |
sentence, that there can be various types of dependency here. |
11 |
|
12 |
Some dependencies will be pure build-time dependencies (for example, |
13 |
app-emulation/qemu needs gcc-3 to build) whereas others will be run-time |
14 |
dependencies (availability of >gcc-4.1 tr1 library when executing the |
15 |
emerged package, inclusion of a particular kernel configuration |
16 |
switch on the target). That gives you active BDEPENDs and active |
17 |
RDEPENDs to consider. Often there will be elements of both - the gcc-4 |
18 |
tr1 dependency may require the compiler to be gcc-4.1, and the target to |
19 |
also contain the gcc-4.1 tr1 library for example. |
20 |
|
21 |
> Currently this isn't really possible, however I while ago I got an |
22 |
> idea how to solve this. Keep in mind this is just a rough idea and |
23 |
> I'm pretty sure some people can/will point out why it is a stupid |
24 |
> idea, but anyway: |
25 |
> |
26 |
> The idea is to add a special category (let's call it "active" for |
27 |
> now) that has the following properties: |
28 |
> - this category doesn't exist in portdir or vdb (= no ebuilds) |
29 |
> - when portage ($pkgmanager) encounters a "active/foo" atom in a |
30 |
> dependency string it executes some special code (e.g. |
31 |
> "$PORTDIR/scripts/active-check/foo =active/foo-1") to determine if |
32 |
> that atom is satisfied |
33 |
|
34 |
This could also be done as an entry point in the ebuild (e.g. |
35 |
pkg_active()) - assuming you can source an ebuild when calculating |
36 |
dependencies. Not sure if that would be better or worse. |
37 |
|
38 |
Either way, these scripts need to be able to deal with the |
39 |
build-time/run-time difference I mentioned above. This comes down to |
40 |
defining the syntax of calling pkg_active() (or the script, for that |
41 |
matter) - e.g. "pkg_active RDEPEND >4.1" |
42 |
|
43 |
Also it's unclear what you intend 'foo' to be - it could be the name of |
44 |
the package that is being checked for active-ness (e.g. 'gcc' - |
45 |
returning true if the required version is active) or it could be |
46 |
related to the package that needs various things active (e.g. |
47 |
'qemu', returning true if gcc-3 is active), or it could be generic |
48 |
(e.g. 'gcc-provides-tr1', returning true if the currently active gcc |
49 |
provides the tr1 library). |
50 |
|
51 |
|
52 |
Next, what do you do if the atom is not satisfied? |
53 |
|
54 |
For normal depends, it would add the required package to the list of |
55 |
stuff to be emerged. That can't happen here, so I guess you'd handle |
56 |
it somewhat like a blocker or mask error. So the difference between |
57 |
this idea, and the current way to handle it (script a build-time check |
58 |
in pkg_setup() fex) is that you find out about the build problem |
59 |
earlier. This is nice, but I don't think it's a significant benefit. |
60 |
|
61 |
Worth bearing in mind that you will be able to get conflicting active |
62 |
dependencies - e.g. 'emerge world' trying to build both |
63 |
app-emulation/qemu (which requires gcc-3 active) and one of these tr1 |
64 |
packages (requiring >gcc-4.1 active). |
65 |
|
66 |
|
67 |
On a general note, introducing dynamic dependencies into the depgraph |
68 |
worries me, although I'm not sure I can articulate why. Currently, |
69 |
everything is static (you can parse the tree, and you get the exact |
70 |
same depgraph on all systems for a given set of USE flags, no matter |
71 |
what), and dynamic requirements must be dealt with at build time |
72 |
(pkg_setup()). Implementing dynamic dependencies means that the |
73 |
depgraph now depends on the host and target systems, as well as the |
74 |
tree. This is a big conceptual change, so I would urge caution. |
75 |
|
76 |
|
77 |
Hmm; one could get the same benefit by introducing a new interface |
78 |
(e.g. pkg_env_check()) which is defined to return true if the |
79 |
environment is ok, false otherwise (with some text to stdout, perhaps). |
80 |
The package manager would then run this function, after building the |
81 |
depgraph and finding the candidate packages to merge, for each |
82 |
candidate package - if any package fails is env_check, none of the |
83 |
packages get emerged. Note this is then completely independent of |
84 |
depgraph creation. |
85 |
|
86 |
In the 'tr1' example, I'd imagine something like this: |
87 |
|
88 |
use.local.desc: boost: Use boost library for tr1 rather than gcc's. |
89 |
|
90 |
ebuild: |
91 |
|
92 |
... |
93 |
inherit ... toolchain-funcs versionator ... |
94 |
... |
95 |
DEPEND=... boost? ( dev-libs/boost ) ... |
96 |
... |
97 |
pkg_env_check() { |
98 |
use boost && return 0 |
99 |
version_is_at_least "4.1" $(gcc-version) && return 0 |
100 |
echo "Either USE boost, or switch to gcc later than 4.1" |
101 |
} |
102 |
|
103 |
|
104 |
(with a default definition, "pkg_env_check() { return 0; }" ) |
105 |
-- |
106 |
Kevin F. Quinn |