Add framework support to ExperimentalObjcLibrary.

--
MOS_MIGRATED_REVID=122988772
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
index 1609f9d..0a2bf6e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java
@@ -692,21 +692,21 @@
      * so getting rid of the overhead of {@code Value} objects significantly reduces memory
      * overhead.
      */
-    static class ValueSequence implements Sequence {
+    public static class ValueSequence implements Sequence {
       private final List<String> values;
 
       /** Builder for value sequences. */
-      static class Builder {
+      public static class Builder {
         private final ImmutableList.Builder<String> values = ImmutableList.builder();
 
         /** Adds a value to the sequence. */
-        Builder addValue(String value) {
+        public Builder addValue(String value) {
           values.add(value);
           return this;
         }
 
         /** Returns an immutable value sequence. */
-        ValueSequence build() {
+        public ValueSequence build() {
           return new ValueSequence(values.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 4559319..846d6c6 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
@@ -1487,20 +1487,25 @@
   /**
    * Returns a list of framework search path flags for clang/swift actions.
    */
-  private static Iterable<String> commonFrameworkFlags(
+  static Iterable<String> commonFrameworkFlags(
+      ObjcProvider provider, AppleConfiguration appleConfiguration) {
+    return Interspersing.beforeEach("-F", commonFrameworkNames(provider, appleConfiguration));
+  }
+
+  /**
+   * Returns a list of frameworks for clang/swift actions.
+   */
+  static Iterable<String> commonFrameworkNames(
       ObjcProvider provider, AppleConfiguration appleConfiguration) {
     Platform platform = Platform.forIosArch(appleConfiguration.getIosCpu());
 
     return new ImmutableList.Builder<String>()
-        .add("-F", AppleToolchain.sdkFrameworkDir(platform, appleConfiguration))
+        .add(AppleToolchain.sdkFrameworkDir(platform, appleConfiguration))
         // As of sdk8.1, XCTest is in a base Framework dir
-        .add("-F", AppleToolchain.platformDeveloperFrameworkDir(appleConfiguration))
+        .add(AppleToolchain.platformDeveloperFrameworkDir(appleConfiguration))
         // Add custom (non-SDK) framework search paths. For each framework foo/bar.framework,
         // include "foo" as a search path.
-        .addAll(
-            Interspersing.beforeEach(
-                "-F",
-                PathFragment.safePathStrings(uniqueParentDirectories(provider.get(FRAMEWORK_DIR)))))
+        .addAll(PathFragment.safePathStrings(uniqueParentDirectories(provider.get(FRAMEWORK_DIR))))
         .build();
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java
index e3ec44e..f200e55 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ExperimentalObjcLibrary.java
@@ -22,9 +22,11 @@
 import com.google.devtools.build.lib.analysis.RuleContext;
 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.CcLibraryHelper;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.Builder;
+import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.ValueSequence;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.Variables.VariablesExtension;
 import com.google.devtools.build.lib.rules.cpp.CcToolchainProvider;
 import com.google.devtools.build.lib.rules.cpp.PrecompiledFiles;
@@ -38,21 +40,48 @@
 public class ExperimentalObjcLibrary implements RuleConfiguredTargetFactory {
 
   private static final String PCH_FILE_VARIABLE_NAME = "pch_file";
+  private static final String FRAMEWORKS_VARIABLE_NAME = "framework_paths";
   private static final Iterable<String> ACTIVATED_ACTIONS =
       ImmutableList.of("objc-compile", "objc++-compile");
-  
-  private VariablesExtension variablesExtension(final RuleContext ruleContext) {
-    return new VariablesExtension() {
-      @Override
-      public void addVariables(Builder builder) {
-        if (ruleContext.getPrerequisiteArtifact("pch", Mode.TARGET) != null) {
-          builder.addVariable(PCH_FILE_VARIABLE_NAME,
-              ruleContext.getPrerequisiteArtifact("pch", Mode.TARGET).getExecPathString());
-        }
+
+  /**
+   * Build variable extensions for templating a toolchain for objc builds.
+   */
+  private static class ObjcVariablesExtension implements VariablesExtension {
+
+    private final RuleContext ruleContext;
+    private final ObjcProvider objcProvider;
+
+    public ObjcVariablesExtension(RuleContext ruleContext, ObjcProvider objcProvider) {
+      this.ruleContext = ruleContext;
+      this.objcProvider = objcProvider;
+    }
+
+    @Override
+    public void addVariables(Builder builder) {
+      addPchVariables(builder);
+      addFrameworkVariables(builder);
+    }
+
+    private void addPchVariables(Builder builder) {
+       if (ruleContext.getPrerequisiteArtifact("pch", Mode.TARGET) != null) {
+        builder.addVariable(
+            PCH_FILE_VARIABLE_NAME,
+            ruleContext.getPrerequisiteArtifact("pch", Mode.TARGET).getExecPathString());
       }
-    };
+    }
+
+    private void addFrameworkVariables(Builder builder) {
+       ValueSequence.Builder frameworkSequence = new ValueSequence.Builder();
+      for (String framework :
+          CompilationSupport.commonFrameworkNames(
+              objcProvider, ruleContext.getFragment(AppleConfiguration.class))) {
+        frameworkSequence.addValue(framework);
+      }
+      builder.addSequence(FRAMEWORKS_VARIABLE_NAME, frameworkSequence.build());      
+    }
   }
-  
+
   @Override
   public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException {
 
@@ -76,8 +105,7 @@
 
     FeatureConfiguration featureConfiguration =
         toolchain.getFeatures().getFeatureConfiguration(activatedCrosstoolSelectables.build());
-   
-    
+
     Collection<Artifact> sources = Sets.newHashSet(compilationArtifacts.getSrcs());
     Collection<Artifact> privateHdrs = Sets.newHashSet(compilationArtifacts.getPrivateHdrs());
     Collection<Artifact> publicHdrs = Sets.newHashSet(compilationAttributes.hdrs());
@@ -85,7 +113,7 @@
     CcLibraryHelper helper =
         new CcLibraryHelper(
                 ruleContext,
-                ObjcCppSemantics.INSTANCE,
+                new ObjcCppSemantics(common.getObjcProvider()),
                 featureConfiguration,
                 CcLibraryHelper.SourceCategory.CC_AND_OBJC)
             .addSources(sources)
@@ -94,7 +122,8 @@
             .addPublicHeaders(publicHdrs)
             .addPrecompiledFiles(precompiledFiles)
             .addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET))
-            .addVariableExtension(variablesExtension(ruleContext));
+            .addVariableExtension(
+                new ObjcVariablesExtension(ruleContext, common.getObjcProvider()));
 
     CcLibraryHelper.Info info = helper.build();
 
@@ -106,7 +135,7 @@
         .build();
   }
 
-  private ObjcCommon common(
+  private static ObjcCommon common(
       RuleContext ruleContext,
       CompilationAttributes compilationAttributes,
       CompilationArtifacts compilationArtifacts) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
index b36523b..8c33932 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java
@@ -14,6 +14,9 @@
 
 package com.google.devtools.build.lib.rules.objc;
 
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.DYNAMIC_FRAMEWORK_FILE;
+import static com.google.devtools.build.lib.rules.objc.ObjcProvider.STATIC_FRAMEWORK_FILE;
+
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.Root;
 import com.google.devtools.build.lib.analysis.RuleContext;
@@ -31,10 +34,18 @@
  */
 public class ObjcCppSemantics implements CppSemantics {
 
-  // We make CppSemantics a singleton object for efficiency and consistency, since we expect
-  // any instance to be identical.
-  public static final CppSemantics INSTANCE = new ObjcCppSemantics();
+  private final ObjcProvider objcProvider;
 
+  /**
+   * Creates an instance of ObjcCppSemantics
+   * 
+   * @param objcProvider  the provider that should be used in determining objc-specific inputs
+   *    to actions
+   */
+  public ObjcCppSemantics(ObjcProvider objcProvider) {
+    this.objcProvider = objcProvider;
+  }
+  
   @Override
   public PathFragment getEffectiveSourcePath(Artifact source) {
     return source.getRootRelativePath();
@@ -49,6 +60,9 @@
     // including header files, as opposed to just the "compile" filegroup.
     actionBuilder.addTransitiveMandatoryInputs(CppHelper.getToolchain(ruleContext).getCrosstool());
     actionBuilder.setShouldScanIncludes(false);
+
+    actionBuilder.addTransitiveMandatoryInputs(objcProvider.get(STATIC_FRAMEWORK_FILE));
+    actionBuilder.addTransitiveMandatoryInputs(objcProvider.get(DYNAMIC_FRAMEWORK_FILE));
   }
 
   @Override