Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Subject: Re: [gentoo-dev] [RFC] Forced/automatic USE flag constraints (codename: ENFORCED_USE)
Date: Mon, 05 Jun 2017 14:10:54
Message-Id: 1496671825.1230.3.camel@gentoo.org
In Reply to: Re: [gentoo-dev] [RFC] Forced/automatic USE flag constraints (codename: ENFORCED_USE) by Alexis Ballier
1 On pon, 2017-06-05 at 09:55 +0200, Alexis Ballier wrote:
2 > On Sun, 4 Jun 2017 10:59:38 +0200
3 > Alexis Ballier <aballier@g.o> wrote:
4 >
5 > > Here's a quick n dirty code to play with, based on yours:
6 > > https://github.com/aballier/required-use
7 >
8 > I've run that on the whole tree (considering all ebuilds with non
9 > empty REQUIRED_USE), some stats:
10 >
11 > $ time python3 classify.py requsel
12 > Stats:
13 > Parse error: 16
14
15 Hmm, how did you get those numbers? I just tested parsing and found only
16 7 unique REQUIRED_USE entries that fail. However, my sample file is
17 only around 1000 entries long, so either I failed to get all of them, or
18 you didn't deduplicate your list ;-). More on it below.
19
20 > Good: 8316
21 > Need topo sort: 140
22 > Cyclic: 57
23 >
24 > real 0m2.996s
25 > user 0m2.950s
26 > sys 0m0.004s
27 >
28 >
29 > Running time is good I think.
30 > Parse error is some nested construct not supported by your parser that
31 > I have not fixed either.
32
33 Yes, the time is great. It means we can actually think about integrating
34 it with repoman/pkgcheck.
35
36 > The cycle is mostly due to:
37 > $ python3 nsolve.py 'llvm? ( gallium ) gallium? ( llvm )'
38 > [...]
39 > toposort.CircularDependencyError: Circular dependencies exist among
40 > these items: {[gallium]? => [llvm]:{[llvm]? => [gallium]}, [llvm]? =>
41 > [gallium]:{[gallium]? => [llvm]}}
42 >
43 >
44 > This is something I had overseen when replacing 'a q'_j is some p_i and
45 > one of q_1 ... q_m might be false' by only 'a q'_j is some p_i'; it can
46 > be replaced without changing anything in the way PM would solve it by
47 > "a q'_j is some p_i and the set of {q_j} is not a subset of q' union
48 > p'" (that is, {q_i} is not trivially true if the 2nd clause is
49 > applied). Extending that, we get those stats:
50
51 I'm not even trying to understand the things you say with indexes but I
52 trust you know what you're doing. For completeness, we need to consider
53 three cross-dependent states:
54
55 a. a? ( b ) b? ( a )
56
57 i.e.:
58
59 y_1 = y_2 = x_1 v x_2
60
61 iow, enabling either of the flags causes both of them being enabled. I'm
62 not sure if we have a valid use case to keep such flags long-term but
63 short-term they could be useful to handle transition periods when
64 upstream merges two features (or makes them cross-dependent) and we want
65 to preserve compatibility with split flags.
66
67 b. !a? ( !b ) !b? ( !a )
68
69 i.e.:
70
71 y_1 = y_2 = x_1 ^ x_2
72
73 iow, you have to enable both flags to keep them enabled. Not sure if we
74 have any valid use case for this.
75
76 c. a? ( b ) !a? ( !b )
77
78 i.e.
79
80 y_1 = y_2 = x_1
81
82 This mostly a reduced result of:
83
84 a? ( || ( b c d ... ) ) !a? ( !b !c !d ... )
85
86 [NB: it would be useful to have a short syntax for that]
87
88 I suspect this will be commonly useful to express provider dependencies,
89 i.e. enforcing a particular constraint for providers only when
90 the feature flag is enabled, and disabling all provider flags when it is
91 not.
92
93 FWICS, my version solves all three cases correctly, and your does not
94 explode on them.
95
96 > I'll let you play with it, but for me it seems this would work quite
97 > nicely.
98 >
99
100 Well, I guess it's time to hit the next level. For a start, we have to
101 handle all-of groups, i.e.:
102
103 ( a b c )
104
105 Stand-alone makes little sense (and little trouble) but as you could
106 have seen it's used nested in other thingies:
107
108 1. || ( ( a b ) ( c d ) e )
109
110 2. ?? ( ( a b ) ( c d ) e )
111
112 3. ^^ ( ( a b ) ( c d ) e )
113
114 For verifying constraints, they are not bad. We just follow the generic
115 rule that the branch evaluates to true if all subexpressions are true. 
116
117 For solving, it might be a little unclear on how to proceed with
118 partially true branches but for the sake of simplicity I would just
119 ignore them and behave as if they were false. That is, case (1) with
120 USE='c' would result in 'a b' being enabled.
121
122 The practical uses I've seen are:
123
124 a. || ( deprecated ( gtk3 introspection ) )
125
126 I guess this one would be equivalent to:
127
128 !gtk3? ( !introspection? ( deprecated ) )
129
130 b. ^^ ( ( !32bit 64bit ) ( 32bit !64bit ) ( 32bit 64bit ) )
131
132 This looks like a crazy way of saying:
133
134 || ( 32bit 64bit )
135
136 c. ^^ ( ( !ruby !s7 ) ( ruby !s7 ) ( !ruby s7 ) )
137
138 This looks like an insane version of:
139
140 ?? ( ruby s7 )
141
142 except that per my solver it just disables both when both are set ;-).
143
144 Not sure if the extra complexity is worth for roughly one valid use
145 case, and a lot of insanity.
146
147 I've pushed a simple update to my parser to account for this. However,
148 it doesn't support replace_nary atm, so it won't work for you.
149
150
151 Of course past that there's a deeper insanity: all those constructs can
152 be nested without limits. Verification is possible, solving maybe -- but
153 I'm not sure if we even want to try to think what the correct solution
154 would be.
155
156 There's only one use of this:
157
158 ?? ( gl3plus ( || ( gles2 gles3 ) ) )
159
160 FWICS, it probably works like this;
161
162  g       g    
163  l       l    
164  3 g g   3 g g
165  p l l   p l l
166  l e e   l e e
167  u s s   u s s
168  s 2 3 | s 2 3
169  0 0 0 | 0 0 0 (==)
170  0 0 1 | 0 0 1 (==)
171  0 1 0 | 0 1 0 (==)
172  0 1 1 | 0 1 1 (==)
173  1 0 0 | 1 0 0 (==)
174  1 0 1 | 1 0 1 [unsolvable due to loop]
175  1 1 0 | 1 1 0 [unsolvable due to loop]
176  1 1 1 | 1 1 1 [unsolvable due to loop]
177
178 i.e. it would be equivalent to:
179
180 gl3plus? ( !gles2 !gles3 )
181
182 unless the author meant something else and failed.
183
184 The question is whether we want to:
185
186 a. actually try to solve this nesting insanity,
187
188 b. declare it unsupported and throw REQUIRED_USE mismatch on user,
189
190 c. ban it altogether.
191
192 --
193 Best regards,
194 Michał Górny

Attachments

File name MIME type
signature.asc application/pgp-signature

Replies