use of com.google.devtools.build.lib.packages.Attribute.SplitTransition in project bazel by bazelbuild.
the class BazelConfigurationCollection method setupTransitions.
static BuildConfiguration setupTransitions(BuildConfiguration targetConfiguration, BuildConfiguration dataConfiguration, BuildConfiguration hostConfiguration, ListMultimap<SplitTransition<?>, BuildConfiguration> splitTransitionsTable) {
Set<BuildConfiguration> allConfigurations = new LinkedHashSet<>();
allConfigurations.add(targetConfiguration);
allConfigurations.add(dataConfiguration);
allConfigurations.add(hostConfiguration);
allConfigurations.addAll(splitTransitionsTable.values());
Table<BuildConfiguration, Transition, ConfigurationHolder> transitionBuilder = HashBasedTable.create();
for (BuildConfiguration from : allConfigurations) {
for (ConfigurationTransition transition : ConfigurationTransition.values()) {
BuildConfiguration to;
if (transition == ConfigurationTransition.HOST) {
to = hostConfiguration;
} else if (transition == ConfigurationTransition.DATA && from == targetConfiguration) {
to = dataConfiguration;
} else {
to = from;
}
transitionBuilder.put(from, transition, new ConfigurationHolder(to));
}
}
// collection.
for (BuildConfiguration config : allConfigurations) {
transitionBuilder.put(config, LipoTransition.LIPO_COLLECTOR, new ConfigurationHolder(config));
transitionBuilder.put(config, LipoTransition.TARGET_CONFIG_FOR_LIPO, new ConfigurationHolder(config.isHostConfiguration() ? null : config));
}
for (BuildConfiguration config : allConfigurations) {
// configuration.
if (config.isHostConfiguration() && config.getTransitions() != null) {
continue;
}
boolean isSplitConfig = splitTransitionsTable.values().contains(config);
// the split transition overwrites the cpu, which it usually does.
if (isSplitConfig && config.getTransitions() != null) {
continue;
}
Transitions outgoingTransitions = new BazelTransitions(config, transitionBuilder.row(config), // DependencyResolver.resolveLateBoundAttributes().
isSplitConfig ? ImmutableListMultimap.<SplitTransition<?>, BuildConfiguration>of() : splitTransitionsTable);
config.setConfigurationTransitions(outgoingTransitions);
}
return targetConfiguration;
}
use of com.google.devtools.build.lib.packages.Attribute.SplitTransition in project bazel by bazelbuild.
the class BazelConfigurationCollection method createConfigurations.
@Override
@Nullable
public BuildConfiguration createConfigurations(ConfigurationFactory configurationFactory, Cache<String, BuildConfiguration> cache, PackageProviderForConfigurations packageProvider, BuildOptions buildOptions, EventHandler eventHandler) throws InvalidConfigurationException, InterruptedException {
// Target configuration
BuildConfiguration targetConfiguration = configurationFactory.getConfiguration(packageProvider, buildOptions, false, cache);
if (targetConfiguration == null) {
return null;
}
BuildConfiguration dataConfiguration = targetConfiguration;
// Host configuration
// Note that this passes in the dataConfiguration, not the target
// configuration. This is intentional.
BuildConfiguration hostConfiguration = getHostConfigurationFromRequest(configurationFactory, packageProvider, dataConfiguration, buildOptions, cache);
if (hostConfiguration == null) {
return null;
}
ListMultimap<SplitTransition<?>, BuildConfiguration> splitTransitionsTable = ArrayListMultimap.create();
for (SplitTransition<BuildOptions> transition : buildOptions.getPotentialSplitTransitions()) {
for (BuildOptions splitOptions : transition.split(buildOptions)) {
BuildConfiguration splitConfig = configurationFactory.getConfiguration(packageProvider, splitOptions, false, cache);
splitTransitionsTable.put(transition, splitConfig);
}
}
if (packageProvider.valuesMissing()) {
return null;
}
BuildConfiguration result = setupTransitions(targetConfiguration, dataConfiguration, hostConfiguration, splitTransitionsTable);
result.reportInvalidOptions(eventHandler);
return result;
}
use of com.google.devtools.build.lib.packages.Attribute.SplitTransition in project bazel by bazelbuild.
the class ComposingSplitTransition method apply.
/**
* Applies the given transition over the given {@link BuildOptions}, returns the result.
*/
// TODO(gregce): move this somewhere more general. This isn't intrinsic to composed splits.
static List<BuildOptions> apply(BuildOptions fromOptions, Transition transition) {
if (transition == ConfigurationTransition.NONE) {
return ImmutableList.<BuildOptions>of(fromOptions);
} else if (transition instanceof PatchTransition) {
return ImmutableList.<BuildOptions>of(((PatchTransition) transition).apply(fromOptions));
} else if (transition instanceof SplitTransition) {
SplitTransition split = (SplitTransition<BuildOptions>) transition;
List<BuildOptions> splitOptions = split.split(fromOptions);
if (splitOptions.isEmpty()) {
Verify.verify(split.defaultsToSelf());
return ImmutableList.<BuildOptions>of(fromOptions);
} else {
return splitOptions;
}
} else {
throw new IllegalStateException(String.format("Unsupported composite transition type: %s", transition.getClass().getName()));
}
}
use of com.google.devtools.build.lib.packages.Attribute.SplitTransition in project bazel by bazelbuild.
the class RuleContext method getSplitPrerequisites.
/**
* Returns the a prerequisites keyed by the CPU of their configurations.
* If the split transition is not active (e.g. split() returned an empty
* list), the key is an empty Optional.
*/
public Map<Optional<String>, ? extends List<? extends TransitiveInfoCollection>> getSplitPrerequisites(String attributeName) {
checkAttribute(attributeName, Mode.SPLIT);
Attribute attributeDefinition = attributes().getAttributeDefinition(attributeName);
// Attribute.java doesn't have the BuildOptions symbol.
@SuppressWarnings("unchecked") SplitTransition<BuildOptions> transition = (SplitTransition<BuildOptions>) attributeDefinition.getSplitTransition(rule);
List<ConfiguredTarget> deps = targetMap.get(attributeName);
List<BuildOptions> splitOptions = transition.split(getConfiguration().getOptions());
if (splitOptions.isEmpty()) {
// The split transition is not active. Defer the decision on which CPU to use.
return ImmutableMap.of(Optional.<String>absent(), deps);
}
Set<String> cpus = new HashSet<>();
for (BuildOptions options : splitOptions) {
// This method should only be called when the split config is enabled on the command line, in
// which case this cpu can't be null.
cpus.add(options.get(BuildConfiguration.Options.class).cpu);
}
// Use an ImmutableListMultimap.Builder here to preserve ordering.
ImmutableListMultimap.Builder<Optional<String>, TransitiveInfoCollection> result = ImmutableListMultimap.builder();
for (TransitiveInfoCollection t : deps) {
if (t.getConfiguration() != null) {
result.put(Optional.of(t.getConfiguration().getCpu()), t);
} else {
// Source files don't have a configuration, so we add them to all architecture entries.
for (String cpu : cpus) {
result.put(Optional.of(cpu), t);
}
}
}
return Multimaps.asMap(result.build());
}
use of com.google.devtools.build.lib.packages.Attribute.SplitTransition in project bazel by bazelbuild.
the class SkylarkAttr method createAttribute.
private static Attribute.Builder<?> createAttribute(Type<?> type, SkylarkDict<String, Object> arguments, FuncallExpression ast, Environment env) throws EvalException, ConversionException {
// We use an empty name now so that we can set it later.
// This trick makes sense only in the context of Skylark (builtin rules should not use it).
Attribute.Builder<?> builder = Attribute.attr("", type);
Object defaultValue = arguments.get(DEFAULT_ARG);
if (!EvalUtils.isNullOrNone(defaultValue)) {
if (defaultValue instanceof UserDefinedFunction) {
// Computed attribute. Non label type attributes already caused a type check error.
SkylarkCallbackFunction callback = new SkylarkCallbackFunction((UserDefinedFunction) defaultValue, ast, env);
// SkylarkComputedDefaultTemplate needs to know the names of all attributes that it depends
// on. However, this method does not know anything about other attributes.
// We solve this problem by asking the SkylarkCallbackFunction for the parameter names used
// in the function definition, which must be the names of attributes used by the callback.
builder.value(new SkylarkComputedDefaultTemplate(type, callback.getParameterNames(), callback, ast.getLocation()));
} else {
builder.defaultValue(defaultValue, env.getGlobals().label());
}
}
for (String flag : SkylarkList.castSkylarkListOrNoneToList(arguments.get(FLAGS_ARG), String.class, FLAGS_ARG)) {
builder.setPropertyFlag(flag);
}
if (containsNonNoneKey(arguments, MANDATORY_ARG) && (Boolean) arguments.get(MANDATORY_ARG)) {
builder.setPropertyFlag("MANDATORY");
}
// TODO(laurentlb): Deprecated, remove in August 2016 (use allow_empty instead).
if (containsNonNoneKey(arguments, NON_EMPTY_ARG) && (Boolean) arguments.get(NON_EMPTY_ARG)) {
builder.setPropertyFlag("NON_EMPTY");
}
if (containsNonNoneKey(arguments, ALLOW_EMPTY_ARG) && !(Boolean) arguments.get(ALLOW_EMPTY_ARG)) {
builder.setPropertyFlag("NON_EMPTY");
}
if (containsNonNoneKey(arguments, EXECUTABLE_ARG) && (Boolean) arguments.get(EXECUTABLE_ARG)) {
builder.setPropertyFlag("EXECUTABLE");
if (!containsNonNoneKey(arguments, CONFIGURATION_ARG)) {
throw new EvalException(ast.getLocation(), "cfg parameter is mandatory when executable=True is provided. Please see " + "https://www.bazel.build/versions/master/docs/skylark/rules.html#configurations " + "for more details.");
}
}
// TODO(laurentlb): Deprecated, remove in August 2016 (use allow_single_file).
if (containsNonNoneKey(arguments, SINGLE_FILE_ARG) && (Boolean) arguments.get(SINGLE_FILE_ARG)) {
if (containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
throw new EvalException(ast.getLocation(), "Cannot specify both single_file (deprecated) and allow_single_file");
}
builder.setPropertyFlag("SINGLE_ARTIFACT");
}
if (containsNonNoneKey(arguments, ALLOW_FILES_ARG) && containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
throw new EvalException(ast.getLocation(), "Cannot specify both allow_files and allow_single_file");
}
if (containsNonNoneKey(arguments, ALLOW_FILES_ARG)) {
Object fileTypesObj = arguments.get(ALLOW_FILES_ARG);
setAllowedFileTypes(ALLOW_FILES_ARG, fileTypesObj, ast, builder);
} else if (containsNonNoneKey(arguments, ALLOW_SINGLE_FILE_ARG)) {
Object fileTypesObj = arguments.get(ALLOW_SINGLE_FILE_ARG);
setAllowedFileTypes(ALLOW_SINGLE_FILE_ARG, fileTypesObj, ast, builder);
builder.setPropertyFlag("SINGLE_ARTIFACT");
} else if (type.getLabelClass() == LabelClass.DEPENDENCY) {
builder.allowedFileTypes(FileTypeSet.NO_FILE);
}
Object ruleClassesObj = arguments.get(ALLOW_RULES_ARG);
if (ruleClassesObj != null && ruleClassesObj != Runtime.NONE) {
builder.allowedRuleClasses(SkylarkList.castSkylarkListOrNoneToList(ruleClassesObj, String.class, "allowed rule classes for attribute definition"));
}
List<Object> values = SkylarkList.castSkylarkListOrNoneToList(arguments.get(VALUES_ARG), Object.class, VALUES_ARG);
if (!Iterables.isEmpty(values)) {
builder.allowedValues(new AllowedValueSet(values));
}
if (containsNonNoneKey(arguments, PROVIDERS_ARG)) {
Object obj = arguments.get(PROVIDERS_ARG);
SkylarkType.checkType(obj, SkylarkList.class, PROVIDERS_ARG);
ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> providersList = buildProviderPredicate((SkylarkList<?>) obj, PROVIDERS_ARG, ast.getLocation());
builder.mandatoryProvidersList(providersList);
}
if (containsNonNoneKey(arguments, CONFIGURATION_ARG)) {
Object trans = arguments.get(CONFIGURATION_ARG);
if (trans.equals("data")) {
builder.cfg(ConfigurationTransition.DATA);
} else if (trans.equals("host")) {
builder.cfg(ConfigurationTransition.HOST);
} else if (trans instanceof SplitTransition<?>) {
builder.cfg((SplitTransition<?>) trans);
} else if (!trans.equals("target")) {
throw new EvalException(ast.getLocation(), "cfg must be either 'data', 'host', or 'target'.");
}
}
if (containsNonNoneKey(arguments, ASPECTS_ARG)) {
Object obj = arguments.get(ASPECTS_ARG);
SkylarkType.checkType(obj, SkylarkList.class, ASPECTS_ARG);
List<SkylarkAspect> aspects = ((SkylarkList<?>) obj).getContents(SkylarkAspect.class, "aspects");
for (SkylarkAspect aspect : aspects) {
builder.aspect(aspect, ast.getLocation());
}
}
return builder;
}
Aggregations