// 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.analysis.config; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.FileProvider; import com.google.devtools.build.lib.analysis.FilesToRunProvider; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.RunfilesProvider; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper; import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.Preconditions; import com.google.devtools.common.options.OptionsBase; import com.google.devtools.common.options.OptionsParser; import com.google.devtools.common.options.OptionsParsingException; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Implementation for the config_setting rule. * *
This is a "pseudo-rule" in that its purpose isn't to generate output artifacts
* from input artifacts. Rather, it provides configuration context to rules that
* depend on it.
*/
public class ConfigSetting implements RuleConfiguredTargetFactory {
@Override
public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException {
// Get the required flag=value settings for this rule.
Map For multi-value List options, returns true iff any of the option's values matches
* the expected value. This means, e.g. "--tool_tag=foo --tool_tag=bar" would match the
* expected condition { 'tool_tag': 'bar' }.
*
* For multi-value Map options, returns true iff the last instance with the same key as the
* expected key has the same value. This means, e.g. "--define foo=1 --define bar=2" would
* match { 'define': 'foo=1' }, but "--define foo=1 --define bar=2 --define foo=3" would not
* match. Note that the definition of --define states that the last instance takes precedence.
*/
private static boolean optionMatches(BuildConfiguration config, String optionName,
Object expectedValue) {
Object actualValue = config.getOptionValue(optionName);
if (actualValue == null) {
return expectedValue == null;
// Single-value case:
} else if (!config.allowsMultipleValues(optionName)) {
return actualValue.equals(expectedValue);
}
// Multi-value case:
Preconditions.checkState(actualValue instanceof List);
Preconditions.checkState(expectedValue instanceof List);
List> actualList = (List>) actualValue;
List> expectedList = (List>) expectedValue;
if (actualList.isEmpty() || expectedList.isEmpty()) {
return actualList.isEmpty() && expectedList.isEmpty();
}
// We're expecting a single value of a multi-value type: the options parser still embeds
// that single value within a List container. Retrieve it here.
Object expectedSingleValue = Iterables.getOnlyElement(expectedList);
// Multi-value map:
if (actualList.get(0) instanceof Map.Entry) {
Map.Entry, ?> expectedEntry = (Map.Entry, ?>) expectedSingleValue;
for (Map.Entry, ?> actualEntry : Lists.reverse((List