aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar Dmitry Shevchenko <dmishe@google.com>2015-08-11 18:19:18 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2015-08-12 15:22:22 +0000
commit6c630794b9a3eea04a2b9de0c00edfec920eff66 (patch)
tree3c0df31848ad8a91facf1bb1c6adbf526eb88f38 /src/main/java/com/google/devtools/build/lib
parentee5e5e17d1ab9b1f2bb10115b23ff1a70fccd014 (diff)
Experimental support for ios_framework rules
* Allows for building and linking to a framework in ios_application * Currently only works for single arch builds * Xcode generation produces correct target type, but is mostly untested The implementation is very similar to that of objc_framework: 1) Build the ios_framework_binary as a dynamic library (-dynamiclib) 2) Symlink the library and public headers to a staging location, inside of "X.framework" bundle. Where X is the name under ios_framework_binary#framework_name 3) Pass the bundle content to ObjcCommon.addFrameworkImports, reusing the core of objc_framework rule implementation. This results in correctly set -F/-framework flags and allows clients to use the framework in a way they would use any SDK/3rd-party framework. It's allowed to import headers via #import <X/X.h> call. 4) Copy the binary and all resources into final application bundle under Frameworks/X.framework 5) Sign the app and nested frameworks -- MOS_MIGRATED_REVID=100397239
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java22
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionBinary.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosFramework.java155
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkBinary.java49
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkBinaryRule.java65
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkProvider.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkRule.java86
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBinary.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java8
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcXcodeprojRule.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java39
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java53
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProductType.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java2
20 files changed, 521 insertions, 53 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 0944470754..b31168d619 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
@@ -101,6 +101,8 @@ 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.IosFrameworkBinaryRule;
+import com.google.devtools.build.lib.rules.objc.IosFrameworkRule;
import com.google.devtools.build.lib.rules.objc.J2ObjcLibraryBaseRule;
import com.google.devtools.build.lib.rules.objc.ObjcBinaryRule;
import com.google.devtools.build.lib.rules.objc.ObjcBuildInfoFactory;
@@ -333,6 +335,8 @@ public class BazelRuleClassProvider {
builder.addRuleDefinition(new IosApplicationRule());
builder.addRuleDefinition(new IosExtensionBinaryRule());
builder.addRuleDefinition(new IosExtensionRule());
+ builder.addRuleDefinition(new IosFrameworkBinaryRule());
+ builder.addRuleDefinition(new IosFrameworkRule());
builder.addRuleDefinition(new J2ObjcLibraryBaseRule());
builder.addRuleDefinition(new BazelJ2ObjcLibraryRule());
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 9117f07b89..21f4518f6f 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
@@ -49,16 +49,22 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
}
private final HasReleaseBundlingSupport hasReleaseBundlingSupport;
- private final ExtraLinkArgs extraLinkArgs;
private final XcodeProductType productType;
protected BinaryLinkingTargetFactory(HasReleaseBundlingSupport hasReleaseBundlingSupport,
- ExtraLinkArgs extraLinkArgs, XcodeProductType productType) {
+ XcodeProductType productType) {
this.hasReleaseBundlingSupport = hasReleaseBundlingSupport;
- this.extraLinkArgs = extraLinkArgs;
this.productType = productType;
}
+ /**
+ * Returns extra linker arguments. Default implementation returns empty list.
+ * Subclasses can override and customize.
+ */
+ protected ExtraLinkArgs getExtraLinkArgs(RuleContext ruleContext) {
+ return new ExtraLinkArgs();
+ }
+
@VisibleForTesting
static final String REQUIRES_AT_LEAST_ONE_LIBRARY_OR_SOURCE_FILE =
"At least one library dependency or source file is required.";
@@ -93,7 +99,8 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
.registerJ2ObjcCompileAndArchiveActions(objcProvider)
.registerCompileAndArchiveActions(common)
.addXcodeSettings(xcodeProviderBuilder, common)
- .registerLinkActions(objcProvider, extraLinkArgs, ImmutableList.<Artifact>of())
+ .registerLinkActions(objcProvider, getExtraLinkArgs(ruleContext),
+ ImmutableList.<Artifact>of())
.validateAttributes();
if (ruleContext.hasErrors()) {
@@ -160,6 +167,7 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
RunfilesSupport runfilesSupport = maybeRunfilesSupport.get();
targetBuilder.setRunfilesSupport(runfilesSupport, runfilesSupport.getExecutable());
}
+ configureTarget(targetBuilder, ruleContext);
return targetBuilder.build();
}
@@ -202,4 +210,10 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
return builder.build();
}
+
+ /**
+ * Performs additional configuration of the target. The default implementation does nothing, but
+ * subclasses may override it to add logic.
+ */
+ protected void configureTarget(RuleConfiguredTargetBuilder target, RuleContext ruleContext) {};
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
index 4aadc81b36..5af6e94f81 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CompilationSupport.java
@@ -20,6 +20,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FORCE_LOAD_L
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_DIR;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_CPP;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_FRAMEWORKS;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_SWIFT;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.HEADER;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY;
@@ -536,8 +537,12 @@ final class CompilationSupport {
}
if (objcProvider.is(USES_SWIFT)) {
+ commandLine.add("-L").add(IosSdkCommands.swiftLibDir(objcConfiguration));
+ }
+
+ if (objcProvider.is(USES_SWIFT) || objcProvider.is(USES_FRAMEWORKS)) {
+ // Enable loading bundled frameworks.
commandLine
- .add("-L").add(IosSdkCommands.swiftLibDir(objcConfiguration))
.add("-Xlinker").add("-rpath")
.add("-Xlinker").add("@executable_path/Frameworks");
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java
index 7b18b97b47..335acb8c3e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java
@@ -44,7 +44,7 @@ public class IosApplication extends ReleaseBundlingTargetFactory {
public IosApplication() {
super(ReleaseBundlingSupport.APP_BUNDLE_DIR_FORMAT, XcodeProductType.APPLICATION,
- ExposeAsNestedBundle.NO, DEPENDENCY_ATTRIBUTES, ConfigurationDistinguisher.APPLICATION);
+ DEPENDENCY_ATTRIBUTES, ConfigurationDistinguisher.APPLICATION);
}
@Override
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
index f16327d3c2..821fa5e8e1 100644
--- 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
@@ -14,6 +14,8 @@
package com.google.devtools.build.lib.rules.objc;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MERGE_ZIP;
+
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -48,8 +50,7 @@ public class IosExtension extends ReleaseBundlingTargetFactory {
public IosExtension() {
super(ReleaseBundlingSupport.EXTENSION_BUNDLE_DIR_FORMAT, XcodeProductType.EXTENSION,
- ExposeAsNestedBundle.YES, ImmutableSet.of(new Attribute("binary", Mode.SPLIT)),
- ConfigurationDistinguisher.EXTENSION);
+ ImmutableSet.of(new Attribute("binary", Mode.SPLIT)), ConfigurationDistinguisher.EXTENSION);
}
@Override
@@ -57,6 +58,14 @@ public class IosExtension extends ReleaseBundlingTargetFactory {
return determineMinimumOsVersion(ObjcRuleClasses.objcConfiguration(ruleContext).getMinimumOs());
}
+ @Override
+ protected ObjcProvider exposedObjcProvider(RuleContext ruleContext) {
+ // Nest this target's bundle under final IPA
+ return new ObjcProvider.Builder()
+ .add(MERGE_ZIP, ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA))
+ .build();
+ }
+
private static String determineMinimumOsVersion(String fromFlag) {
if (Double.parseDouble(fromFlag) < Double.parseDouble(EXTENSION_MINIMUM_OS_VERSION)) {
// Extensions are not accepted by Apple below version 8.0. While applications built with a
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 e85e4c44f5..77742442b8 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
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.rules.objc;
+import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
/**
@@ -21,8 +22,11 @@ import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs
*/
public class IosExtensionBinary extends BinaryLinkingTargetFactory {
public IosExtensionBinary() {
- super(HasReleaseBundlingSupport.NO,
- new ExtraLinkArgs("-e", "_NSExtensionMain", "-fapplication-extension"),
- XcodeProductType.LIBRARY_STATIC);
+ super(HasReleaseBundlingSupport.NO, XcodeProductType.LIBRARY_STATIC);
+ }
+
+ @Override
+ protected ExtraLinkArgs getExtraLinkArgs(RuleContext ruleContext) {
+ return new ExtraLinkArgs("-e", "_NSExtensionMain", "-fapplication-extension");
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosFramework.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFramework.java
new file mode 100644
index 0000000000..0774559a35
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFramework.java
@@ -0,0 +1,155 @@
+// 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.common.base.Preconditions.checkNotNull;
+import static com.google.devtools.build.lib.rules.objc.ObjcCommon.uniqueContainers;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FLAG;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_DIR;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.FRAMEWORK_FILE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.Flag.USES_FRAMEWORKS;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MERGE_ZIP;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+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.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.actions.SymlinkAction;
+import com.google.devtools.build.lib.rules.cpp.CcCommon;
+import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.SplitArchTransition.ConfigurationDistinguisher;
+import com.google.devtools.build.lib.vfs.PathFragment;
+
+/**
+ * Implementation for {@code ios_framework}.
+ */
+public class IosFramework extends ReleaseBundlingTargetFactory {
+
+ @VisibleForTesting static final String MINIMUM_OS_VERSION = "8.0";
+
+ public IosFramework() {
+ super(
+ ReleaseBundlingSupport.FRAMEWORK_BUNDLE_DIR_FORMAT,
+ XcodeProductType.FRAMEWORK,
+ ImmutableSet.of(new Attribute("binary", Mode.SPLIT)),
+ ConfigurationDistinguisher.FRAMEWORK);
+ }
+
+ @Override
+ protected String bundleName(RuleContext ruleContext) {
+ String frameworkName = null;
+
+ for (IosFrameworkProvider provider :
+ ruleContext.getPrerequisites("binary", Mode.SPLIT, IosFrameworkProvider.class)) {
+ frameworkName = provider.getFrameworkName();
+ }
+
+
+ return checkNotNull(frameworkName);
+ }
+
+ @Override
+ protected String bundleMinimumOsVersion(RuleContext ruleContext) {
+ String flagValue = ObjcRuleClasses.objcConfiguration(ruleContext).getMinimumOs();
+
+ return String.valueOf(
+ Math.max(Double.parseDouble(MINIMUM_OS_VERSION), Double.parseDouble(flagValue)));
+ }
+
+ /**
+ * Returns a map of original {@code Artifact} to symlinked {@code Artifact} inside framework
+ * bundle.
+ */
+ private ImmutableMap<Artifact, Artifact> getExtraArtifacts(RuleContext ruleContext) {
+ IntermediateArtifacts intermediateArtifacts =
+ ObjcRuleClasses.intermediateArtifacts(ruleContext);
+
+ ImmutableList<Artifact> headers = ImmutableList.copyOf(CcCommon.getHeaders(ruleContext));
+
+ ImmutableMap.Builder<Artifact, Artifact> builder = new ImmutableMap.Builder<>();
+
+ // Create framework binary
+ Artifact frameworkBinary =
+ outputArtifact(ruleContext, new PathFragment(bundleName(ruleContext)));
+ builder.put(intermediateArtifacts.combinedArchitectureBinary(), frameworkBinary);
+
+ // Create framework headers
+ for (Artifact header : headers) {
+ Artifact frameworkHeader =
+ outputArtifact(ruleContext, new PathFragment("Headers/" + header.getFilename()));
+
+ builder.put(header, frameworkHeader);
+ }
+
+ return builder.build();
+ }
+
+ @Override
+ protected ObjcProvider exposedObjcProvider(RuleContext ruleContext) {
+ // Assemble framework binary and headers in the label-scoped location, so that it's possible to
+ // pass -F X.framework to the compiler and -framework X to the linker. This mimics usage of
+ // frameworks when built from Xcode.
+
+ // To do this, we symlink all required artifacts into destination and pass them to
+ // FRAMEWORK_IMPORTS list, thus utilizing ObjcFramework rule to do the work of propagating
+ // them correctly.
+ Iterable<Artifact> frameworkImports = getExtraArtifacts(ruleContext).values();
+
+ ObjcProvider frameworkProvider =
+ new ObjcProvider.Builder()
+ .add(MERGE_ZIP, ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA))
+ .add(FLAG, USES_FRAMEWORKS)
+ .addAll(FRAMEWORK_FILE, frameworkImports)
+ .addAll(
+ FRAMEWORK_DIR,
+ uniqueContainers(frameworkImports, ObjcCommon.FRAMEWORK_CONTAINER_TYPE))
+ .build();
+
+ return frameworkProvider;
+ }
+
+ @Override
+ protected void configureTarget(
+ RuleConfiguredTargetBuilder target,
+ RuleContext ruleContext,
+ ReleaseBundlingSupport releaseBundlingSupport) {
+ // Create generating actions for framework artifacts
+ for (ImmutableMap.Entry<Artifact, Artifact> entry : getExtraArtifacts(ruleContext).entrySet()) {
+ ruleContext.registerAction(
+ new SymlinkAction(
+ ruleContext.getActionOwner(),
+ entry.getKey(),
+ entry.getValue(),
+ "Symlinking framework artifact"));
+ }
+ }
+
+ /**
+ * Returns an artifact at given path under "package/_frameworks/bundleName.framework" directory.
+ */
+ private Artifact outputArtifact(RuleContext ruleContext, PathFragment path) {
+ PathFragment frameworkRoot =
+ new PathFragment(
+ new PathFragment("_frameworks"),
+ new PathFragment(bundleName(ruleContext) + ".framework"),
+ path);
+
+ return ruleContext.getPackageRelativeArtifact(
+ frameworkRoot, ruleContext.getBinOrGenfilesDirectory());
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkBinary.java
new file mode 100644
index 0000000000..cd2930b5d9
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkBinary.java
@@ -0,0 +1,49 @@
+// 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 com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
+
+/**
+ * Implementation for the "ios_framework_binary" rule.
+ */
+public class IosFrameworkBinary extends BinaryLinkingTargetFactory {
+ public IosFrameworkBinary() {
+ super(HasReleaseBundlingSupport.NO, XcodeProductType.LIBRARY_STATIC);
+ }
+
+ @Override
+ protected ExtraLinkArgs getExtraLinkArgs(RuleContext ruleContext) {
+ String frameworkName = getFrameworkName(ruleContext);
+
+ return new ExtraLinkArgs(
+ "-dynamiclib",
+ String.format("-install_name @rpath/%1$s.framework/%1$s", frameworkName));
+ }
+
+ private String getFrameworkName(RuleContext ruleContext) {
+ return ruleContext.getLabel().getName();
+ }
+
+ @Override
+ protected void configureTarget(RuleConfiguredTargetBuilder target, RuleContext ruleContext) {
+ IosFrameworkProvider frameworkProvider =
+ new IosFrameworkProvider(getFrameworkName(ruleContext));
+
+ target.addProvider(IosFrameworkProvider.class, frameworkProvider);
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkBinaryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkBinaryRule.java
new file mode 100644
index 0000000000..af8f8b07bf
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkBinaryRule.java
@@ -0,0 +1,65 @@
+// 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 com.google.devtools.build.lib.analysis.BaseRuleClasses;
+import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.RuleClass.Builder;
+
+/**
+ * Rule definition for ios_framework_binary.
+ */
+public class IosFrameworkBinaryRule implements RuleDefinition {
+
+ @Override
+ public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
+ return builder
+ /*<!-- #BLAZE_RULE(ios_framework_binary).IMPLICIT_OUTPUTS -->
+ <ul>
+ <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(XcodeSupport.PBXPROJ)
+ // TODO(bazel-team): Add version fields that are passed to the linker as
+ // -compatibility_version X -current_version Y and then embedded into dynamic library.
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("ios_framework_binary")
+ .factoryClass(IosFrameworkBinary.class)
+ .ancestors(BaseRuleClasses.BaseRule.class, ObjcRuleClasses.LinkingRule.class,
+ ObjcRuleClasses.XcodegenRule.class)
+ .build();
+ }
+}
+
+/*<!-- #BLAZE_RULE (NAME = ios_framework_binary, TYPE = BINARY, FAMILY = Objective-C) -->
+
+${ATTRIBUTE_SIGNATURE}
+
+<p>This rule produces a dynamic library for a framework by linking one or more Objective-C
+libraries.</p>
+
+${IMPLICIT_OUTPUTS}
+
+${ATTRIBUTE_DEFINITION}
+
+<!-- #END_BLAZE_RULE -->*/ \ No newline at end of file
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkProvider.java
new file mode 100644
index 0000000000..b9e55186cf
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkProvider.java
@@ -0,0 +1,39 @@
+// 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 com.google.common.base.Preconditions;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+
+/**
+ * Provider for iOS Framework info.
+ */
+@Immutable
+public final class IosFrameworkProvider implements TransitiveInfoProvider {
+
+ private final String frameworkName;
+
+ public IosFrameworkProvider(String frameworkName) {
+ this.frameworkName = Preconditions.checkNotNull(frameworkName);
+ }
+
+ /**
+ * Returns the name of the framework.
+ */
+ public String getFrameworkName() {
+ return frameworkName;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkRule.java
new file mode 100644
index 0000000000..766b86ca17
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosFrameworkRule.java
@@ -0,0 +1,86 @@
+// 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 static com.google.devtools.build.lib.packages.Type.LABEL_LIST;
+
+import com.google.devtools.build.lib.analysis.BaseRuleClasses;
+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_framework.
+ */
+public class IosFrameworkRule implements RuleDefinition {
+
+ @Override
+ public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) {
+ return builder
+ // TODO(blaze-team): IPA is not right here, should probably be just zipped framework bundle.
+ .setImplicitOutputsFunction(
+ ImplicitOutputsFunction.fromFunctions(ReleaseBundlingSupport.IPA, XcodeSupport.PBXPROJ))
+ /* <!-- #BLAZE_RULE(ios_framework).ATTRIBUTE(binary) -->
+ The binary target included in the framework bundle.
+ ${SYNOPSIS}
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(attr("binary", LABEL)
+ .allowedRuleClasses("ios_framework_binary")
+ .allowedFileTypes()
+ .mandatory()
+ .direct_compile_time_input()
+ .cfg(IosExtension.MINIMUM_OS_AND_SPLIT_ARCH_TRANSITION))
+ /* <!-- #BLAZE_RULE(ios_framework).ATTRIBUTE(hdrs) -->
+ Public headers to include in the framework bundle.
+ ${SYNOPSIS}
+ <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
+ .add(attr("hdrs", LABEL_LIST)
+ .direct_compile_time_input()
+ .allowedFileTypes(ObjcRuleClasses.HDRS_TYPE))
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("ios_framework")
+ .factoryClass(IosFramework.class)
+ .ancestors(BaseRuleClasses.BaseRule.class, ObjcRuleClasses.ReleaseBundlingRule.class,
+ ObjcRuleClasses.XcodegenRule.class)
+ .build();
+ }
+}
+
+/*<!-- #BLAZE_RULE (NAME = ios_framework, TYPE = BINARY, FAMILY = Objective-C) -->
+
+${ATTRIBUTE_SIGNATURE}
+
+<p>This rule produces a bundled binary for a framework from a compiled binary and bundle
+metadata.</p>
+
+<p>A framework is a bundle that contains a dynamic library (the "binary"), public headers (that
+clients of the framework can use) and any resources. Framework headers are stripped out of the
+final app bundle and only used during compilation stage.
+
+<p>Bundles generated by this rule use a bundle directory called
+<code>Frameworks/<var>framework_name</var>.framework</code>.
+
+${ATTRIBUTE_DEFINITION}
+
+<!-- #END_BLAZE_RULE -->*/
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 02bf67f88c..9e19fc8461 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
@@ -14,8 +14,6 @@
package com.google.devtools.build.lib.rules.objc;
-import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
-
/**
* Implementation for the "objc_binary" rule.
*/
@@ -25,7 +23,6 @@ public class ObjcBinary extends BinaryLinkingTargetFactory {
// TODO(bazel-team): Remove the enum and delete all code depending on YES case once all
// bundle users are migrated to ios_application.
HasReleaseBundlingSupport.YES,
- new ExtraLinkArgs(),
// TODO(bazel-team): Use LIBRARY_STATIC as parameter instead of APPLICATION once objc_binary
// no longer creates an application bundle
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
index f76964bc50..688fa13738 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommon.java
@@ -505,7 +505,7 @@ public final class ObjcCommon {
static final FileType ASSET_CATALOG_CONTAINER_TYPE = FileType.of(".xcassets");
- static final FileType FRAMEWORK_CONTAINER_TYPE = FileType.of(".framework");
+ public static final FileType FRAMEWORK_CONTAINER_TYPE = FileType.of(".framework");
private final ObjcProvider objcProvider;
private final Optional<CompilationArtifacts> compilationArtifacts;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
index 1737c0de00..413ed2d5b2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
@@ -212,7 +212,13 @@ public final class ObjcProvider implements TransitiveInfoProvider {
* Indicates that Swift source files are present. This affects bundling, compiling and linking
* actions.
*/
- USES_SWIFT
+ USES_SWIFT,
+
+ /**
+ * Indicates that the resulting bundle will have embedded frameworks. This affects linking step.
+ */
+ USES_FRAMEWORKS
+
}
private final ImmutableMap<Key<?>, NestedSet<?>> items;
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 4009d5e292..05789407c4 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
@@ -327,6 +327,9 @@ public class ObjcRuleClasses {
static final FileType XIB_TYPE = FileType.of(".xib");
+ // TODO(bazel-team): Restrict this to actual header files only.
+ static final FileTypeSet HDRS_TYPE = FileTypeSet.ANY_FILE;
+
/**
* Common attributes for {@code objc_*} rules that allow the definition of resources such as
* storyboards. These resources are used during compilation of the declaring rule as well as when
@@ -513,7 +516,7 @@ public class ObjcRuleClasses {
<!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
.add(attr("hdrs", LABEL_LIST)
.direct_compile_time_input()
- .allowedFileTypes(FileTypeSet.ANY_FILE))
+ .allowedFileTypes(HDRS_TYPE))
/* <!-- #BLAZE_RULE($objc_compile_dependency_rule).ATTRIBUTE(includes) -->
List of <code>#include/#import</code> search paths to add to this target
and all depending targets.
@@ -558,7 +561,8 @@ public class ObjcRuleClasses {
"objc_framework",
"objc_proto_library",
"j2objc_library",
- "cc_library");
+ "cc_library",
+ "ios_framework");
@Override
public RuleClass build(Builder builder, RuleDefinitionEnvironment env) {
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 395806e7ba..fda1e68233 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
@@ -50,7 +50,9 @@ public class ObjcXcodeprojRule implements RuleDefinition {
"ios_application",
"ios_extension_binary",
"ios_extension",
- "ios_test",
+ "ios_framework",
+ "ios_framework_binary",
+ "ios_test",
"objc_bundle_library",
"objc_import",
"objc_library")
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 f17a8bf24f..d7644bc84d 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
@@ -93,6 +93,8 @@ public final class ReleaseBundlingSupport {
static final String APP_BUNDLE_DIR_FORMAT = "Payload/%s.app";
@VisibleForTesting
static final String EXTENSION_BUNDLE_DIR_FORMAT = "PlugIns/%s.appex";
+ @VisibleForTesting
+ static final String FRAMEWORK_BUNDLE_DIR_FORMAT = "Frameworks/%s.framework";
/**
* Command string for "sed" that tries to extract the application version number from a larger
@@ -141,22 +143,47 @@ public final class ReleaseBundlingSupport {
* 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"})
+ * @param bundleName name of the bundle, used with bundleDirFormat
* @param bundleMinimumOsVersion the minimum OS version this bundle's plist should be generated
* for (<b>not</b> the minimum OS version its binary is compiled with, that needs to be set
* through the configuration)
*/
ReleaseBundlingSupport(RuleContext ruleContext, ObjcProvider objcProvider,
- LinkedBinary linkedBinary, String bundleDirFormat, String bundleMinimumOsVersion) {
+ LinkedBinary linkedBinary, String bundleDirFormat, String bundleName,
+ String bundleMinimumOsVersion) {
this.linkedBinary = linkedBinary;
this.attributes = new Attributes(ruleContext);
this.ruleContext = ruleContext;
this.objcProvider = objcProvider;
this.intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext);
- bundling = bundling(ruleContext, objcProvider, bundleDirFormat, bundleMinimumOsVersion);
+ bundling = bundling(ruleContext, objcProvider, bundleDirFormat, bundleName,
+ bundleMinimumOsVersion);
bundleSupport = new BundleSupport(ruleContext, bundling, extraActoolArgs());
}
/**
+ * Creates a new application support within the given rule context.
+ *
+ * {@code bundleName} defaults to label name
+ *
+ * @param ruleContext context for the application-generating rule
+ * @param objcProvider provider containing all dependencies' information as well as some of this
+ * rule's
+ * @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"})
+ * @param bundleMinimumOsVersion the minimum OS version this bundle's plist should be generated
+ * for (<b>not</b> the minimum OS version its binary is compiled with, that needs to be set
+ * through the configuration)
+ */
+ ReleaseBundlingSupport(RuleContext ruleContext, ObjcProvider objcProvider,
+ LinkedBinary linkedBinary, String bundleDirFormat, String bundleMinimumOsVersion) {
+ this(ruleContext, objcProvider, linkedBinary, bundleDirFormat, ruleContext.getLabel().getName(),
+ bundleMinimumOsVersion);
+ }
+
+ /**
* Validates application-related attributes set on this rule and registers any errors with the
* rule context.
*
@@ -440,7 +467,7 @@ public final class ReleaseBundlingSupport {
}
private Bundling bundling(RuleContext ruleContext, ObjcProvider objcProvider,
- String bundleDirFormat, String minimumOsVersion) {
+ String bundleDirFormat, String bundleName, String minimumOsVersion) {
ImmutableList<BundleableFile> extraBundleFiles;
ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
if (objcConfiguration.getBundlingPlatform() == Platform.DEVICE) {
@@ -461,7 +488,7 @@ public final class ReleaseBundlingSupport {
}
return new Bundling.Builder()
- .setName(ruleContext.getLabel().getName())
+ .setName(bundleName)
// Architecture that determines which nested bundles are kept.
.setArchitecture(objcConfiguration.getDependencySingleArchitecture())
.setBundleDirFormat(bundleDirFormat)
@@ -544,7 +571,7 @@ public final class ReleaseBundlingSupport {
ImmutableList.Builder<String> dirsToSign = new ImmutableList.Builder<>();
- // Explicitly sign Swift frameworks. Unfortunately --deep option on codesign doesn't do this
+ // Explicitly sign Swift dylibs. Unfortunately --deep option on codesign doesn't do this
// automatically.
// The order here is important. The innermost code must singed first.
String bundleDir = ShellUtils.shellEscape(bundling.getBundleDir());
@@ -943,7 +970,7 @@ public final class ReleaseBundlingSupport {
* transition may exist with the same value in a single Bazel invocation.
*/
enum ConfigurationDistinguisher {
- EXTENSION, APPLICATION, UNKNOWN
+ EXTENSION, APPLICATION, FRAMEWORK, UNKNOWN
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
index 5d474f20b9..b1d26cc9fa 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java
@@ -14,9 +14,6 @@
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.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
@@ -27,39 +24,34 @@ import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.LinkedBinary;
import com.google.devtools.build.lib.rules.objc.ReleaseBundlingSupport.SplitArchTransition.ConfigurationDistinguisher;
+import javax.annotation.Nullable;
+
/**
* Base class for rules that bundle releases.
*/
public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTargetFactory {
- /**
- * Indicates whether a target factory should export an {@link ObjcProvider} containing itself as
- * a nested bundle.
- */
- protected enum ExposeAsNestedBundle { YES, NO }
-
private final String bundleDirFormat;
private final XcodeProductType xcodeProductType;
- private final ExposeAsNestedBundle exposeAsNestedBundle;
private final ImmutableSet<Attribute> dependencyAttributes;
private final ConfigurationDistinguisher configurationDistinguisher;
/**
* @param bundleDirFormat format string representing the bundle's directory with a single
* placeholder for the target name (e.g. {@code "Payload/%s.app"})
- * @param exposeAsNestedBundle whether to export an {@link ObjcProvider} with this target as a
* @param dependencyAttributes all attributes that contain dependencies of this rule. Any
* dependency so listed must expose {@link XcodeProvider} and {@link ObjcProvider}.
* @param configurationDistinguisher distinguisher used for cases where inputs from dependencies
* of this bundle may need distinguishing because they come from configurations that are only
* different by this value
*/
- public ReleaseBundlingTargetFactory(String bundleDirFormat, XcodeProductType xcodeProductType,
- ExposeAsNestedBundle exposeAsNestedBundle, ImmutableSet<Attribute> dependencyAttributes,
+ public ReleaseBundlingTargetFactory(
+ String bundleDirFormat,
+ XcodeProductType xcodeProductType,
+ ImmutableSet<Attribute> dependencyAttributes,
ConfigurationDistinguisher configurationDistinguisher) {
this.bundleDirFormat = bundleDirFormat;
this.xcodeProductType = xcodeProductType;
- this.exposeAsNestedBundle = exposeAsNestedBundle;
this.dependencyAttributes = dependencyAttributes;
this.configurationDistinguisher = configurationDistinguisher;
}
@@ -73,7 +65,7 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg
ReleaseBundlingSupport releaseBundlingSupport = new ReleaseBundlingSupport(
ruleContext, common.getObjcProvider(), LinkedBinary.DEPENDENCIES_ONLY, bundleDirFormat,
- bundleMinimumOsVersion(ruleContext));
+ bundleName(ruleContext), bundleMinimumOsVersion(ruleContext));
releaseBundlingSupport
.registerActions()
.addXcodeSettings(xcodeProviderBuilder)
@@ -94,22 +86,16 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg
xcodeSupport.registerActions(xcodeProviderBuilder.build());
- Optional<ObjcProvider> exposedObjcProvider;
- if (exposeAsNestedBundle == ExposeAsNestedBundle.YES) {
- exposedObjcProvider = Optional.of(new ObjcProvider.Builder()
- .add(MERGE_ZIP, ruleContext.getImplicitOutputArtifact(ReleaseBundlingSupport.IPA))
- .build());
- } else {
- exposedObjcProvider = Optional.absent();
- }
-
RuleConfiguredTargetBuilder targetBuilder =
ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build())
.addProvider(XcTestAppProvider.class, releaseBundlingSupport.xcTestAppProvider())
.addProvider(XcodeProvider.class, xcodeProviderBuilder.build());
- if (exposedObjcProvider.isPresent()) {
- targetBuilder.addProvider(ObjcProvider.class, exposedObjcProvider.get());
+
+ ObjcProvider exposedObjcProvider = exposedObjcProvider(ruleContext);
+ if (exposedObjcProvider != null) {
+ targetBuilder.addProvider(ObjcProvider.class, exposedObjcProvider);
}
+
configureTarget(targetBuilder, ruleContext, releaseBundlingSupport);
return targetBuilder.build();
}
@@ -130,6 +116,21 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg
protected void configureTarget(RuleConfiguredTargetBuilder target, RuleContext ruleContext,
ReleaseBundlingSupport releaseBundlingSupport) {}
+ /**
+ * Returns the name of this target's bundle.
+ */
+ protected String bundleName(RuleContext ruleContext) {
+ return ruleContext.getLabel().getName();
+ }
+
+ /**
+ * Returns an exposed {@code ObjcProvider} object.
+ */
+ @Nullable
+ protected ObjcProvider exposedObjcProvider(RuleContext ruleContext) {
+ return null;
+ }
+
private ObjcCommon common(RuleContext ruleContext) {
ObjcCommon.Builder builder = new ObjcCommon.Builder(ruleContext)
.setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext));
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProductType.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProductType.java
index 1a68206d61..72e2f0b095 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProductType.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProductType.java
@@ -23,7 +23,8 @@ enum XcodeProductType {
BUNDLE("com.apple.product-type.bundle"),
APPLICATION("com.apple.product-type.application"),
UNIT_TEST("com.apple.product-type.bundle.unit-test"),
- EXTENSION("com.apple.product-type.app-extension");
+ EXTENSION("com.apple.product-type.app-extension"),
+ FRAMEWORK("com.apple.product-type.framework");
private final String identifier;
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 445f50b4b7..58db685f08 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
@@ -464,7 +464,7 @@ public final class XcodeProvider implements TransitiveInfoProvider {
@VisibleForTesting
static final EnumSet<XcodeProductType> CAN_LINK_PRODUCT_TYPES = EnumSet.of(
XcodeProductType.APPLICATION, XcodeProductType.BUNDLE, XcodeProductType.UNIT_TEST,
- XcodeProductType.EXTENSION);
+ XcodeProductType.EXTENSION, XcodeProductType.FRAMEWORK);
/**
* Returns the name of the Xcode target that corresponds to a build target with the given name.