diff options
6 files changed, 58 insertions, 62 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleWatch1ExtensionRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleWatch1ExtensionRule.java index 6c9ac5a69a..d3826119a5 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleWatch1ExtensionRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleWatch1ExtensionRule.java @@ -17,7 +17,9 @@ package com.google.devtools.build.lib.rules.objc; import static com.google.devtools.build.lib.packages.Attribute.attr; import static com.google.devtools.build.lib.packages.BuildType.LABEL; import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; +import static com.google.devtools.build.lib.syntax.Type.STRING_LIST; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.analysis.BaseRuleClasses; import com.google.devtools.build.lib.analysis.RuleDefinition; @@ -35,6 +37,7 @@ public class AppleWatch1ExtensionRule implements RuleDefinition { private static final Iterable<String> ALLOWED_DEPS_RULE_CLASSES = ImmutableSet.of("objc_library", "objc_import"); static final String WATCH_APP_DEPS_ATTR = "app_deps"; + static final String WATCH_EXT_FAMILIES_ATTR = "ext_families"; @Override public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { @@ -69,6 +72,21 @@ public class AppleWatch1ExtensionRule implements RuleDefinition { .allowedRuleClasses(ALLOWED_DEPS_RULE_CLASSES) .allowedFileTypes() .cfg(AppleWatch1Extension.MINIMUM_OS_AND_SPLIT_ARCH_TRANSITION)) + /* <!-- #BLAZE_RULE(apple_watch1_extension).ATTRIBUTE(ext_families) --> + The device families to which the watch extension is targeted. + + This is known as the <code>TARGETED_DEVICE_FAMILY</code> build setting + in Xcode project files. It is a list of one or more of the strings + <code>"iphone"</code> and <code>"ipad"</code>. + + <p>By default this is set to <code>"iphone"</code>. If it is explicitly specified it may not + be empty.</p> + <p>The watch application is always built for <code>"watch"</code> for device builds and + <code>"iphone, watch"</code> for simulator builds. + <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ + .add( + attr(WATCH_EXT_FAMILIES_ATTR, STRING_LIST) + .value(ImmutableList.of(TargetDeviceFamily.IPHONE.getNameInRule()))) .build(); } 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 023b81ff80..ae9b7d8f48 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 @@ -1364,7 +1364,6 @@ public class ObjcRuleClasses { static final String WATCH_EXT_RESOURCES_ATTR = "ext_resources"; static final String WATCH_EXT_STRUCTURED_RESOURCES_ATTR = "ext_structured_resources"; static final String WATCH_EXT_STRINGS_ATTR = "ext_strings"; - static final String WATCH_EXT_FAMILIES_ATTR = "ext_families"; @Override public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { @@ -1401,21 +1400,6 @@ public class ObjcRuleClasses { <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ .add(attr(WATCH_EXT_ENTITLEMENTS_ATTR, LABEL) .allowedFileTypes(ENTITLEMENTS_TYPE)) - /* <!-- #BLAZE_RULE($watch_extension_bundle_rule).ATTRIBUTE(ext_families) --> - The device families to which the watch extension is targeted. - - This is known as the <code>TARGETED_DEVICE_FAMILY</code> build setting - in Xcode project files. It is a list of one or more of the strings - <code>"iphone"</code> and <code>"ipad"</code>. - - <p>By default this is set to <code>"iphone"</code>, if explicitly specified may not be - empty.</p> - <p>The watch application is always built for <code>"watch"</code> for device builds and - <code>"iphone, watch"</code> for simulator builds. - <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ - .add( - attr(WATCH_EXT_FAMILIES_ATTR, STRING_LIST) - .value(ImmutableList.of(TargetDeviceFamily.IPHONE.getNameInRule()))) /* <!-- #BLAZE_RULE($watch_extension_bundle_rule).ATTRIBUTE(ext_infoplists) --> Infoplist files to be merged. The merged output corresponds to <i>appname</i>-Info.plist in Xcode projects. Duplicate keys between infoplist files will cause an error if diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java index 476f274db9..9a1c601e5e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java @@ -297,12 +297,12 @@ public final class ReleaseBundlingSupport { throws InterruptedException { bundleSupport.registerActions(objcProvider); - registerCombineArchitecturesAction(); + Artifact combinedArchBinary = prepareCombinedArchitecturesArtifact(); registerCopyDsymFilesAction(dsymOutputType); registerCopyDsymPlistAction(dsymOutputType); registerCopyLinkmapFilesAction(); - registerSwiftStdlibActionsIfNecessary(); - registerSwiftSupportActionsIfNecessary(); + registerSwiftStdlibActionsIfNecessary(combinedArchBinary); + registerSwiftSupportActionsIfNecessary(combinedArchBinary); registerEmbedLabelPlistAction(); registerEnvironmentPlistAction(); @@ -806,17 +806,17 @@ public final class ReleaseBundlingSupport { return bundling.build(); } - private void registerCombineArchitecturesAction() { - // Skip combining binaries when building for watch as there is only one stub binary and it - // it should not be corrupted when combining. - if (bundleSupport.isBuildingForWatch()) { - return; + private Artifact prepareCombinedArchitecturesArtifact() { + Artifact dependentMultiArchBinary = attributes.dependentMultiArchBinary(); + if (dependentMultiArchBinary != null) { + return dependentMultiArchBinary; } Artifact resultingLinkedBinary = intermediateArtifacts.combinedArchitectureBinary(); new LipoSupport(ruleContext).registerCombineArchitecturesAction(linkedBinaries(), resultingLinkedBinary, platform); + return resultingLinkedBinary; } private NestedSet<Artifact> linkedBinaries() { @@ -1050,7 +1050,7 @@ public final class ReleaseBundlingSupport { } /** Registers an action to copy Swift standard library dylibs into app bundle. */ - private void registerSwiftStdlibActionsIfNecessary() { + private void registerSwiftStdlibActionsIfNecessary(Artifact combinedArchBinary) { if (!objcProvider.is(USES_SWIFT)) { return; } @@ -1061,7 +1061,7 @@ public final class ReleaseBundlingSupport { .add("Frameworks") .add("--platform") .add(platform.getLowerCaseNameInPlist()) - .addExecPath("--scan-executable", intermediateArtifacts.combinedArchitectureBinary()); + .addExecPath("--scan-executable", combinedArchBinary); ruleContext.registerAction( ObjcRuleClasses.spawnAppleEnvActionBuilder(ruleContext, platform) @@ -1069,12 +1069,12 @@ public final class ReleaseBundlingSupport { .setExecutable(attributes.swiftStdlibToolWrapper()) .setCommandLine(commandLine.build()) .addOutput(intermediateArtifacts.swiftFrameworksFileZip()) - .addInput(intermediateArtifacts.combinedArchitectureBinary()) + .addInput(combinedArchBinary) .build(ruleContext)); } /** Registers an action to copy Swift standard library dylibs into SwiftSupport root directory. */ - private void registerSwiftSupportActionsIfNecessary() { + private void registerSwiftSupportActionsIfNecessary(Artifact combinedArchBinary) { if (!objcProvider.is(USES_SWIFT)) { return; } @@ -1085,7 +1085,7 @@ public final class ReleaseBundlingSupport { .add("SwiftSupport/" + platform.getLowerCaseNameInPlist()) .add("--platform") .add(platform.getLowerCaseNameInPlist()) - .addExecPath("--scan-executable", intermediateArtifacts.combinedArchitectureBinary()); + .addExecPath("--scan-executable", combinedArchBinary); ruleContext.registerAction( ObjcRuleClasses.spawnAppleEnvActionBuilder(ruleContext, platform) @@ -1093,7 +1093,7 @@ public final class ReleaseBundlingSupport { .setExecutable(attributes.swiftStdlibToolWrapper()) .setCommandLine(commandLine.build()) .addOutput(intermediateArtifacts.swiftSupportZip()) - .addInput(intermediateArtifacts.combinedArchitectureBinary()) + .addInput(combinedArchBinary) .build(ruleContext)); } @@ -1183,6 +1183,24 @@ public final class ReleaseBundlingSupport { return ruleContext.getExecutablePrerequisite("ipa_post_processor", Mode.TARGET); } + /** + * Returns the multi-arch binary provided by the label under the "binary" attribute of the + * current rule, or null if there is no such binary available. + */ + @Nullable Artifact dependentMultiArchBinary() { + if (ruleContext.attributes().getAttributeDefinition("binary") == null) { + return null; + } + + for (ObjcProvider provider + : ruleContext.getPrerequisites("binary", Mode.DONT_CHECK, ObjcProvider.class)) { + if (!provider.get(ObjcProvider.MULTI_ARCH_LINKED_BINARIES).isEmpty()) { + return Iterables.getOnlyElement(provider.get(ObjcProvider.MULTI_ARCH_LINKED_BINARIES)); + } + } + return null; + } + NestedSet<? extends Artifact> dependentLinkedBinaries() { if (ruleContext.attributes().getAttributeDefinition("binary") == null) { return NestedSetBuilder.emptySet(Order.STABLE_ORDER); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/Watch2ExtensionSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/Watch2ExtensionSupport.java index e3b96a46ee..d65c31f780 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/Watch2ExtensionSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/Watch2ExtensionSupport.java @@ -18,11 +18,9 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.BUNDLE_FILE; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.GENERAL_RESOURCE_DIR; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.GENERAL_RESOURCE_FILE; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STRINGS; -import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingRule.FAMILIES_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_BUNDLE_ID_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_DEFAULT_PROVISIONING_PROFILE_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_ENTITLEMENTS_ATTR; -import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_FAMILIES_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_INFOPLISTS_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_PROVISIONING_PROFILE_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_RESOURCES_ATTR; @@ -44,10 +42,7 @@ 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.Platform.PlatformType; import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary; -import com.google.devtools.build.lib.rules.objc.TargetDeviceFamily.InvalidFamilyNameException; -import com.google.devtools.build.lib.rules.objc.TargetDeviceFamily.RepeatedFamilyNameException; import com.google.devtools.build.lib.syntax.Type; -import java.util.List; import javax.annotation.Nullable; /** @@ -102,19 +97,13 @@ public class Watch2ExtensionSupport { registerWatchExtensionAutomaticPlistAction(); - ImmutableSet<TargetDeviceFamily> families = attributes.families(); - - if (families.isEmpty()) { - ruleContext.attributeError(FAMILIES_ATTR, ReleaseBundling.INVALID_FAMILIES_ERROR); - } - ReleaseBundling.Builder releaseBundling = new ReleaseBundling.Builder() .setIpaArtifact(ipaArtifact) .setBundleId(attributes.bundleId()) .setProvisioningProfile(attributes.provisioningProfile()) .setProvisioningProfileAttributeName(WATCH_EXT_PROVISIONING_PROFILE_ATTR) - .setTargetDeviceFamilies(families) + .setTargetDeviceFamilies(ImmutableSet.of(TargetDeviceFamily.WATCH)) .setIntermediateArtifacts(intermediateArtifacts) .setInfoPlistsFromRule(attributes.infoPlists()) .addInfoplistInput(intermediateArtifacts.watchExtensionAutomaticPlist()) @@ -173,21 +162,6 @@ public class Watch2ExtensionSupport { this.ruleContext = ruleContext; } - /** - * Returns the value of the {@code families} attribute in a form that is more useful than a list - * of strings. Returns an empty set for any invalid {@code families} attribute value, including - * an empty list. - */ - ImmutableSet<TargetDeviceFamily> families() { - List<String> rawFamilies = - ruleContext.attributes().get(WATCH_EXT_FAMILIES_ATTR, Type.STRING_LIST); - try { - return ImmutableSet.copyOf(TargetDeviceFamily.fromNamesInRule(rawFamilies)); - } catch (InvalidFamilyNameException | RepeatedFamilyNameException e) { - return ImmutableSet.of(); - } - } - @Nullable Artifact provisioningProfile() { Artifact explicitProvisioningProfile = diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/WatchApplicationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/WatchApplicationSupport.java index 9153ace1f7..4e9feca5ea 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/WatchApplicationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/WatchApplicationSupport.java @@ -214,7 +214,10 @@ final class WatchApplicationSupport { } /** - * Returns the {@link TargetDeviceFamily} that the watch application bundle is targeting. + * Returns the {@link TargetDeviceFamily} that the watch application bundle is targeting. This + * is always {@code TargetDeviceFamily.WATCH}, except for WatchOS1, which has the following + * special rules: + * * For simulator builds, this returns a set of {@code TargetDeviceFamily.IPHONE} and * {@code TargetDeviceFamily.WATCH} and for non-simulator builds, this returns * {@code TargetDeviceFamily.WATCH}. @@ -222,7 +225,7 @@ final class WatchApplicationSupport { private ImmutableSet<TargetDeviceFamily> families() { Platform platform = ruleContext.getFragment(AppleConfiguration.class).getMultiArchPlatform(PlatformType.IOS); - if (platform == Platform.IOS_DEVICE) { + if (watchOSVersion != WatchOSVersion.OS1 || platform == Platform.IOS_DEVICE) { return ImmutableSet.of(TargetDeviceFamily.WATCH); } else { return ImmutableSet.of(TargetDeviceFamily.IPHONE, TargetDeviceFamily.WATCH); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/WatchExtensionSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/WatchExtensionSupport.java index a9730002fa..652e8a92b1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/WatchExtensionSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/WatchExtensionSupport.java @@ -24,7 +24,6 @@ import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.BundlingR import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_BUNDLE_ID_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_DEFAULT_PROVISIONING_PROFILE_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_ENTITLEMENTS_ATTR; -import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_FAMILIES_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_INFOPLISTS_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_PROVISIONING_PROFILE_ATTR; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.WatchExtensionBundleRule.WATCH_EXT_RESOURCES_ATTR; @@ -253,8 +252,8 @@ public class WatchExtensionSupport { * an empty list. */ ImmutableSet<TargetDeviceFamily> families() { - List<String> rawFamilies = ruleContext.attributes().get(WATCH_EXT_FAMILIES_ATTR, - Type.STRING_LIST); + List<String> rawFamilies = ruleContext.attributes().get( + AppleWatch1ExtensionRule.WATCH_EXT_FAMILIES_ATTR, Type.STRING_LIST); try { return ImmutableSet.copyOf(TargetDeviceFamily.fromNamesInRule(rawFamilies)); } catch (InvalidFamilyNameException | RepeatedFamilyNameException e) { |