diff options
author | 2015-03-13 17:01:45 +0000 | |
---|---|---|
committer | 2015-03-16 17:34:00 +0000 | |
commit | 01889715e70b55b9d197e546593878f16cdc0f26 (patch) | |
tree | ab7e3350552b5fead62d1abdf473d5882b537271 | |
parent | 09cff8f0a83d340729a0e61ca482e56614141487 (diff) |
Split ios_application configurations based on --ios_multi_cpus.
Using the new flag works only on ios_application and ios_extension targets,
resulting in their output binaries being "universal" with all given architectures
included.
Internally this is achieved by splitting the "binary" dependency (and its transitive
dependencies) of ios_{application,extension} to be built in one of the architectures
using split transitions. The results are then combined. Since an ios_application may
depend on ios_extension, we transition back to the top-level configuration when
encoutering such a dependency using the newly introduced TOP_LEVEL transition and then
split configurations again.
RELNOTES: --ios_multi_cpus allows building fat ios_applications.
--
MOS_MIGRATED_REVID=88555540
16 files changed, 202 insertions, 35 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/Attribute.java b/src/main/java/com/google/devtools/build/lib/rules/objc/Attribute.java new file mode 100644 index 0000000000..95e628d624 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/Attribute.java @@ -0,0 +1,43 @@ +// Copyright 2015 Google Inc. 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.analysis.RuleConfiguredTarget.Mode; +import com.google.devtools.build.lib.analysis.RuleContext; + +/** + * Container for an attribute name and access mode such as are commonly passed to + * {@link RuleContext#getPrerequisite(String, Mode)} and related methods. + */ +public class Attribute { + private final String name; + private final Mode accessMode; + + /** + * Creates an attribute reference with the given name and access mode. + */ + public Attribute(String name, Mode accessMode) { + this.name = name; + this.accessMode = accessMode; + } + + public String getName() { + return name; + } + + public Mode getAccessMode() { + return accessMode; + } +} 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 4e166eaee8..1710c96149 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 @@ -124,9 +124,9 @@ abstract class BinaryLinkingTargetFactory implements RuleConfiguredTargetFactory // TODO(bazel-team): Use LIBRARY_STATIC as parameter instead of APPLICATION once objc_binary // no longer creates an application bundle .addXcodeSettings(xcodeProviderBuilder, objcProvider, productType) - .addDependencies(xcodeProviderBuilder, "bundles") - .addDependencies(xcodeProviderBuilder, "deps") - .addDependencies(xcodeProviderBuilder, "non_propagated_deps") + .addDependencies(xcodeProviderBuilder, new Attribute("bundles", Mode.TARGET)) + .addDependencies(xcodeProviderBuilder, new Attribute("deps", Mode.TARGET)) + .addDependencies(xcodeProviderBuilder, new Attribute("non_propagated_deps", Mode.TARGET)) .addFilesToBuild(filesToBuild); XcodeProvider xcodeProvider = xcodeProviderBuilder.build(); xcodeSupport.registerActions(xcodeProvider); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java index d35bfa0618..72a4046437 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplication.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.rules.objc; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; @@ -26,9 +27,14 @@ import com.google.devtools.build.xcode.common.Platform; */ public class IosApplication extends ReleaseBundlingTargetFactory { + private static final ImmutableSet<Attribute> DEPENDENCY_ATTRIBUTES = + ImmutableSet.of( + new Attribute("binary", Mode.SPLIT), + new Attribute("extensions", Mode.TARGET)); + public IosApplication() { super(ReleaseBundlingSupport.APP_BUNDLE_DIR_FORMAT, XcodeProductType.APPLICATION, - ExposeAsNestedBundle.NO); + ExposeAsNestedBundle.NO, DEPENDENCY_ATTRIBUTES); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplicationRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplicationRule.java index 497955ea92..040a81f77f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplicationRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosApplicationRule.java @@ -18,6 +18,7 @@ import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTran import static com.google.devtools.build.lib.packages.Attribute.attr; import static com.google.devtools.build.lib.packages.Type.BOOLEAN; import static com.google.devtools.build.lib.packages.Type.LABEL; +import static com.google.devtools.build.lib.packages.Type.LABEL_LIST; import com.google.devtools.build.lib.analysis.BaseRuleClasses; import com.google.devtools.build.lib.analysis.BlazeRule; @@ -60,6 +61,15 @@ public class IosApplicationRule implements RuleDefinition { .allowedRuleClasses("objc_binary") .allowedFileTypes() .mandatory() + .direct_compile_time_input() + .cfg(ReleaseBundlingSupport.SPLIT_ARCH_TRANSITION)) + /* <!-- #BLAZE_RULE(ios_application).ATTRIBUTE(extensions) --> + Any extensions to include in the final application. + ${SYNOPSIS} + <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ + .add(attr("extensions", LABEL_LIST) + .allowedRuleClasses("ios_extension") + .allowedFileTypes() .direct_compile_time_input()) .add(attr("$runner_script_template", LABEL).cfg(HOST) .value(env.getLabel("//tools/objc:ios_runner.sh.mac_template"))) diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java index 163d133189..fa2e8fbef6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtension.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.rules.objc; +import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; @@ -24,7 +25,7 @@ public class IosExtension extends ReleaseBundlingTargetFactory { public IosExtension() { super(ReleaseBundlingSupport.EXTENSION_BUNDLE_DIR_FORMAT, XcodeProductType.EXTENSION, - ExposeAsNestedBundle.YES); + ExposeAsNestedBundle.YES, ImmutableSet.of(new Attribute("binary", Mode.SPLIT))); } protected OptionsProvider optionsProvider(RuleContext ruleContext) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java index a3491e0b9d..ca35f478ed 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosExtensionRule.java @@ -56,7 +56,8 @@ public class IosExtensionRule implements RuleDefinition { .allowedRuleClasses("ios_extension_binary") .allowedFileTypes() .mandatory() - .direct_compile_time_input()) + .direct_compile_time_input() + .cfg(ReleaseBundlingSupport.SPLIT_ARCH_TRANSITION)) .build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java index 1c94e9e14f..b2b836ef60 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/IosTest.java @@ -50,6 +50,9 @@ public abstract class IosTest implements RuleConfiguredTargetFactory { @VisibleForTesting public static final String REQUIRES_SOURCE_ERROR = "ios_test requires at least one source file in srcs or non_arc_srcs"; + @VisibleForTesting + public static final String NO_MULTI_CPUS_ERROR = + "ios_test cannot be built for multiple CPUs at the same time"; /** * Creates a target, including registering actions, just as {@link #create(RuleContext)} does. @@ -70,6 +73,10 @@ public abstract class IosTest implements RuleConfiguredTargetFactory { ruleContext.ruleError(REQUIRES_SOURCE_ERROR); } + if (!ObjcRuleClasses.objcConfiguration(ruleContext).getIosMultiCpus().isEmpty()) { + ruleContext.ruleError(NO_MULTI_CPUS_ERROR); + } + XcodeProvider.Builder xcodeProviderBuilder = new XcodeProvider.Builder(); NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder() .addTransitive(common.getStoryboards().getOutputZips()) @@ -132,9 +139,9 @@ public abstract class IosTest implements RuleConfiguredTargetFactory { new XcodeSupport(ruleContext) .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), productType) - .addDependencies(xcodeProviderBuilder, "bundles") - .addDependencies(xcodeProviderBuilder, "deps") - .addDependencies(xcodeProviderBuilder, "non_propagated_deps") + .addDependencies(xcodeProviderBuilder, new Attribute("bundles", Mode.TARGET)) + .addDependencies(xcodeProviderBuilder, new Attribute("deps", Mode.TARGET)) + .addDependencies(xcodeProviderBuilder, new Attribute("non_propagated_deps", Mode.TARGET)) .addFilesToBuild(filesToBuild) .registerActions(xcodeProviderBuilder.build()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java index 253fe32814..e25e274674 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcBundleLibrary.java @@ -58,7 +58,7 @@ public class ObjcBundleLibrary implements RuleConfiguredTargetFactory { new XcodeSupport(ruleContext) .addFilesToBuild(filesToBuild) .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), BUNDLE) - .addDependencies(xcodeProviderBuilder, "bundles") + .addDependencies(xcodeProviderBuilder, new Attribute("bundles", Mode.TARGET)) .registerActions(xcodeProviderBuilder.build()); ObjcProvider nestedBundleProvider = new ObjcProvider.Builder() 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 2e42ff9bd4..8937340c7c 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 @@ -17,9 +17,13 @@ package com.google.devtools.build.lib.rules.objc; import static com.google.devtools.build.xcode.common.BuildOptionsUtil.DEFAULT_OPTIONS_NAME; import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; +import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.FragmentOptions; +import com.google.devtools.build.lib.packages.Attribute.SplitTransition; import com.google.devtools.build.lib.syntax.Label; +import com.google.devtools.common.options.Converters.CommaSeparatedOptionListConverter; import com.google.devtools.common.options.Option; import java.util.List; @@ -92,8 +96,28 @@ public class help = "Enable checking for memory leaks in ios_test targets.") public boolean runMemleaks; + @Option(name = "ios_multi_cpus", + converter = CommaSeparatedOptionListConverter.class, + defaultValue = "", + category = "flags", + help = "Comma-separated list of architectures to build an ios_application with. The result " + + "is a universal binary containing all specified architectures.") + public List<String> iosMultiCpus; + + @Option(name = "ios_split_cpu", + defaultValue = "", + category = "undocumented", + help = + "Don't set this value from the command line - it is derived from ios_multi_cpus only.") + public String iosSplitCpu; + @VisibleForTesting static final String DEFAULT_MINIMUM_IOS = "7.0"; @Override public void addAllLabels(Multimap<String, Label> labelMap) {} + + @Override + public List<SplitTransition<BuildOptions>> getPotentialSplitTransitions() { + return ImmutableList.of(ReleaseBundlingSupport.SPLIT_ARCH_TRANSITION); + } } 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 4f8b3f5f27..e452ddb38c 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 @@ -18,7 +18,10 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.CompilationMode; +import com.google.devtools.build.lib.events.Event; +import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.syntax.Label; import com.google.devtools.build.xcode.common.Platform; @@ -53,6 +56,8 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { private final boolean runMemleaks; private final List<String> copts; private final CompilationMode compilationMode; + private final List<String> iosMultiCpus; + private final String iosSplitCpu; // We only load this label if coverage mode is enabled. That is know as part of the // BuildConfiguration. This label needs to be part of a configuration because only configurations @@ -79,6 +84,8 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { this.copts = ImmutableList.copyOf(objcOptions.copts); this.compilationMode = Preconditions.checkNotNull(options.compilationMode, "compilationMode"); this.gcovLabel = gcovLabel; + this.iosMultiCpus = Preconditions.checkNotNull(objcOptions.iosMultiCpus, "iosMultiCpus"); + this.iosSplitCpu = Preconditions.checkNotNull(objcOptions.iosSplitCpu, "iosSplitCpu"); } public String getIosSdkVersion() { @@ -106,7 +113,7 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { } public String getIosCpu() { - return iosCpu; + return iosSplitCpu.isEmpty() ? iosCpu : iosSplitCpu; } public Platform getPlatform() { @@ -164,6 +171,14 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { return gcovLabel; } + /** + * List of all CPUs that this invocation is being built for. Different from {@link #getIosCpu()} + * which is the specific CPU <b>this target</b> is being built for. + */ + public List<String> getIosMultiCpus() { + return iosMultiCpus; + } + @Override public String getName() { return "Objective-C"; @@ -173,4 +188,18 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment { public String cacheKey() { return iosSdkVersion; } + + @Nullable + @Override + public String getOutputDirectoryName() { + return !iosSplitCpu.isEmpty() ? "ios-" + iosSplitCpu : null; + } + + @Override + public void reportInvalidOptions(EventHandler reporter, BuildOptions buildOptions) { + if (generateDebugSymbols && !iosMultiCpus.isEmpty()) { + reporter.handle(Event.error( + "--objc_generate_debug_symbols is not supported when --ios_multi_cpus is set")); + } + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java index 616bfc0b9a..631def29c4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcImport.java @@ -58,7 +58,7 @@ public class ObjcImport implements RuleConfiguredTargetFactory { new XcodeSupport(ruleContext) .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), LIBRARY_STATIC) - .addDependencies(xcodeProviderBuilder, "bundles") + .addDependencies(xcodeProviderBuilder, new Attribute("bundles", Mode.TARGET)) .registerActions(xcodeProviderBuilder.build()) .addFilesToBuild(filesToBuild); diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java index cf4bfcb3ec..2271f4931f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcLibrary.java @@ -101,9 +101,9 @@ public class ObjcLibrary implements RuleConfiguredTargetFactory { new XcodeSupport(ruleContext) .addFilesToBuild(filesToBuild) .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), LIBRARY_STATIC) - .addDependencies(xcodeProviderBuilder, "bundles") - .addDependencies(xcodeProviderBuilder, "deps") - .addDependencies(xcodeProviderBuilder, "non_propagated_deps") + .addDependencies(xcodeProviderBuilder, new Attribute("bundles", Mode.TARGET)) + .addDependencies(xcodeProviderBuilder, new Attribute("deps", Mode.TARGET)) + .addDependencies(xcodeProviderBuilder, new Attribute("non_propagated_deps", Mode.TARGET)) .registerActions(xcodeProviderBuilder.build()); return common.configuredTarget( 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 5e28bfb414..d253cf693a 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 @@ -384,7 +384,7 @@ public class ObjcRuleClasses { <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/ .add(attr("bundles", LABEL_LIST) .direct_compile_time_input() - .allowedRuleClasses("objc_bundle", "objc_bundle_library", "ios_extension") + .allowedRuleClasses("objc_bundle", "objc_bundle_library") .allowedFileTypes()) .add(attr("$momczip_deploy", LABEL).cfg(HOST) .value(env.getLabel("//tools/objc:momczip_deploy.jar"))) 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 6a6e74a830..67befa23d4 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 @@ -33,9 +33,11 @@ import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.SpawnAction; import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction; import com.google.devtools.build.lib.analysis.actions.TemplateExpansionAction.Substitution; +import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; +import com.google.devtools.build.lib.packages.Attribute.SplitTransition; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction; import com.google.devtools.build.lib.packages.Type; import com.google.devtools.build.lib.rules.objc.ObjcActionsBuilder.ExtraActoolArgs; @@ -68,6 +70,35 @@ public final class ReleaseBundlingSupport { */ public static final SafeImplicitOutputsFunction IPA = fromTemplates("%{name}.ipa"); + /** + * Transition that when applied to a target generates a configured target for each value in + * {@code --ios_multi_cpus}, such that {@code --ios_cpu} is set to a different one of those values + * in the configured targets. + */ + public static final SplitTransition<BuildOptions> SPLIT_ARCH_TRANSITION = + new SplitTransition<BuildOptions>() { + @Override + public List<BuildOptions> split(BuildOptions buildOptions) { + List<String> iosMultiCpus = buildOptions.get(ObjcCommandLineOptions.class).iosMultiCpus; + if (iosMultiCpus.isEmpty()) { + return ImmutableList.of(); + } + + ImmutableList.Builder<BuildOptions> splitBuildOptions = ImmutableList.builder(); + for (String iosCpu : iosMultiCpus) { + BuildOptions splitOptions = buildOptions.clone(); + splitOptions.get(ObjcCommandLineOptions.class).iosSplitCpu = iosCpu; + splitBuildOptions.add(splitOptions); + } + return splitBuildOptions.build(); + } + + @Override + public boolean defaultsToSelf() { + return true; + } + }; + @VisibleForTesting static final String NO_ASSET_CATALOG_ERROR_FORMAT = "a value was specified (%s), but this app does not have any asset catalogs"; @@ -620,8 +651,13 @@ public final class ReleaseBundlingSupport { return NestedSetBuilder.emptySet(Order.STABLE_ORDER); } - return ruleContext.getPrerequisite("binary", Mode.TARGET, ObjcProvider.class) - .get(ObjcProvider.LINKED_BINARY); + NestedSetBuilder<Artifact> linkedBinaries = NestedSetBuilder.stableOrder(); + for (ObjcProvider provider + : ruleContext.getPrerequisites("binary", Mode.DONT_CHECK, ObjcProvider.class)) { + linkedBinaries.addTransitive(provider.get(ObjcProvider.LINKED_BINARY)); + } + + return linkedBinaries.build(); } FilesToRunProvider bundleMergeExecutable() { diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java index 4bae44af82..88481393b9 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ReleaseBundlingTargetFactory.java @@ -17,9 +17,9 @@ package com.google.devtools.build.lib.rules.objc; import static com.google.devtools.build.lib.rules.objc.ObjcProvider.MERGE_ZIP; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; 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.collect.nestedset.NestedSetBuilder; @@ -40,19 +40,22 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg private final String bundleDirFormat; private final XcodeProductType xcodeProductType; private final ExposeAsNestedBundle exposeAsNestedBundle; + private final ImmutableSet<Attribute> dependencyAttributes; /** * @param bundleDirFormat format string representing the bundle's directory with a single * placeholder for the target name (e.g. {@code "Payload/%s.app"}) * @param exposeAsNestedBundle whether to export an {@link ObjcProvider} with this target as a - * nested bundle + * @param dependencyAttributes all attributes that contain dependencies of this rule. Any + * dependency so listed must expose {@link XcodeProvider} and {@link ObjcProvider}. */ public ReleaseBundlingTargetFactory(String bundleDirFormat, XcodeProductType xcodeProductType, - ExposeAsNestedBundle exposeAsNestedBundle) { + ExposeAsNestedBundle exposeAsNestedBundle, ImmutableSet<Attribute> dependencyAttributes) { this.bundleDirFormat = bundleDirFormat; this.xcodeProductType = xcodeProductType; this.exposeAsNestedBundle = exposeAsNestedBundle; + this.dependencyAttributes = dependencyAttributes; } @Override @@ -71,14 +74,16 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg .addFilesToBuild(filesToBuild) .validateAttributes(); - new XcodeSupport(ruleContext) + XcodeSupport xcodeSupport = new XcodeSupport(ruleContext) .addFilesToBuild(filesToBuild) - .addXcodeSettings( - xcodeProviderBuilder, common.getObjcProvider(), xcodeProductType) - .addDummySource(xcodeProviderBuilder) - .addDependencies(xcodeProviderBuilder, "binary") - .registerActions(xcodeProviderBuilder.build()); + .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), xcodeProductType) + .addDummySource(xcodeProviderBuilder); + for (Attribute attribute : dependencyAttributes) { + xcodeSupport.addDependencies(xcodeProviderBuilder, attribute); + } + + xcodeSupport.registerActions(xcodeProviderBuilder.build()); Optional<ObjcProvider> exposedObjcProvider; if (exposeAsNestedBundle == ExposeAsNestedBundle.YES) { @@ -112,10 +117,13 @@ public abstract class ReleaseBundlingTargetFactory implements RuleConfiguredTarg ReleaseBundlingSupport releaseBundlingSupport) {} private ObjcCommon common(RuleContext ruleContext) { - return new ObjcCommon.Builder(ruleContext) - .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext)) - .addDepObjcProviders( - ruleContext.getPrerequisites("binary", Mode.TARGET, ObjcProvider.class)) - .build(); + ObjcCommon.Builder builder = new ObjcCommon.Builder(ruleContext) + .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext)); + for (Attribute attribute : dependencyAttributes) { + builder.addDepObjcProviders( + ruleContext.getPrerequisites( + attribute.getName(), attribute.getAccessMode(), ObjcProvider.class)); + } + return builder.build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java index ca2524a37b..16cc88bb1e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/XcodeSupport.java @@ -21,6 +21,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.SafeImplicitOutputsFunction; +import com.google.devtools.build.lib.rules.objc.XcodeProvider.Builder; /** * Support for Objc rule types that export an Xcode provider or generate xcode project files. @@ -104,9 +105,10 @@ public final class XcodeSupport { * * @return this xcode support */ - XcodeSupport addDependencies(XcodeProvider.Builder xcodeProviderBuilder, String attribute) { - xcodeProviderBuilder - .addDependencies(ruleContext.getPrerequisites(attribute, Mode.TARGET, XcodeProvider.class)); + XcodeSupport addDependencies(Builder xcodeProviderBuilder, Attribute attribute) { + xcodeProviderBuilder.addDependencies( + ruleContext.getPrerequisites( + attribute.getName(), attribute.getAccessMode(), XcodeProvider.class)); return this; } } |