// 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.config; import static com.google.devtools.build.lib.packages.Attribute.attr; import static com.google.devtools.build.lib.packages.BuildType.LABEL_KEYED_STRING_DICT; import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; import static com.google.devtools.build.lib.syntax.Type.STRING; import static com.google.devtools.build.lib.syntax.Type.STRING_DICT; import static com.google.devtools.build.lib.syntax.Type.STRING_LIST; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.analysis.BaseRuleClasses; import com.google.devtools.build.lib.analysis.PlatformConfiguration; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.Attribute.LabelListLateBoundDefault; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.syntax.Type; import java.util.List; /** * Definitions for rule classes that specify or manipulate configuration settings. * *
These are not "traditional" rule classes in that they can't be requested as top-level * targets and don't translate input artifacts into output artifacts. Instead, they affect * how *other* rules work. See individual class comments for details. */ public class ConfigRuleClasses { private static final String NONCONFIGURABLE_ATTRIBUTE_REASON = "part of a rule class that *triggers* configurable behavior"; /** * Common settings for all configurability rules. */ public static final class ConfigBaseRule implements RuleDefinition { @Override public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { return builder .override(attr("tags", Type.STRING_LIST) // No need to show up in ":all", etc. target patterns. .value(ImmutableList.of("manual")) .nonconfigurable(NONCONFIGURABLE_ATTRIBUTE_REASON)) .exemptFromConstraintChecking( "these rules don't include content that gets built into their dependers") .build(); } @Override public Metadata getMetadata() { return RuleDefinition.Metadata.builder() .name("$config_base_rule") .type(RuleClass.Builder.RuleClassType.ABSTRACT) .ancestors(BaseRuleClasses.BaseRule.class) .build(); } } /** * A named "partial configuration setting" that specifies a set of command-line * "flag=value" bindings. * *
For example: *
* config_setting( * name = 'foo', * values = { * 'flag1': 'aValue' * 'flag2': 'bValue' * }) ** *
declares a setting that binds command-line flag
flag1to value *
aValueand
flag2to
bValue. * *
This is used by configurable attributes to determine which branch to * follow based on which
config_settinginstance matches all its * flag values in the configurable attribute owner's configuration. * *
This rule isn't accessed through the standard {@link RuleContext#getPrerequisites} * interface. This is because Bazel constructs a rule's configured attribute map *before* * its {@link RuleContext} is created (in fact, the map is an input to the context's * constructor). And the config_settings referenced by the rule's configurable attributes are * themselves inputs to that map. So Bazel has special logic to read and properly apply * config_setting instances. See {@link ConfiguredTargetFunction#getConfigConditions} for details. */ public static final class ConfigSettingRule implements RuleDefinition { /** * The name of this rule. */ public static final String RULE_NAME = "config_setting"; /** The name of the attribute that declares flag bindings. */ public static final String SETTINGS_ATTRIBUTE = "values"; /** The name of the attribute that declares "--define foo=bar" flag bindings.*/ public static final String DEFINE_SETTINGS_ATTRIBUTE = "define_values"; /** The name of the attribute that declares user-defined flag bindings. */ public static final String FLAG_SETTINGS_ATTRIBUTE = "flag_values"; /** The name of the attribute that declares constraint_values. */ public static final String CONSTRAINT_VALUES_ATTRIBUTE = "constraint_values"; /** The name of the late bound attribute that declares the target platforms list. */ public static final String TARGET_PLATFORMS_ATTRIBUTE = ":target_platforms"; /** Implementation for the :target_platform attribute. */ public static final LabelListLateBoundDefault> TARGET_PLATFORMS = LabelListLateBoundDefault.fromTargetConfiguration( PlatformConfiguration.class, (rule, attributes, platformConfig) -> ConfigSettingRule.getTargetPlatformsIfRelevant(attributes, platformConfig)); private static ImmutableList