aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
diff options
context:
space:
mode:
authorGravatar Florian Weikert <fwe@google.com>2015-09-07 12:06:02 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2015-09-08 09:04:15 +0000
commit3f8aac93ff0b2f06bc01b60614a265304aec177d (patch)
treea700689c1961f917d0d35cf5aca7c7a9e962d32f /src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
parent7a046e16d135821d224382352c7098e0c004a779 (diff)
Skylark: configuration fragments for host configuration can now be accessed via ctx.host_fragments.
-- MOS_MIGRATED_REVID=102490502
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java137
1 files changed, 79 insertions, 58 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
index e2540342c7..42449c534a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.lib.rules;
import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.DATA;
import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST;
+import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.NONE;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
import static com.google.devtools.build.lib.packages.Type.INTEGER;
@@ -33,7 +34,7 @@ import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
+import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.analysis.BaseRuleClasses;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.RunUnder;
@@ -78,6 +79,7 @@ import com.google.devtools.build.lib.syntax.SkylarkSignature.Param;
import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
import com.google.devtools.build.lib.vfs.PathFragment;
+import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
@@ -232,72 +234,91 @@ public class SkylarkRuleClassFunctions {
@Param(name = "output_to_genfiles", type = Boolean.class, defaultValue = "False",
doc = "If true, the files will be generated in the genfiles directory instead of the "
+ "bin directory. This is used for compatibility with existing rules."),
- @Param(name = "fragments", type = SkylarkList.class, generic1 = String.class,
+ @Param(name = "fragments", type = SkylarkList.class, generic1 = String.class,
defaultValue = "[]",
- doc = "List of names of configuration fragments that the rule requires.")},
+ doc =
+ "List of names of configuration fragments that the rule requires "
+ + "in target configuration."),
+ @Param(name = "host_fragments", type = SkylarkList.class, generic1 = String.class,
+ defaultValue = "[]",
+ doc =
+ "List of names of configuration fragments that the rule requires "
+ + "in host configuration.")},
useAst = true, useEnvironment = true)
private static final BuiltinFunction rule = new BuiltinFunction("rule") {
- @SuppressWarnings({"rawtypes", "unchecked"}) // castMap produces
- // an Attribute.Builder instead of a Attribute.Builder<?> but it's OK.
- public BaseFunction invoke(BaseFunction implementation, Boolean test, Object attrs,
- Object implicitOutputs, Boolean executable, Boolean outputToGenfiles,
- SkylarkList fragments, FuncallExpression ast, Environment funcallEnv)
- throws EvalException, ConversionException {
-
- funcallEnv.checkLoadingPhase("rule", ast.getLocation());
- RuleClassType type = test ? RuleClassType.TEST : RuleClassType.NORMAL;
- RuleClass parent = test ? testBaseRule : (executable ? binaryBaseRule : baseRule);
-
- // We'll set the name later, pass the empty string for now.
- RuleClass.Builder builder = new RuleClass.Builder("", type, true, parent);
-
- if (attrs != Runtime.NONE) {
- for (Map.Entry<String, Attribute.Builder> attr : castMap(
- attrs, String.class, Attribute.Builder.class, "attrs").entrySet()) {
- Attribute.Builder<?> attrBuilder = (Attribute.Builder<?>) attr.getValue();
- String attrName = attributeToNative(attr.getKey(), ast.getLocation(),
- attrBuilder.hasLateBoundValue());
- builder.addOrOverrideAttribute(attrBuilder.build(attrName));
- }
- }
- if (executable || test) {
- builder.addOrOverrideAttribute(
- attr("$is_executable", BOOLEAN).value(true)
- .nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")
- .build());
- builder.setOutputsDefaultExecutable();
+ @SuppressWarnings({"rawtypes", "unchecked"}) // castMap produces
+ // an Attribute.Builder instead of a Attribute.Builder<?> but it's OK.
+ public BaseFunction invoke(BaseFunction implementation, Boolean test, Object attrs,
+ Object implicitOutputs, Boolean executable, Boolean outputToGenfiles, SkylarkList fragments,
+ SkylarkList hostFragments, FuncallExpression ast, Environment funcallEnv)
+ throws EvalException, ConversionException {
+ funcallEnv.checkLoadingPhase("rule", ast.getLocation());
+ RuleClassType type = test ? RuleClassType.TEST : RuleClassType.NORMAL;
+ RuleClass parent = test ? testBaseRule : (executable ? binaryBaseRule : baseRule);
+
+ // We'll set the name later, pass the empty string for now.
+ RuleClass.Builder builder = new RuleClass.Builder("", type, true, parent);
+
+ if (attrs != Runtime.NONE) {
+ for (Map.Entry<String, Attribute.Builder> attr :
+ castMap(attrs, String.class, Attribute.Builder.class, "attrs").entrySet()) {
+ Attribute.Builder<?> attrBuilder = (Attribute.Builder<?>) attr.getValue();
+ String attrName =
+ attributeToNative(attr.getKey(), ast.getLocation(), attrBuilder.hasLateBoundValue());
+ builder.addOrOverrideAttribute(attrBuilder.build(attrName));
}
+ }
+ if (executable || test) {
+ builder.addOrOverrideAttribute(
+ attr("$is_executable", BOOLEAN)
+ .value(true)
+ .nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")
+ .build());
+ builder.setOutputsDefaultExecutable();
+ }
- if (implicitOutputs != Runtime.NONE) {
- if (implicitOutputs instanceof BaseFunction) {
- BaseFunction func = (BaseFunction) implicitOutputs;
- final SkylarkCallbackFunction callback =
- new SkylarkCallbackFunction(func, ast, (SkylarkEnvironment) funcallEnv);
- builder.setImplicitOutputsFunction(
- new SkylarkImplicitOutputsFunctionWithCallback(callback, ast.getLocation()));
- } else {
- builder.setImplicitOutputsFunction(new SkylarkImplicitOutputsFunctionWithMap(
- ImmutableMap.copyOf(castMap(implicitOutputs, String.class, String.class,
- "implicit outputs of the rule class"))));
- }
+ if (implicitOutputs != Runtime.NONE) {
+ if (implicitOutputs instanceof BaseFunction) {
+ BaseFunction func = (BaseFunction) implicitOutputs;
+ final SkylarkCallbackFunction callback =
+ new SkylarkCallbackFunction(func, ast, (SkylarkEnvironment) funcallEnv);
+ builder.setImplicitOutputsFunction(
+ new SkylarkImplicitOutputsFunctionWithCallback(callback, ast.getLocation()));
+ } else {
+ builder.setImplicitOutputsFunction(
+ new SkylarkImplicitOutputsFunctionWithMap(ImmutableMap.copyOf(castMap(implicitOutputs,
+ String.class, String.class, "implicit outputs of the rule class"))));
}
+ }
- if (outputToGenfiles) {
- builder.setOutputToGenfiles();
- }
+ if (outputToGenfiles) {
+ builder.setOutputToGenfiles();
+ }
- if (!fragments.isEmpty()) {
- builder.requiresConfigurationFragments(
- new SkylarkModuleNameResolver(),
- Iterables.toArray(castList(fragments, String.class), String.class));
- }
+ registerRequiredFragments(fragments, hostFragments, builder);
- builder.setConfiguredTargetFunction(implementation);
- builder.setRuleDefinitionEnvironment(
- ((SkylarkEnvironment) funcallEnv).getGlobalEnvironment());
- return new RuleFunction(builder, type);
- }
- };
+ builder.setConfiguredTargetFunction(implementation);
+ builder.setRuleDefinitionEnvironment(
+ ((SkylarkEnvironment) funcallEnv).getGlobalEnvironment());
+ return new RuleFunction(builder, type);
+ }
+
+ private void registerRequiredFragments(
+ SkylarkList fragments, SkylarkList hostFragments, RuleClass.Builder builder) {
+ Map<ConfigurationTransition, ImmutableSet<String>> map = new HashMap<>();
+ addFragmentsToMap(map, fragments, NONE); // NONE represents target configuration
+ addFragmentsToMap(map, hostFragments, HOST);
+
+ builder.requiresConfigurationFragments(new SkylarkModuleNameResolver(), map);
+ }
+
+ private void addFragmentsToMap(Map<ConfigurationTransition, ImmutableSet<String>> map,
+ SkylarkList fragments, ConfigurationTransition config) {
+ if (!fragments.isEmpty()) {
+ map.put(config, ImmutableSet.copyOf(castList(fragments, String.class)));
+ }
+ }
+ };
// This class is needed for testing
static final class RuleFunction extends BaseFunction {