-
Notifications
You must be signed in to change notification settings - Fork 4.1k
/
ActionAnalysisMetadata.java
237 lines (214 loc) · 10.6 KB
/
ActionAnalysisMetadata.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.lib.actions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import java.util.Collection;
import java.util.Map;
import javax.annotation.Nullable;
/**
* An Analysis phase interface for an {@link Action} or Action-like object, containing only
* side-effect-free query methods for information needed during action analysis.
*/
public interface ActionAnalysisMetadata {
/**
* Return this key from {@link #getKey} to signify a failed key computation.
*
* <p>Actions that return this value should fail to execute.
*
* <p>Consumers must either gracefully handle multiple failed actions having the same key,
* (recommended), or check against this value explicitly.
*/
String KEY_ERROR = "1ea50e01-0349-4552-80cf-76cf520e8592";
/**
* Returns the owner of this executable if this executable can supply verbose information. This is
* typically the rule that constructed it; see ActionOwner class comment for details.
*/
ActionOwner getOwner();
/**
* Returns true if the action can be shared, i.e. multiple configured targets can create the same
* action.
*
* <p>In theory, these should not exist, but in practice, they do.
*/
boolean isShareable();
/**
* Returns a mnemonic (string constant) for this kind of action; written into
* the master log so that the appropriate parser can be invoked for the output
* of the action. Effectively a public method as the value is used by the
* extra_action feature to match actions.
*/
String getMnemonic();
/**
* Returns a string encoding all of the significant behaviour of this Action that might affect the
* output. The general contract of <code>getKey</code> is this: if the work to be performed by the
* execution of this action changes, the key must change.
*
* <p>As a corollary, the build system is free to omit the execution of an Action <code>a1</code>
* if (a) at some time in the past, it has already executed an Action <code>a0</code> with the
* same key as <code>a1</code>, (b) the names and contents of the input files listed by <code>
* a1.getInputs()</code> are identical to the names and contents of the files listed by <code>
* a0.getInputs()</code>, and (c) the names and values in the client environment of the variables
* listed by <code>a1.getClientEnvironmentVariables()</code> are identical to those listed by
* <code>a0.getClientEnvironmentVariables()</code>.
*
* <p>Examples of changes that should affect the key are:
*
* <ul>
* <li>Changes to the BUILD file that materially affect the rule which gave rise to this Action.
* <li>Changes to the command-line options, environment, or other global configuration resources
* which affect the behaviour of this kind of Action (other than changes to the names of the
* input/output files, which are handled externally).
* <li>An upgrade to the build tools which changes the program logic of this kind of Action
* (typically this is achieved by incorporating a UUID into the key, which is changed each
* time the program logic of this action changes).
* </ul>
*
* <p>Note the following exception: for actions that discover inputs, the key must change if any
* input names change or else action validation may falsely validate.
*
* <p>In case the {@link ArtifactExpander} is not provided, the key is not guaranteed to be
* correct. In fact, getting the key of an action is generally impossible until we have all the
* information necessary to execute the action. An example of this is when arguments to an action
* are defined as a lazy evaluation of Starlark over outputs of another action, after expanding
* directories. In such case, if the dependent action outputs a tree artifact, creating a truly
* unique key will depend on knowing the tree artifact contents. At analysis time, we only know
* about the tree artifact directory and we find what is in it only after we execute that action.
*/
String getKey(ActionKeyContext actionKeyContext, @Nullable ArtifactExpander artifactExpander)
throws InterruptedException;
/**
* Returns a pretty string representation of this action, suitable for use in
* progress messages or error messages.
*/
String prettyPrint();
/** Returns a description of this action. */
String describe();
/**
* Returns the tool Artifacts that this Action depends upon. May be empty. This is a subset of
* getInputs().
*
* <p>This may be used by spawn strategies to determine whether an external tool has not changed
* since the last time it was used and could thus be reused, or whether it has to be restarted.
*
* <p>See {@link AbstractAction#getTools()} for an explanation of why it's important that this set
* contains exactly the right set of artifacts in order for the build to stay correct and the
* worker strategy to work.
*/
NestedSet<Artifact> getTools();
/**
* Returns the input Artifacts that this Action depends upon. May be empty.
*
* <p>During execution, the {@link Iterable} returned by {@code getInputs} <em>must not</em> be
* concurrently modified before the value is fully read in {@code JavaDistributorDriver#exec} (via
* the {@code Iterable<ActionInput>} argument there). Violating this would require somewhat
* pathological behavior by the {@link Action}, since it would have to modify its inputs, as a
* list, say, without reassigning them. This should never happen with any Action subclassing
* AbstractAction, since AbstractAction's implementation of getInputs() returns an immutable
* iterable.
*/
NestedSet<Artifact> getInputs();
/**
* Returns the environment variables from the client environment that this action depends on. May
* be empty.
*
* <p>Warning: For optimization reasons, the available environment variables are restricted to
* those white-listed on the command line. If actions want to specify additional client
* environment variables to depend on, that restriction must be lifted in {@link
* com.google.devtools.build.lib.runtime.CommandEnvironment}.
*/
Collection<String> getClientEnvironmentVariables();
/**
* Returns the (unordered, immutable) set of output Artifacts that
* this action generates. (It would not make sense for this to be empty.)
*/
ImmutableSet<Artifact> getOutputs();
/**
* Returns input files that need to be present to allow extra_action rules to shadow this action
* correctly when run remotely. This is at least the normal inputs of the action, but may include
* other files as well. For example C(++) compilation may perform include file header scanning.
* This needs to be mirrored by the extra_action rule. Called by {@link
* com.google.devtools.build.lib.analysis.extra.ExtraAction} at execution time for actions that
* return true for {link #discoversInputs()}.
*
* @param actionExecutionContext Services in the scope of the action, like the Out/Err streams.
* @throws ActionExecutionException only when code called from this method throws that exception.
* @throws InterruptedException if interrupted
*/
NestedSet<Artifact> getInputFilesForExtraAction(ActionExecutionContext actionExecutionContext)
throws ActionExecutionException, InterruptedException;
/**
* Returns the set of output Artifacts that are required to be saved. This is
* used to identify items that would otherwise be potentially identified as
* orphaned (not consumed by any downstream {@link Action}s and potentially
* discarded during the build process.
*/
ImmutableSet<Artifact> getMandatoryOutputs();
/**
* Returns the "primary" input of this action, if applicable.
*
* <p>For example, a C++ compile action would return the .cc file which is being compiled,
* irrespective of the other inputs.
*
* <p>May return null.
*/
Artifact getPrimaryInput();
/**
* Returns the "primary" output of this action.
*
* <p>For example, the linked library would be the primary output of a LinkAction.
*
* <p>Never returns null.
*/
Artifact getPrimaryOutput();
/**
* Returns an iterable of input Artifacts that MUST exist prior to executing an action. In other
* words, in case when action is scheduled for execution, builder will ensure that all artifacts
* returned by this method are present in the filesystem (artifact.getPath().exists() is true) or
* action execution will be aborted with an error that input file does not exist. While in
* majority of cases this method will return all action inputs, for some actions (e.g.
* CppCompileAction) it can return a subset of inputs because that not all action inputs might be
* mandatory for action execution to succeed (e.g. header files retrieved from *.d file from the
* previous build).
*/
NestedSet<Artifact> getMandatoryInputs();
/**
* @return true iff path prefix conflict (conflict where two actions generate
* two output artifacts with one of the artifact's path being the
* prefix for another) between this action and another action should
* be reported.
*/
boolean shouldReportPathPrefixConflict(ActionAnalysisMetadata action);
/** Returns the action type. Must not be {@code null}. */
MiddlemanType getActionType();
/** Returns a String to String map containing the execution properties of this action. */
ImmutableMap<String, String> getExecProperties();
/**
* Returns the {@link PlatformInfo} platform this action should be executed on. If the execution
* platform is {@code null}, then the host platform is assumed.
*/
@Nullable
PlatformInfo getExecutionPlatform();
/**
* Returns the execution requirements for this action, or null if the action type does not have
* access to execution requirements.
*/
@Nullable
default Map<String, String> getExecutionInfo() {
return null;
}
}