blob: c2cb253b1df46e6b45eb030b88c1ffcd0d8ea9b0 [file] [log] [blame]
// 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.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
import static com.google.devtools.build.lib.packages.Type.STRING;
import static com.google.devtools.build.lib.packages.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.analysis.config.HostTransition;
import com.google.devtools.build.lib.packages.RuleClass;
/**
* Rule definition for extra_action rule.
*/
public final class ExtraActionRule implements RuleDefinition {
@Override
public RuleClass build(RuleClass.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(HostTransition.createFactory()).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, BaseRuleClasses.MakeVariableExpandingRule.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_base.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 -->*/