aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar Philipp Wollermann <philwo@google.com>2015-05-12 16:17:45 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2015-05-15 09:35:34 +0000
commit5e14a92104c8862849d26badc764b5ea2b8f01bb (patch)
tree2635e3175e751c34ea4781915ed9d92a78dab02e /src/main/java/com/google
parent5da9a0e2db3005f251e9db4dd429af2397d94668 (diff)
Support --objc_generate_debug_symbols when --ios_multi_cpus is set.
When an ios_application is built, Bazel now collects the .breakpad files for each architecture and tweaks the first line of each file to reflect the name of the app, instead of the name of the binary: MODULE mac arm64 5A70922132B738E194DDBC456F90F43F0 PrenotCalculatorBinary_bin becomes MODULE mac arm64 5A70922132B738E194DDBC456F90F43F0 PrenotCalculator Bazel also correctly renames the files to end with their architecture, so that the crash server can use them: armv7/.../PrenotCalculatorBinary.breakpad becomes PrenotCalculator_armv7.breakpad -- MOS_MIGRATED_REVID=93419816
Diffstat (limited to 'src/main/java/com/google')
-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);