use of com.google.devtools.build.lib.actions.Artifact in project bazel by bazelbuild.
the class ArtifactFunction method createAggregatingValue.
private static AggregatingArtifactValue createAggregatingValue(Artifact artifact, ActionAnalysisMetadata action, FileArtifactValue value, SkyFunction.Environment env) throws InterruptedException {
// This artifact aggregates other artifacts. Keep track of them so callers can find them.
ImmutableList.Builder<Pair<Artifact, FileArtifactValue>> inputs = ImmutableList.builder();
for (Map.Entry<SkyKey, SkyValue> entry : env.getValues(ArtifactSkyKey.mandatoryKeys(action.getInputs())).entrySet()) {
Artifact input = ArtifactSkyKey.artifact(entry.getKey());
SkyValue inputValue = entry.getValue();
Preconditions.checkNotNull(inputValue, "%s has null dep %s", artifact, input);
if (!(inputValue instanceof FileArtifactValue)) {
// We do not recurse in aggregating middleman artifacts.
Preconditions.checkState(!(inputValue instanceof AggregatingArtifactValue), "%s %s %s", artifact, action, inputValue);
continue;
}
inputs.add(Pair.of(input, (FileArtifactValue) inputValue));
}
return new AggregatingArtifactValue(inputs.build(), value);
}
use of com.google.devtools.build.lib.actions.Artifact in project bazel by bazelbuild.
the class ConfiguredTargetFunction method createConfiguredTarget.
@Nullable
private ConfiguredTargetValue createConfiguredTarget(SkyframeBuildView view, Environment env, Target target, BuildConfiguration configuration, OrderedSetMultimap<Attribute, ConfiguredTarget> depValueMap, ImmutableMap<Label, ConfigMatchingProvider> configConditions, NestedSetBuilder<Package> transitivePackages) throws ConfiguredTargetFunctionException, InterruptedException {
StoredEventHandler events = new StoredEventHandler();
BuildConfiguration ownerConfig = (configuration == null) ? null : configuration.getArtifactOwnerConfiguration();
CachingAnalysisEnvironment analysisEnvironment = view.createAnalysisEnvironment(new ConfiguredTargetKey(target.getLabel(), ownerConfig), false, events, env, configuration);
if (env.valuesMissing()) {
return null;
}
Preconditions.checkNotNull(depValueMap);
ConfiguredTarget configuredTarget = view.createConfiguredTarget(target, configuration, analysisEnvironment, depValueMap, configConditions);
events.replayOn(env.getListener());
if (events.hasErrors()) {
analysisEnvironment.disable(target);
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException("Analysis of target '" + target.getLabel() + "' failed; build aborted", target.getLabel()));
}
Preconditions.checkState(!analysisEnvironment.hasErrors(), "Analysis environment hasError() but no errors reported");
if (env.valuesMissing()) {
return null;
}
analysisEnvironment.disable(target);
Preconditions.checkNotNull(configuredTarget, target);
ImmutableMap<Artifact, ActionAnalysisMetadata> generatingActions;
// rule implementation).
try {
generatingActions = Actions.filterSharedActionsAndThrowActionConflict(analysisEnvironment.getRegisteredActions());
} catch (ActionConflictException e) {
throw new ConfiguredTargetFunctionException(e);
}
return new ConfiguredTargetValue(configuredTarget, generatingActions, transitivePackages.build());
}
use of com.google.devtools.build.lib.actions.Artifact in project bazel by bazelbuild.
the class ActionExecutionFunction method addDiscoveredInputs.
private static void addDiscoveredInputs(Map<Artifact, FileArtifactValue> inputData, Map<Artifact, Collection<Artifact>> expandedArtifacts, Iterable<Artifact> discoveredInputs, Environment env) throws InterruptedException {
// We do not do a getValuesOrThrow() call for the following reasons:
// 1. No exceptions can be thrown for non-mandatory inputs;
// 2. Any derived inputs must be in the transitive closure of this action's inputs. Therefore,
// if there was an error building one of them, then that exception would have percolated up to
// this action already, through one of its declared inputs, and we would not have reached input
// discovery.
// Therefore there is no need to catch and rethrow exceptions as there is with #checkInputs.
Map<SkyKey, SkyValue> nonMandatoryDiscovered = env.getValues(newlyDiscoveredInputsToSkyKeys(discoveredInputs, inputData.keySet()));
if (!env.valuesMissing()) {
for (Entry<SkyKey, SkyValue> entry : nonMandatoryDiscovered.entrySet()) {
Artifact input = ArtifactSkyKey.artifact(entry.getKey());
if (entry.getValue() instanceof TreeArtifactValue) {
TreeArtifactValue treeValue = (TreeArtifactValue) entry.getValue();
expandedArtifacts.put(input, ImmutableSet.<Artifact>copyOf(treeValue.getChildren()));
inputData.putAll(treeValue.getChildValues());
inputData.put(input, treeValue.getSelfData());
} else {
inputData.put(input, (FileArtifactValue) entry.getValue());
}
}
}
}
use of com.google.devtools.build.lib.actions.Artifact in project bazel by bazelbuild.
the class ActionExecutionFunction method checkInputs.
/**
* Declare dependency on all known inputs of action. Throws exception if any are known to be
* missing. Some inputs may not yet be in the graph, in which case the builder should abort.
*/
private Pair<Map<Artifact, FileArtifactValue>, Map<Artifact, Collection<Artifact>>> checkInputs(Environment env, Action action, Map<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> inputDeps) throws ActionExecutionException {
int missingCount = 0;
int actionFailures = 0;
boolean catastrophe = false;
// Only populate input data if we have the input values, otherwise they'll just go unused.
// We still want to loop through the inputs to collect missing deps errors. During the
// evaluator "error bubbling", we may get one last chance at reporting errors even though
// some deps are still missing.
boolean populateInputData = !env.valuesMissing();
NestedSetBuilder<Cause> rootCauses = NestedSetBuilder.stableOrder();
Map<Artifact, FileArtifactValue> inputArtifactData = new HashMap<>(populateInputData ? inputDeps.size() : 0);
Map<Artifact, Collection<Artifact>> expandedArtifacts = new HashMap<>(populateInputData ? 128 : 0);
ActionExecutionException firstActionExecutionException = null;
for (Map.Entry<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> depsEntry : inputDeps.entrySet()) {
Artifact input = ArtifactSkyKey.artifact(depsEntry.getKey());
try {
SkyValue value = depsEntry.getValue().get();
if (populateInputData) {
if (value instanceof AggregatingArtifactValue) {
AggregatingArtifactValue aggregatingValue = (AggregatingArtifactValue) value;
for (Pair<Artifact, FileArtifactValue> entry : aggregatingValue.getInputs()) {
inputArtifactData.put(entry.first, entry.second);
}
// We have to cache the "digest" of the aggregating value itself,
// because the action cache checker may want it.
inputArtifactData.put(input, aggregatingValue.getSelfData());
ImmutableList.Builder<Artifact> expansionBuilder = ImmutableList.builder();
for (Pair<Artifact, FileArtifactValue> pair : aggregatingValue.getInputs()) {
expansionBuilder.add(pair.first);
}
expandedArtifacts.put(input, expansionBuilder.build());
} else if (value instanceof TreeArtifactValue) {
TreeArtifactValue treeValue = (TreeArtifactValue) value;
expandedArtifacts.put(input, ImmutableSet.<Artifact>copyOf(treeValue.getChildren()));
inputArtifactData.putAll(treeValue.getChildValues());
// Again, we cache the "digest" of the value for cache checking.
inputArtifactData.put(input, treeValue.getSelfData());
} else {
Preconditions.checkState(value instanceof FileArtifactValue, depsEntry);
inputArtifactData.put(input, (FileArtifactValue) value);
}
}
} catch (MissingInputFileException e) {
missingCount++;
if (input.getOwner() != null) {
rootCauses.add(new LabelCause(input.getOwner()));
}
} catch (ActionExecutionException e) {
actionFailures++;
if (firstActionExecutionException == null) {
firstActionExecutionException = e;
}
catastrophe = catastrophe || e.isCatastrophe();
rootCauses.addTransitive(e.getRootCauses());
}
}
// We need to rethrow first exception because it can contain useful error message
if (firstActionExecutionException != null) {
if (missingCount == 0 && actionFailures == 1) {
// having to copy the root causes to the upwards transitive closure.
throw firstActionExecutionException;
}
throw new ActionExecutionException(firstActionExecutionException.getMessage(), firstActionExecutionException.getCause(), action, rootCauses.build(), catastrophe, firstActionExecutionException.getExitCode());
}
if (missingCount > 0) {
for (Cause missingInput : rootCauses.build()) {
env.getListener().handle(Event.error(action.getOwner().getLocation(), String.format("%s: missing input file '%s'", action.getOwner().getLabel(), missingInput.getLabel())));
}
throw new ActionExecutionException(missingCount + " input file(s) do not exist", action, rootCauses.build(), /*catastrophe=*/
false);
}
return Pair.of(inputArtifactData, expandedArtifacts);
}
use of com.google.devtools.build.lib.actions.Artifact in project bazel by bazelbuild.
the class SandboxStrategy method getMounts.
public Map<PathFragment, Path> getMounts(Spawn spawn, ActionExecutionContext executionContext) throws ExecException {
try {
Map<PathFragment, ActionInput> inputMap = spawnInputExpander.getInputMapping(spawn, executionContext.getArtifactExpander(), executionContext.getActionInputFileCache(), executionContext.getExecutor().getContext(FilesetActionContext.class));
Map<PathFragment, Path> mounts = new TreeMap<>();
for (Map.Entry<PathFragment, ActionInput> e : inputMap.entrySet()) {
mounts.put(e.getKey(), execRoot.getRelative(e.getValue().getExecPath()));
}
// inputs.
for (ActionInput input : spawn.getInputFiles()) {
if (input instanceof Artifact && ((Artifact) input).isTreeArtifact()) {
List<Artifact> containedArtifacts = new ArrayList<>();
executionContext.getArtifactExpander().expand((Artifact) input, containedArtifacts);
// only mount empty TreeArtifacts as directories.
if (containedArtifacts.isEmpty()) {
inputMap.put(input.getExecPath(), input);
}
}
}
return mounts;
} catch (IOException e) {
throw new EnvironmentalExecException("Could not prepare mounts for sandbox execution", e);
}
}
Aggregations