aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar Matthew DeVore <matvore@google.com>2015-02-20 15:48:41 +0000
committerGravatar Han-Wen Nienhuys <hanwen@google.com>2015-02-20 15:48:41 +0000
commit344bcbc4a2b4ca6f76b0b43929c0d8f0a3cc2662 (patch)
treec94fdbc893d38b454f81cdb5273ac7133e437ace /src/main/java/com/google
parent254aee40df78e79ac1b19fe6d20ae20bb05129a8 (diff)
Implement ios_extension rule. See IosExtensionRule.java for information on how app extensions are built and how they differ from application bundles.
RELNOTES: Support ios_extension and ios_extension_binary rules for creating iOS app extensions. -- MOS_MIGRATED_REVID=86788086
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/objc/BazelIosTestRule.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java36
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java58
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java81
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java102
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryRule.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcXcodeprojRule.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java (renamed from src/main/java/com/google/devtools/build/lib/rules/objc/ApplicationSupport.java)47
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java12
19 files changed, 284 insertions, 105 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 e6ab3674f6..18232e3f8f 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
@@ -72,6 +72,7 @@ import com.google.devtools.build.lib.rules.java.JvmConfigurationLoader;
import com.google.devtools.build.lib.rules.objc.IosApplicationRule;
import com.google.devtools.build.lib.rules.objc.IosDeviceRule;
import com.google.devtools.build.lib.rules.objc.IosExtensionBinaryRule;
+import com.google.devtools.build.lib.rules.objc.IosExtensionRule;
import com.google.devtools.build.lib.rules.objc.ObjcBinaryRule;
import com.google.devtools.build.lib.rules.objc.ObjcBundleLibraryRule;
import com.google.devtools.build.lib.rules.objc.ObjcBundleRule;
@@ -260,6 +261,7 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(ObjcRuleClasses.ResourceToolsRule.class);
builder.addRuleDefinition(IosApplicationRule.class);
builder.addRuleDefinition(IosExtensionBinaryRule.class);
+ builder.addRuleDefinition(IosExtensionRule.class);
builder.addRuleDefinition(BazelExtraActionRule.class);
builder.addRuleDefinition(BazelActionListenerRule.class);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/objc/BazelIosTestRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/objc/BazelIosTestRule.java
index d65de5c53c..d2454a363a 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/objc/BazelIosTestRule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/objc/BazelIosTestRule.java
@@ -24,8 +24,8 @@ import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
-import com.google.devtools.build.lib.rules.objc.ApplicationSupport;
import com.google.devtools.build.lib.rules.objc.ObjcRuleClasses;
+import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport;
import com.google.devtools.build.lib.rules.objc.XcodeSupport;
/**
@@ -51,7 +51,7 @@ public final class BazelIosTestRule implements RuleDefinition {
</ul>
<!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS -->*/
.setImplicitOutputsFunction(
- ImplicitOutputsFunction.fromFunctions(ApplicationSupport.IPA, XcodeSupport.PBXPROJ))
+ ImplicitOutputsFunction.fromFunctions(ReleaseBundlingSupport.IPA, XcodeSupport.PBXPROJ))
.add(attr(BazelIosTest.IOS_TEST_ON_BAZEL_ATTR, LABEL)
.value(env.getLabel("//tools/objc:ios_test_on_bazel")).exec())
.build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
index 0438091476..54ae2a1955 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java
@@ -27,11 +27,11 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
-import com.google.devtools.build.lib.rules.objc.ApplicationSupport.LinkedBinary;
import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkArgs;
import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkInputs;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes;
import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes;
+import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary;
/**
* Implementation for rules that link binaries.
@@ -41,17 +41,17 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
* Indicates whether this binary generates an application bundle. If so, it causes the
* {@code infoplist} attribute to be read and a bundle to be added to the files-to-build.
*/
- enum HasApplicationSupport {
+ enum HasReleaseBundlingSupport {
YES, NO;
}
- private final HasApplicationSupport hasApplicationSupport;
+ private final HasReleaseBundlingSupport hasReleaseBundlingSupport;
private final ExtraLinkArgs extraLinkArgs;
private final XcodeProductType productType;
- protected BinaryLinkingTargetFactory(HasApplicationSupport hasApplicationSupport,
+ protected BinaryLinkingTargetFactory(HasReleaseBundlingSupport hasReleaseBundlingSupport,
ExtraLinkArgs extraLinkArgs, XcodeProductType productType) {
- this.hasApplicationSupport = hasApplicationSupport;
+ this.hasReleaseBundlingSupport = hasReleaseBundlingSupport;
this.extraLinkArgs = extraLinkArgs;
this.productType = productType;
}
@@ -76,25 +76,25 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
.add(ObjcRuleClasses.intermediateArtifacts(ruleContext).singleArchitectureBinary());
new CompilationSupport(ruleContext)
- .registerJ2ObjcCompileAndArchiveActions(optionsProvider, common.getObjcProvider())
+ .registerJ2ObjcCompileAndArchiveActions(optionsProvider, objcProvider)
.registerCompileAndArchiveActions(common, optionsProvider)
.addXcodeSettings(xcodeProviderBuilder, common, optionsProvider)
- .registerLinkActions(common.getObjcProvider(), extraLinkArgs, new ExtraLinkInputs())
+ .registerLinkActions(objcProvider, extraLinkArgs, new ExtraLinkInputs())
.validateAttributes();
Optional<XcTestAppProvider> xcTestAppProvider;
- switch (hasApplicationSupport) {
+ switch (hasReleaseBundlingSupport) {
case YES:
// TODO(bazel-team): Remove once all bundle users are migrated to ios_application.
- ApplicationSupport applicationSupport = new ApplicationSupport(
- ruleContext, common.getObjcProvider(), optionsProvider,
- LinkedBinary.LOCAL_AND_DEPENDENCIES);
- applicationSupport
+ ReleaseBundlingSupport releaseBundlingSupport = new ReleaseBundlingSupport(
+ ruleContext, objcProvider, optionsProvider,
+ LinkedBinary.LOCAL_AND_DEPENDENCIES, "Payload/%s.app");
+ releaseBundlingSupport
.registerActions()
.addXcodeSettings(xcodeProviderBuilder)
.addFilesToBuild(filesToBuild)
.validateAttributes();
- xcTestAppProvider = Optional.of(applicationSupport.xcTestAppProvider());
+ xcTestAppProvider = Optional.of(releaseBundlingSupport.xcTestAppProvider());
break;
case NO:
xcTestAppProvider = Optional.absent();
@@ -111,8 +111,10 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
XcodeSupport xcodeSupport = new XcodeSupport(ruleContext)
// TODO(bazel-team): Use LIBRARY_STATIC as parameter instead of APPLICATION once objc_binary
// no longer creates an application bundle
- .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), productType)
- .addDependencies(xcodeProviderBuilder)
+ .addXcodeSettings(xcodeProviderBuilder, objcProvider, productType)
+ .addDependencies(xcodeProviderBuilder, "bundles")
+ .addDependencies(xcodeProviderBuilder, "deps")
+ .addDependencies(xcodeProviderBuilder, "non_propagated_deps")
.addFilesToBuild(filesToBuild);
XcodeProvider xcodeProvider = xcodeProviderBuilder.build();
xcodeSupport.registerActions(xcodeProvider);
@@ -122,7 +124,7 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
return common.configuredTarget(
filesToBuild.build(),
Optional.of(xcodeProvider),
- Optional.<ObjcProvider>absent(),
+ Optional.of(objcProvider),
xcTestAppProvider,
Optional.<J2ObjcSrcsProvider>absent());
}
@@ -132,7 +134,7 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
.addCopts(ruleContext.getTokenizedStringListAttr("copts"))
.addTransitive(Optional.fromNullable(
ruleContext.getPrerequisite("options", Mode.TARGET, OptionsProvider.class)));
- if (hasApplicationSupport == HasApplicationSupport.YES) {
+ if (hasReleaseBundlingSupport == HasReleaseBundlingSupport.YES) {
provider
.addInfoplists(ruleContext.getPrerequisiteArtifacts("infoplist", Mode.TARGET).list());
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java
index 695dffc4d6..224e9bf449 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/BundleMergeControlBytes.java
@@ -54,14 +54,13 @@ final class BundleMergeControlBytes extends ByteSource {
@Override
public InputStream openStream() {
- return control("Payload/", "Payload/", rootBundling)
+ return control("", rootBundling)
.toByteString()
.newInput();
}
- private Control control(String mergeZipPrefix, String bundleDirPrefix, Bundling bundling) {
+ private Control control(String mergeZipPrefix, Bundling bundling) {
ObjcProvider objcProvider = bundling.getObjcProvider();
- String bundleDir = bundleDirPrefix + bundling.getBundleDir();
mergeZipPrefix += bundling.getBundleDir() + "/";
BundleMergeProtos.Control.Builder control = BundleMergeProtos.Control.newBuilder()
@@ -73,7 +72,7 @@ final class BundleMergeControlBytes extends ByteSource {
.setMinimumOsVersion(objcConfiguration.getMinimumOs())
.setSdkVersion(objcConfiguration.getIosSdkVersion())
.setPlatform(objcConfiguration.getPlatform().name())
- .setBundleRoot(bundleDir);
+ .setBundleRoot(bundling.getBundleDir());
for (Artifact mergeZip : bundling.getMergeZips()) {
control.addMergeZip(MergeZip.newBuilder()
@@ -113,7 +112,7 @@ final class BundleMergeControlBytes extends ByteSource {
}
for (Bundling nestedBundling : bundling.getObjcProvider().get(NESTED_BUNDLE)) {
- control.addNestedBundle(control(mergeZipPrefix, "", nestedBundling));
+ control.addNestedBundle(control(mergeZipPrefix, nestedBundling));
}
return control.build();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java b/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java
index 484c553678..7ba2f6ea7e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/Bundling.java
@@ -31,7 +31,7 @@ import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.xcode.util.Value;
+import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Map;
@@ -39,10 +39,10 @@ import java.util.Map;
* Contains information regarding the creation of an iOS bundle.
*/
@Immutable
-final class Bundling extends Value<Bundling> {
+final class Bundling {
static final class Builder {
private String name;
- private String bundleDirSuffix;
+ private String bundleDirFormat;
private ImmutableList<BundleableFile> extraBundleFiles = ImmutableList.of();
private ObjcProvider objcProvider;
private InfoplistMerging infoplistMerging;
@@ -53,8 +53,8 @@ final class Bundling extends Value<Bundling> {
return this;
}
- public Builder setBundleDirSuffix(String bundleDirSuffix) {
- this.bundleDirSuffix = bundleDirSuffix;
+ public Builder setBundleDirFormat(String bundleDirFormat) {
+ this.bundleDirFormat = bundleDirFormat;
return this;
}
@@ -98,7 +98,7 @@ final class Bundling extends Value<Bundling> {
if (!Iterables.isEmpty(objcProvider.get(LIBRARY))
|| !Iterables.isEmpty(objcProvider.get(IMPORTED_LIBRARY))) {
combinedArchitectureBinary =
- Optional.of(intermediateArtifacts.combinedArchitectureBinary(bundleDirSuffix));
+ Optional.of(intermediateArtifacts.combinedArchitectureBinary());
}
NestedSet<Artifact> mergeZips = NestedSetBuilder.<Artifact>stableOrder()
@@ -115,13 +115,13 @@ final class Bundling extends Value<Bundling> {
.addAll(Xcdatamodel.outputZips(objcProvider.get(XCDATAMODEL)))
.build();
- return new Bundling(name, bundleDirSuffix, combinedArchitectureBinary, extraBundleFiles,
+ return new Bundling(name, bundleDirFormat, combinedArchitectureBinary, extraBundleFiles,
objcProvider, infoplistMerging, actoolzipOutput, bundleContentArtifacts, mergeZips);
}
}
private final String name;
- private final String bundleDirSuffix;
+ private final String bundleDirFormat;
private final Optional<Artifact> combinedArchitectureBinary;
private final ImmutableList<BundleableFile> extraBundleFiles;
private final ObjcProvider objcProvider;
@@ -132,7 +132,7 @@ final class Bundling extends Value<Bundling> {
private Bundling(
String name,
- String bundleDirSuffix,
+ String bundleDirFormat,
Optional<Artifact> combinedArchitectureBinary,
ImmutableList<BundleableFile> extraBundleFiles,
ObjcProvider objcProvider,
@@ -140,36 +140,24 @@ final class Bundling extends Value<Bundling> {
Optional<Artifact> actoolzipOutput,
NestedSet<Artifact> bundleContentArtifacts,
NestedSet<Artifact> mergeZips) {
- super(new ImmutableMap.Builder<String, Object>()
- .put("name", name)
- .put("bundleDirSuffix", bundleDirSuffix)
- .put("combinedArchitectureBinary", combinedArchitectureBinary)
- .put("extraBundleFiles", extraBundleFiles)
- .put("objcProvider", objcProvider)
- .put("infoplistMerging", infoplistMerging)
- .put("actoolzipOutput", actoolzipOutput)
- .put("bundleContentArtifacts", bundleContentArtifacts)
- .put("mergeZips", mergeZips)
- .build());
- this.name = name;
- this.bundleDirSuffix = bundleDirSuffix;
- this.combinedArchitectureBinary = combinedArchitectureBinary;
- this.extraBundleFiles = extraBundleFiles;
- this.objcProvider = objcProvider;
- this.infoplistMerging = infoplistMerging;
- this.actoolzipOutput = actoolzipOutput;
- this.bundleContentArtifacts = bundleContentArtifacts;
- this.mergeZips = mergeZips;
+ this.name = Preconditions.checkNotNull(name);
+ this.bundleDirFormat = Preconditions.checkNotNull(bundleDirFormat);
+ this.combinedArchitectureBinary = Preconditions.checkNotNull(combinedArchitectureBinary);
+ this.extraBundleFiles = Preconditions.checkNotNull(extraBundleFiles);
+ this.objcProvider = Preconditions.checkNotNull(objcProvider);
+ this.infoplistMerging = Preconditions.checkNotNull(infoplistMerging);
+ this.actoolzipOutput = Preconditions.checkNotNull(actoolzipOutput);
+ this.bundleContentArtifacts = Preconditions.checkNotNull(bundleContentArtifacts);
+ this.mergeZips = Preconditions.checkNotNull(mergeZips);
}
/**
- * The bundle directory. For apps, {@code "Payload/" + bundleDir} is the directory in the bundle
- * zip archive in which every file is found including the linked binary, nested bundles, and
- * everything returned by {@link #getExtraBundleFiles()}. In an application bundle, for instance,
- * this function returns {@code "(name).app"}.
+ * The bundle directory. For apps, this would be {@code "Payload/TARGET_NAME.app"}, which is where
+ * in the bundle zip archive every file is found, including the linked binary, nested bundles, and
+ * everything returned by {@link #getExtraBundleFiles()}.
*/
public String getBundleDir() {
- return name + bundleDirSuffix;
+ return String.format(bundleDirFormat, name);
}
/**
@@ -241,7 +229,7 @@ final class Bundling extends Value<Bundling> {
public Map<String, String> variableSubstitutions() {
return ImmutableMap.of(
"EXECUTABLE_NAME", name,
- "BUNDLE_NAME", name + bundleDirSuffix,
+ "BUNDLE_NAME", new PathFragment(getBundleDir()).getBaseName(),
"PRODUCT_NAME", name);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
index d87b4fb52e..2961d2ae6a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java
@@ -111,12 +111,9 @@ final class IntermediateArtifacts {
/**
* Lipo binary generated by combining one or more linked binaries. This binary is the one included
* in generated bundles and invoked as entry point to the application.
- *
- * @param bundleDirSuffix suffix of the bundle containing this binary
*/
- public Artifact combinedArchitectureBinary(String bundleDirSuffix) {
- String baseName = ownerLabel.toPathFragment().getBaseName();
- return appendExtension(bundleDirSuffix + "/" + baseName);
+ public Artifact combinedArchitectureBinary() {
+ return appendExtension("_lipobin");
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java
new file mode 100644
index 0000000000..4b6079acd8
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java
@@ -0,0 +1,81 @@
+// Copyright 2014 Google Inc. 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.objc;
+
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MERGE_ZIP;
+
+import com.google.common.base.Optional;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary;
+
+/**
+ * Implementation for {@code ios_extension}.
+ */
+public class IosExtension implements RuleConfiguredTargetFactory {
+
+ @Override
+ public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException {
+ ObjcCommon common = common(ruleContext);
+
+ XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder();
+ NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
+
+ ReleaseBundlingSupport releaseBundlingSupport = new ReleaseBundlingSupport(
+ ruleContext, common.getObjcProvider(), optionsProvider(ruleContext),
+ LinkedBinary.DEPENDENCIES_ONLY, "PlugIns/%s.appex");
+ releaseBundlingSupport
+ .registerActions()
+ .addXcodeSettings(xcodeProviderBuilder)
+ .addFilesToBuild(filesToBuild)
+ .validateAttributes();
+
+ new XcodeSupport(ruleContext)
+ .addFilesToBuild(filesToBuild)
+ .addXcodeSettings(
+ xcodeProviderBuilder, common.getObjcProvider(), XcodeProductType.EXTENSION)
+ .addDependencies(xcodeProviderBuilder, "binary")
+ .registerActions(xcodeProviderBuilder.build());
+
+ ObjcProvider nestedBundleProvider = new ObjcProvider.Builder()
+ .add(MERGE_ZIP, ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA))
+ .build();
+
+ return common.configuredTarget(
+ filesToBuild.build(),
+ Optional.of(xcodeProviderBuilder.build()),
+ Optional.of(nestedBundleProvider),
+ Optional.<XcTestAppProvider>absent(),
+ Optional.<J2ObjcSrcsProvider>absent());
+ }
+
+ private OptionsProvider optionsProvider(RuleContext ruleContext) {
+ return new OptionsProvider.Builder()
+ .addInfoplists(ruleContext.getPrerequisiteArtifacts("infoplist", Mode.TARGET).list())
+ .build();
+ }
+
+ private ObjcCommon common(RuleContext ruleContext) {
+ return new ObjcCommon.Builder(ruleContext)
+ .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
+ .addDepObjcProviders(
+ ruleContext.getPrerequisites("binary", Mode.TARGET, ObjcProvider.class))
+ .build();
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java
index c930a84005..cecc3d9f2c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java
@@ -21,7 +21,7 @@ import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkArgs
*/
public class IosExtensionBinary extends BinaryLinkingTargetFactory {
public IosExtensionBinary() {
- super(HasApplicationSupport.NO,
+ super(HasReleaseBundlingSupport.NO,
new ExtraLinkArgs("-e", "_NSExtensionMain", "-fapplication-extension"),
XcodeProductType.LIBRARY_STATIC);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java
new file mode 100644
index 0000000000..a3491e0b9d
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java
@@ -0,0 +1,102 @@
+// Copyright 2015 Google Inc. 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.objc;
+
+import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.Type.LABEL;
+
+import com.google.devtools.build.lib.analysis.BaseRuleClasses;
+import com.google.devtools.build.lib.analysis.BlazeRule;
+import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.packages.ImplicitOutputsFunction;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.RuleClass.Builder;
+
+/**
+ * Rule definition for ios_extension.
+ */
+@BlazeRule(name = "ios_extension",
+ factoryClass = IosExtension.class,
+ ancestors = {
+ BaseRuleClasses.BaseRule.class,
+ ObjcRuleClasses.ReleaseBundlingRule.class,
+ ObjcRuleClasses.XcodegenRule.class })
+public class IosExtensionRule implements RuleDefinition {
+ @Override
+ public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
+ return builder
+ /*<!-- #BLAZE_RULE(ios_extension).IMPLICIT_OUTPUTS -->
+ <ul>
+ <li><code><var>name</var>.ipa</code>: the extension bundle as an <code>.ipa</code>
+ file</li>
+ <li><code><var>name</var>.xcodeproj/project.pbxproj</code>: An Xcode project file which
+ can be used to develop or build on a Mac.</li>
+ </ul>
+ <!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS -->*/
+ .setImplicitOutputsFunction(
+ ImplicitOutputsFunction.fromFunctions(ReleaseBundlingSupport.IPA, XcodeSupport.PBXPROJ))
+ /* <!-- #BLAZE_RULE(ios_extension).ATTRIBUTE(binary) -->
+ The binary target containing the logic for the extension.
+ ${SYNOPSIS}
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(attr("binary", LABEL)
+ .allowedRuleClasses("ios_extension_binary")
+ .allowedFileTypes()
+ .mandatory()
+ .direct_compile_time_input())
+ .build();
+ }
+}
+
+/*<!-- #BLAZE_RULE (NAME = ios_extension, TYPE = BINARY, FAMILY = Objective-C) -->
+
+${ATTRIBUTE_SIGNATURE}
+
+<p>This rule produces a bundled binary for an iOS app extension from a compiled binary and bundle
+metadata.</p>
+
+<p>An iOS app extension is a nested bundle that is located inside the application bundle and is
+released with it. An iOS app extension cannot be released alone, although this rule allows you to
+build an <code>.ipa</code> with only the extension.
+
+<p>Bundles generated by this rule use a bundle directory called
+<code>PlugIns/<var>target-name</var>.appex</code>, while an application bundle uses
+<code>Payload/<var>target-name</var>.app</code>. For instance, if an application call Foo has an app
+extension called Bar, the Bar extension bundle files will be stored in
+<code>Payload/Foo.app/PlugIns/Bar.appex</code> in the final application <code>.ipa</code>.
+
+<p>There are many similarities between app extensions and applications with little to no difference
+between how each thing is processed:
+<ul>
+ <li>both have entitlements and Info.plist files
+ <li>both are code-signed. Signing and merging happens in this order: the extension is code-signed,
+ bundles are merged, application is code-signed
+ <li>both can have an app icon and launch image, and of course asset catalogs and all kinds of
+ resources
+ <li>both have linked binaries. The app extension binary is different in that it is linked with
+ these additional flags:
+ <ul>
+ <li><code>-e _NSExtensionMain</code> - sets the entry point to a standard function in the
+ iOS runtime rather than <code>main()</code>
+ <li><code>-fapplicationextension</code>
+ </ul>
+</ul>
+
+${IMPLICIT_OUTPUTS}
+
+${ATTRIBUTE_DEFINITION}
+
+<!-- #END_BLAZE_RULE -->*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
index d814c84bc7..b1645ba7f8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java
@@ -26,9 +26,9 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
-import com.google.devtools.build.lib.rules.objc.ApplicationSupport.LinkedBinary;
import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkArgs;
import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraLinkInputs;
+import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary;
import java.util.ArrayList;
import java.util.List;
@@ -115,8 +115,10 @@ public abstract class IosTest implements RuleConfiguredTargetFactory {
.addXcodeSettings(xcodeProviderBuilder, common, optionsProvider)
.validateAttributes();
- new ApplicationSupport(
- ruleContext, common.getObjcProvider(), optionsProvider, LinkedBinary.LOCAL_AND_DEPENDENCIES)
+ ReleaseBundlingSupport releaseBundlingSupport = new ReleaseBundlingSupport(
+ ruleContext, common.getObjcProvider(), optionsProvider, LinkedBinary.LOCAL_AND_DEPENDENCIES,
+ "Payload/%s.app");
+ releaseBundlingSupport
.registerActions()
.addXcodeSettings(xcodeProviderBuilder)
.addFilesToBuild(filesToBuild)
@@ -129,7 +131,9 @@ public abstract class IosTest implements RuleConfiguredTargetFactory {
new XcodeSupport(ruleContext)
.addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), productType)
- .addDependencies(xcodeProviderBuilder)
+ .addDependencies(xcodeProviderBuilder, "bundles")
+ .addDependencies(xcodeProviderBuilder, "deps")
+ .addDependencies(xcodeProviderBuilder, "non_propagated_deps")
.addFilesToBuild(filesToBuild)
.registerActions(xcodeProviderBuilder.build());
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java
index 23bd8ea515..37b772b99e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java
@@ -24,7 +24,7 @@ public class ObjcBinary extends BinaryLinkingTargetFactory {
super(
// TODO(bazel-team): Remove the enum and delete all code depending on YES case once all
// bundle users are migrated to ios_application.
- HasApplicationSupport.YES,
+ HasReleaseBundlingSupport.YES,
new ExtraLinkArgs(),
// TODO(bazel-team): Use LIBRARY_STATIC as parameter instead of APPLICATION once objc_binary
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryRule.java
index 97c7ee41ea..7e16a213e5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinaryRule.java
@@ -47,7 +47,7 @@ public class ObjcBinaryRule implements RuleDefinition {
</ul>
<!-- #END_BLAZE_RULE.IMPLICIT_OUTPUTS -->*/
.setImplicitOutputsFunction(
- ImplicitOutputsFunction.fromFunctions(ApplicationSupport.IPA, XcodeSupport.PBXPROJ))
+ ImplicitOutputsFunction.fromFunctions(ReleaseBundlingSupport.IPA, XcodeSupport.PBXPROJ))
.build();
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
index 0e7f6b0962..253fe32814 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java
@@ -58,6 +58,7 @@ public class ObjcBundleLibrary implements RuleConfiguredTargetFactory {
new XcodeSupport(ruleContext)
.addFilesToBuild(filesToBuild)
.addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), BUNDLE)
+ .addDependencies(xcodeProviderBuilder, "bundles")
.registerActions(xcodeProviderBuilder.build());
ObjcProvider nestedBundleProvider = new ObjcProvider.Builder()
@@ -84,7 +85,7 @@ public class ObjcBundleLibrary implements RuleConfiguredTargetFactory {
ObjcRuleClasses.intermediateArtifacts(ruleContext);
return new Bundling.Builder()
.setName(ruleContext.getLabel().getName())
- .setBundleDirSuffix(".bundle")
+ .setBundleDirFormat("%s.bundle")
.setObjcProvider(common.getObjcProvider())
.setInfoplistMerging(
BundleSupport.infoPlistMerging(ruleContext, common.getObjcProvider(), optionsProvider))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
index 702f9c1809..c13b510882 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java
@@ -96,7 +96,9 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory {
new XcodeSupport(ruleContext)
.addFilesToBuild(filesToBuild)
.addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), LIBRARY_STATIC)
- .addDependencies(xcodeProviderBuilder)
+ .addDependencies(xcodeProviderBuilder, "bundles")
+ .addDependencies(xcodeProviderBuilder, "deps")
+ .addDependencies(xcodeProviderBuilder, "non_propagated_deps")
.registerActions(xcodeProviderBuilder.build());
return common.configuredTarget(
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 9041d7dc14..62cef87f72 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
@@ -350,7 +350,7 @@ public class ObjcRuleClasses {
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("bundles", LABEL_LIST)
.direct_compile_time_input()
- .allowedRuleClasses("objc_bundle", "objc_bundle_library")
+ .allowedRuleClasses("objc_bundle", "objc_bundle_library", "ios_extension")
.allowedFileTypes())
.add(attr("$momczip_deploy", LABEL).cfg(HOST)
.value(env.getLabel("//tools/objc:momczip_deploy.jar")))
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcXcodeprojRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcXcodeprojRule.java
index 0063c6da68..09be934efd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcXcodeprojRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcXcodeprojRule.java
@@ -53,6 +53,7 @@ public class ObjcXcodeprojRule implements RuleDefinition {
.allowedRuleClasses(
"objc_binary",
"ios_extension_binary",
+ "ios_extension",
"ios_test",
"objc_bundle_library",
"objc_import",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ApplicationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
index 67c6fcbf6d..e0dfb9c1af 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ApplicationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java
@@ -49,15 +49,15 @@ import java.util.Set;
import javax.annotation.Nullable;
/**
- * Support for application-generating ObjC rules. An application is generally composed of a
- * top-level {@link BundleSupport bundle}, potentially signed, as well as some debug information, if
- * {@link ObjcConfiguration#generateDebugSymbols() requested}.
+ * Support for released bundles, such as an application or extension. Such a bundle is generally
+ * composed of a top-level {@link BundleSupport bundle}, potentially signed, as well as some debug
+ * information, if {@link ObjcConfiguration#generateDebugSymbols() requested}.
*
* <p>Contains actions, validation logic and provider value generation.
*
* <p>Methods on this class can be called in any order without impacting the result.
*/
-public final class ApplicationSupport {
+public final class ReleaseBundlingSupport {
/**
* Template for the containing application folder.
@@ -113,17 +113,19 @@ public final class ApplicationSupport {
* dependencies
* @param linkedBinary whether to look for a linked binary from this rule and dependencies or just
* the latter
+ * @param bundleDirFormat format string representing the bundle's directory with a single
+ * placeholder for the target name (e.g. {@code "Payload/%s.app"})
*/
- ApplicationSupport(
+ ReleaseBundlingSupport(
RuleContext ruleContext, ObjcProvider objcProvider, OptionsProvider optionsProvider,
- LinkedBinary linkedBinary) {
+ LinkedBinary linkedBinary, String bundleDirFormat) {
this.linkedBinary = linkedBinary;
this.attributes = new Attributes(ruleContext);
this.ruleContext = ruleContext;
this.objcProvider = objcProvider;
this.families = ImmutableSet.copyOf(attributes.families());
this.intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext);
- bundling = bundling(ruleContext, objcProvider, optionsProvider);
+ bundling = bundling(ruleContext, objcProvider, optionsProvider, bundleDirFormat);
bundleSupport = new BundleSupport(ruleContext, families, bundling, extraActoolArgs());
}
@@ -133,7 +135,7 @@ public final class ApplicationSupport {
*
* @return this application support
*/
- ApplicationSupport validateAttributes() {
+ ReleaseBundlingSupport validateAttributes() {
bundleSupport.validateAttributes();
// No asset catalogs. That means you cannot specify app_icon or
@@ -166,7 +168,7 @@ public final class ApplicationSupport {
*
* @return this application support
*/
- ApplicationSupport registerActions() {
+ ReleaseBundlingSupport registerActions() {
bundleSupport.registerActions(objcProvider);
registerCombineArchitecturesAction();
@@ -218,7 +220,7 @@ public final class ApplicationSupport {
*
* @return this application support
*/
- ApplicationSupport addXcodeSettings(XcodeProvider.Builder xcodeProviderBuilder) {
+ ReleaseBundlingSupport addXcodeSettings(XcodeProvider.Builder xcodeProviderBuilder) {
bundleSupport.addXcodeSettings(xcodeProviderBuilder);
xcodeProviderBuilder.addXcodeprojBuildSettings(buildSettings());
@@ -231,7 +233,7 @@ public final class ApplicationSupport {
*
* @return this application support
*/
- ApplicationSupport addFilesToBuild(NestedSetBuilder<Artifact> filesToBuild) {
+ ReleaseBundlingSupport addFilesToBuild(NestedSetBuilder<Artifact> filesToBuild) {
NestedSetBuilder<Artifact> debugSymbolBuilder = NestedSetBuilder.<Artifact>stableOrder()
.addTransitive(objcProvider.get(ObjcProvider.DEBUG_SYMBOLS));
@@ -244,7 +246,7 @@ public final class ApplicationSupport {
.add(intermediateArtifacts.breakpadSym());
}
- filesToBuild.add(ruleContext.getImplicitOutputArtifact(ApplicationSupport.IPA))
+ filesToBuild.add(ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA))
// TODO(bazel-team): Fat binaries may require some merging of these file rather than just
// making them available.
.addTransitive(debugSymbolBuilder.build());
@@ -285,13 +287,14 @@ public final class ApplicationSupport {
return new ExtraActoolArgs(extraArgs.build());
}
- private Bundling bundling(
- RuleContext ruleContext, ObjcProvider objcProvider, OptionsProvider optionsProvider) {
+ private static Bundling bundling(
+ RuleContext ruleContext, ObjcProvider objcProvider, OptionsProvider optionsProvider,
+ String bundleDirFormat) {
ImmutableList<BundleableFile> extraBundleFiles;
ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
if (objcConfiguration.getPlatform() == Platform.DEVICE) {
extraBundleFiles = ImmutableList.of(new BundleableFile(
- attributes.provisioningProfile(),
+ new Attributes(ruleContext).provisioningProfile(),
PROVISIONING_PROFILE_BUNDLE_FILE));
} else {
extraBundleFiles = ImmutableList.of();
@@ -299,17 +302,17 @@ public final class ApplicationSupport {
return new Bundling.Builder()
.setName(ruleContext.getLabel().getName())
- .setBundleDirSuffix(".app")
+ .setBundleDirFormat(bundleDirFormat)
.setExtraBundleFiles(extraBundleFiles)
.setObjcProvider(objcProvider)
.setInfoplistMerging(
BundleSupport.infoPlistMerging(ruleContext, objcProvider, optionsProvider))
- .setIntermediateArtifacts(intermediateArtifacts)
+ .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
.build();
}
private void registerCombineArchitecturesAction() {
- Artifact resultingLinkedBinary = intermediateArtifacts.combinedArchitectureBinary(".app");
+ Artifact resultingLinkedBinary = intermediateArtifacts.combinedArchitectureBinary();
NestedSet<Artifact> linkedBinaries = linkedBinaries();
ruleContext.registerAction(ObjcActionsBuilder.spawnOnDarwinActionBuilder()
@@ -368,7 +371,7 @@ public final class ApplicationSupport {
return buildSettings.build();
}
- private ApplicationSupport registerSignBundleAction(
+ private ReleaseBundlingSupport registerSignBundleAction(
Artifact entitlements, Artifact ipaOutput, Artifact ipaUnsigned) {
// TODO(bazel-team): Support variable substitution
ruleContext.registerAction(ObjcActionsBuilder.spawnOnDarwinActionBuilder()
@@ -385,9 +388,9 @@ public final class ApplicationSupport {
+ codesignCommand(
attributes.provisioningProfile(),
entitlements,
- String.format("${t}/Payload/%s.app", ruleContext.getLabel().getName())) + " && "
+ "${t}/" + bundling.getBundleDir())
// Using zip since we need to preserve permissions
- + "cd \"${t}\" && /usr/bin/zip -q -r \"${signed_ipa}\" .")
+ + " && cd \"${t}\" && /usr/bin/zip -q -r \"${signed_ipa}\" .")
.addInput(ipaUnsigned)
.addInput(attributes.provisioningProfile())
.addInput(entitlements)
@@ -440,7 +443,7 @@ public final class ApplicationSupport {
.build(ruleContext));
}
- private ApplicationSupport registerExtractEntitlementsAction(Artifact entitlements) {
+ private ReleaseBundlingSupport registerExtractEntitlementsAction(Artifact entitlements) {
// See Apple Glossary (http://goo.gl/EkhXOb)
// An Application Identifier is constructed as: TeamID.BundleID
// TeamID is extracted from the provisioning profile.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java
index b244cd9839..e492f95a71 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java
@@ -345,7 +345,8 @@ public final class XcodeProvider implements TransitiveInfoProvider {
}
private static final EnumSet<XcodeProductType> CAN_LINK_PRODUCT_TYPES = EnumSet.of(
- XcodeProductType.APPLICATION, XcodeProductType.BUNDLE, XcodeProductType.UNIT_TEST);
+ XcodeProductType.APPLICATION, XcodeProductType.BUNDLE, XcodeProductType.UNIT_TEST,
+ XcodeProductType.EXTENSION);
private TargetControl targetControl() {
String buildFilePath = label.getPackageFragment().getSafePathString() + "/BUILD";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java
index 111fef27aa..7eec1b2a01 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java
@@ -16,7 +16,6 @@ package com.google.devtools.build.lib.rules.objc;
import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates;
-import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
@@ -89,16 +88,13 @@ public final class XcodeSupport {
}
/**
- * Adds dependencies to the given provider builder from the {@code deps} and {@code bundles}
- * attributes.
+ * Adds dependencies to the given provider builder from the given attribute.
*
* @return this xcode support
*/
- XcodeSupport addDependencies(XcodeProvider.Builder xcodeProviderBuilder) {
- for (String attribute : ImmutableSet.of("deps", "non_propagated_deps", "bundles")) {
- xcodeProviderBuilder.addDependencies(
- ruleContext.getPrerequisites(attribute, Mode.TARGET, XcodeProvider.class));
- }
+ XcodeSupport addDependencies(XcodeProvider.Builder xcodeProviderBuilder, String attribute) {
+ xcodeProviderBuilder
+ .addDependencies(ruleContext.getPrerequisites(attribute, Mode.TARGET, XcodeProvider.class));
return this;
}
}