From 877ec1e39db6810b4206ef75834c243e7816f575 Mon Sep 17 00:00:00 2001 From: Dave MacLachlan Date: Thu, 31 Mar 2016 00:19:12 +0000 Subject: Add support for objc_generate_linkmap argument that controls whether a link map is generated. R_FUTURE=cparsons -- MOS_MIGRATED_REVID=118631953 --- .../lib/rules/objc/BinaryLinkingTargetFactory.java | 4 +++ .../build/lib/rules/objc/CompilationSupport.java | 24 ++++++++++++++--- .../lib/rules/objc/IntermediateArtifacts.java | 28 +++++++++++++++++-- .../lib/rules/objc/ObjcCommandLineOptions.java | 6 +++++ .../devtools/build/lib/rules/objc/ObjcCommon.java | 14 ++++++++-- .../build/lib/rules/objc/ObjcConfiguration.java | 6 +++++ .../build/lib/rules/objc/ObjcProvider.java | 6 +++++ .../lib/rules/objc/ReleaseBundlingSupport.java | 31 ++++++++++++++++++++++ 8 files changed, 111 insertions(+), 8 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib/rules/objc') 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 dsymBundle; + Optional 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 extraLinkInputs, Optional dsymBundle, - Iterable prunedJ2ObjcArchives) { + Iterable prunedJ2ObjcArchives, Optional linkmap) { ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext); @@ -853,7 +861,7 @@ public final class CompilationSupport { NestedSet 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 dsymBundle, - Iterable ccLibraries, Iterable bazelBuiltLibraries) { + Iterable ccLibraries, Iterable bazelBuiltLibraries, + Optional linkmap) { ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class); Iterable 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; @@ -319,18 +322,39 @@ public final class IntermediateArtifacts { ".app.dSYM/Contents/Resources/DWARF/%s_%s", ruleContext.getLabel().getName(), arch)); } + /** + * 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 extraImportLibraries = ImmutableList.of(); private boolean shouldAddDebugArtifacts; private Optional linkedBinary = Optional.absent(); + private Optional linkmapFile = Optional.absent(); private Iterable depCcHeaderProviders = ImmutableList.of(); private Iterable depCcLinkProviders = ImmutableList.of(); @@ -432,6 +434,14 @@ public final class ObjcCommon { return this; } + /** + * 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. */ @@ -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 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 @@ -243,6 +243,12 @@ public final class ObjcProvider implements TransitiveInfoProvider { public static final Key BREAKPAD_FILE = new Key<>(STABLE_ORDER, "breakpad_file", Artifact.class); + /** + * Single-architecture link map for a binary. + */ + public static final Key LINKMAP_FILE = + new Key<>(STABLE_ORDER, "linkmap_file", Artifact.class); + /** * Artifacts for storyboard sources. */ 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 debugSymbolBuilder = NestedSetBuilder.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 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 getLinkmapFiles() { + ImmutableMap.Builder results = ImmutableMap.builder(); + for (Entry 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 cpuSpecificLinkmapFiles() { + return cpuSpecificArtifacts(ObjcProvider.LINKMAP_FILE); + } + ImmutableMap cpuSpecificArtifacts(ObjcProvider.Key key) { ImmutableMap.Builder results = ImmutableMap.builder(); if (ruleContext.attributes().has("binary", BuildType.LABEL)) { -- cgit v1.2.3