aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Dmitry Shevchenko <dmishe@google.com>2017-01-26 22:19:37 +0000
committerGravatar Laszlo Csomor <laszlocsomor@google.com>2017-01-26 23:05:36 +0000
commit8290d582f3ea816a73cf2a565acc7491e195d933 (patch)
tree584a0add224b3e48b076012cbaaa3a1cef596de6 /src
parenta77686686ac2395a80563bb7c846bc8b1e20b633 (diff)
Add Bitcode symbol maps and AppleDebugOutputsProvider
* Bitcode symbol maps allow Apple to provide a new dSYM output when they recompile bitcode on the App Store. This makes it possible to debug apps build with embedded bitcode. * The new debug outputs provider makes it easy (and correct) for other rules to post-process (package, analyze, upload) dSYM and Bitcode artifacts. -- PiperOrigin-RevId: 145720293 MOS_MIGRATED_REVID=145720293
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java19
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/AppleDebugOutputsProvider.java117
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/IntermediateArtifacts.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java26
4 files changed, 163 insertions, 8 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
index 298b31493d..6fd9b70e7a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java
@@ -34,10 +34,12 @@ import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.rules.apple.AppleCommandLineOptions.AppleBitcodeMode;
import com.google.devtools.build.lib.rules.apple.AppleConfiguration;
import com.google.devtools.build.lib.rules.apple.Platform;
import com.google.devtools.build.lib.rules.apple.Platform.PlatformType;
import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider;
+import com.google.devtools.build.lib.rules.objc.AppleDebugOutputsProvider.OutputType;
import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs;
import java.util.Map;
import java.util.Set;
@@ -156,6 +158,23 @@ public class AppleBinary implements RuleConfiguredTargetFactory {
targetBuilder.addProvider(
AppleExecutableBinaryProvider.class, new AppleExecutableBinaryProvider(outputArtifact));
}
+
+ AppleDebugOutputsProvider.Builder builder = AppleDebugOutputsProvider.Builder.create();
+
+ if (appleConfiguration.getBitcodeMode() == AppleBitcodeMode.EMBEDDED) {
+ for (BuildConfiguration c : childConfigurations) {
+ String arch = c.getFragment(AppleConfiguration.class).getSingleArchitecture();
+ IntermediateArtifacts intermediateArtifacts =
+ new IntermediateArtifacts(
+ ruleContext, /*archiveFileNameSuffix*/ "", /*outputPrefix*/ "", c);
+ Artifact bitcodeSymbol = intermediateArtifacts.bitcodeSymbolMap();
+
+ builder.addOutput(arch, OutputType.BITCODE_SYMBOLS, bitcodeSymbol);
+ }
+ }
+
+ targetBuilder.addProvider(AppleDebugOutputsProvider.class, builder.build());
+
return targetBuilder.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDebugOutputsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDebugOutputsProvider.java
new file mode 100644
index 0000000000..d80c3238c4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleDebugOutputsProvider.java
@@ -0,0 +1,117 @@
+// Copyright 2017 The Bazel Authors. 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.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
+import java.util.HashMap;
+import java.util.Map.Entry;
+
+/**
+ * A provider that holds debug outputs of an Apple binary rule.
+ *
+ * <p>This provider has no native interface and is intended to be read in Skylark code.
+ *
+ * <p>The only field it has is {@code output_map}, which is a dictionary of: { arch: { output_type:
+ * Artifact, output_type: Artifact, ... } }
+ *
+ * <p>Where {@code arch} is any Apple architecture such as "arm64" or "armv7", {@code output_type}
+ * is currently "bitcode_symbols", and the artifact is an instance of the {@link
+ * Artifact} class.
+ *
+ * <p>Example: { "arm64": { "bitcode_symbols": Artifact } }
+ */
+@Immutable
+public final class AppleDebugOutputsProvider extends SkylarkClassObject
+ implements TransitiveInfoProvider {
+
+ /** Expected types of debug outputs. */
+ enum OutputType {
+
+ // TODO(b/33839914): Add DWARF binaries for dSYM outputs.
+
+ /** A Bitcode symbol map, per architecture. */
+ BITCODE_SYMBOLS;
+
+ @Override
+ public String toString() {
+ return name().toLowerCase();
+ }
+ }
+
+ public static final SkylarkClassObjectConstructor SKYLARK_PROVIDER =
+ SkylarkClassObjectConstructor.createNative("AppleDebugOutputs");
+
+ /**
+ * Creates a new provider instance.
+ *
+ * @param map a map of
+ * <pre>{@code
+ * {
+ * arch: { output_type: Artifact, output_type: Artifact, ... },
+ * }
+ * }</pre>
+ * Where:
+ * <ul>
+ * <li>arch - {@link String}, any Apple supported architecture (e.g. arm64, x86_64)
+ * <li>output_type - an instance of {@link OutputType}
+ * </ul>
+ */
+ private AppleDebugOutputsProvider(ImmutableMap<String, ImmutableMap<String, Artifact>> map) {
+ super(SKYLARK_PROVIDER, ImmutableMap.<String, Object>of("outputs_map", map));
+ }
+
+ /** A builder for {@link AppleDebugOutputsProvider}. */
+ public static class Builder {
+ private final HashMap<String, HashMap<String, Artifact>> outputsByArch = Maps.newHashMap();
+
+ private Builder() {}
+
+ public static Builder create() {
+ return new Builder();
+ }
+
+ /**
+ * Adds an output to the provider.
+ *
+ * @param arch any Apple architecture string, e.g. arm64, armv7.
+ * @param outputType {@link OutputType} corresponding to the artifact.
+ * @param artifact an {@link Artifact} that contains debug information.
+ * @return this builder.
+ */
+ public Builder addOutput(String arch, OutputType outputType, Artifact artifact) {
+ if (!outputsByArch.containsKey(arch)) {
+ outputsByArch.put(arch, new HashMap<String, Artifact>());
+ }
+
+ outputsByArch.get(arch).put(outputType.toString(), artifact);
+ return this;
+ }
+
+ public AppleDebugOutputsProvider build() {
+ ImmutableMap.Builder<String, ImmutableMap<String, Artifact>> builder = ImmutableMap.builder();
+
+ for (Entry<String, HashMap<String, Artifact>> e : outputsByArch.entrySet()) {
+ builder.put(e.getKey(), ImmutableMap.copyOf(e.getValue()));
+ }
+
+ return new AppleDebugOutputsProvider(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 2f588e7c6c..db3c1ad425 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
@@ -372,9 +372,12 @@ public final class IntermediateArtifacts {
suffix));
}
- /**
- * Representation for a specific architecture.
- */
+ /** Bitcode symbol map generated for a linked binary, for a specific architecture. */
+ public Artifact bitcodeSymbolMap() {
+ return appendExtension(".bcsymbolmap");
+ }
+
+ /** Representation for a specific architecture. */
private Artifact architectureRepresentation(String arch, String suffix) {
return appendExtension(String.format("_%s%s", arch, suffix));
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java
index f9b541ee73..3dfdd5f4c8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/LegacyCompilationSupport.java
@@ -515,6 +515,7 @@ public class LegacyCompilationSupport extends CompilationSupport {
DsymOutputType dsymOutputType) {
Optional<Artifact> dsymBundleZip;
Optional<Artifact> linkmap;
+ Optional<Artifact> bitcodeSymbolMap;
if (objcConfiguration.generateDsym()) {
registerDsymActions(dsymOutputType);
dsymBundleZip = Optional.of(intermediateArtifacts.tempDsymBundleZip(dsymOutputType));
@@ -532,13 +533,20 @@ public class LegacyCompilationSupport extends CompilationSupport {
linkmap = Optional.absent();
}
+ if (appleConfiguration.getBitcodeMode() == AppleBitcodeMode.EMBEDDED) {
+ bitcodeSymbolMap = Optional.of(intermediateArtifacts.bitcodeSymbolMap());
+ } else {
+ bitcodeSymbolMap = Optional.absent();
+ }
+
registerLinkAction(
objcProvider,
extraLinkArgs,
extraLinkInputs,
dsymBundleZip,
prunedJ2ObjcArchives,
- linkmap);
+ linkmap,
+ bitcodeSymbolMap);
return this;
}
@@ -552,7 +560,8 @@ public class LegacyCompilationSupport extends CompilationSupport {
Iterable<Artifact> extraLinkInputs,
Optional<Artifact> dsymBundleZip,
Iterable<Artifact> prunedJ2ObjcArchives,
- Optional<Artifact> linkmap) {
+ Optional<Artifact> linkmap,
+ Optional<Artifact> bitcodeSymbolMap) {
Artifact binaryToLink = getBinaryToLink();
ImmutableList<Artifact> objcLibraries = objcProvider.getObjcLibraries();
@@ -567,7 +576,8 @@ public class LegacyCompilationSupport extends CompilationSupport {
dsymBundleZip,
ccLibraries,
bazelBuiltLibraries,
- linkmap);
+ linkmap,
+ bitcodeSymbolMap);
ruleContext.registerAction(
ObjcRuleClasses.spawnAppleEnvActionBuilder(
appleConfiguration, appleConfiguration.getSingleArchPlatform())
@@ -577,6 +587,7 @@ public class LegacyCompilationSupport extends CompilationSupport {
.addOutput(binaryToLink)
.addOutputs(dsymBundleZip.asSet())
.addOutputs(linkmap.asSet())
+ .addOutputs(bitcodeSymbolMap.asSet())
.addInputs(bazelBuiltLibraries)
.addTransitiveInputs(objcProvider.get(IMPORTED_LIBRARY))
.addTransitiveInputs(objcProvider.get(STATIC_FRAMEWORK_FILE))
@@ -633,7 +644,8 @@ public class LegacyCompilationSupport extends CompilationSupport {
Optional<Artifact> dsymBundleZip,
Iterable<Artifact> ccLibraries,
Iterable<Artifact> bazelBuiltLibraries,
- Optional<Artifact> linkmap) {
+ Optional<Artifact> linkmap,
+ Optional<Artifact> bitcodeSymbolMap) {
Iterable<String> libraryNames = libraryNames(objcProvider);
CustomCommandLine.Builder commandLine = CustomCommandLine.builder()
@@ -680,7 +692,11 @@ public class LegacyCompilationSupport extends CompilationSupport {
if (bitcodeMode == AppleBitcodeMode.EMBEDDED) {
commandLine.add("-Xlinker").add("-bitcode_verify");
commandLine.add("-Xlinker").add("-bitcode_hide_symbols");
- // TODO(b/32910627): Add Bitcode symbol maps outputs.
+ commandLine
+ .add("-Xlinker")
+ .add("-bitcode_symbol_map")
+ .add("-Xlinker")
+ .add(bitcodeSymbolMap.get().getExecPathString());
}
commandLine