aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Chris Parsons <cparsons@google.com>2016-01-29 22:27:40 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-02-01 09:45:54 +0000
commit4be631ec58ad8aacec12c7bca76865ee63eb5669 (patch)
tree7d747712bd55118585544a311ceee40f57b7c11c /src
parentf941d56acfad5f8c819c81b494f806ea74ea7fd8 (diff)
Redesign xcode_config rule to be evaluated at the level of configuration instead of target depss
-- MOS_MIGRATED_REVID=113398355
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java73
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java23
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java206
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigProvider.java53
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigRule.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersion.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionRule.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionRuleData.java (renamed from src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionProvider.java)27
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java6
12 files changed, 229 insertions, 206 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
index 5ad748a217..de868a123f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleCommandLineOptions.java
@@ -131,6 +131,7 @@ public class AppleCommandLineOptions extends FragmentOptions {
if (getPlatform() == Platform.IOS_DEVICE) {
labelMap.put("default_provisioning_profile", defaultProvisioningProfile);
}
+ labelMap.put("xcode_version_config", xcodeVersionConfig);
}
/**
@@ -193,6 +194,7 @@ public class AppleCommandLineOptions extends FragmentOptions {
AppleCommandLineOptions host = (AppleCommandLineOptions) super.getHost(fallback);
// Set options needed in the host configuration.
+ host.xcodeVersionConfig = xcodeVersionConfig;
host.xcodeVersion = xcodeVersion;
host.appleBitcodeMode = appleBitcodeMode;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
index 73096ec15a..01265a618f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleConfiguration.java
@@ -48,17 +48,20 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
**/
public static final String APPLE_SDK_PLATFORM_ENV_NAME = "APPLE_SDK_PLATFORM";
+ private static final DottedVersion MINIMUM_BITCODE_XCODE_VERSION = DottedVersion.fromString("7");
+
private final DottedVersion iosSdkVersion;
private final String iosCpu;
- private final Optional<DottedVersion> xcodeVersionOverride;
+ private final Optional<DottedVersion> xcodeVersion;
private final List<String> iosMultiCpus;
private final AppleBitcodeMode bitcodeMode;
private final Label xcodeConfigLabel;
@Nullable private final Label defaultProvisioningProfileLabel;
- AppleConfiguration(AppleCommandLineOptions appleOptions) {
+ AppleConfiguration(AppleCommandLineOptions appleOptions,
+ Optional<DottedVersion> xcodeVersionOverride) {
this.iosSdkVersion = Preconditions.checkNotNull(appleOptions.iosSdkVersion, "iosSdkVersion");
- this.xcodeVersionOverride = Optional.fromNullable(appleOptions.xcodeVersion);
+ this.xcodeVersion = Preconditions.checkNotNull(xcodeVersionOverride);
this.iosCpu = Preconditions.checkNotNull(appleOptions.iosCpu, "iosCpu");
this.iosMultiCpus = Preconditions.checkNotNull(appleOptions.iosMultiCpus, "iosMultiCpus");
this.bitcodeMode = appleOptions.appleBitcodeMode;
@@ -76,14 +79,12 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
}
/**
- * Returns the value of the xcode version build flag if available. This is obtained directly from
- * the {@code --xcode_version} build flag.
- *
- * <p>Most rules should avoid using this flag value, and instead obtain the appropriate xcode
- * version from {@link XcodeConfigProvider#getXcodeVersion}.
+ * Returns the value of the xcode version, if available. This is determined based on a combination
+ * of the {@code --xcode_version} build flag and the {@code xcode_config} target defined in the
+ * {@code --xcode_version_config} flag.
*/
- public Optional<DottedVersion> getXcodeVersionOverrideFlag() {
- return xcodeVersionOverride;
+ public Optional<DottedVersion> getXcodeVersion() {
+ return xcodeVersion;
}
/**
@@ -97,6 +98,20 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
mapBuilder.putAll(appleTargetPlatformEnv(Platform.forIosArch(getIosCpu())));
return mapBuilder.build();
}
+
+ /**
+ * Returns a map of environment variables that should be propagated for actions that build on an
+ * apple host system. These environment variables are needed by the apple toolchain. Keys are
+ * variable names and values are their corresponding values.
+ */
+ public Map<String, String> getAppleHostSystemEnv() {
+ Optional<DottedVersion> xcodeVersion = getXcodeVersion();
+ ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+ if (xcodeVersion.isPresent()) {
+ builder.put(AppleConfiguration.XCODE_VERSION_ENV_NAME, xcodeVersion.get().toString());
+ }
+ return builder.build();
+ }
/**
* Returns a map of environment variables (derived from configuration) that should be propagated
@@ -198,8 +213,23 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
public AppleConfiguration create(ConfigurationEnvironment env, BuildOptions buildOptions)
throws InvalidConfigurationException {
AppleCommandLineOptions appleOptions = buildOptions.get(AppleCommandLineOptions.class);
+ Optional<DottedVersion> xcodeVersionFlag = getXcodeVersion(env, appleOptions);
+ AppleConfiguration configuration = new AppleConfiguration(appleOptions, xcodeVersionFlag);
- return new AppleConfiguration(appleOptions);
+ validate(configuration);
+ return configuration;
+ }
+
+ private void validate(AppleConfiguration config)
+ throws InvalidConfigurationException {
+ Optional<DottedVersion> xcodeVersion = config.getXcodeVersion();
+ if (config.getBitcodeMode() != AppleBitcodeMode.NONE
+ && xcodeVersion.isPresent()
+ && xcodeVersion.get().compareTo(MINIMUM_BITCODE_XCODE_VERSION) < 0) {
+ throw new InvalidConfigurationException(
+ String.format("apple_bitcode mode '%s' is unsupported for xcode version '%s'",
+ config.getBitcodeMode(), xcodeVersion.get()));
+ }
}
@Override
@@ -211,5 +241,26 @@ public class AppleConfiguration extends BuildConfiguration.Fragment {
public ImmutableSet<Class<? extends FragmentOptions>> requiredOptions() {
return ImmutableSet.<Class<? extends FragmentOptions>>of(AppleCommandLineOptions.class);
}
+
+ /**
+ * Uses the {@link AppleCommandLineOptions#xcodeVersion} and
+ * {@link AppleCommandLineOptions#xcodeVersionConfig} command line options to determine and
+ * return the effective xcode version. Returns absent if no explicit xcode version is
+ * declared, and host system defaults should be used.
+ *
+ * @param env the current configuration environment
+ * @param appleOptions the command line options
+ * @throws InvalidConfigurationException if the options given (or configuration targets) were
+ * malformed and thus the xcode version could not be determined
+ */
+ private Optional<DottedVersion> getXcodeVersion(ConfigurationEnvironment env,
+ AppleCommandLineOptions appleOptions) throws InvalidConfigurationException {
+ Optional<DottedVersion> xcodeVersionCommandLineFlag =
+ Optional.fromNullable(appleOptions.xcodeVersion);
+ Label xcodeVersionConfigLabel = appleOptions.xcodeVersionConfig;
+
+ return XcodeConfig.resolveXcodeVersion(env, xcodeVersionConfigLabel,
+ xcodeVersionCommandLineFlag, "xcode_version_config");
+ }
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
index e05b686760..bf55f10a67 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/AppleToolchain.java
@@ -20,7 +20,6 @@ import static com.google.devtools.build.lib.packages.BuildType.LABEL;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.RuleDefinition;
@@ -34,8 +33,6 @@ import com.google.devtools.build.lib.packages.RuleClass.Builder;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.XcodeprojBuildSetting;
-import java.util.Map;
-
/**
* Utility class for resolving items for the Apple toolchain (such as common tool flags, and paths).
*/
@@ -168,25 +165,7 @@ public class AppleToolchain {
}
});
}
-
- /**
- * Returns a map of environment variables (derived from configuration) that should be propagated
- * for actions that build on an apple host system. These environment variables are needed by
- * the apple toolchain. Keys are variable names and values are their corresponding values.
- *
- * @param configProvider info derived from the {@code xcode_config} rule targeted by the label
- * of the build flag {@code --xcode_config}
- */
- public static Map<String, String> appleHostSystemEnv(XcodeConfigProvider configProvider) {
- Preconditions.checkNotNull(configProvider);
- ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
- if (configProvider.getXcodeVersion().isPresent()) {
- builder.put(AppleConfiguration.XCODE_VERSION_ENV_NAME,
- configProvider.getXcodeVersion().get().toString());
- }
- return builder.build();
- }
-
+
/**
* Base rule definition to be ancestor for rules which may require an xcode toolchain.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
index eb789b3c50..1740a12de1 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfig.java
@@ -14,21 +14,28 @@
package com.google.devtools.build.lib.rules.apple;
-import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
-
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
-import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RedirectChaser;
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.analysis.config.ConfigurationEnvironment;
+import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.BuildType;
+import com.google.devtools.build.lib.packages.NoSuchPackageException;
+import com.google.devtools.build.lib.packages.NoSuchTargetException;
+import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
+import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
-import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions.AppleBitcodeMode;
+import com.google.devtools.build.lib.syntax.Type;
+import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
@@ -38,43 +45,40 @@ import javax.annotation.Nullable;
*/
public class XcodeConfig implements RuleConfiguredTargetFactory {
- private static final DottedVersion MINIMUM_BITCODE_XCODE_VERSION = DottedVersion.fromString("7");
-
@Override
public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException {
- AppleConfiguration configuration = ruleContext.getFragment(AppleConfiguration.class);
- Optional<DottedVersion> versionOverrideFlag = configuration.getXcodeVersionOverrideFlag();
-
- DottedVersion targetVersion = resolveExplicitlyDefinedVersion(ruleContext);
-
- XcodeConfigProvider xcodeConfigProvider;
- if (targetVersion == null) {
- if (versionOverrideFlag.isPresent()) {
- xcodeConfigProvider = new XcodeConfigProvider(versionOverrideFlag.get());
- } else {
- xcodeConfigProvider = XcodeConfigProvider.hostSystemDefault();
- }
- } else {
- xcodeConfigProvider = new XcodeConfigProvider(targetVersion);
- }
-
- validateXcodeConfig(ruleContext, configuration, xcodeConfigProvider);
-
return new RuleConfiguredTargetBuilder(ruleContext)
.addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY)
- .addProvider(XcodeConfigProvider.class, xcodeConfigProvider)
.build();
}
-
- private void validateXcodeConfig(RuleContext ruleContext, AppleConfiguration config,
- XcodeConfigProvider xcodeConfigProvider) {
- Optional<DottedVersion> xcodeVersion = xcodeConfigProvider.getXcodeVersion();
- if (config.getBitcodeMode() != AppleBitcodeMode.NONE
- && xcodeVersion.isPresent()
- && xcodeVersion.get().compareTo(MINIMUM_BITCODE_XCODE_VERSION) < 0) {
- ruleContext.ruleError(
- String.format("apple_bitcode mode '%s' is unsupported for xcode version '%s'",
- config.getBitcodeMode(), xcodeVersion.get()));
+
+ /**
+ * Uses the {@link AppleCommandLineOptions#xcodeVersion} and
+ * {@link AppleCommandLineOptions#xcodeVersionConfig} command line options to determine and
+ * return the effective xcode version.
+ *
+ * @param env the current configuration environment
+ * @param xcodeConfigLabel the label for the xcode_config target to parse
+ * @param xcodeVersionOverrideFlag the value of the command line flag to override the default
+ * xcode version, absent if unspecified
+ * @param errorDescription a description of the origin of {@code #xcodeConfigLabel} for messaging
+ * parse errors
+ * @throws InvalidConfigurationException if the options given (or configuration targets) were
+ * malformed and thus the xcode version could not be determined
+ */
+ public static Optional<DottedVersion> resolveXcodeVersion(ConfigurationEnvironment env,
+ Label xcodeConfigLabel, Optional<DottedVersion> xcodeVersionOverrideFlag,
+ String errorDescription) throws InvalidConfigurationException {
+ Rule xcodeConfigRule =
+ getRuleForLabel(xcodeConfigLabel, "xcode_config", env, errorDescription);
+
+ DottedVersion dottedVersion =
+ resolveExplicitlyDefinedVersion(env, xcodeConfigRule, xcodeVersionOverrideFlag);
+
+ if (dottedVersion != null) {
+ return Optional.of(dottedVersion);
+ } else {
+ return xcodeVersionOverrideFlag;
}
}
@@ -83,70 +87,126 @@ public class XcodeConfig implements RuleConfiguredTargetFactory {
* is an available {@code xcode_version} target which recognizes the flag value as either
* an official version or an alias. Returns null if no such target is found.
*/
- @Nullable private DottedVersion resolveExplicitlyDefinedVersion(RuleContext ruleContext) {
- AppleConfiguration configuration = ruleContext.getFragment(AppleConfiguration.class);
- Optional<DottedVersion> versionOverrideFlag = configuration.getXcodeVersionOverrideFlag();
+ @Nullable private static DottedVersion resolveExplicitlyDefinedVersion(
+ ConfigurationEnvironment env, Rule xcodeConfigTarget,
+ Optional<DottedVersion> versionOverrideFlag) throws InvalidConfigurationException {
if (versionOverrideFlag.isPresent()) {
// The version override flag is not necessarily an actual version - it may be a version
// alias.
- DottedVersion explicitVerison =
- aliasesToVersionMap(ruleContext).get(versionOverrideFlag.get().toString());
- if (explicitVerison != null) {
- return explicitVerison;
+ DottedVersion explicitVersion =
+ aliasesToVersionMap(env, xcodeConfigTarget).get(versionOverrideFlag.get().toString());
+ if (explicitVersion != null) {
+ return explicitVersion;
}
} else { // No override specified. Use default.
- XcodeVersionProvider defaultProvider = ruleContext.getPrerequisite(
- XcodeConfigRule.DEFAULT_ATTR_NAME, Mode.TARGET, XcodeVersionProvider.class);
-
- if (defaultProvider != null) {
- return defaultProvider.getVersion();
+ DottedVersion defaultVersion = getDefaultVersion(env, xcodeConfigTarget);
+
+ if (defaultVersion != null) {
+ return defaultVersion;
}
}
-
- boolean requireDefinedVersions = ruleContext.attributes().get(
- XcodeConfigRule.REQUIRE_DEFINED_VERSIONS_ATTR_NAME, BOOLEAN);
+
+ boolean requireDefinedVersions = NonconfigurableAttributeMapper.of(xcodeConfigTarget)
+ .get(XcodeConfigRule.REQUIRE_DEFINED_VERSIONS_ATTR_NAME, Type.BOOLEAN);
if (requireDefinedVersions) {
- ruleContext.ruleError(
+ throw new InvalidConfigurationException(
"xcode version config required an explicitly defined version, but none was available");
}
return null;
}
- private static Map<String, DottedVersion> aliasesToVersionMap(RuleContext ruleContext) {
- Iterable<XcodeVersionProvider> xcodeVersionProviders =
- ruleContext.getPrerequisites(XcodeConfigRule.VERSIONS_ATTR_NAME, Mode.TARGET,
- XcodeVersionProvider.class);
+ /**
+ * Returns the default xcode version to use, if no {@code --xcode_version} command line flag
+ * was specified.
+ */
+ @Nullable private static DottedVersion getDefaultVersion(ConfigurationEnvironment env,
+ Rule xcodeConfigTarget) throws InvalidConfigurationException {
+ Label defaultVersionLabel = NonconfigurableAttributeMapper.of(xcodeConfigTarget)
+ .get(XcodeConfigRule.DEFAULT_ATTR_NAME, BuildType.LABEL);
+ if (defaultVersionLabel != null) {
+ Rule defaultVersionRule = getRuleForLabel(
+ defaultVersionLabel, "xcode_version", env, "default xcode version");
+ return new XcodeVersionRuleData(defaultVersionLabel, defaultVersionRule).getVersion();
+ } else {
+ return null;
+ }
+ }
+
+ private static Map<String, DottedVersion> aliasesToVersionMap(ConfigurationEnvironment env,
+ Rule xcodeConfigTarget) throws InvalidConfigurationException {
+ List<Label> xcodeVersionLabels = NonconfigurableAttributeMapper.of(xcodeConfigTarget)
+ .get(XcodeConfigRule.VERSIONS_ATTR_NAME, BuildType.LABEL_LIST);
+ ImmutableList.Builder<XcodeVersionRuleData> xcodeVersionRuleListBuilder =
+ ImmutableList.builder();
+ for (Label label : xcodeVersionLabels) {
+ Rule xcodeVersionRule = getRuleForLabel(label, "xcode_version", env, "xcode_version");
+ xcodeVersionRuleListBuilder.add(new XcodeVersionRuleData(label, xcodeVersionRule));
+ }
+ ImmutableList<XcodeVersionRuleData> xcodeVersionRules = xcodeVersionRuleListBuilder.build();
Map<String, DottedVersion> aliasesToVersionMap = Maps.newLinkedHashMap();
- for (XcodeVersionProvider versionProvider : xcodeVersionProviders) {
- for (String alias : versionProvider.getAliases()) {
- if (aliasesToVersionMap.put(alias, versionProvider.getVersion()) != null) {
- ruleErrorDuplicateAlias(alias, ruleContext);
+ for (XcodeVersionRuleData xcodeVersionRule : xcodeVersionRules) {
+ for (String alias : xcodeVersionRule.getAliases()) {
+ if (aliasesToVersionMap.put(alias, xcodeVersionRule.getVersion()) != null) {
+ configErrorDuplicateAlias(alias, xcodeVersionRules);
}
}
if (aliasesToVersionMap.put(
- versionProvider.getVersion().toString(), versionProvider.getVersion()) != null) {
- ruleErrorDuplicateAlias(versionProvider.getVersion().toString(), ruleContext);
+ xcodeVersionRule.getVersion().toString(), xcodeVersionRule.getVersion()) != null) {
+ configErrorDuplicateAlias(xcodeVersionRule.getVersion().toString(), xcodeVersionRules);
}
}
return aliasesToVersionMap;
}
- private static void ruleErrorDuplicateAlias(String alias, RuleContext ruleContext) {
- Iterable<XcodeVersionProvider> xcodeVersionProviders =
- ruleContext.getPrerequisites(XcodeConfigRule.VERSIONS_ATTR_NAME, Mode.TARGET,
- XcodeVersionProvider.class);
-
+ /**
+ * Convenience method for throwing an {@link InvalidConfigurationException} due to presence
+ * of duplicate aliases in an {@code xcode_config} target definition.
+ */
+ private static void configErrorDuplicateAlias(String alias,
+ List<XcodeVersionRuleData> xcodeVersionRules) throws InvalidConfigurationException {
+
ImmutableList.Builder<Label> labelsContainingAlias = ImmutableList.builder();
- for (XcodeVersionProvider versionProvider : xcodeVersionProviders) {
- if (versionProvider.getAliases().contains(alias)
- || versionProvider.getVersion().toString().equals(alias)) {
- labelsContainingAlias.add(versionProvider.getLabel());
+ for (XcodeVersionRuleData xcodeVersionRule : xcodeVersionRules) {
+ if (xcodeVersionRule.getAliases().contains(alias)
+ || xcodeVersionRule.getVersion().toString().equals(alias)) {
+ labelsContainingAlias.add(xcodeVersionRule.getLabel());
+ }
+ }
+
+ throw new InvalidConfigurationException(
+ String.format("'%s' is registered to multiple labels (%s) in a single xcode_config rule",
+ alias, Joiner.on(", ").join(labelsContainingAlias.build())));
+ }
+
+ /**
+ * If the given label (following redirects) is a target for a rule of type {@code type},
+ * then returns the {@link Rule} representing that target. Otherwise, throws a
+ * {@link InvalidConfigurationException}.
+ */
+ private static Rule getRuleForLabel(Label label, String type, ConfigurationEnvironment env,
+ String description) throws InvalidConfigurationException {
+ label = RedirectChaser.followRedirects(env, label, description);
+
+ if (label == null) {
+ throw new InvalidConfigurationException(String.format(
+ "Expected value of %s (%s) to resolve to a target of type %s",
+ description, label, type));
+ }
+
+ try {
+ Target target = env.getTarget(label);
+
+ if (target instanceof Rule && ((Rule) target).getRuleClass().equals(type)) {
+ return (Rule) target;
+ } else {
+ throw new InvalidConfigurationException(String.format(
+ "Expected value of %s (%s) to resolve to a target of type %s",
+ description, label, type));
}
+ } catch (NoSuchPackageException | NoSuchTargetException exception) {
+ throw new InvalidConfigurationException(exception);
}
- ruleContext.ruleError(String.format(
- "'%s' is registered to multiple labels (%s) in a single xcode version "
- + "configuration", alias, Joiner.on(", ").join(labelsContainingAlias.build())));
}
} \ No newline at end of file
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigProvider.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigProvider.java
deleted file mode 100644
index 5241e04867..0000000000
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigProvider.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2015 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.apple;
-
-import com.google.common.base.Optional;
-import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
-import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-
-/**
- * Provides a version of xcode based on a combination of the {@code --xcode_version} build flag
- * and a {@code xcode_config} target. This version of xcode should be used for selecting apple
- * toolchains and SDKs.
- */
-@Immutable
-public final class XcodeConfigProvider implements TransitiveInfoProvider {
- private final Optional<DottedVersion> xcodeVersion;
-
- XcodeConfigProvider(DottedVersion xcodeVersion) {
- this.xcodeVersion = Optional.of(xcodeVersion);
- }
-
- private XcodeConfigProvider() {
- this.xcodeVersion = Optional.absent();
- }
-
- /**
- * Returns a {@link XcodeConfigProvider} with no xcode version specified. The host system
- * default xcode should be used. See {@link #getXcodeVersion}.
- */
- static XcodeConfigProvider hostSystemDefault() {
- return new XcodeConfigProvider();
- }
-
- /**
- * Returns either an explicit xcode version which should be used in actions which require an
- * apple toolchain, or {@link Optional#absent} if the host system default should be used.
- */
- public Optional<DottedVersion> getXcodeVersion() {
- return xcodeVersion;
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigRule.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigRule.java
index 58275f034f..ecfb643458 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigRule.java
@@ -47,7 +47,8 @@ public class XcodeConfigRule implements RuleDefinition {
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(attr(DEFAULT_ATTR_NAME, LABEL)
.allowedRuleClasses("xcode_version")
- .allowedFileTypes())
+ .allowedFileTypes()
+ .nonconfigurable("this rule determines configuration"))
/* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(version) -->
Accepted <code>xcode_version<code> targets that may be used.
If the value of the <code>xcode_version</code> build flag matches one of the aliases
@@ -56,14 +57,17 @@ public class XcodeConfigRule implements RuleDefinition {
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(attr(VERSIONS_ATTR_NAME, LABEL_LIST)
.allowedRuleClasses("xcode_version")
- .allowedFileTypes())
+ .allowedFileTypes()
+ .nonconfigurable("this rule determines configuration"))
/* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(version) -->
Whether to require the build's xcode version match one of the declared targets.
If true, this will raise an error if either the <code>xcode_version</code> flag value
or <code>default</code> attribute value do not match one of the versions declared
among <code>xcode_verison</code> targets.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
- .add(attr(REQUIRE_DEFINED_VERSIONS_ATTR_NAME, BOOLEAN).value(false))
+ .add(attr(REQUIRE_DEFINED_VERSIONS_ATTR_NAME, BOOLEAN)
+ .value(false)
+ .nonconfigurable("this rule determines configuration"))
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersion.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersion.java
index 2b363e6c62..f7e321f285 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersion.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersion.java
@@ -14,17 +14,12 @@
package com.google.devtools.build.lib.rules.apple;
-import static com.google.devtools.build.lib.syntax.Type.STRING;
-import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
-
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
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.rules.RuleConfiguredTargetFactory;
-import java.util.List;
-
/**
* Implementation for the {@code xcode_version} rule.
*/
@@ -32,15 +27,8 @@ public class XcodeVersion implements RuleConfiguredTargetFactory {
@Override
public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException {
- DottedVersion version = DottedVersion.fromString(
- ruleContext.attributes().get(XcodeVersionRule.VERSION_ATTR_NAME, STRING));
- List<String> aliases =
- ruleContext.attributes().get(XcodeVersionRule.ALIASES_ATTR_NAME, STRING_LIST);
-
return new RuleConfiguredTargetBuilder(ruleContext)
.addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY)
- .addProvider(XcodeVersionProvider.class,
- new XcodeVersionProvider(ruleContext.getLabel(), version, aliases))
.build();
}
} \ No newline at end of file
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionRule.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionRule.java
index d78337bcdf..f6e8274902 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionRule.java
@@ -41,13 +41,16 @@ public class XcodeVersionRule implements RuleDefinition {
/* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(version) -->
The official version number of a version of Xcode.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
- .add(attr(VERSION_ATTR_NAME, STRING).mandatory())
+ .add(attr(VERSION_ATTR_NAME, STRING)
+ .mandatory()
+ .nonconfigurable("this rule determines configuration"))
/* <!-- #BLAZE_RULE(proto_library).ATTRIBUTE(version) -->
Accepted aliases for this version of Xcode.
If the value of the <code>xcode_version</code> build flag matches any of the given
alias strings, this xcode version will be used.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
- .add(attr(ALIASES_ATTR_NAME, STRING_LIST))
+ .add(attr(ALIASES_ATTR_NAME, STRING_LIST)
+ .nonconfigurable("this rule determines configuration"))
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionProvider.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionRuleData.java
index f7b15b60d6..02bf38dc48 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeVersionRuleData.java
@@ -15,30 +15,35 @@
package com.google.devtools.build.lib.rules.apple;
import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
+import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.syntax.Type;
import java.util.List;
/**
- * Provides the information in a single {@code xcode_version} target. A single target of this rule
- * contains an official version label decided by Apple and a number of supported aliases one might
- * use to reference this version.
+ * A tuple containing the information in a single target of the {@code xcode_version} rule.
+ * A single target of this rule contains an official version label decided by Apple and a number
+ * of supported aliases one might use to reference this version.
*
* <p>For example, one may want to reference official xcode version 7.0.1 using the "7" or
* "7.0" aliases.
*/
-@Immutable
-public final class XcodeVersionProvider implements TransitiveInfoProvider {
+public class XcodeVersionRuleData {
private final Label label;
private final DottedVersion version;
private final ImmutableList<String> aliases;
-
- XcodeVersionProvider(Label label, DottedVersion version, List<String> aliases) {
+
+ XcodeVersionRuleData(Label label, Rule rule) {
+ NonconfigurableAttributeMapper attrMapper =
+ NonconfigurableAttributeMapper.of(rule);
+
this.label = label;
- this.version = version;
- this.aliases = ImmutableList.copyOf(aliases);
+ this.version = DottedVersion.fromString(
+ attrMapper.get(XcodeVersionRule.VERSION_ATTR_NAME, Type.STRING));
+ this.aliases = ImmutableList.copyOf(
+ attrMapper.get(XcodeVersionRule.ALIASES_ATTR_NAME, Type.STRING_LIST));
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
index 54bfe47c41..01d1899595 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
@@ -36,7 +36,6 @@ import com.google.devtools.build.lib.actions.PackageRootResolver;
import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.actions.extra.CppCompileInfo;
import com.google.devtools.build.lib.actions.extra.ExtraActionInfo;
-import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.PerLabelOptions;
@@ -51,9 +50,7 @@ import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.profiler.Profiler;
import com.google.devtools.build.lib.profiler.ProfilerTask;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
-import com.google.devtools.build.lib.rules.apple.AppleToolchain;
import com.google.devtools.build.lib.rules.apple.Platform;
-import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppCompileActionContext.Reply;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
@@ -157,9 +154,6 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
private final Iterable<IncludeScannable> lipoScannables;
private final CppCompileCommandLine cppCompileCommandLine;
private final boolean usePic;
- // TODO(bazel-team): Needed for lazily evaluating xcode configuration attribute. Remove when
- // this logic is refactored into crosstool expansion.
- private final RuleContext ruleContext;
@VisibleForTesting
final CppConfiguration cppConfiguration;
@@ -274,7 +268,6 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
this.lipoScannables = lipoScannables;
this.actionClassId = actionClassId;
this.usePic = usePic;
- this.ruleContext = ruleContext;
// We do not need to include the middleman artifact since it is a generated
// artifact and will definitely exist prior to this action execution.
@@ -612,9 +605,7 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable
// evaluation here.
AppleConfiguration appleConfiguration = configuration.getFragment(AppleConfiguration.class);
if (CppConfiguration.MAC_SYSTEM_NAME.equals(getHostSystemName())) {
- XcodeConfigProvider xcodeConfigProvider =
- ruleContext.getPrerequisite(":xcode_config", Mode.HOST, XcodeConfigProvider.class);
- environment.putAll(AppleToolchain.appleHostSystemEnv(xcodeConfigProvider));
+ environment.putAll(appleConfiguration.getAppleHostSystemEnv());
}
if (Platform.isApplePlatform(cppConfiguration.getTargetCpu())) {
environment.putAll(appleConfiguration.appleTargetPlatformEnv(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
index 99c880f8b6..23acbd12ad 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java
@@ -53,7 +53,6 @@ import com.google.devtools.build.lib.rules.apple.AppleToolchain;
import com.google.devtools.build.lib.rules.apple.AppleToolchain.RequiresXcodeConfigRule;
import com.google.devtools.build.lib.rules.apple.DottedVersion;
import com.google.devtools.build.lib.rules.apple.Platform;
-import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.FileTypeSet;
@@ -165,12 +164,10 @@ public class ObjcRuleClasses {
*/
static SpawnAction.Builder spawnXcrunActionBuilder(RuleContext ruleContext) {
AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
- XcodeConfigProvider xcodeConfigProvider =
- ruleContext.getPrerequisite(":xcode_config", Mode.HOST, XcodeConfigProvider.class);
ImmutableMap.Builder<String, String> envBuilder = ImmutableMap.<String, String>builder()
.putAll(appleConfiguration.getEnvironmentForIosAction())
- .putAll(AppleToolchain.appleHostSystemEnv(xcodeConfigProvider));
+ .putAll(appleConfiguration.getAppleHostSystemEnv());
return spawnOnDarwinActionBuilder()
.setEnvironment(envBuilder.build());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
index aca9e11dd5..ce49995630 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/TestSupport.java
@@ -32,8 +32,6 @@ import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Su
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
-import com.google.devtools.build.lib.rules.apple.AppleToolchain;
-import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider;
import com.google.devtools.build.lib.rules.test.TestEnvironmentProvider;
import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.FileType;
@@ -234,13 +232,11 @@ public class TestSupport {
*/
public Map<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> getExtraProviders() {
AppleConfiguration configuration = ruleContext.getFragment(AppleConfiguration.class);
- XcodeConfigProvider xcodeConfigProvider =
- ruleContext.getPrerequisite(":xcode_config", Mode.HOST, XcodeConfigProvider.class);
ImmutableMap.Builder<String, String> envBuilder = ImmutableMap.builder();
envBuilder.putAll(configuration.getEnvironmentForIosAction());
- envBuilder.putAll(AppleToolchain.appleHostSystemEnv(xcodeConfigProvider));
+ envBuilder.putAll(configuration.getAppleHostSystemEnv());
if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
envBuilder.put("COVERAGE_GCOV_PATH",