// 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.ImmutableSet; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import javax.annotation.Nullable; /** * Side-effect free query methods for information about an {@link Action}. * *

This method is intended for use in situations when the intention is to pass around information * about an action without allowing actual execution of the action. * *

The split between {@link Action} and {@link ActionMetadata} is somewhat arbitrary, other than * that all methods with side effects must belong to the former. */ public interface ActionMetadata { /** * If this executable can supply verbose information, returns a string that can be used as a * progress message while this executable is running. A return value of {@code null} indicates no * message should be reported. */ @Nullable String getProgressMessage(); /** * 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. Returns * {@code null} if no owner can be determined. * *

If this executable does not supply verbose information, this function may throw an * IllegalStateException. */ ActionOwner getOwner(); /** * 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 pretty string representation of this action, suitable for use in * progress messages or error messages. */ String prettyPrint(); /** * Returns true iff the getInputs set is known to be complete. * *

For most Actions, this always returns true, but in some cases (e.g. C++ compilation), inputs * are dynamically discovered from the previous execution of the Action, and so before the initial * execution, this method will return false in those cases. * *

Any builder must unconditionally execute an Action for which inputsKnown() returns * false, regardless of all other inferences made by its dependency analysis. In addition, all * prerequisites mentioned in the (possibly incomplete) value returned by getInputs must also be * built first, as usual. */ @ThreadSafe boolean inputsKnown(); /** * Returns true iff inputsKnown() may ever return false. */ @ThreadSafe boolean discoversInputs(); /** * Returns the tool Artifacts that this Action depends upon. May be empty. This is a subset of * getInputs(). * *

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. * *

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. */ Iterable getTools(); /** * Returns the input Artifacts that this Action depends upon. May be empty. * *

During execution, the {@link Iterable} returned by {@code getInputs} must not be * concurrently modified before the value is fully read in {@code JavaDistributorDriver#exec} (via * the {@code Iterable} 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. */ Iterable getInputs(); /** * Get the {@link RunfilesSupplier} providing runfiles needed by this action. */ RunfilesSupplier getRunfilesSupplier(); /** * Returns the (unordered, immutable) set of output Artifacts that * this action generates. (It would not make sense for this to be empty.) */ ImmutableSet getOutputs(); /** * 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 getMandatoryOutputs(); /** * Returns the "primary" input of this action, if applicable. * *

For example, a C++ compile action would return the .cc file which is being compiled, * irrespective of the other inputs. * *

May return null. */ Artifact getPrimaryInput(); /** * Returns the "primary" output of this action. * *

For example, the linked library would be the primary output of a LinkAction. * *

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). */ Iterable getMandatoryInputs(); /** *

Returns a string encoding all of the significant behaviour of this * Action that might affect the output. The general contract of * getKey is this: if the work to be performed by the * execution of this action changes, the key must change.

* *

As a corollary, the build system is free to omit the execution of an * Action a1 if (a) at some time in the past, it has already * executed an Action a0 with the same key as * a1, and (b) the names and contents of the input files listed * by a1.getInputs() are identical to the names and contents of * the files listed by a0.getInputs().

* *

Examples of changes that should affect the key are: *

*/ String getKey(); /** * Returns a human-readable description of the inputs to {@link #getKey()}. * Used in the output from '--explain', and in error messages for * '--check_up_to_date' and '--check_tests_up_to_date'. * May return null, meaning no extra information is available. * *

If the return value is non-null, for consistency it should be a multiline message of the * form: *

   *   Summary
   *     Fieldname: value
   *     Fieldname: value
   *     ...
   * 
* where each line after the first one is intended two spaces, and where any fields that might * contain newlines or other funny characters are escaped using {@link * com.google.devtools.build.lib.shell.ShellUtils#shellEscape}. * For example: *
   *   Compiling foo.cc
   *     Command: /usr/bin/gcc
   *     Argument: '-c'
   *     Argument: foo.cc
   *     Argument: '-o'
   *     Argument: foo.o
   * 
*/ @Nullable String describeKey(); }