diff options
author | 2016-04-27 01:16:46 +0000 | |
---|---|---|
committer | 2016-04-27 11:47:56 +0000 | |
commit | b5a76c5938c126b999fd78056bde31355f9c7a42 (patch) | |
tree | a90d9ae68659f5e34b4b30a37f2efcfc5d6154f2 | |
parent | 140634eccee693b567ba7591df550f7b72db1612 (diff) |
Introduce apple_binary, which links together one or more c-family libraries and produces a potentially multi-architecture binary, controlled by the --ios_multi_cpus flag
--
MOS_MIGRATED_REVID=120874805
8 files changed, 341 insertions, 20 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java index 3f7896bbde..9bda692164 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java @@ -101,6 +101,7 @@ import com.google.devtools.build.lib.rules.java.JavaOptions; import com.google.devtools.build.lib.rules.java.JavaToolchainRule; import com.google.devtools.build.lib.rules.java.JvmConfigurationLoader; import com.google.devtools.build.lib.rules.java.ProguardLibraryRule; +import com.google.devtools.build.lib.rules.objc.AppleBinaryRule; import com.google.devtools.build.lib.rules.objc.AppleSkylarkCommon; import com.google.devtools.build.lib.rules.objc.AppleWatch1ExtensionRule; import com.google.devtools.build.lib.rules.objc.AppleWatchExtensionBinaryRule; @@ -361,6 +362,7 @@ public class BazelRuleClassProvider { builder.addRuleDefinition(new IosTestRule()); builder.addRuleDefinition(new IosDeviceRule()); + builder.addRuleDefinition(new AppleBinaryRule()); builder.addRuleDefinition(new ObjcBinaryRule()); builder.addRuleDefinition(new ExperimentalObjcLibraryRule()); builder.addRuleDefinition(new ObjcBundleRule()); 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 new file mode 100644 index 0000000000..026307684a --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinary.java @@ -0,0 +1,159 @@ +// Copyright 2016 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 static com.google.devtools.build.lib.rules.objc.ObjcProvider.IMPORTED_LIBRARY; +import static com.google.devtools.build.lib.rules.objc.ObjcProvider.LIBRARY; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; +import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; +import com.google.devtools.build.lib.analysis.RuleContext; +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.AppleConfiguration; +import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider; +import com.google.devtools.build.lib.rules.cpp.CppCompilationContext; +import com.google.devtools.build.lib.rules.objc.CompilationSupport.ExtraLinkArgs; +import com.google.devtools.build.lib.rules.objc.ObjcCommon.CompilationAttributes; +import com.google.devtools.build.lib.rules.objc.ObjcCommon.ResourceAttributes; + +import java.util.List; +import java.util.Set; + +/** + * Implementation for the "apple_binary" rule. + */ +public class AppleBinary implements RuleConfiguredTargetFactory { + @VisibleForTesting + static final String REQUIRES_AT_LEAST_ONE_LIBRARY_OR_SOURCE_FILE = + "At least one library dependency or source file is required."; + + @Override + public final ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException { + ImmutableListMultimap<BuildConfiguration, ObjcProvider> configurationToObjcDepMap = + ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT, ObjcProvider.class); + ImmutableListMultimap<BuildConfiguration, CppCompilationContext> configurationToCcDepMap = + ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT, + CppCompilationContext.class); + ImmutableListMultimap<BuildConfiguration, ObjcProvider> configurationToNonPropagatedObjcMap = + ruleContext.getPrerequisitesByConfiguration("non_propagated_deps", Mode.SPLIT, + ObjcProvider.class); + + Set<BuildConfiguration> childConfigurations = getChildConfigurations(ruleContext); + + IntermediateArtifacts ruleIntermediateArtifacts = + ObjcRuleClasses.intermediateArtifacts(ruleContext); + + NestedSetBuilder<Artifact> binariesToLipo = + NestedSetBuilder.<Artifact>stableOrder(); + NestedSetBuilder<Artifact> filesToBuild = + NestedSetBuilder.<Artifact>stableOrder() + .add(ruleIntermediateArtifacts.combinedArchitectureBinary()); + + for (BuildConfiguration childConfig : childConfigurations) { + IntermediateArtifacts intermediateArtifacts = + ObjcRuleClasses.intermediateArtifacts(ruleContext, childConfig); + ObjcCommon common = common(ruleContext, childConfig, intermediateArtifacts, + nullToEmptyList(configurationToObjcDepMap.get(childConfig)), + nullToEmptyList(configurationToNonPropagatedObjcMap.get(childConfig)), + nullToEmptyList(configurationToCcDepMap.get(childConfig))); + ObjcProvider objcProvider = common.getObjcProvider(); + if (!hasLibraryOrSources(objcProvider)) { + ruleContext.ruleError(REQUIRES_AT_LEAST_ONE_LIBRARY_OR_SOURCE_FILE); + return null; + } + if (ruleContext.hasErrors()) { + return null; + } + binariesToLipo.add(intermediateArtifacts.strippedSingleArchitectureBinary()); + new CompilationSupport(ruleContext, childConfig) + .registerCompileAndArchiveActions(common) + .registerLinkActions( + objcProvider, new ExtraLinkArgs(), ImmutableList.<Artifact>of(), + DsymOutputType.APP) + .validateAttributes(); + + if (ruleContext.hasErrors()) { + return null; + } + } + + AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class); + + new LipoSupport(ruleContext).registerCombineArchitecturesAction( + binariesToLipo.build(), + ruleIntermediateArtifacts.combinedArchitectureBinary(), + appleConfiguration.getIosCpuPlatform()); + + RuleConfiguredTargetBuilder targetBuilder = + ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build()); + + return targetBuilder.build(); + } + + private boolean hasLibraryOrSources(ObjcProvider objcProvider) { + return !Iterables.isEmpty(objcProvider.get(LIBRARY)) // Includes sources from this target. + || !Iterables.isEmpty(objcProvider.get(IMPORTED_LIBRARY)); + } + + private ObjcCommon common(RuleContext ruleContext, BuildConfiguration buildConfiguration, + IntermediateArtifacts intermediateArtifacts, List<ObjcProvider> propagatedObjcDeps, + List<ObjcProvider> nonPropagatedObjcDeps, List<CppCompilationContext> cppDeps) { + CompilationArtifacts compilationArtifacts = + CompilationSupport.compilationArtifacts(ruleContext, intermediateArtifacts); + + return new ObjcCommon.Builder(ruleContext, buildConfiguration) + .setCompilationAttributes(new CompilationAttributes(ruleContext)) + .setResourceAttributes(new ResourceAttributes(ruleContext)) + .setCompilationArtifacts(compilationArtifacts) + .addDefines(ruleContext.getTokenizedStringListAttr("defines")) + .addDepObjcProviders(propagatedObjcDeps) + .addDepCcHeaderProviders(cppDeps) + // TODO(cparsons): The below call only gets CC link params from one child configuration, + // as it is accessed via Mode.TARGET. This poses a problem with multi-architecture + // builds with CC dependencies. + .addDepCcLinkProviders(ruleContext) + .addDepObjcProviders( + ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class)) + .addNonPropagatedDepObjcProviders(nonPropagatedObjcDeps) + .setIntermediateArtifacts(intermediateArtifacts) + .setAlwayslink(false) + .setHasModuleMap() + .setLinkedBinary(intermediateArtifacts.strippedSingleArchitectureBinary()) + .build(); + } + + private <T> List<T> nullToEmptyList(List<T> inputList) { + return inputList != null ? inputList : ImmutableList.<T>of(); + } + + private Set<BuildConfiguration> getChildConfigurations(RuleContext ruleContext) { + // This is currently a hack to obtain all child configurations regardless of the attribute + // values of this rule -- this rule does not currently use the actual info provided by + // this attribute. b/28403953 tracks cc toolchain usage. + ImmutableListMultimap<BuildConfiguration, CcToolchainProvider> configToProvider = + ruleContext.getPrerequisitesByConfiguration(":cc_toolchain", Mode.SPLIT, + CcToolchainProvider.class); + + return configToProvider.keySet(); + } +}
\ No newline at end of file diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java new file mode 100644 index 0000000000..498789c3fa --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleBinaryRule.java @@ -0,0 +1,84 @@ +// Copyright 2016 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 static com.google.devtools.build.lib.packages.Attribute.attr; +import static com.google.devtools.build.lib.packages.BuildType.LABEL; +import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; +import static com.google.devtools.build.lib.packages.ImplicitOutputsFunction.fromTemplates; +import static com.google.devtools.build.lib.syntax.Type.BOOLEAN; + +import com.google.devtools.build.lib.analysis.BaseRuleClasses; +import com.google.devtools.build.lib.analysis.RuleDefinition; +import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; +import com.google.devtools.build.lib.packages.ImplicitOutputsFunction; +import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction; +import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.packages.RuleClass.Builder; +import com.google.devtools.build.lib.rules.apple.AppleConfiguration; + +/** + * Rule definition for apple_binary. + */ +public class AppleBinaryRule implements RuleDefinition { + + /** + * Template for the fat binary output (using Apple's "lipo" tool to combine binaries of + * multiple architectures). + */ + private static final SafeImplicitOutputsFunction LIPOBIN = fromTemplates("%{name}_lipobin"); + + @Override + public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { + return builder + .requiresConfigurationFragments(ObjcConfiguration.class, J2ObjcConfiguration.class, + AppleConfiguration.class) + .add(attr("$is_executable", BOOLEAN).value(true) + .nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")) + .override(attr("deps", LABEL_LIST) + .cfg(IosApplication.SPLIT_ARCH_TRANSITION) + .direct_compile_time_input() + .allowedRuleClasses(ObjcRuleClasses.CompilingRule.ALLOWED_DEPS_RULE_CLASSES) + .allowedFileTypes()) + .override(attr("non_propagated_deps", LABEL_LIST) + .direct_compile_time_input() + .cfg(IosApplication.SPLIT_ARCH_TRANSITION) + .allowedRuleClasses(ObjcRuleClasses.CompilingRule.ALLOWED_DEPS_RULE_CLASSES) + .allowedFileTypes()) + .override(attr("srcs", LABEL_LIST) + .direct_compile_time_input() + .cfg(IosApplication.SPLIT_ARCH_TRANSITION) + .allowedFileTypes(ObjcRuleClasses.SRCS_TYPE)) + // This is currently a hack to obtain all child configurations regardless of the attribute + // values of this rule -- this rule does not currently use the actual info provided by + // this attribute. + .add(attr(":cc_toolchain", LABEL) + .cfg(IosApplication.SPLIT_ARCH_TRANSITION) + .value(ObjcRuleClasses.APPLE_TOOLCHAIN)) + .setImplicitOutputsFunction( + ImplicitOutputsFunction.fromFunctions(LIPOBIN)) + .build(); + } + + @Override + public Metadata getMetadata() { + return RuleDefinition.Metadata.builder() + .name("apple_binary") + .factoryClass(AppleBinary.class) + .ancestors(BaseRuleClasses.BaseRule.class, ObjcRuleClasses.LinkingRule.class, + ObjcRuleClasses.XcodegenRule.class, ObjcRuleClasses.SimulatorRule.class) + .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 e1eff2af67..c2547836bc 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 @@ -204,6 +204,18 @@ public final class CompilationSupport { */ // TODO(bazel-team): Remove this information from ObjcCommon and move it internal to this class. static CompilationArtifacts compilationArtifacts(RuleContext ruleContext) { + return compilationArtifacts(ruleContext, ObjcRuleClasses.intermediateArtifacts(ruleContext)); + } + + /** + * Returns information about the given rule's compilation artifacts. Dependencies specified + * in the current rule's attributes are obtained via {@code ruleContext}. Output locations + * are determined using the given {@code intermediateArtifacts} object. The fact that these + * are distinct objects allows the caller to generate compilation actions pertaining to + * a configuration separate from the current rule's configuration. + */ + static CompilationArtifacts compilationArtifacts(RuleContext ruleContext, + IntermediateArtifacts intermediateArtifacts) { PrerequisiteArtifacts srcs = ruleContext.getPrerequisiteArtifacts("srcs", Mode.TARGET) .errorsForNonMatching(SRCS_TYPE); return new CompilationArtifacts.Builder() @@ -215,7 +227,7 @@ public final class CompilationSupport { .list()) .addPrivateHdrs(srcs.filter(HEADERS).list()) .addPrecompiledSrcs(srcs.filter(PRECOMPILED_SRCS_TYPE).list()) - .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext)) + .setIntermediateArtifacts(intermediateArtifacts) .setPchFile(Optional.fromNullable(ruleContext.getPrerequisiteArtifact("pch", Mode.TARGET))) .build(); } @@ -1219,7 +1231,8 @@ public final class CompilationSupport { .addHeaders(attributes.hdrs()) .addHeaders(attributes.textualHdrs()) .addUserHeaderSearchPaths(ObjcCommon.userHeaderSearchPaths(buildConfiguration)) - .addHeaderSearchPaths("$(WORKSPACE_ROOT)", attributes.headerSearchPaths()) + .addHeaderSearchPaths("$(WORKSPACE_ROOT)", + attributes.headerSearchPaths(buildConfiguration.getGenfilesFragment())) .addHeaderSearchPaths("$(WORKSPACE_ROOT)", includeSystemPaths) .addHeaderSearchPaths("$(SDKROOT)/usr/include", attributes.sdkIncludes()) .addNonPropagatedHeaderSearchPaths( diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java new file mode 100644 index 0000000000..f79039664b --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/LipoSupport.java @@ -0,0 +1,53 @@ +// Copyright 2016 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.devtools.build.lib.actions.Artifact; +import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; +import com.google.devtools.build.lib.collect.nestedset.NestedSet; +import com.google.devtools.build.lib.rules.apple.Platform; + +/** + * Support for registering actions using the Apple tool "lipo", which combines artifacts of + * different architectures to make multi-architecture artifacts. + */ +public class LipoSupport { + private final RuleContext ruleContext; + + public LipoSupport(RuleContext ruleContext) { + this.ruleContext = ruleContext; + } + + /** + * Registers an action to invoke "lipo" on all artifacts in {@code inputBinaries} to create the + * {@code outputBinary} multi-architecture artifact, built for platform {@code platform}. + */ + public void registerCombineArchitecturesAction(NestedSet<Artifact> inputBinaries, + Artifact outputBinary, Platform platform) { + + ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder(ruleContext, platform) + .setMnemonic("ObjcCombiningArchitectures") + .addTransitiveInputs(inputBinaries) + .addOutput(outputBinary) + .setExecutable(CompilationSupport.xcrunwrapper(ruleContext)) + .setCommandLine(CustomCommandLine.builder() + .add(ObjcRuleClasses.LIPO) + .addExecPaths("-create", inputBinaries) + .addExecPath("-o", outputBinary) + .build()) + .build(ruleContext)); + } +} 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 6464a9968b..64c98bf7a4 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 @@ -174,13 +174,13 @@ public final class ObjcCommon { * Returns the exec paths of all header search paths that should be added to this target and * dependers on this target, obtained from the {@code includes} attribute. */ - ImmutableList<PathFragment> headerSearchPaths() { + ImmutableList<PathFragment> headerSearchPaths(PathFragment genfilesFragment) { ImmutableList.Builder<PathFragment> paths = new ImmutableList.Builder<>(); PathFragment packageFragment = ruleContext.getLabel().getPackageIdentifier().getPathFragment(); List<PathFragment> rootFragments = ImmutableList.of( packageFragment, - ruleContext.getConfiguration().getGenfilesFragment().getRelative(packageFragment)); + genfilesFragment.getRelative(packageFragment)); Iterable<PathFragment> relativeIncludes = Iterables.filter(includes(), Predicates.not(PathFragment.IS_ABSOLUTE)); @@ -292,6 +292,7 @@ public final class ObjcCommon { static class Builder { private RuleContext context; + private BuildConfiguration buildConfiguration; private Optional<CompilationAttributes> compilationAttributes = Optional.absent(); private Optional<ResourceAttributes> resourceAttributes = Optional.absent(); private Iterable<SdkFramework> extraSdkFrameworks = ImmutableList.of(); @@ -314,8 +315,22 @@ public final class ObjcCommon { private Iterable<CppCompilationContext> depCcHeaderProviders = ImmutableList.of(); private Iterable<CcLinkParamsProvider> depCcLinkProviders = ImmutableList.of(); + /** + * Builder for {@link ObjcCommon} obtaining both attribute data and configuration data from + * the given rule context. + */ Builder(RuleContext context) { + this(context, context.getConfiguration()); + } + + /** + * Builder for {@link ObjcCommon} obtaining attribute data from the rule context and + * configuration data from the given configuration object for use in situations where a single + * target's outputs are under multiple configurations. + */ + Builder(RuleContext context, BuildConfiguration buildConfiguration) { this.context = Preconditions.checkNotNull(context); + this.buildConfiguration = Preconditions.checkNotNull(buildConfiguration); } public Builder setCompilationAttributes(CompilationAttributes baseCompilationAttributes) { @@ -542,7 +557,7 @@ public final class ObjcCommon { objcProvider .addAll(HEADER, attributes.hdrs()) .addAll(HEADER, attributes.textualHdrs()) - .addAll(INCLUDE, attributes.headerSearchPaths()) + .addAll(INCLUDE, attributes.headerSearchPaths(buildConfiguration.getGenfilesFragment())) .addAll(INCLUDE, sdkIncludes) .addAll(SDK_FRAMEWORK, attributes.sdkFrameworks()) .addAll(WEAK_SDK_FRAMEWORK, attributes.weakSdkFrameworks()) @@ -631,7 +646,8 @@ public final class ObjcCommon { } } - if (hasModuleMap && ObjcRuleClasses.objcConfiguration(context).moduleMapsEnabled()) { + if (hasModuleMap + && buildConfiguration.getFragment(ObjcConfiguration.class).moduleMapsEnabled()) { CppModuleMap moduleMap = intermediateArtifacts.moduleMap(); objcProvider.add(MODULE_MAP, moduleMap.getArtifact()); objcProvider.add(TOP_LEVEL_MODULE_MAP, moduleMap); 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 e3350d1f82..ac5d8301ad 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 @@ -668,7 +668,10 @@ public class ObjcRuleClasses { * Common attributes for {@code objc_*} rules that contain compilable content. */ public static class CompilingRule implements RuleDefinition { - private static final Iterable<String> ALLOWED_DEPS_RULE_CLASSES = + /** + * Rule class names which are allowed as targets of the 'deps' attribute of this rule. + */ + static final Iterable<String> ALLOWED_DEPS_RULE_CLASSES = ImmutableSet.of( "objc_library", "objc_import", 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 e2fd865718..1d8bf7c210 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 @@ -783,19 +783,10 @@ public final class ReleaseBundlingSupport { } Artifact resultingLinkedBinary = intermediateArtifacts.combinedArchitectureBinary(); - NestedSet<Artifact> linkedBinaries = linkedBinaries(); - - ruleContext.registerAction(ObjcRuleClasses.spawnAppleEnvActionBuilder(ruleContext) - .setMnemonic("ObjcCombiningArchitectures") - .addTransitiveInputs(linkedBinaries) - .addOutput(resultingLinkedBinary) - .setExecutable(CompilationSupport.xcrunwrapper(ruleContext)) - .setCommandLine(CustomCommandLine.builder() - .add(ObjcRuleClasses.LIPO) - .addExecPaths("-create", linkedBinaries) - .addExecPath("-o", resultingLinkedBinary) - .build()) - .build(ruleContext)); + AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class); + + new LipoSupport(ruleContext).registerCombineArchitecturesAction(linkedBinaries(), + resultingLinkedBinary, appleConfiguration.getIosCpuPlatform()); } private NestedSet<Artifact> linkedBinaries() { |