Gentoo Archives: gentoo-dev

From: Alexis Ballier <aballier@g.o>
To: gentoo-dev@l.g.o
Subject: Re: [gentoo-dev] [RFC] Forced/automatic USE flag constraints (codename: ENFORCED_USE)
Date: Thu, 01 Jun 2017 08:55:40
Message-Id: 20170601105523.08a9234e@gentoo.org
In Reply to: Re: [gentoo-dev] [RFC] Forced/automatic USE flag constraints (codename: ENFORCED_USE) by "Michał Górny"
1 On Wed, 31 May 2017 21:02:24 +0200
2 Michał Górny <mgorny@g.o> wrote:
3
4 > On śro, 2017-05-31 at 19:39 +0200, Alexis Ballier wrote:
5 > > > > Again, you *need* to process the constraints in order. '!a?
6 > > > > ( b ) !b? ( a )' is not deterministic when none of a and b are
7 > > > > enabled otherwise.
8 > > >
9 > > > You can't rely on any particular order of constraints, especially
10 > > > when eclass stacking comes into play. You could try defining some
11 > > > constraint- sorting algorithm but it's going to be complex and
12 > > > it's usefulness will be limited anyway due to various kinds of
13 > > > grouping.
14 > >
15 > >
16 > > Better have some order: If half of the above constraint comes from
17 > > ebuild and the other half comes from eclass, then PM might toggle
18 > > 'a' or 'b' depending on the phase of the moon which is specifically
19 > > what we're trying to avoid.
20 >
21 > No, it can't. That's the whole point. The algorithm must be defined so
22 > that it is always predictable independently of order (maybe except
23 > the ordering inside ^^, ||, ??) and independently of how it's nested
24 > (i.e. 'a? ( b? ( c ) )' must give the same result as 'b? ( a? ( c )
25 > )').
26
27 This is a lot of handwaving without real description of how it would
28 work. This starts to look a lot like confluence in rewriting systems
29 and you want developers to write only confluent rules and repoman to
30 decide that. Good luck with that.
31
32 Let's look at real world examples:
33 gtk+:
34
35 REQUIRED_USE="
36 || ( aqua wayland X )
37 xinerama? ( X )
38 "
39
40 Let's assume aqua is masked, which reduces to:
41 REQUIRED_USE="
42 || ( wayland X )
43 xinerama? ( X )
44 "
45
46 With USE='-* xinerama' this one is invalid: applying the first
47 constraint first enables wayland, then the 2nd enables X, giving a
48 result of USE="xinerama wayland X". Applying the 2nd first enables X,
49 then the 1st does nothing, giving a result of USE="xinerama X".
50
51
52 Now the funny one:
53 $ portageq metadata / ebuild dev-lang/php-7.0.18 REQUIRED_USE
54 cli? ( ^^ ( readline libedit ) ) truetype? ( gd ) webp? ( gd ) cjk?
55 ( gd ) exif? ( gd ) xpm? ( gd ) gd? ( zlib ) simplexml? ( xml ) soap?
56 ( xml ) wddx? ( xml ) xmlrpc? ( || ( xml iconv ) ) xmlreader? ( xml )
57 xslt? ( xml ) ldap-sasl? ( ldap ) mhash? ( hash ) phar? ( hash ) qdbm?
58 ( !gdbm ) readline? ( !libedit ) recode? ( !imap !mysqli ) sharedmem?
59 ( !threads ) mysql? ( || ( mysqli pdo ) ) || ( cli cgi fpm apache2
60 embed phpdbg )
61
62
63
64 There are probably dozens of ways to make that non deterministic.
65 Here's one: USE='-*'. Apply '|| ( cli cgi fpm apache2 embed phpdbg )'
66 last; this enables 'cli'. Since it's the last one, REQUIRED_USE is not
67 satisfied because of 'cli? ( ^^ ( readline libedit ) )'.
68 If you process it first, then you enable cli and readline and are good.
69
70 > If you start relying on stuff like ordering, you're one step from
71 > making stuff suddenly fail or change meaning due to minor changes,
72 > like sorting stuff.
73
74 What we want to ensure is that for 2 identical inputs the results are
75 identical. If ordering is specified, then re-ordering REQUIRED_USE in
76 an ebuild is not minor anymore. That's a trade off.
77
78
79 > > eclass stacking is not a problem: specify if it's append or prepend
80 > > and be done.
81 >
82 > What about multiple inherits with guards? Next thing I know, we end up
83 > putting REQUIRED_USE outside guards (like we have to do with
84 > EXPORT_FUNCTIONS now) because you need a specific order, and guards
85 > make it unpredictable.
86
87 guards wont make much of a difference: They'll simply de-duplicate
88 constraints by keeping only the rightmost one in the prepend case and
89 the leftmost one in the append case I think.
90
91 > > Note that if you want to remove the need for an order, you'll need
92 > > to ensure that all orderings of the constraints give the same
93 > > result. It's not sufficient to "only" check all possible inputs.
94 >
95 > That's the matter of the algorithm.
96
97 For what I know, this algorithm does not even exist.
98
99 > > Also, what happens if we applied all the constraints and obtained
100 > > some useflags setting that still fails REQUIRED_USE check ?
101 >
102 > It can't happen. If you can apply all the constraints, then implicitly
103 > REQUIRED_USE is satisfied. If you can't apply all the constraints,
104 > then it just fails. Of course, we want to ultimately avoid that case.
105
106 See the php example above. How do you ensure this does not happen?
107
108 Note that your assertion 'If you can apply all the constraints, then
109 implicitly REQUIRED_USE is satisfied.' is false: You're changing the
110 values of useflags, thus might violate some previously checked
111 constraint.
112
113
114 > > > The point would be: by definition, the solver should be able to
115 > > > touch *any* USE flag. If it can't, it mostly implies that you
116 > > > can't use the automatic solver, and so the case is irrelevant for
117 > > > checking. Attempting to go beyond that is going to give a lot of
118 > > > complexity and most likely kill the whole idea.
119 > > >
120 > > > One thing we need to worry about are masks. We need to think about
121 > > > them.
122 > >
123 > > It makes zero difference for any solver if you replace variables
124 > > (useflags) by 'true' or 'false' constants (masked/forced/user-forced
125 > > useflags). It's even simpler actually. Whether the formula is not
126 > > constantly 'true' (ie REQUIRED_USE is useless) or constantly
127 > > 'false' (ie there's no way to solve it) is equivalent to solving
128 > > SAT. We likely don't want that for repoman running on php.
129 > >
130 >
131 > Well, probably yes. We just need to make sure to apply them correctly
132 > in different contexts, to avoid accidentally skipping some
133 > constraints. I think it would be reasonably to assume that:
134 [...]
135
136 Yes, you can eliminate constants. It is probably even confluent, i.e.
137 the order in which you eliminate them does not matter and it always
138 converges to the same result.
139
140 Alexis.

Replies