// Copyright 2016 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.analysis.actions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; import com.google.devtools.build.lib.actions.ActionInputHelper; import com.google.devtools.build.lib.actions.ActionOwner; import com.google.devtools.build.lib.actions.Actions; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; import com.google.devtools.build.lib.actions.ArtifactOwner; import com.google.devtools.build.lib.actions.ArtifactPrefixConflictException; import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.build.lib.vfs.PathFragment; import java.util.Map; /** * A placeholder action that, at execution time, expands into a list of {@link SpawnAction}s that * will be executed. * *
SpawnActionTemplate is for users who want to dynamically register SpawnActions operating on * individual {@link TreeFileArtifact} inside input and output TreeArtifacts at execution time. * *
It takes in one TreeArtifact and generates one TreeArtifact. The following happens at * execution time for SpawnActionTemplate: *
Users of SpawnActionTemplate must provide a mapper object implementing this interface.
* SpawnActionTemplate uses the mapper to query for the path of output artifact associated with
* each input {@link TreeFileArtifact} resolved at execution time.
*/
public interface OutputPathMapper {
/**
* Given the input {@link TreeFileArtifact}, returns the parent-relative path of the associated
* output {@link TreeFileArtifact}.
*
* @param input the input {@link TreeFileArtifact}
*/
PathFragment parentRelativeOutputPath(TreeFileArtifact input);
}
private SpawnActionTemplate(
ActionOwner actionOwner,
Artifact inputTreeArtifact,
Artifact outputTreeArtifact,
NestedSet This method is called by Skyframe to expand the input TreeArtifact into child
* TreeFileArtifacts. Skyframe then expands this SpawnActionTemplate with the TreeFileArtifacts
* through {@link #generateActionForInputArtifacts}.
*/
public Artifact getInputTreeArtifact() {
return inputTreeArtifact;
}
/** Returns the output TreeArtifact. */
public Artifact getOutputTreeArtifact() {
return outputTreeArtifact;
}
@Override
public ActionOwner getOwner() {
return actionOwner;
}
@Override
public final String getMnemonic() {
return mnemonic;
}
@Override
public Iterable Calling this method overrides any previous values set via calls to
* {@link #setExecutable(Artifact)} and {@link #setExecutable(PathFragment)}.
*/
public Builder setExecutable(FilesToRunProvider executableProvider) {
Preconditions.checkArgument(
executableProvider.getExecutable() != null, "The target does not have an executable");
spawnActionBuilder.setExecutable(executableProvider);
addCommonTool(executableProvider);
this.executable = executableProvider.getExecutable().getExecPath();
return this;
}
/**
* Sets the executable path used by expanded actions. The path is interpreted relative to the
* execution root.
*
* Calling this method overrides any previous values set via calls to
* {@link #setExecutable(Artifact)} and {@link #setExecutable(FilesToRunProvider)}.
*/
public Builder setExecutable(PathFragment executable) {
spawnActionBuilder.setExecutable(executable);
this.executable = executable;
return this;
}
/**
* Sets the executable artifact used by expanded actions. The path is interpreted relative to
* the execution root.
*
* Calling this method overrides any previous values set via calls to
* {@link #setExecutable(FilesToRunProvider)} and {@link #setExecutable(PathFragment)}.
*/
public Builder setExecutable(Artifact artifact) {
spawnActionBuilder.setExecutable(artifact);
addCommonTools(ImmutableList.of(artifact));
this.executable = artifact.getExecPath();
return this;
}
/**
* Sets the command line template used to expand actions.
*/
public Builder setCommandLineTemplate(CustomCommandLine commandLineTemplate) {
this.commandLineTemplate = commandLineTemplate;
return this;
}
/**
* Sets the {@link OutputPathMapper} object used to get the parent-relative paths of output
* {@link TreeFileArtifact}.
*/
public Builder setOutputPathMapper(OutputPathMapper outputPathMapper) {
this.outputPathMapper = outputPathMapper;
return this;
}
/**
* Builds and returns the {@link SpawnActionTemplate} using the accumulated builder information.
*
* @param actionOwner the action owner of the SpawnActionTemplate to be built.
*/
public SpawnActionTemplate build(ActionOwner actionOwner) {
Preconditions.checkNotNull(executable);
return new SpawnActionTemplate(
actionOwner,
Preconditions.checkNotNull(inputTreeArtifact),
Preconditions.checkNotNull(outputTreeArtifact),
inputsBuilder.build(),
toolsBuilder.build(),
Preconditions.checkNotNull(outputPathMapper),
Preconditions.checkNotNull(commandLineTemplate),
actionTemplateMnemonic,
spawnActionBuilder);
}
}
}