Blaze CcLibraryHelper: make creating a CppCompilationContext public

Also, don't require the :stl attribute to be defined by all rules that
use CcLibraryHelper.

This makes it possible for other languages to use CcLibraryHelper to
create a CppCompilationContext.

--
MOS_MIGRATED_REVID=112494452
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
index 280ad7b..200edc4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibraryHelper.java
@@ -617,23 +617,8 @@
       }
     }
 
-    CppModel model = new CppModel(ruleContext, semantics)
-        .addSources(sources)
-        .addCopts(copts)
-        .setLinkTargetType(linkType)
-        .setNeverLink(neverlink)
-        .setFake(fake)
-        .setAllowInterfaceSharedObjects(emitInterfaceSharedObjects)
-        .setCreateDynamicLibrary(emitDynamicLibrary)
-        // Note: this doesn't actually save the temps, it just makes the CppModel use the
-        // configurations --save_temps setting to decide whether to actually save the temps.
-        .setSaveTemps(true)
-        .setNoCopts(nocopts)
-        .setDynamicLibrary(dynamicLibrary)
-        .addLinkopts(linkopts)
-        .setFeatureConfiguration(featureConfiguration);
-    CppCompilationContext cppCompilationContext =
-        initializeCppCompilationContext(model, featureConfiguration);
+    CppModel model = initializeCppModel();
+    CppCompilationContext cppCompilationContext = initializeCppCompilationContext(model);
     model.setContext(cppCompilationContext);
     boolean compileHeaderModules = featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULES);
     Preconditions.checkState(
@@ -724,10 +709,30 @@
   }
 
   /**
+   * Creates the C/C++ compilation action creator.
+   */
+  private CppModel initializeCppModel() {
+    return new CppModel(ruleContext, semantics)
+        .addSources(sources)
+        .addCopts(copts)
+        .setLinkTargetType(linkType)
+        .setNeverLink(neverlink)
+        .setFake(fake)
+        .setAllowInterfaceSharedObjects(emitInterfaceSharedObjects)
+        .setCreateDynamicLibrary(emitDynamicLibrary)
+        // Note: this doesn't actually save the temps, it just makes the CppModel use the
+        // configurations --save_temps setting to decide whether to actually save the temps.
+        .setSaveTemps(true)
+        .setNoCopts(nocopts)
+        .setDynamicLibrary(dynamicLibrary)
+        .addLinkopts(linkopts)
+        .setFeatureConfiguration(featureConfiguration);
+  }
+
+  /**
    * Create context for cc compile action from generated inputs.
    */
-  private CppCompilationContext initializeCppCompilationContext(CppModel model,
-      FeatureConfiguration featureConfiguration) {
+  private CppCompilationContext initializeCppCompilationContext(CppModel model) {
     CppCompilationContext.Builder contextBuilder =
         new CppCompilationContext.Builder(ruleContext);
 
@@ -820,14 +825,23 @@
     return contextBuilder.build();
   }
 
+  /**
+   * Creates context for cc compile action from generated inputs.
+   */
+  public CppCompilationContext initializeCppCompilationContext() {
+    return initializeCppCompilationContext(initializeCppModel());
+  }
+
   private Iterable<CppModuleMap> collectModuleMaps() {
     // Cpp module maps may be null for some rules. We filter the nulls out at the end.
     List<CppModuleMap> result = new ArrayList<>();
     Iterables.addAll(result, Iterables.transform(deps, CPP_DEPS_TO_MODULES));
-    CppCompilationContext stl =
-        ruleContext.getPrerequisite(":stl", Mode.TARGET, CppCompilationContext.class);
-    if (stl != null) {
-      result.add(stl.getCppModuleMap());
+    if (ruleContext.getRule().getAttributeDefinition(":stl") != null) {
+      CppCompilationContext stl =
+          ruleContext.getPrerequisite(":stl", Mode.TARGET, CppCompilationContext.class);
+      if (stl != null) {
+        result.add(stl.getCppModuleMap());
+      }
     }
 
     CcToolchainProvider toolchain = CppHelper.getToolchain(ruleContext);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
index 94c6896..97db3a5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppHelper.java
@@ -81,12 +81,14 @@
    */
   public static void mergeToolchainDependentContext(RuleContext ruleContext,
       Builder contextBuilder) {
-    TransitiveInfoCollection stl = ruleContext.getPrerequisite(":stl", Mode.TARGET);
-    if (stl != null) {
-      // TODO(bazel-team): Clean this up.
-      contextBuilder.addSystemIncludeDir(
-          stl.getLabel().getPackageIdentifier().getPathFragment().getRelative("gcc3"));
-      contextBuilder.mergeDependentContext(stl.getProvider(CppCompilationContext.class));
+    if (ruleContext.getRule().getAttributeDefinition(":stl") != null) {
+      TransitiveInfoCollection stl = ruleContext.getPrerequisite(":stl", Mode.TARGET);
+      if (stl != null) {
+        // TODO(bazel-team): Clean this up.
+        contextBuilder.addSystemIncludeDir(
+            stl.getLabel().getPackageIdentifier().getPathFragment().getRelative("gcc3"));
+        contextBuilder.mergeDependentContext(stl.getProvider(CppCompilationContext.class));
+      }
     }
     CcToolchainProvider toolchain = getToolchain(ruleContext);
     if (toolchain != null) {