In apple_binary, propagate cc_library dependencies for all child configurations of the split transition

--
MOS_MIGRATED_REVID=121146341
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index cc3118b..9c85ce9 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -696,8 +696,7 @@
     AnalysisUtils.checkProvider(classType);
     List<? extends TransitiveInfoCollection> transitiveInfoCollections =
         getPrerequisites(attributeName, mode);
-    
-    // Use an ImmutableListMultimap.Builder here to preserve ordering.
+
     ImmutableListMultimap.Builder<BuildConfiguration, C> result =
         ImmutableListMultimap.builder();
     for (TransitiveInfoCollection prerequisite : transitiveInfoCollections) {
@@ -710,6 +709,24 @@
   }
 
   /**
+   * For a given attribute, returns all {@link TransitiveInfoCollection}s provided by targets
+   * of that attribute. Each {@link TransitiveInfoCollection} is keyed by the
+   * {@link BuildConfiguration} under which the collection was created.
+   */
+  public ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection>
+      getPrerequisitesByConfiguration(String attributeName, Mode mode) {
+    List<? extends TransitiveInfoCollection> transitiveInfoCollections =
+        getPrerequisites(attributeName, mode);
+
+    ImmutableListMultimap.Builder<BuildConfiguration, TransitiveInfoCollection> result =
+        ImmutableListMultimap.builder();
+    for (TransitiveInfoCollection prerequisite : transitiveInfoCollections) {
+      result.put(prerequisite.getConfiguration(), prerequisite);
+    }
+    return result.build();
+  }
+
+  /**
    * Returns all the providers of the specified type that are listed under the specified attribute
    * of this target in the BUILD file.
    */
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
index 0263076..9928c4a 100644
--- 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
@@ -26,6 +26,7 @@
 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.TransitiveInfoCollection;
 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;
@@ -49,14 +50,11 @@
 
   @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);
+    ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap =
+        ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT);
     
     Set<BuildConfiguration> childConfigurations = getChildConfigurations(ruleContext);
     
@@ -73,9 +71,8 @@
       IntermediateArtifacts intermediateArtifacts =
           ObjcRuleClasses.intermediateArtifacts(ruleContext, childConfig);
       ObjcCommon common = common(ruleContext, childConfig, intermediateArtifacts,
-          nullToEmptyList(configurationToObjcDepMap.get(childConfig)),
-          nullToEmptyList(configurationToNonPropagatedObjcMap.get(childConfig)),
-          nullToEmptyList(configurationToCcDepMap.get(childConfig)));
+          nullToEmptyList(configToDepsCollectionMap.get(childConfig)),
+          nullToEmptyList(configurationToNonPropagatedObjcMap.get(childConfig)));
       ObjcProvider objcProvider = common.getObjcProvider();
       if (!hasLibraryOrSources(objcProvider)) {
         ruleContext.ruleError(REQUIRES_AT_LEAST_ONE_LIBRARY_OR_SOURCE_FILE);
@@ -116,8 +113,22 @@
   }
 
   private ObjcCommon common(RuleContext ruleContext, BuildConfiguration buildConfiguration,
-      IntermediateArtifacts intermediateArtifacts, List<ObjcProvider> propagatedObjcDeps,
-      List<ObjcProvider> nonPropagatedObjcDeps, List<CppCompilationContext> cppDeps) {
+      IntermediateArtifacts intermediateArtifacts,
+      List<TransitiveInfoCollection> propagatedDeps,
+      List<ObjcProvider> nonPropagatedObjcDeps) {
+    ImmutableList.Builder<ObjcProvider> propagatedObjcDeps = ImmutableList.<ObjcProvider>builder();
+    ImmutableList.Builder<CppCompilationContext> cppDeps =
+        ImmutableList.<CppCompilationContext>builder();
+    
+    for (TransitiveInfoCollection dep : propagatedDeps) {
+      if (dep.getProvider(ObjcProvider.class) != null) {
+        propagatedObjcDeps.add(dep.getProvider(ObjcProvider.class));
+      }
+      if (dep.getProvider(CppCompilationContext.class) != null) {
+        cppDeps.add(dep.getProvider(CppCompilationContext.class));
+      }
+    }
+
     CompilationArtifacts compilationArtifacts =
         CompilationSupport.compilationArtifacts(ruleContext, intermediateArtifacts);
 
@@ -126,12 +137,9 @@
         .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(propagatedObjcDeps.build())
+        .addDepCcHeaderProviders(cppDeps.build())
+        .addDepCcLinkProviders(propagatedDeps)
         .addDepObjcProviders(
             ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
         .addNonPropagatedDepObjcProviders(nonPropagatedObjcDeps)
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 61fc074..9b8add0 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
@@ -211,7 +211,7 @@
                 ruleContext.getPrerequisites("deps", Mode.TARGET, ObjcProvider.class))
             .addDepCcHeaderProviders(
                 ruleContext.getPrerequisites("deps", Mode.TARGET, CppCompilationContext.class))
-            .addDepCcLinkProviders(ruleContext)
+            .addDepCcLinkProviders(ruleContext.getPrerequisites("deps", Mode.TARGET))
             .addDepObjcProviders(
                 ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class))
             .addNonPropagatedDepObjcProviders(
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 64c98bf..33b652a 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
@@ -478,10 +478,12 @@
     }
 
     /**
-     * Sets information from {@code cc_library} dependencies to be used during linking.
+     * Sets information from {@code cc_library} dependencies to be used during linking from
+     * the {@link TransitiveInfoCollection} objects which contain the relevant link providers
+     * (for example, from the current rule's "deps" attribute).
      */
-    public Builder addDepCcLinkProviders(RuleContext ruleContext) {
-      for (TransitiveInfoCollection dep : ruleContext.getPrerequisites("deps", Mode.TARGET)) {
+    public Builder addDepCcLinkProviders(List<? extends TransitiveInfoCollection> deps) {
+      for (TransitiveInfoCollection dep : deps) {
         // Hack to determine if dep is a cc target. Required so objc_library archives packed in
         // CcLinkParamsProvider do not get consumed as cc targets.
         if (dep.getProvider(CppRunfilesProvider.class) != null) {
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 88e7a21..991a6d8 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
@@ -89,7 +89,7 @@
             ruleContext.getPrerequisites("non_propagated_deps", Mode.TARGET, ObjcProvider.class))
         .addDepCcHeaderProviders(
             ruleContext.getPrerequisites("deps", Mode.TARGET, CppCompilationContext.class))
-        .addDepCcLinkProviders(ruleContext)
+        .addDepCcLinkProviders(ruleContext.getPrerequisites("deps", Mode.TARGET))
         .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
         .setAlwayslink(alwayslink)
         .setHasModuleMap()