// 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.rules.extra; import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST; import static com.google.devtools.build.lib.packages.Attribute.attr; import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; import static com.google.devtools.build.lib.syntax.Type.BOOLEAN; import static com.google.devtools.build.lib.syntax.Type.STRING; import static com.google.devtools.build.lib.syntax.Type.STRING_LIST; import com.google.devtools.build.lib.analysis.BaseRuleClasses; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.RuleClass.Builder; /** * Rule definition for extra_action rule. */ public final class ExtraActionRule implements RuleDefinition { @Override public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) { /*<!-- #BLAZE_RULE(extra_action).NAME --> You may refer to this rule by <code>label</code> in the <code>extra_actions</code> argument of <a href="${link action_listener}"><code> action_listener</code></a> rules. <!-- #END_BLAZE_RULE.NAME -->*/ return builder /*<!-- #BLAZE_RULE(extra_action).ATTRIBUTE(tools) --> A list of <code>tool</code> dependencies for this rule. <p> See the definition of <a href="../build-ref.html#deps">dependencies</a> for more information. </p> <p> The build system ensures these prerequisites are built before running the <code>extra_action</code> command; they are built using the <a href='${link user-manual#configurations}'><code>host</code>configuration</a>, since they must run as a tool during the build itself. The path of an individual <code>tools</code> target <code>//x:y</code> can be obtained using <code>$(location //x:y)</code>. </p> <p> All tools and their data dependencies are consolidated into a single tree within which the command can use relative paths. The working directory will be the root of that unified tree. </p> <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ .add(attr("tools", LABEL_LIST).cfg(HOST).allowedFileTypes().exec()) /*<!-- #BLAZE_RULE(extra_action).ATTRIBUTE(out_templates) --> A list of templates for files generated by the <code>extra_action</code> command. <p> The template can use the following variables: <ul> <li> $(ACTION_ID), an id uniquely identifying this <code>extra_action</code>. Used to generate a unique output file. </li> </ul> </p> <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ .add(attr("out_templates", STRING_LIST)) /*<!-- #BLAZE_RULE(extra_action).ATTRIBUTE(cmd) --> The command to run. <p> Like <a href="${link genrule.cmd}">genrule cmd attribute</a> with the following differences: </p> <ol> <li> <p> No heuristic label expansion. Only labels using $(location ...) are expanded. </p> </li> <li> <p> An additional pass is applied to the string to replace all occurrences of the outputs created from the <code>out_templates</code> attribute. All occurrences of <code>$(output <i>out_template</i>)</code> are replaced with the path to the file denoted by <code>label</code>. </p> <p> E.g. out_template <code>$(ACTION_ID).analysis</code> can be matched with <code>$(output $(ACTION_ID).analysis)</code>. </p> <p> In effect, this is the same substitution as <code>$(location)</code> but with a different scope. </p> </li> </ol> <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ .add(attr("cmd", STRING).mandatory()) /*<!-- #BLAZE_RULE(extra_action).ATTRIBUTE(requires_action_output) --> Indicates this <code>extra_action</code> requires the output of the original action to be present as input to this <code>extra_action</code>. <p> When true (default false), the extra_action can assume that the original action outputs are available as part of its inputs. </p> <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ .add(attr("requires_action_output", BOOLEAN)) .removeAttribute("deps") .removeAttribute(":action_listener") .build(); } @Override public Metadata getMetadata() { return RuleDefinition.Metadata.builder() .name("extra_action") .ancestors(BaseRuleClasses.RuleBase.class) .factoryClass(ExtraActionFactory.class) .build(); } } /*<!-- #BLAZE_RULE (NAME = extra_action, TYPE = LIBRARY, FAMILY = Extra Actions)[GENERIC_RULE] --> <p> An <code>extra_action</code> rule doesn't produce any meaningful output when specified as a regular build target. Instead, it allows tool developers to insert additional actions into the build graph that shadow existing actions. </p> <p> See <a href="${link action_listener}"><code>action_listener</code></a> for details on how to enable <code>extra_action</code>s. </p> <p> The <code>extra_action</code>s run as a command-line. The command-line tool gets access to a file containing a protocol buffer as $(EXTRA_ACTION_FILE) with detailed information on the original action it is shadowing. It also has access to all the input files the original action has access to. See <tt>extra_actions.proto</tt> for details on the data stored inside the protocol buffer. Each proto file contains an ExtraActionInfo message. </p> <p> Just like all other actions, extra actions are sandboxed, and should be designed to handle that. </p> <!-- #END_BLAZE_RULE -->*/