aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/XcodeProvider.java64
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java19
3 files changed, 84 insertions, 3 deletions
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 979909ea78..0566525aac 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
@@ -130,6 +130,10 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
.addNonPropagatedDependencies(
xcodeProviderBuilder, new Attribute("non_propagated_deps", Mode.TARGET))
.addFilesToBuild(filesToBuild);
+
+ if (productType != XcodeProductType.LIBRARY_STATIC) {
+ xcodeSupport.generateCompanionLibXcodeTarget(xcodeProviderBuilder);
+ }
XcodeProvider xcodeProvider = xcodeProviderBuilder.build();
xcodeSupport.registerActions(xcodeProvider);
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 64268664ab..a7cbd61883 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
@@ -24,6 +24,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.WEAK_SDK_FRAMEWORK;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.XCASSETS_DIR;
+import static com.google.devtools.build.lib.rules.objc.XcodeProductType.LIBRARY_STATIC;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
@@ -59,6 +60,8 @@ import java.util.Set;
*/
@Immutable
public final class XcodeProvider implements TransitiveInfoProvider {
+ private static final String COMPANION_LIB_TARGET_LABEL_SUFFIX = "_static_lib";
+
/**
* A builder for instances of {@link XcodeProvider}.
*/
@@ -92,6 +95,7 @@ public final class XcodeProvider implements TransitiveInfoProvider {
private final ImmutableList.Builder<XcodeProvider> extensions = new ImmutableList.Builder<>();
private String architecture;
private ImmutableList.Builder<PathFragment> datamodelDirs = new ImmutableList.Builder<>();
+ private boolean generateCompanionLibTarget = false;
/**
* Sets the label of the build target which corresponds to this Xcode target.
@@ -285,6 +289,17 @@ public final class XcodeProvider implements TransitiveInfoProvider {
return this;
}
+ /**
+ * Generates an extra LIBRARY_STATIC Xcode target with the same compilation artifacts. Dependent
+ * Xcode targets will pick this companion library target as its dependency, rather than the
+ * main Xcode target of this provider.
+ */
+ // TODO(bazel-team): Remove this when the binary rule types and bundling rule types are merged.
+ public Builder generateCompanionLibTarget() {
+ this.generateCompanionLibTarget = true;
+ return this;
+ }
+
public XcodeProvider build() {
Preconditions.checkState(
!testHost.isPresent() || (productType == XcodeProductType.UNIT_TEST),
@@ -340,7 +355,7 @@ public final class XcodeProvider implements TransitiveInfoProvider {
ImmutableList.Builder<TargetControl> controls = new ImmutableList.Builder<>();
for (XcodeProvider provider : providerSet) {
- controls.add(provider.targetControl());
+ controls.addAll(provider.targetControls());
}
return controls.build();
}
@@ -367,6 +382,7 @@ public final class XcodeProvider implements TransitiveInfoProvider {
private final ImmutableList<XcodeProvider> extensions;
private final String architecture;
private final ImmutableList<PathFragment> datamodelDirs;
+ private final boolean generateCompanionLibTarget;
private XcodeProvider(Builder builder) {
this.label = Preconditions.checkNotNull(builder.label);
@@ -390,6 +406,7 @@ public final class XcodeProvider implements TransitiveInfoProvider {
this.extensions = builder.extensions.build();
this.architecture = Preconditions.checkNotNull(builder.architecture);
this.datamodelDirs = builder.datamodelDirs.build();
+ this.generateCompanionLibTarget = builder.generateCompanionLibTarget;
}
private void collectProviders(Set<XcodeProvider> allProviders) {
@@ -420,11 +437,41 @@ public final class XcodeProvider implements TransitiveInfoProvider {
* the project navigator is too narrow to show the entire name.
*/
static String xcodeTargetName(Label label) {
- String pathFromWorkspaceRoot = label.toString().replace("//", "").replace(':', '/');
+ return xcodeTargetName(label, /*labelSuffix=*/"");
+ }
+
+ /**
+ * Returns the name of the companion Xcode library target that corresponds to a build target with
+ * the given name. See {@link XcodeSupport#generateCompanionLibXcodeTarget} for the rationale of
+ * the companion library target and {@link #xcodeTargetName(Label)} for naming details.
+ */
+ static String xcodeCompanionLibTargetName(Label label) {
+ return xcodeTargetName(label, COMPANION_LIB_TARGET_LABEL_SUFFIX);
+ }
+
+ private static String xcodeTargetName(Label label, String labelSuffix) {
+ String pathFromWorkspaceRoot = (label + labelSuffix).replace("//", "")
+ .replace(':', '/');
List<String> components = Splitter.on('/').splitToList(pathFromWorkspaceRoot);
return Joiner.on('_').join(Lists.reverse(components));
}
+ /**
+ * Returns the name of the xcode target in this provider to be referenced as a dep for dependents.
+ */
+ private String dependencyXcodeTargetName() {
+ return generateCompanionLibTarget ? xcodeCompanionLibTargetName(label) : xcodeTargetName(label);
+ }
+
+ private Iterable<TargetControl> targetControls() {
+ TargetControl mainTargetControl = targetControl();
+ if (generateCompanionLibTarget) {
+ return ImmutableList.of(mainTargetControl, companionLibTargetControl(mainTargetControl));
+ } else {
+ return ImmutableList.of(mainTargetControl);
+ }
+ }
+
private TargetControl targetControl() {
String buildFilePath = label.getPackageFragment().getSafePathString() + "/BUILD";
NestedSet<String> userHeaderSearchPaths = NestedSetBuilder.<String>stableOrder()
@@ -483,7 +530,7 @@ public final class XcodeProvider implements TransitiveInfoProvider {
&& dependency.compilationArtifacts.get().getArchive().isPresent();
if (hasSources || (dependency.productType == XcodeProductType.BUNDLE)) {
targetControl.addDependency(DependencyControl.newBuilder()
- .setTargetLabel(xcodeTargetName(dependency.label))
+ .setTargetLabel(dependency.dependencyXcodeTargetName())
.build());
}
}
@@ -528,6 +575,17 @@ public final class XcodeProvider implements TransitiveInfoProvider {
return targetControl.build();
}
+ private TargetControl companionLibTargetControl(TargetControl mainTargetControl) {
+ return TargetControl.newBuilder()
+ .mergeFrom(mainTargetControl)
+ .setName(label.getName() + COMPANION_LIB_TARGET_LABEL_SUFFIX)
+ .setLabel(xcodeCompanionLibTargetName(label))
+ .setProductType(LIBRARY_STATIC.getIdentifier())
+ .clearInfoplist()
+ .clearDependency()
+ .build();
+ }
+
/**
* Prepends the given path to each path in {@code paths}. Empty paths are
* transformed to the value of {@code variable} rather than {@code variable + "/."}
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 db59f0112a..e2d057d990 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
@@ -129,4 +129,23 @@ public final class XcodeSupport {
ObjcRuleClasses.objcConfiguration(ruleContext));
return this;
}
+
+ /**
+ * Generates an extra {@link XcodeProductType#LIBRARY_STATIC} Xcode target with the same
+ * compilation artifacts as the main Xcode target associated with this Xcode support. The extra
+ * Xcode library target, instead of the main Xcode target, will act as a dependency for all
+ * dependent Xcode targets.
+ *
+ * <p>This is needed to build the Xcode binary target generated by ios_application in XCode.
+ * Currently there is an Xcode target dependency between the binary target from ios_application
+ * and the binary target from objc_binary. But Xcode does not link in compiled artifacts from
+ * binary dependencies, so any sources specified on objc_binary rules will not be compiled and
+ * linked into the app bundle in dependent binary targets associated with ios_application in
+ * XCode.
+ */
+ // TODO(bazel-team): Remove this when the binary rule types and bundling rule types are merged.
+ XcodeSupport generateCompanionLibXcodeTarget(Builder xcodeProviderBuilder) {
+ xcodeProviderBuilder.generateCompanionLibTarget();
+ return this;
+ }
}