diff options
author | lberki <lberki@google.com> | 2017-08-24 10:08:17 +0200 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2017-08-24 14:00:15 +0200 |
commit | efba8c2f29624da2750f7f0f75f42955600ed720 (patch) | |
tree | b55dfd1c85d26a4c654030f808ba6c1e4ff72dfe /src/main/java/com/google | |
parent | a4634cfb8aa1ee6c6d4f304554ace8fe95782d67 (diff) |
Add an xcode_config_alias rule that is an alias to the current xcode_config rule in use and expose data in XcodeConfigProvider to Skylark.
This gives us a way to discover Xcode version information from Skylark in a way other than by AppleConfiguration, which in turn makes it possible to remove said data (and thus dependencies on BUILD files) from AppleConfiguration.
Work towards https://github.com/bazelbuild/bazel/issues/3424 .
RELNOTES: None.
PiperOrigin-RevId: 166311454
Diffstat (limited to 'src/main/java/com/google')
6 files changed, 132 insertions, 7 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java index 6111fe9757..97a55c02b5 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java @@ -88,6 +88,7 @@ import com.google.devtools.build.lib.rules.android.DexArchiveAspect; import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions; 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.XcodeConfigAlias.XcodeConfigAliasRule; import com.google.devtools.build.lib.rules.apple.XcodeConfigRule; import com.google.devtools.build.lib.rules.apple.XcodeVersionRule; import com.google.devtools.build.lib.rules.apple.cpp.AppleCcToolchainRule; @@ -592,6 +593,7 @@ public class BazelRuleClassProvider { builder.addRuleDefinition(new ObjcRuleClasses.WatchApplicationBundleRule()); builder.addRuleDefinition(new ObjcRuleClasses.CrosstoolRule()); builder.addRuleDefinition(new XcodeConfigRule()); + builder.addRuleDefinition(new XcodeConfigAliasRule()); builder.addRuleDefinition(new XcodeVersionRule()); } 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 fed83662a7..618647aaef 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 @@ -461,7 +461,7 @@ public class AppleConfiguration extends BuildConfiguration.Fragment { name = "single_arch_platform", doc = "The platform of the current configuration. This should only be invoked in a context " + "where only a single architecture may be supported; consider " - + "<a href='#multi_arch_platform'>mutli_arch_platform</a> for other cases.", + + "<a href='#multi_arch_platform'>multi_arch_platform</a> for other cases.", structField = true ) public ApplePlatform getSingleArchPlatform() { 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 42b3296551..d2b5859ef9 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 @@ -152,7 +152,7 @@ public class XcodeConfig implements RuleConfiguredTargetFactory { return new RuleConfiguredTargetBuilder(ruleContext) .addProvider(RunfilesProvider.class, RunfilesProvider.EMPTY) - .addProvider(xcodeVersions) + .addNativeDeclaredProvider(xcodeVersions) .addNativeDeclaredProvider(xcodeVersionProperties) .build(); } @@ -337,7 +337,7 @@ public class XcodeConfig implements RuleConfiguredTargetFactory { XcodeConfigProvider versions = ruleContext.getPrerequisite( XcodeConfigRule.XCODE_CONFIG_ATTR_NAME, RuleConfiguredTarget.Mode.TARGET, - XcodeConfigProvider.class); + XcodeConfigProvider.PROVIDER); DottedVersion fromProvider = versions.getMinimumOsForPlatformType(platformType); DottedVersion fromConfig = config.getMinimumOsForPlatformType(platformType); // This sanity check is there to keep this provider in sync with AppleConfiguration until the @@ -355,7 +355,7 @@ public class XcodeConfig implements RuleConfiguredTargetFactory { XcodeConfigProvider versions = ruleContext.getPrerequisite( XcodeConfigRule.XCODE_CONFIG_ATTR_NAME, RuleConfiguredTarget.Mode.TARGET, - XcodeConfigProvider.class); + XcodeConfigProvider.PROVIDER); DottedVersion fromProvider = versions.getSdkVersionForPlatform(platform); DottedVersion fromConfig = ruleContext.getFragment(AppleConfiguration.class) .getSdkVersionForPlatform(platform); @@ -373,7 +373,8 @@ public class XcodeConfig implements RuleConfiguredTargetFactory { public static DottedVersion getXcodeVersion(RuleContext ruleContext) { XcodeConfigProvider versions = ruleContext.getPrerequisite( XcodeConfigRule.XCODE_CONFIG_ATTR_NAME, - RuleConfiguredTarget.Mode.TARGET, XcodeConfigProvider.class); + RuleConfiguredTarget.Mode.TARGET, + XcodeConfigProvider.PROVIDER); DottedVersion fromProvider = versions.getXcodeVersion(); DottedVersion fromConfig = ruleContext.getFragment(AppleConfiguration.class).getXcodeVersion(); // This sanity check is there to keep this provider in sync with AppleConfiguration until the diff --git a/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigAlias.java b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigAlias.java new file mode 100644 index 0000000000..f3b56a5238 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/apple/XcodeConfigAlias.java @@ -0,0 +1,85 @@ +// Copyright 2017 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.collect.ImmutableMap; +import com.google.devtools.build.lib.analysis.AliasProvider; +import com.google.devtools.build.lib.analysis.BaseRuleClasses; +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; +import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; +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.analysis.VisibilityProvider; +import com.google.devtools.build.lib.analysis.VisibilityProviderImpl; +import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.rules.AliasConfiguredTarget; + +/** + * Implementation of the {@code xcode_config_alias} rule. + * + * <p>This rule is an alias to the {@code xcode_config} rule currently in use, which is in turn + * depends on the current configuration, in particular, the value of the {@code --xcode_config} + * flag. + */ +public class XcodeConfigAlias implements RuleConfiguredTargetFactory { + @Override + public ConfiguredTarget create(RuleContext ruleContext) + throws InterruptedException, RuleErrorException { + ConfiguredTarget actual = (ConfiguredTarget) ruleContext.getPrerequisite( + XcodeConfigRule.XCODE_CONFIG_ATTR_NAME, Mode.TARGET); + return new AliasConfiguredTarget( + ruleContext, + actual, + ImmutableMap.of( + AliasProvider.class, + AliasProvider.fromAliasRule(ruleContext.getLabel(), actual), + VisibilityProvider.class, + new VisibilityProviderImpl(ruleContext.getVisibility()))); + } + + /** + * Rule definition for the {@code xcode_config_alias} rule. + * + * <p>This rule is an alias to the {@code xcode_config} rule currently in use, which is in turn + * depends on the current configuration, in particular, the value of the {@code --xcode_config} + * flag. + * + * <p>This is intentionally undocumented for users; the workspace is expected to contain exactly + * one instance of this rule under {@code @bazel_tools//tools/osx} and people who want to get + * data this rule provides should depend on that one. + */ + public static class XcodeConfigAliasRule implements RuleDefinition { + + @Override + public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) { + return builder + .requiresConfigurationFragments(AppleConfiguration.class) + .removeAttribute("licenses") + .removeAttribute("distribs") + .build(); + } + + @Override + public Metadata getMetadata() { + return Metadata.builder() + .name("xcode_config_alias") + .ancestors(BaseRuleClasses.BaseRule.class, AppleToolchain.RequiresXcodeConfigRule.class) + .factoryClass(XcodeConfigAlias.class) + .build(); + } + } +} 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 index ce138da4dc..d711bd4506 100644 --- 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 @@ -14,15 +14,29 @@ package com.google.devtools.build.lib.rules.apple; import com.google.common.base.Preconditions; -import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; +import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.packages.NativeInfo; +import com.google.devtools.build.lib.packages.NativeProvider; +import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import javax.annotation.Nullable; /** * The set of Apple versions computed from command line options and the {@code xcode_config} rule. */ @Immutable -public class XcodeConfigProvider implements TransitiveInfoProvider { +@SkylarkModule( + name = XcodeConfigProvider.SKYLARK_NAME, + doc = "The set of Apple versions computed from command line options and the xcode_config rule.") +public class XcodeConfigProvider extends NativeInfo { + /** Skylark name for this provider. */ + public static final String SKYLARK_NAME = "XcodeVersionConfig"; + + /** Provider identifier for {@link XcodeConfigProvider}. */ + public static final NativeProvider<XcodeConfigProvider> PROVIDER = + new NativeProvider<XcodeConfigProvider>(XcodeConfigProvider.class, SKYLARK_NAME) {}; + private final DottedVersion iosSdkVersion; private final DottedVersion iosMinimumOsVersion; private final DottedVersion watchosSdkVersion; @@ -39,6 +53,7 @@ public class XcodeConfigProvider implements TransitiveInfoProvider { DottedVersion tvosSdkVersion, DottedVersion tvosMinimumOsVersion, DottedVersion macosSdkVersion, DottedVersion macosMinimumOsVersion, DottedVersion xcodeVersion) { + super(PROVIDER, ImmutableMap.of()); this.iosSdkVersion = Preconditions.checkNotNull(iosSdkVersion); this.iosMinimumOsVersion = Preconditions.checkNotNull(iosMinimumOsVersion); this.watchosSdkVersion = Preconditions.checkNotNull(watchosSdkVersion); @@ -50,10 +65,18 @@ public class XcodeConfigProvider implements TransitiveInfoProvider { this.xcodeVersion = xcodeVersion; } + @SkylarkCallable(name = "xcode_version", + doc = "Returns the Xcode version that is being used to build.<p>" + + "This will return <code>None</code> if no Xcode versions are available.", + allowReturnNones = true) public DottedVersion getXcodeVersion() { return xcodeVersion; } + @SkylarkCallable( + name = "minimum_os_for_platform_type", + doc = "The minimum compatible OS version for target simulator and devices for a particular " + + "platform type.") public DottedVersion getMinimumOsForPlatformType(ApplePlatform.PlatformType platformType) { // TODO(b/37240784): Look into using only a single minimum OS flag tied to the current // apple_platform_type. @@ -71,6 +94,10 @@ public class XcodeConfigProvider implements TransitiveInfoProvider { } } + @SkylarkCallable( + name = "sdk_version_for_platform", + doc = "The version of the platform SDK that will be used to build targets for the given " + + "platform.") public DottedVersion getSdkVersionForPlatform(ApplePlatform platform) { switch (platform) { case IOS_DEVICE: diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java index 4291fbed0d..be4df25559 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java @@ -26,6 +26,7 @@ import com.google.devtools.build.lib.rules.apple.ApplePlatform; import com.google.devtools.build.lib.rules.apple.ApplePlatform.PlatformType; import com.google.devtools.build.lib.rules.apple.AppleToolchain; import com.google.devtools.build.lib.rules.apple.DottedVersion; +import com.google.devtools.build.lib.rules.apple.XcodeConfigProvider; import com.google.devtools.build.lib.rules.apple.XcodeVersionProperties; import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key; import com.google.devtools.build.lib.skylarkinterface.Param; @@ -151,6 +152,15 @@ public class AppleSkylarkCommon { } @SkylarkCallable( + name = XcodeConfigProvider.SKYLARK_NAME, + doc = "The constructor/key for the <code>XcodeVersionConfig</code> provider.", + structField = true + ) + public Provider getXcodeVersionConfigConstructor() { + return XcodeConfigProvider.PROVIDER; + } + + @SkylarkCallable( // TODO(b/63899207): This currently does not match ObjcProvider.SKYLARK_NAME as it requires // a migration of existing skylark rules. name = "Objc", |