aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/BinaryLinkingTargetFactory.java11
-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/ObjcCommon.java14
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingSupport.java81
6 files changed, 115 insertions, 9 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 7475baf6f2..fde2683978 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
@@ -175,7 +175,7 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
CompilationArtifacts compilationArtifacts =
CompilationSupport.compilationArtifacts(ruleContext);
- return new ObjcCommon.Builder(ruleContext)
+ ObjcCommon.Builder builder = new ObjcCommon.Builder(ruleContext)
.setCompilationAttributes(new CompilationAttributes(ruleContext))
.setResourceAttributes(new ResourceAttributes(ruleContext))
.setCompilationArtifacts(compilationArtifacts)
@@ -188,7 +188,12 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory
.setIntermediateArtifacts(intermediateArtifacts)
.setAlwayslink(false)
.addExtraImportLibraries(ObjcRuleClasses.j2ObjcLibraries(ruleContext))
- .setLinkedBinary(intermediateArtifacts.singleArchitectureBinary())
- .build();
+ .setLinkedBinary(intermediateArtifacts.singleArchitectureBinary());
+
+ if (ObjcRuleClasses.objcConfiguration(ruleContext).generateDebugSymbols()) {
+ builder.setBreakpadFile(intermediateArtifacts.breakpadSym());
+ }
+
+ return builder.build();
}
}
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 ee1a3edf88..9e1372e8d4 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
@@ -258,6 +258,13 @@ final class IntermediateArtifacts {
}
/**
+ * Breakpad debug symbol representation for a specific architecture.
+ */
+ public Artifact breakpadSym(String arch) {
+ return appendExtension(String.format("_%s.breakpad", arch));
+ }
+
+ /**
* Shell script that launches the binary.
*/
public Artifact runnerScript() {
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 c84c7291d1..775a211555 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
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.rules.objc;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.ASSET_CATALOG;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.BREAKPAD_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.BUNDLE_FILE;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.BUNDLE_IMPORT_DIR;
import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DEFINE;
@@ -214,6 +215,7 @@ public final class ObjcCommon {
private boolean alwayslink;
private Iterable<Artifact> extraImportLibraries = ImmutableList.of();
private Optional<Artifact> linkedBinary = Optional.absent();
+ private Optional<Artifact> breakpadFile = Optional.absent();
Builder(RuleContext context) {
this.context = Preconditions.checkNotNull(context);
@@ -322,6 +324,15 @@ public final class ObjcCommon {
return this;
}
+ /**
+ * Sets a breakpad file (used by the breakpad crash reporting system) generated by this rule to
+ * be propagated to dependers.
+ */
+ Builder setBreakpadFile(Artifact breakpadFile) {
+ this.breakpadFile = Optional.of(breakpadFile);
+ return this;
+ }
+
ObjcCommon build() {
Iterable<BundleableFile> bundleImports = BundleableFile.bundleImportsFromRule(context);
@@ -418,7 +429,8 @@ public final class ObjcCommon {
}
}
- objcProvider.addAll(LINKED_BINARY, linkedBinary.asSet());
+ objcProvider.addAll(LINKED_BINARY, linkedBinary.asSet())
+ .addAll(BREAKPAD_FILE, breakpadFile.asSet());
return new ObjcCommon(context, objcProvider.build(), compilationArtifacts);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
index b9b2d00b4d..81a15e0b5c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
@@ -275,11 +275,6 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment {
@Override
public void reportInvalidOptions(EventHandler reporter, BuildOptions buildOptions) {
- if (generateDebugSymbols && !iosMultiCpus.isEmpty()) {
- reporter.handle(Event.error(
- "--objc_generate_debug_symbols is not supported when --ios_multi_cpus is set"));
- }
-
// TODO(bazel-team): Remove this constraint once getBundlingPlatform can return multiple values.
Platform platform = null;
for (String architecture : iosMultiCpus) {
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 12692ba011..ce344cf44b 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
@@ -164,6 +164,12 @@ public final class ObjcProvider implements TransitiveInfoProvider {
public static final Key<Artifact> DEBUG_SYMBOLS = new Key<>(STABLE_ORDER);
/**
+ * Generated breakpad file containing debug information used by the breakpad crash reporting
+ * system.
+ */
+ public static final Key<Artifact> BREAKPAD_FILE = new Key<>(STABLE_ORDER);
+
+ /**
* Artifacts for storyboard sources.
*/
public static final Key<Artifact> STORYBOARD = new Key<>(STABLE_ORDER);
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 a51e4b787e..f98185c15e 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
@@ -21,6 +21,7 @@ import static com.google.devtools.build.lib.rules.objc.TargetDeviceFamily.UI_DEV
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
@@ -30,6 +31,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesSupport;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.BinaryFileWriteAction;
import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
import com.google.devtools.build.lib.analysis.actions.SpawnAction;
@@ -50,6 +52,7 @@ import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.xcode.xcodegen.proto.XcodeGenProtos.XcodeprojBuildSetting;
import java.util.List;
+import java.util.Map.Entry;
import java.util.Set;
import javax.annotation.Nullable;
@@ -195,6 +198,7 @@ public final class ReleaseBundlingSupport {
bundleSupport.registerActions(objcProvider);
registerCombineArchitecturesAction();
+ registerTransformAndCopyBreakpadFilesAction();
ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
Artifact ipaOutput = ruleContext.getImplicitOutputArtifact(IPA);
@@ -304,6 +308,10 @@ public final class ReleaseBundlingSupport {
NestedSetBuilder<Artifact> debugSymbolBuilder = NestedSetBuilder.<Artifact>stableOrder()
.addTransitive(objcProvider.get(ObjcProvider.DEBUG_SYMBOLS));
+ for (Artifact breakpadFile : getBreakpadFiles().values()) {
+ filesToBuild.add(breakpadFile);
+ }
+
if (linkedBinary == LinkedBinary.LOCAL_AND_DEPENDENCIES
&& ObjcRuleClasses.objcConfiguration(ruleContext).generateDebugSymbols()) {
IntermediateArtifacts intermediateArtifacts =
@@ -537,6 +545,59 @@ public final class ReleaseBundlingSupport {
.build(ruleContext));
}
+ /**
+ * Registers the actions that transform and copy the breakpad files from the CPU-specific binaries
+ * that are part of this application. There are two steps involved: 1) The breakpad files have to
+ * be renamed to include their corresponding CPU architecture as a suffix. 2) The first line of
+ * the breakpad file has to be rewritten, as it has to include the name of the application instead
+ * of the name of the binary artifact.
+ *
+ * <p>Example:<br>
+ * The ios_application "PrenotCalculator" is specified to use "PrenotCalculatorBinary" as its
+ * binary. Assuming that the application is built for armv7 and arm64 CPUs, in the build process
+ * two binaries with a corresponding breakpad file each will be built:
+ *
+ * <pre>blaze-out/xyz-crosstool-ios-arm64/.../PrenotCalculatorBinary_bin
+ * blaze-out/xyz-crosstool-ios-arm64/.../PrenotCalculatorBinary.breakpad
+ * blaze-out/xyz-crosstool-ios-armv7/.../PrenotCalculatorBinary_bin
+ * blaze-out/xyz-crosstool-ios-armv7/.../PrenotCalculatorBinary.breakpad</pre>
+ *
+ * <p>The first line of the breakpad files will look like this:
+ * <pre>MODULE mac arm64 8A7A2DDD28E83E27B339E63631ADBEF30 PrenotCalculatorBinary_bin</pre>
+ *
+ * <p>For our application, we have to transform & copy these breakpad files like this:
+ * <pre>$ head -n1 blaze-bin/.../PrenotCalculator_arm64.breakpad
+ * MODULE mac arm64 8A7A2DDD28E83E27B339E63631ADBEF30 PrenotCalculator</pre>
+ */
+ private void registerTransformAndCopyBreakpadFilesAction() {
+ for (Entry<Artifact, Artifact> breakpadFiles : getBreakpadFiles().entrySet()) {
+ ruleContext.registerAction(
+ new SpawnAction.Builder().setMnemonic("CopyBreakpadFile")
+ .setShellCommand(String.format(
+ // This sed command replaces the last word of the first line with the application
+ // name.
+ "sed -r \"1 s/^(MODULE \\w* \\w* \\w*).*$/\\1 %s/\" < %s > %s",
+ ruleContext.getLabel().getName(), breakpadFiles.getKey().getExecPathString(),
+ breakpadFiles.getValue().getExecPathString()))
+ .addInput(breakpadFiles.getKey())
+ .addOutput(breakpadFiles.getValue())
+ .build(ruleContext));
+ }
+ }
+
+ /**
+ * Returns a map of input breakpad artifacts from the CPU-specific binaries built for this
+ * ios_application to the new output breakpad artifacts.
+ */
+ private ImmutableMap<Artifact, Artifact> getBreakpadFiles() {
+ ImmutableMap.Builder<Artifact, Artifact> results = ImmutableMap.builder();
+ for (Entry<String, Artifact> breakpadFile : attributes.cpuSpecificBreakpadFiles().entrySet()) {
+ Artifact destBreakpad = intermediateArtifacts.breakpadSym(breakpadFile.getKey());
+ results.put(breakpadFile.getValue(), destBreakpad);
+ }
+ return results.build();
+ }
+
private void registerExtractTeamPrefixAction(Artifact teamPrefixFile) {
ruleContext.registerAction(ObjcActionsBuilder.spawnOnDarwinActionBuilder()
.setMnemonic("ExtractIosTeamPrefix")
@@ -724,6 +785,26 @@ public final class ReleaseBundlingSupport {
return checkNotNull(stringAttribute("bundle_id"));
}
+ ImmutableMap<String, Artifact> cpuSpecificBreakpadFiles() {
+ ImmutableMap.Builder<String, Artifact> results = ImmutableMap.builder();
+ if (ruleContext.attributes().has("binary", Type.LABEL)) {
+ for (TransitiveInfoCollection prerequisite
+ : ruleContext.getPrerequisites("binary", Mode.DONT_CHECK)) {
+ ObjcProvider prerequisiteProvider = prerequisite.getProvider(ObjcProvider.class);
+ if (prerequisiteProvider != null) {
+ Artifact sourceBreakpad = Iterables.getOnlyElement(
+ prerequisiteProvider.get(ObjcProvider.BREAKPAD_FILE), null);
+ if (sourceBreakpad != null) {
+ String cpu =
+ prerequisite.getConfiguration().getFragment(ObjcConfiguration.class).getIosCpu();
+ results.put(cpu, sourceBreakpad);
+ }
+ }
+ }
+ }
+ return results.build();
+ }
+
@Nullable
private String stringAttribute(String attribute) {
String value = ruleContext.attributes().get(attribute, Type.STRING);