aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
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
parent7a046e16d135821d224382352c7098e0c004a779 (diff)
Skylark: configuration fragments for host configuration can now be accessed via ctx.host_fragments.
-- MOS_MIGRATED_REVID=102490502
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/RuleClass.java58
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java137
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java35
5 files changed, 183 insertions, 105 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index af05afd28d..b6affcacf9 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -39,6 +39,7 @@ import com.google.devtools.build.lib.analysis.buildinfo.BuildInfoFactory.BuildIn
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment;
import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
+import com.google.devtools.build.lib.analysis.config.FragmentCollection;
import com.google.devtools.build.lib.collect.ImmutableSortedKeyListMultimap;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
@@ -257,26 +258,44 @@ public final class RuleContext extends TargetContext
* Returns a configuration fragment for this this target.
*/
@Nullable
- public <T extends Fragment> T getFragment(Class<T> fragment) {
+ public <T extends Fragment> T getFragment(Class<T> fragment, ConfigurationTransition config) {
// TODO(bazel-team): The fragments can also be accessed directly through BuildConfiguration.
// Can we lock that down somehow?
- Preconditions.checkArgument(isLegalFragment(fragment),
- "%s does not have access to %s", rule.getRuleClass(), fragment);
- return getConfiguration().getFragment(fragment);
+ Preconditions.checkArgument(isLegalFragment(fragment, config),
+ "%s does not have access to '%s' in %s configuration", rule.getRuleClass(),
+ fragment.getSimpleName(), FragmentCollection.getConfigurationName(config));
+ return getConfiguration(config).getFragment(fragment);
+ }
+
+ @Nullable
+ public <T extends Fragment> T getFragment(Class<T> fragment) {
+ // NONE means target configuration.
+ return getFragment(fragment, ConfigurationTransition.NONE);
}
@Nullable
- public Fragment getSkylarkFragment(String name) {
- Class<? extends Fragment> fragmentClass = getConfiguration().getSkylarkFragmentByName(name);
- return (fragmentClass == null) ? null : getFragment(fragmentClass);
+ public Fragment getSkylarkFragment(String name, ConfigurationTransition config) {
+ Class<? extends Fragment> fragmentClass =
+ getConfiguration(config).getSkylarkFragmentByName(name);
+ return (fragmentClass == null) ? null : getFragment(fragmentClass, config);
+ }
+
+ public ImmutableCollection<String> getSkylarkFragmentNames(ConfigurationTransition config) {
+ return getConfiguration(config).getSkylarkFragmentNames();
}
- public ImmutableCollection<String> getSkylarkFragmentNames() {
- return getConfiguration().getSkylarkFragmentNames();
+ public <T extends Fragment> boolean isLegalFragment(
+ Class<T> fragment, ConfigurationTransition config) {
+ return rule.getRuleClassObject().isLegalConfigurationFragment(fragment, config);
}
public <T extends Fragment> boolean isLegalFragment(Class<T> fragment) {
- return rule.getRuleClassObject().isLegalConfigurationFragment(fragment);
+ // NONE means target configuration.
+ return isLegalFragment(fragment, ConfigurationTransition.NONE);
+ }
+
+ protected BuildConfiguration getConfiguration(ConfigurationTransition config) {
+ return config.equals(ConfigurationTransition.HOST) ? hostConfiguration : getConfiguration();
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java
index d649f47b51..a7d935a23c 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java
@@ -17,6 +17,7 @@ import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableCollection;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
import com.google.devtools.build.lib.syntax.ClassObject;
import com.google.devtools.build.lib.syntax.SkylarkModule;
@@ -30,30 +31,38 @@ import javax.annotation.Nullable;
@SkylarkModule(name = "fragments", documented = false, doc = "")
public class FragmentCollection implements ClassObject {
private final RuleContext ruleContext;
+ private final ConfigurationTransition config;
- public FragmentCollection(RuleContext ruleContext) {
+ public FragmentCollection(RuleContext ruleContext, ConfigurationTransition config) {
this.ruleContext = ruleContext;
+ this.config = config;
}
@Override
@Nullable
public Object getValue(String name) {
- return ruleContext.getSkylarkFragment(name);
+ return ruleContext.getSkylarkFragment(name, config);
}
@Override
public ImmutableCollection<String> getKeys() {
- return ruleContext.getSkylarkFragmentNames();
+ return ruleContext.getSkylarkFragmentNames(config);
}
@Override
@Nullable
public String errorMessage(String name) {
- return String.format("There is no configuration fragment named '%s'. Available fragments: %s",
- name, printKeys());
+ return String.format(
+ "There is no configuration fragment named '%s' in %s configuration. "
+ + "Available fragments: %s",
+ name, getConfigurationName(config), printKeys());
}
private String printKeys() {
return String.format("'%s'", Joiner.on("', '").join(getKeys()));
}
+
+ public static String getConfigurationName(ConfigurationTransition config) {
+ return (config == ConfigurationTransition.HOST) ? "host" : "target";
+ }
} \ No newline at end of file
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index 59fcbb595b..1202f0465c 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.syntax.Argument;
import com.google.devtools.build.lib.syntax.BaseFunction;
@@ -501,7 +502,8 @@ public final class RuleClass {
private SkylarkEnvironment ruleDefinitionEnvironment = null;
private Set<Class<?>> configurationFragments = new LinkedHashSet<>();
private MissingFragmentPolicy missingFragmentPolicy = MissingFragmentPolicy.FAIL_ANALYSIS;
- private Set<String> requiredFragmentNames = new LinkedHashSet<>();
+ private Map<ConfigurationTransition, ImmutableSet<String>> requiredFragmentNames =
+ new LinkedHashMap<>();
private FragmentClassNameResolver fragmentNameResolver;
private boolean supportsConstraintChecking = true;
@@ -590,7 +592,7 @@ public final class RuleClass {
configuredTargetFactory, validityPredicate, preferredDependencyPredicate,
ImmutableSet.copyOf(advertisedProviders), configuredTargetFunction,
externalBindingsFunction, ruleDefinitionEnvironment, configurationFragments,
- requiredFragmentNames, fragmentNameResolver, missingFragmentPolicy,
+ ImmutableMap.copyOf(requiredFragmentNames), fragmentNameResolver, missingFragmentPolicy,
supportsConstraintChecking, attributes.values().toArray(new Attribute[0]));
}
@@ -615,14 +617,18 @@ public final class RuleClass {
this.missingFragmentPolicy = missingFragmentPolicy;
return this;
}
-
+
/**
- * Does the same as {@link #requiresConfigurationFragments(Class...)}, except for taking names
- * of fragments instead of classes.
+ * Declares the configuration fragments that are required by this rule.
+ *
+ * <p>In contrast to {@link #requiresConfigurationFragments(Class...)}, this method a) takes the
+ * names of fragments instead of their classes and b) distinguishes whether the fragments can be
+ * accessed in host (HOST) or target (NONE) configuration.
*/
public Builder requiresConfigurationFragments(
- FragmentClassNameResolver fragmentNameResolver, String... configurationFragmentNames) {
- Collections.addAll(requiredFragmentNames, configurationFragmentNames);
+ FragmentClassNameResolver fragmentNameResolver,
+ Map<ConfigurationTransition, ImmutableSet<String>> configurationFragmentNames) {
+ requiredFragmentNames.putAll(configurationFragmentNames);
this.fragmentNameResolver = fragmentNameResolver;
return this;
}
@@ -974,10 +980,12 @@ public final class RuleClass {
private final ImmutableSet<Class<?>> requiredConfigurationFragments;
/**
- * Same idea as requiredConfigurationFragments, but stores fragments by name instead of by class
+ * A dictionary that maps configurations (NONE for target configuration, HOST for host
+ * configuration) to lists of names of required configuration fragments.
*/
- private final ImmutableSet<String> requiredConfigurationFragmentNames;
-
+ private final ImmutableMap<ConfigurationTransition, ImmutableSet<String>>
+ requiredConfigurationFragmentNames;
+
/**
* Used to resolve the names of fragments in order to compare them to values in {@link
* #requiredConfigurationFragmentNames}
@@ -1037,7 +1045,8 @@ public final class RuleClass {
externalBindingsFunction,
ruleDefinitionEnvironment,
allowedConfigurationFragments,
- ImmutableSet.<String>of(), null,
+ ImmutableMap.<ConfigurationTransition, ImmutableSet<String>>of(),
+ null, // FragmentClassNameResolver
missingFragmentPolicy,
supportsConstraintChecking,
attributes);
@@ -1078,7 +1087,7 @@ public final class RuleClass {
Function<? super Rule, Map<String, Label>> externalBindingsFunction,
@Nullable SkylarkEnvironment ruleDefinitionEnvironment,
Set<Class<?>> allowedConfigurationFragments,
- Set<String> allowedConfigurationFragmentNames,
+ ImmutableMap<ConfigurationTransition, ImmutableSet<String>> allowedConfigurationFragmentNames,
@Nullable FragmentClassNameResolver fragmentNameResolver,
MissingFragmentPolicy missingFragmentPolicy,
boolean supportsConstraintChecking,
@@ -1102,8 +1111,7 @@ public final class RuleClass {
this.workspaceOnly = workspaceOnly;
this.outputsDefaultExecutable = outputsDefaultExecutable;
this.requiredConfigurationFragments = ImmutableSet.copyOf(allowedConfigurationFragments);
- this.requiredConfigurationFragmentNames =
- ImmutableSet.copyOf(allowedConfigurationFragmentNames);
+ this.requiredConfigurationFragmentNames = allowedConfigurationFragmentNames;
this.fragmentNameResolver = fragmentNameResolver;
this.missingFragmentPolicy = missingFragmentPolicy;
this.supportsConstraintChecking = supportsConstraintChecking;
@@ -1260,24 +1268,32 @@ public final class RuleClass {
}
/**
- * Checks if the configuration fragment may be accessed (i.e., if it's declared). If no fragments
- * are declared, this allows access to all fragments for backwards compatibility.
+ * Checks if the configuration fragment may be accessed (i.e., if it's declared) in the specified
+ * configuration (target or host).
*/
- public boolean isLegalConfigurationFragment(Class<?> configurationFragment) {
+ public boolean isLegalConfigurationFragment(
+ Class<?> configurationFragment, ConfigurationTransition config) {
return requiredConfigurationFragments.contains(configurationFragment)
- || hasLegalFragmentName(configurationFragment);
+ || hasLegalFragmentName(configurationFragment, config);
+ }
+
+ public boolean isLegalConfigurationFragment(Class<?> configurationFragment) {
+ // NONE means target configuration.
+ return isLegalConfigurationFragment(configurationFragment, ConfigurationTransition.NONE);
}
/**
- * Checks whether the name of the given fragment class was declared as required fragment
+ * Checks whether the name of the given fragment class was declared as required fragment in the
+ * specified configuration (target or host).
*/
- private boolean hasLegalFragmentName(Class<?> configurationFragment) {
+ private boolean hasLegalFragmentName(
+ Class<?> configurationFragment, ConfigurationTransition config) {
if (fragmentNameResolver == null) {
return false;
}
String name = fragmentNameResolver.resolveName(configurationFragment);
- return (name != null && requiredConfigurationFragmentNames.contains(name));
+ return (name != null && requiredConfigurationFragmentNames.get(config).contains(name));
}
/**
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 {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
index af962f076a..d3909fbcf8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
@@ -36,6 +36,7 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.FragmentCollection;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.packages.Attribute;
+import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SkylarkImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.OutputFile;
@@ -94,9 +95,11 @@ public final class SkylarkRuleContext {
});
private final RuleContext ruleContext;
-
+
private final FragmentCollection fragments;
+ private final FragmentCollection hostFragments;
+
// TODO(bazel-team): support configurable attributes.
private final SkylarkClassObject attrObject;
@@ -120,7 +123,8 @@ public final class SkylarkRuleContext {
*/
public SkylarkRuleContext(RuleContext ruleContext) throws EvalException {
this.ruleContext = Preconditions.checkNotNull(ruleContext);
- fragments = new FragmentCollection(ruleContext);
+ fragments = new FragmentCollection(ruleContext, ConfigurationTransition.NONE);
+ hostFragments = new FragmentCollection(ruleContext, ConfigurationTransition.HOST);
HashMap<String, Object> outputsBuilder = new HashMap<>();
if (ruleContext.getRule().getRuleClassObject().outputsDefaultExecutable()) {
@@ -326,19 +330,28 @@ public final class SkylarkRuleContext {
return ruleContext.getLabel();
}
- @SkylarkCallable(
- name = "fragments",
- structField = true,
- doc =
- "Allows access to configuration fragments. Possible fields are <code>cpp</code>, "
- + "<code>java</code> and <code>jvm</code>. "
- + "However, rules have to declare their required fragments in order to access them "
- + "(see <a href=\"../rules.html#fragments\">here</a>)."
- )
+ @SkylarkCallable(name = "fragments", structField = true,
+ doc =
+ "Allows access to configuration fragments in target configuration. "
+ + "Possible fields are <code>cpp</code>, "
+ + "<code>java</code> and <code>jvm</code>. "
+ + "However, rules have to declare their required fragments in order to access them "
+ + "(see <a href=\"../rules.html#fragments\">here</a>).")
public FragmentCollection getFragments() {
return fragments;
}
+ @SkylarkCallable(name = "host_fragments", structField = true,
+ doc =
+ "Allows access to configuration fragments in host configuration. "
+ + "Possible fields are <code>cpp</code>, "
+ + "<code>java</code> and <code>jvm</code>. "
+ + "However, rules have to declare their required fragments in order to access them "
+ + "(see <a href=\"../rules.html#fragments\">here</a>).")
+ public FragmentCollection getHostFragments() {
+ return hostFragments;
+ }
+
@SkylarkCallable(name = "configuration", structField = true,
doc = "Returns the default configuration. See the <a href=\"configuration.html\">"
+ "configuration</a> type for more details.")