diff options
author | 2016-03-31 00:19:12 +0000 | |
---|---|---|
committer | 2016-03-31 07:11:57 +0000 | |
commit | 877ec1e39db6810b4206ef75834c243e7816f575 (patch) | |
tree | 9257354723418b6f57436246f5d911b55eb76b7c /src/main/java/com/google | |
parent | 213623c9197f9c90aa929a51a47aae95d579785c (diff) |
Add support for objc_generate_linkmap argument that controls whether a link map is generated.
R_FUTURE=cparsons
--
MOS_MIGRATED_REVID=118631953
Diffstat (limited to 'src/main/java/com/google')
8 files changed, 111 insertions, 8 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 b3eced121d..4887a01f0b 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 @@ -220,6 +220,10 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory builder.addDebugArtifacts(); } + if (ObjcRuleClasses.objcConfiguration(ruleContext).generateLinkmap()) { + builder.setLinkmapFile(intermediateArtifacts.linkmap()); + } + return builder.build(); } 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 c4be16767a..fcb992d285 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 @@ -747,6 +747,7 @@ public final class CompilationSupport { IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext); Optional<Artifact> dsymBundle; + Optional<Artifact> linkmap; if (ObjcRuleClasses.objcConfiguration(ruleContext).generateDebugSymbols()) { registerDsymActions(); dsymBundle = Optional.of(intermediateArtifacts.dsymBundle()); @@ -761,12 +762,19 @@ public final class CompilationSupport { prunedJ2ObjcArchives = j2objcPrunedLibraries(objcProvider); } + if (ObjcRuleClasses.objcConfiguration(ruleContext).generateLinkmap()) { + linkmap = Optional.of(intermediateArtifacts.linkmap()); + } else { + linkmap = Optional.absent(); + } + registerLinkAction( objcProvider, extraLinkArgs, extraLinkInputs, dsymBundle, - prunedJ2ObjcArchives); + prunedJ2ObjcArchives, + linkmap); return this; } @@ -834,7 +842,7 @@ public final class CompilationSupport { private void registerLinkAction(ObjcProvider objcProvider, ExtraLinkArgs extraLinkArgs, Iterable<Artifact> extraLinkInputs, Optional<Artifact> dsymBundle, - Iterable<Artifact> prunedJ2ObjcArchives) { + Iterable<Artifact> prunedJ2ObjcArchives, Optional<Artifact> linkmap) { ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext); @@ -853,7 +861,7 @@ public final class CompilationSupport { NestedSet<Artifact> bazelBuiltLibraries = Iterables.isEmpty(prunedJ2ObjcArchives) ? objcProvider.get(LIBRARY) : substituteJ2ObjcPrunedLibraries(objcProvider); CommandLine commandLine = linkCommandLine(extraLinkArgs, objcProvider, binaryToLink, - dsymBundle, ccLibraries, bazelBuiltLibraries); + dsymBundle, ccLibraries, bazelBuiltLibraries, linkmap); ruleContext.registerAction( ObjcRuleClasses.spawnAppleEnvActionBuilder(ruleContext) .setMnemonic("ObjcLink") @@ -861,6 +869,7 @@ public final class CompilationSupport { .setCommandLine(new SingleArgCommandLine(commandLine)) .addOutput(binaryToLink) .addOutputs(dsymBundle.asSet()) + .addOutputs(linkmap.asSet()) .addTransitiveInputs(bazelBuiltLibraries) .addTransitiveInputs(objcProvider.get(IMPORTED_LIBRARY)) .addTransitiveInputs(objcProvider.get(FRAMEWORK_FILE)) @@ -948,7 +957,8 @@ public final class CompilationSupport { private CommandLine linkCommandLine(ExtraLinkArgs extraLinkArgs, ObjcProvider objcProvider, Artifact linkedBinary, Optional<Artifact> dsymBundle, - Iterable<Artifact> ccLibraries, Iterable<Artifact> bazelBuiltLibraries) { + Iterable<Artifact> ccLibraries, Iterable<Artifact> bazelBuiltLibraries, + Optional<Artifact> linkmap) { ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class); Iterable<String> libraryNames = libraryNames(objcProvider); @@ -1020,6 +1030,12 @@ public final class CompilationSupport { for (String linkopt : attributes.linkopts()) { commandLine.add("-Wl," + linkopt); } + + if (linkmap.isPresent()) { + commandLine + .add("-Xlinker -map") + .add("-Xlinker " + linkmap.get().getExecPath()); + } // Call to dsymutil for debug symbol generation must happen in the link action. // All debug symbol information is encoded in object files inside archive files. To generate 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 eec5ef3bdf..b22c830413 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 @@ -37,6 +37,9 @@ public final class IntermediateArtifacts { */ static final String TMP_DSYM_BUNDLE_SUFFIX = ".temp.app.dSYM.zip"; + static final String LINKMAP_SUFFIX = ".linkmap"; + static final String BREAKPAD_SUFFIX = ".breakpad"; + private final RuleContext ruleContext; private final String archiveFileNameSuffix; @@ -320,17 +323,38 @@ public final class IntermediateArtifacts { } /** + * Representation for a specific architecture. + */ + private Artifact architectureRepresentation(String arch, String suffix) { + return appendExtension(String.format("_%s%s", arch, suffix)); + } + + /** * Breakpad debug symbol representation. */ public Artifact breakpadSym() { - return appendExtension(".breakpad"); + return appendExtension(BREAKPAD_SUFFIX); } /** * Breakpad debug symbol representation for a specific architecture. */ public Artifact breakpadSym(String arch) { - return appendExtension(String.format("_%s.breakpad", arch)); + return architectureRepresentation(arch, BREAKPAD_SUFFIX); + } + + /** + * Linkmap representation + */ + public Artifact linkmap() { + return appendExtension(LINKMAP_SUFFIX); + } + + /** + * Linkmap representation for a specific architecture. + */ + public Artifact linkmap(String arch) { + return architectureRepresentation(arch, LINKMAP_SUFFIX); } /** diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java index 123a7f84da..86e5b3df81 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCommandLineOptions.java @@ -60,6 +60,12 @@ public class ObjcCommandLineOptions extends FragmentOptions { help = "Specifies whether to generate debug symbol(.dSYM) file.") public boolean generateDebugSymbols; + @Option(name = "objc_generate_linkmap", + defaultValue = "false", + category = "flags", + help = "Specifies whether to generate a linkmap file.") + public boolean generateLinkmap; + @Option(name = "objccopt", allowMultiple = true, defaultValue = "", 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 f2fd4efe4d..492443e079 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 @@ -39,6 +39,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcProvider.INCLUDE_SYST import static com.google.devtools.build.lib.rules.objc.ObjcProvider.J2OBJC_LIBRARY; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LINKED_BINARY; +import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LINKMAP_FILE; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LINKOPT; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MODULE_MAP; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.SDK_DYLIB; @@ -308,6 +309,7 @@ public final class ObjcCommon { private Iterable<Artifact> extraImportLibraries = ImmutableList.of(); private boolean shouldAddDebugArtifacts; private Optional<Artifact> linkedBinary = Optional.absent(); + private Optional<Artifact> linkmapFile = Optional.absent(); private Iterable<CppCompilationContext> depCcHeaderProviders = ImmutableList.of(); private Iterable<CcLinkParamsProvider> depCcLinkProviders = ImmutableList.of(); @@ -433,6 +435,14 @@ public final class ObjcCommon { } /** + * Sets a linkmap file generated by this rule to be propagated to dependers. + */ + Builder setLinkmapFile(Artifact linkmapFile) { + this.linkmapFile = Optional.of(linkmapFile); + return this; + } + + /** * Sets information from {@code cc_library} dependencies to be used during compilation. */ public Builder addDepCcHeaderProviders(Iterable<CppCompilationContext> depCcHeaderProviders) { @@ -611,8 +621,8 @@ public final class ObjcCommon { objcProvider.add(TOP_LEVEL_MODULE_MAP, moduleMap); } - - objcProvider.addAll(LINKED_BINARY, linkedBinary.asSet()); + objcProvider.addAll(LINKED_BINARY, linkedBinary.asSet()) + .addAll(LINKMAP_FILE, linkmapFile.asSet()); if (shouldAddDebugArtifacts) { objcProvider 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 6f12170998..36f73aa8ae 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 @@ -56,6 +56,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { private final DottedVersion iosSimulatorVersion; private final String iosSimulatorDevice; private final boolean generateDebugSymbols; + private final boolean generateLinkmap; private final boolean runMemleaks; private final ImmutableList<String> copts; private final CompilationMode compilationMode; @@ -80,6 +81,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { this.iosSimulatorVersion = Preconditions.checkNotNull(objcOptions.iosSimulatorVersion, "iosSimulatorVersion"); this.generateDebugSymbols = objcOptions.generateDebugSymbols; + this.generateLinkmap = objcOptions.generateLinkmap; this.runMemleaks = objcOptions.runMemleaks; this.copts = ImmutableList.copyOf(objcOptions.copts); this.compilationMode = Preconditions.checkNotNull(options.compilationMode, "compilationMode"); @@ -121,6 +123,10 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { return generateDebugSymbols; } + public boolean generateLinkmap() { + return generateLinkmap; + } + public boolean runMemleaks() { return runMemleaks; } 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 6ea0b72ceb..5535bdee10 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 @@ -244,6 +244,12 @@ public final class ObjcProvider implements TransitiveInfoProvider { new Key<>(STABLE_ORDER, "breakpad_file", Artifact.class); /** + * Single-architecture link map for a binary. + */ + public static final Key<Artifact> LINKMAP_FILE = + new Key<>(STABLE_ORDER, "linkmap_file", Artifact.class); + + /** * Artifacts for storyboard sources. */ public static final Key<Artifact> STORYBOARD = 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 a2a56cf82b..84a817d64c 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 @@ -286,6 +286,7 @@ public final class ReleaseBundlingSupport { registerTransformAndCopyBreakpadFilesAction(); registerCopyDsymFilesAction(); registerCopyDsymPlistAction(); + registerCopyLinkmapFilesAction(); registerSwiftStdlibActionsIfNecessary(); registerEmbedLabelPlistAction(); @@ -588,6 +589,10 @@ public final class ReleaseBundlingSupport { throws InterruptedException { NestedSetBuilder<Artifact> debugSymbolBuilder = NestedSetBuilder.<Artifact>stableOrder(); + for (Artifact linkmapFile : getLinkmapFiles().values()) { + filesToBuild.add(linkmapFile); + } + if (ObjcRuleClasses.objcConfiguration(ruleContext).generateDebugSymbols()) { filesToBuild.addAll(getBreakpadFiles().values()); filesToBuild.addAll(getDsymFiles().values()); @@ -868,6 +873,15 @@ public final class ReleaseBundlingSupport { } } + private void registerCopyLinkmapFilesAction() { + for (Entry<Artifact, Artifact> linkmapFile : getLinkmapFiles().entrySet()) { + ruleContext.registerAction( + new SymlinkAction(ruleContext.getActionOwner(), linkmapFile.getKey(), + linkmapFile.getValue(), String.format("Copying Linkmap %s", + linkmapFile.getValue().prettyPrint()))); + } + } + /** * Registers the actions that copy the debug symbol files from the CPU-specific binaries that are * part of this application. The only one step executed is that he dsym files have to be renamed @@ -939,6 +953,19 @@ public final class ReleaseBundlingSupport { return null; } + /** + * Returns a map of input linkmap artifacts from the CPU-specific binaries built for this + * ios_application to the new output linkmap artifacts. + */ + private ImmutableMap<Artifact, Artifact> getLinkmapFiles() { + ImmutableMap.Builder<Artifact, Artifact> results = ImmutableMap.builder(); + for (Entry<String, Artifact> linkmapFile : attributes.cpuSpecificLinkmapFiles().entrySet()) { + Artifact destLinkMap = intermediateArtifacts.linkmap(linkmapFile.getKey()); + results.put(linkmapFile.getValue(), destLinkMap); + } + return results.build(); + } + private void registerExtractTeamPrefixAction(Artifact teamPrefixFile) { String shellCommand = "set -e && " + "PLIST=$(mktemp -t teamprefix.plist) && trap \"rm ${PLIST}\" EXIT && " @@ -1188,6 +1215,10 @@ public final class ReleaseBundlingSupport { return cpuSpecificArtifacts(ObjcProvider.DEBUG_SYMBOLS_PLIST); } + ImmutableMap<String, Artifact> cpuSpecificLinkmapFiles() { + return cpuSpecificArtifacts(ObjcProvider.LINKMAP_FILE); + } + ImmutableMap<String, Artifact> cpuSpecificArtifacts(ObjcProvider.Key<Artifact> key) { ImmutableMap.Builder<String, Artifact> results = ImmutableMap.builder(); if (ruleContext.attributes().has("binary", BuildType.LABEL)) { |