From adc4a02d95a9b59d3c76f600cdebab71081e5708 Mon Sep 17 00:00:00 2001 From: Rumou Duan Date: Mon, 22 Jun 2015 18:22:20 +0000 Subject: Add two binary size optimizations when --compilation_mode=opt and --objc_enable_binary_stripping are specified: 1. Symbol strippings. A new strip action is registered that uses Darwin tool /usr/bin/strip to remove the symbol table of the linked binary. 2. Dead-code strippings, which uses linker flag "--dead_strip" to remove unreachable code in binary link action. RELNOTES: Add a flag "objc_enable_binary_stripping" to enable symbol and dead code strippings on linked binaries generated by ObjC rules. -- MOS_MIGRATED_REVID=96587585 --- .../lib/rules/objc/BinaryLinkingTargetFactory.java | 44 ++++--- .../build/lib/rules/objc/CompilationSupport.java | 143 +++++++++++++++++---- .../lib/rules/objc/IntermediateArtifacts.java | 17 ++- .../lib/rules/objc/ObjcCommandLineOptions.java | 8 ++ .../build/lib/rules/objc/ObjcConfiguration.java | 13 +- .../build/lib/rules/objc/ObjcRuleClasses.java | 1 + .../lib/rules/objc/ReleaseBundlingSupport.java | 12 +- 7 files changed, 185 insertions(+), 53 deletions(-) (limited to 'src/main/java/com/google/devtools/build') 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 b59bbe30c9..b1a4bce67d 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 @@ -77,8 +77,9 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory ObjcRuleClasses.intermediateArtifacts(ruleContext); XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder(); - NestedSetBuilder filesToBuild = NestedSetBuilder.stableOrder() - .add(intermediateArtifacts.singleArchitectureBinary()); + NestedSetBuilder filesToBuild = + NestedSetBuilder.stableOrder() + .add(intermediateArtifacts.strippedSingleArchitectureBinary()); new CompilationSupport(ruleContext) .registerJ2ObjcCompileAndArchiveActions(objcProvider) @@ -165,24 +166,27 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory CompilationArtifacts compilationArtifacts = CompilationSupport.compilationArtifacts(ruleContext); - ObjcCommon.Builder builder = new ObjcCommon.Builder(ruleContext) - .setCompilationAttributes(new CompilationAttributes(ruleContext)) - .setResourceAttributes(new ResourceAttributes(ruleContext)) - .setCompilationArtifacts(compilationArtifacts) - .addDefines(ruleContext.getTokenizedStringListAttr("defines")) - .addDepObjcProviders(ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class)) - .addDepCcHeaderProviders( - ruleContext.getPrerequisites("deps", Mode.TARGET, CppCompilationContext.class)) - .addDepCcLinkProviders( - ruleContext.getPrerequisites("deps", Mode.TARGET, CcLinkParamsProvider.class)) - .addDepObjcProviders( - ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class)) - .addNonPropagatedDepObjcProviders( - ruleContext.getPrerequisites("non_propagated_deps", Mode.TARGET, ObjcProvider.class)) - .setIntermediateArtifacts(intermediateArtifacts) - .setAlwayslink(false) - .addExtraImportLibraries(ObjcRuleClasses.j2ObjcLibraries(ruleContext)) - .setLinkedBinary(intermediateArtifacts.singleArchitectureBinary()); + ObjcCommon.Builder builder = + new ObjcCommon.Builder(ruleContext) + .setCompilationAttributes(new CompilationAttributes(ruleContext)) + .setResourceAttributes(new ResourceAttributes(ruleContext)) + .setCompilationArtifacts(compilationArtifacts) + .addDefines(ruleContext.getTokenizedStringListAttr("defines")) + .addDepObjcProviders( + ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class)) + .addDepCcHeaderProviders( + ruleContext.getPrerequisites("deps", Mode.TARGET, CppCompilationContext.class)) + .addDepCcLinkProviders( + ruleContext.getPrerequisites("deps", Mode.TARGET, CcLinkParamsProvider.class)) + .addDepObjcProviders( + ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class)) + .addNonPropagatedDepObjcProviders( + ruleContext.getPrerequisites( + "non_propagated_deps", Mode.TARGET, ObjcProvider.class)) + .setIntermediateArtifacts(intermediateArtifacts) + .setAlwayslink(false) + .addExtraImportLibraries(ObjcRuleClasses.j2ObjcLibraries(ruleContext)) + .setLinkedBinary(intermediateArtifacts.strippedSingleArchitectureBinary()); if (ObjcRuleClasses.objcConfiguration(ruleContext).generateDebugSymbols()) { builder.setBreakpadFile(intermediateArtifacts.breakpadSym()); 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 9aaffb63b2..0c1088c7b8 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 @@ -33,6 +33,7 @@ import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.CLANG_PLU import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.DSYMUTIL; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.NON_ARC_SRCS_TYPE; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.SRCS_TYPE; +import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.STRIP; import static com.google.devtools.build.lib.rules.objc.ObjcRuleClasses.SWIFT; import com.google.common.annotations.VisibleForTesting; @@ -52,6 +53,7 @@ import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.FileWriteAction; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.collect.nestedset.NestedSet; +import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.rules.cpp.LinkerInputs; import com.google.devtools.build.lib.rules.java.J2ObjcConfiguration; import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes; @@ -201,6 +203,12 @@ final class CompilationSupport { commandLine.addPath(intermediateArtifacts.swiftHeader().getExecPath().getParentDirectory()); additionalInputs.add(intermediateArtifacts.swiftHeader()); } + + // The linker needs full debug symbol information to perform binary dead-code stripping. + if (objcConfiguration.shouldStripBinary()) { + commandLine.add("-g"); + } + commandLine .add(IosSdkCommands.compileFlagsForClang(objcConfiguration)) .add(IosSdkCommands.commonLinkAndCompileFlagsForClang( @@ -378,8 +386,15 @@ final class CompilationSupport { } /** - * Registers any actions necessary to link this rule and its dependencies. Debug symbols are - * generated if {@link ObjcConfiguration#generateDebugSymbols()} is set. + * Registers any actions necessary to link this rule and its dependencies. + * + *

Dsym bundle and breakpad files are generated if + * {@link ObjcConfiguration#generateDebugSymbols()} is set. + * + *

When Bazel flags {@code --compilation_mode=opt} and {@code --objc_enable_binary_stripping} + * are specified, additional optimizations will be performed on the linked binary: all-symbol + * stripping (using {@code /usr/bin/strip}) and dead-code stripping (using linker flags: + * {@code -dead_strip} and {@code -no_dead_strip_inits_and_terms}). * * @param objcProvider common information about this rule's attributes and its dependencies * @param extraLinkArgs any additional arguments to pass to the linker @@ -405,8 +420,19 @@ final class CompilationSupport { private void registerLinkAction(ObjcProvider objcProvider, ExtraLinkArgs extraLinkArgs, Iterable extraLinkInputs, Optional dsymBundle) { - Artifact linkedBinary = - ObjcRuleClasses.intermediateArtifacts(ruleContext).singleArchitectureBinary(); + ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); + IntermediateArtifacts intermediateArtifacts = + ObjcRuleClasses.intermediateArtifacts(ruleContext); + + // When compilation_mode=opt and objc_enable_binary_stripping are specified, the unstripped + // binary containing debug symbols is generated by the linker, which also needs the debug + // symbols for dead-code removal. The binary is also used to generate dSYM bundle if + // --objc_generate_debug_symbol is specified. A symbol strip action is later registered to strip + // the symbol table from the unstripped binary. + Artifact binaryToLink = + objcConfiguration.shouldStripBinary() + ? intermediateArtifacts.unstrippedSingleArchitectureBinary() + : intermediateArtifacts.strippedSingleArchitectureBinary(); ImmutableList ccLibraries = ccLibraries(objcProvider); ruleContext.registerAction( @@ -414,8 +440,8 @@ final class CompilationSupport { .setMnemonic("ObjcLink") .setShellCommand(ImmutableList.of("/bin/bash", "-c")) .setCommandLine( - linkCommandLine(extraLinkArgs, objcProvider, linkedBinary, dsymBundle, ccLibraries)) - .addOutput(linkedBinary) + linkCommandLine(extraLinkArgs, objcProvider, binaryToLink, dsymBundle, ccLibraries)) + .addOutput(binaryToLink) .addOutputs(dsymBundle.asSet()) .addTransitiveInputs(objcProvider.get(LIBRARY)) .addTransitiveInputs(objcProvider.get(IMPORTED_LIBRARY)) @@ -423,6 +449,24 @@ final class CompilationSupport { .addInputs(ccLibraries) .addInputs(extraLinkInputs) .build(ruleContext)); + + if (objcConfiguration.shouldStripBinary()) { + // For test targets, only debug symbols are stripped off, since /usr/bin/strip is not able + // to strip off all symbols in XCTest bundle. + boolean isTestTarget = TargetUtils.isTestRule(ruleContext.getRule()); + Iterable stripArgs = + isTestTarget ? ImmutableList.of("-S") : ImmutableList.of(); + Artifact strippedBinary = intermediateArtifacts.strippedSingleArchitectureBinary(); + + ruleContext.registerAction( + ObjcRuleClasses.spawnOnDarwinActionBuilder() + .setMnemonic("ObjcBinarySymbolStrip") + .setExecutable(STRIP) + .setCommandLine(symbolStripCommandLine(stripArgs, binaryToLink, strippedBinary)) + .addOutput(strippedBinary) + .addInput(binaryToLink) + .build(ruleContext)); + } } private ImmutableList ccLibraries(ObjcProvider objcProvider) { @@ -433,6 +477,15 @@ final class CompilationSupport { return ccLibraryBuilder.build(); } + private static CommandLine symbolStripCommandLine( + Iterable extraFlags, Artifact unstrippedArtifact, Artifact strippedArtifact) { + return CustomCommandLine.builder() + .add(extraFlags) + .addExecPath("-o", strippedArtifact) + .addPath(unstrippedArtifact.getExecPath()) + .build(); + } + private CommandLine linkCommandLine(ExtraLinkArgs extraLinkArgs, ObjcProvider objcProvider, Artifact linkedBinary, Optional dsymBundle, ImmutableList ccLibraries) { @@ -447,10 +500,20 @@ final class CompilationSupport { } else { commandLine.addPath(CLANG); } + + // Do not perform code stripping on tests because XCTest binary is linked not as an executable + // but as a bundle without any entry point. + boolean isTestTarget = TargetUtils.isTestRule(ruleContext.getRule()); + if (objcConfiguration.shouldStripBinary() && !isTestTarget) { + commandLine.add("-dead_strip").add("-no_dead_strip_inits_and_terms"); + } + commandLine .add(IosSdkCommands.commonLinkAndCompileFlagsForClang(objcProvider, objcConfiguration)) - .add("-Xlinker").add("-objc_abi_version") - .add("-Xlinker").add("2") + .add("-Xlinker") + .add("-objc_abi_version") + .add("-Xlinker") + .add("2") .add("-fobjc-link-runtime") .add(IosSdkCommands.DEFAULT_LINKER_FLAGS) .addBeforeEach("-framework", frameworkNames(objcProvider)) @@ -657,22 +720,49 @@ final class CompilationSupport { private CompilationSupport registerDsymActions() { IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext); + ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext); + Artifact dsymBundle = intermediateArtifacts.dsymBundle(); + Artifact linkedBinary = + objcConfiguration.shouldStripBinary() + ? intermediateArtifacts.unstrippedSingleArchitectureBinary() + : intermediateArtifacts.strippedSingleArchitectureBinary(); Artifact debugSymbolFile = intermediateArtifacts.dsymSymbol(); - ruleContext.registerAction(new SpawnAction.Builder() - .setMnemonic("UnzipDsym") - .setProgressMessage("Unzipping dSYM file: " + ruleContext.getLabel()) - .setExecutable(new PathFragment("/usr/bin/unzip")) - .addInput(dsymBundle) - .setCommandLine(CustomCommandLine.builder() - .add(dsymBundle.getExecPathString()) - .add("-d") - .add(stripSuffix(dsymBundle.getExecPathString(), - IntermediateArtifacts.TMP_DSYM_BUNDLE_SUFFIX) + ".app.dSYM") - .build()) - .addOutput(intermediateArtifacts.dsymPlist()) - .addOutput(debugSymbolFile) - .build(ruleContext)); + Artifact dsymPlist = intermediateArtifacts.dsymPlist(); + + PathFragment dsymOutputDir = + replaceSuffix( + dsymBundle.getExecPath(), IntermediateArtifacts.TMP_DSYM_BUNDLE_SUFFIX, ".app.dSYM"); + PathFragment dsymPlistZipEntry = dsymPlist.getExecPath().relativeTo(dsymOutputDir); + PathFragment debugSymbolFileZipEntry = + debugSymbolFile + .getExecPath() + .replaceName(linkedBinary.getFilename()) + .relativeTo(dsymOutputDir); + + StringBuilder unzipDsymCommand = new StringBuilder(); + unzipDsymCommand + .append( + String.format( + "unzip -p %s %s > %s", + dsymBundle.getExecPathString(), + dsymPlistZipEntry, + dsymPlist.getExecPathString())) + .append( + String.format( + " && unzip -p %s %s > %s", + dsymBundle.getExecPathString(), + debugSymbolFileZipEntry, + debugSymbolFile.getExecPathString())); + + ruleContext.registerAction( + new SpawnAction.Builder() + .setMnemonic("UnzipDsym") + .setShellCommand(unzipDsymCommand.toString()) + .addInput(dsymBundle) + .addOutput(dsymPlist) + .addOutput(debugSymbolFile) + .build(ruleContext)); Artifact dumpsyms = ruleContext.getPrerequisiteArtifact(":dumpsyms", Mode.HOST); Artifact breakpadFile = intermediateArtifacts.breakpadSym(); @@ -691,9 +781,14 @@ final class CompilationSupport { return this; } - private String stripSuffix(String str, String suffix) { + private PathFragment replaceSuffix(PathFragment path, String suffix, String newSuffix) { // TODO(bazel-team): Throw instead of returning null? - return str.endsWith(suffix) ? str.substring(0, str.length() - suffix.length()) : null; + String name = path.getBaseName(); + if (name.endsWith(suffix)) { + return path.replaceName(name.substring(0, name.length() - suffix.length()) + newSuffix); + } else { + return null; + } } /** 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 b52de70399..d2bac9cf37 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 @@ -119,12 +119,25 @@ final class IntermediateArtifacts { /** * The artifact which is the binary (or library) which is comprised of one or more .a files linked - * together. + * together. Compared to the artifact returned by {@link #unstrippedSingleArchitectureBinary}, + * this artifact is stripped of symbol table when --compilation_mode=opt and + * --objc_enable_binary_stripping are specified. */ - public Artifact singleArchitectureBinary() { + public Artifact strippedSingleArchitectureBinary() { return appendExtension("_bin"); } + /** + * The artifact which is the binary (or library) which is comprised of one or more .a files linked + * together. It also contains full debug symbol information, compared to the artifact returned + * by {@link #strippedSingleArchitectureBinary}. This artifact will serve as input for the symbol + * strip action and is only created when --compilation_mode=opt and + * --objc_enable_binary_stripping are specified. + */ + public Artifact unstrippedSingleArchitectureBinary() { + return appendExtension("_bin_unstripped"); + } + /** * Lipo binary generated by combining one or more linked binaries. This binary is the one included * in generated bundles and invoked as entry point to the application. 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 6e926bc4c5..0a927afb15 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 @@ -136,6 +136,14 @@ public class ObjcCommandLineOptions extends FragmentOptions { + "built with --cpu set to \"ios_<--ios_cpu>\" for any values in --ios_multi_cpu.") public boolean enableCcDeps; + @Option(name = "objc_enable_binary_stripping", + defaultValue = "false", + category = "flags", + help = "Whether to perform symbol and dead-code strippings on linked binaries. Binary " + + "strippings will be performed if both this flag and --compilationMode=opt are " + + "specified.") + public boolean enableBinaryStripping; + // This option exists because two configurations are not allowed to have the same cache key // (partially derived from options). Since we have multiple transitions (see // getPotentialSplitTransitions below) that may result in the same configuration values at runtime 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 c16d632090..25c83acc8e 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 @@ -49,7 +49,8 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { @VisibleForTesting static final ImmutableList OPT_COPTS = - ImmutableList.of("-Os", "-DNDEBUG=1", "-Wno-unused-variable", "-Winit-self", "-Wno-extra"); + ImmutableList.of( + "-Os", "-DNDEBUG=1", "-Wno-unused-variable", "-Winit-self", "-Wno-extra"); private final String iosSdkVersion; private final String iosMinimumOs; @@ -64,6 +65,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { private final List iosMultiCpus; private final String iosSplitCpu; private final boolean perProtoIncludes; + private final boolean enableBinaryStripping; private final ConfigurationDistinguisher configurationDistinguisher; @Nullable private final Path clientWorkspaceRoot; @@ -97,6 +99,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { this.iosMultiCpus = Preconditions.checkNotNull(objcOptions.iosMultiCpus, "iosMultiCpus"); this.iosSplitCpu = Preconditions.checkNotNull(objcOptions.iosSplitCpu, "iosSplitCpu"); this.perProtoIncludes = objcOptions.perProtoIncludes; + this.enableBinaryStripping = objcOptions.enableBinaryStripping; this.configurationDistinguisher = objcOptions.configurationDistinguisher; this.clientWorkspaceRoot = directories != null ? directories.getWorkspace() : null; } @@ -300,6 +303,14 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { return this.perProtoIncludes; } + /** + * Returns whether to perform symbol and dead-code strippings on linked binaries. The strippings + * are performed iff --compilation_mode=opt and --objc_enable_binary_stripping are specified. + */ + public boolean shouldStripBinary() { + return this.enableBinaryStripping && getCompilationMode() == CompilationMode.OPT; + } + /** * Returns the absolute path of the root of Bazel client workspace. Null if passed-in * {@link BlazeDirectories} is null or Bazel fails to find the workspace root directory. diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java index 8e41f35aad..5207f1ecf0 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcRuleClasses.java @@ -67,6 +67,7 @@ public class ObjcRuleClasses { static final PathFragment LIPO = new PathFragment(BIN_DIR + "/lipo"); static final PathFragment IBTOOL = new PathFragment(IosSdkCommands.IBTOOL_PATH); static final PathFragment SWIFT_STDLIB_TOOL = new PathFragment(BIN_DIR + "/swift-stdlib-tool"); + static final PathFragment STRIP = new PathFragment(BIN_DIR + "/strip"); private static final PathFragment JAVA = new PathFragment("/usr/bin/java"); 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 e10dee00f6..d2d1a9e2c7 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 @@ -217,7 +217,7 @@ public final class ReleaseBundlingSupport { } else { maybeSignedIpa = registerBundleSigningActions(ipaOutput); } - + registerEmbedLabelPlistAction(); BundleMergeControlBytes bundleMergeControlBytes = new BundleMergeControlBytes( @@ -417,8 +417,8 @@ public final class ReleaseBundlingSupport { } else { extraBundleFiles = ImmutableList.of(); } - - String primaryBundleId = null; + + String primaryBundleId = null; String fallbackBundleId = null; if (ruleContext.attributes().isAttributeValueExplicitlySpecified("bundle_id")) { @@ -463,7 +463,7 @@ public final class ReleaseBundlingSupport { NestedSetBuilder linkedBinariesBuilder = NestedSetBuilder.stableOrder() .addTransitive(attributes.dependentLinkedBinaries()); if (linkedBinary == LinkedBinary.LOCAL_AND_DEPENDENCIES) { - linkedBinariesBuilder.add(intermediateArtifacts.singleArchitectureBinary()); + linkedBinariesBuilder.add(intermediateArtifacts.strippedSingleArchitectureBinary()); } return linkedBinariesBuilder.build(); } @@ -700,14 +700,14 @@ public final class ReleaseBundlingSupport { .add("Frameworks") .addPath(ObjcRuleClasses.SWIFT_STDLIB_TOOL) .add("--platform").add(IosSdkCommands.swiftPlatform(objcConfiguration)) - .addExecPath("--scan-executable", intermediateArtifacts.singleArchitectureBinary()); + .addExecPath("--scan-executable", intermediateArtifacts.strippedSingleArchitectureBinary()); ruleContext.registerAction( ObjcRuleClasses.spawnJavaOnDarwinActionBuilder(attributes.swiftStdlibToolDeployJar()) .setMnemonic("SwiftStdlibCopy") .setCommandLine(commandLine.build()) .addOutput(intermediateArtifacts.swiftFrameworksFileZip()) - .addInput(intermediateArtifacts.singleArchitectureBinary()) + .addInput(intermediateArtifacts.strippedSingleArchitectureBinary()) .build(ruleContext)); } -- cgit v1.2.3