C++: Refactors CLIF rule to go through CcLibraryHelper.

TBD: finish pulling out CLIF logic from the C++ rules implementation. This involves refactoring ArtifactCategory and CppSource.Type.

CLIF does PIC compilation now. This detail should be irrelevant to users since CLIF only cares about the matched protobuf output file.

SKIP_KOKORO=flakes

RELNOTES:none
PiperOrigin-RevId: 183396902
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java
index 01a86a2..f1a816e 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java
@@ -57,6 +57,7 @@
 import com.google.devtools.build.lib.rules.cpp.CppConfiguration;
 import com.google.devtools.build.lib.rules.cpp.CppFileTypes;
 import com.google.devtools.build.lib.rules.cpp.CppRuleClasses;
+import com.google.devtools.build.lib.rules.cpp.TransitiveLipoInfoProvider;
 import com.google.devtools.build.lib.rules.cpp.transitions.LipoContextCollectorTransition;
 import com.google.devtools.build.lib.util.FileTypeSet;
 
@@ -222,7 +223,7 @@
           <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
           .add(attr("includes", STRING_LIST))
           .add(
-              attr(":lipo_context_collector", LABEL)
+              attr(TransitiveLipoInfoProvider.LIPO_CONTEXT_COLLECTOR, LABEL)
                   .cfg(LipoContextCollectorTransition.INSTANCE)
                   .value(CppRuleClasses.LIPO_CONTEXT_COLLECTOR)
                   .skipPrereqValidatorCheck())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationOutputs.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationOutputs.java
index 1b0f2aa..6bcbc5c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationOutputs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationOutputs.java
@@ -195,9 +195,7 @@
       return this;
     }
 
-    /**
-     * Adds an .o file.
-     */
+    /** Adds an object file. */
     public Builder addObjectFile(Artifact artifact) {
       // We skip file extension checks for TreeArtifacts because they represent directory artifacts
       // without a file extension.
@@ -215,9 +213,7 @@
       return this;
     }
 
-    /**
-     * Adds a .pic.o file.
-     */
+    /** Adds a pic object file. */
     public Builder addPicObjectFile(Artifact artifact) {
       picObjectFiles.add(artifact);
       return this;
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 a85223f..62bbc15 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
@@ -99,14 +99,15 @@
    * Determines what file types CcLibraryHelper considers sources and what action configs are
    * configured in the CROSSTOOL.
    */
-  public static enum SourceCategory {
+  public enum SourceCategory {
     CC(
         FileTypeSet.of(
             CppFileTypes.CPP_SOURCE,
             CppFileTypes.CPP_HEADER,
             CppFileTypes.C_SOURCE,
             CppFileTypes.ASSEMBLER,
-            CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR)),
+            CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR,
+            CppFileTypes.CLIF_INPUT_PROTO)),
     CC_AND_OBJC(
         FileTypeSet.of(
             CppFileTypes.CPP_SOURCE,
@@ -322,6 +323,8 @@
   private final List<Artifact> publicTextualHeaders = new ArrayList<>();
   private final List<Artifact> privateHeaders = new ArrayList<>();
   private final List<Artifact> additionalInputs = new ArrayList<>();
+  private final List<Artifact> compilationMandatoryInputs = new ArrayList<>();
+  private final List<Artifact> additionalIncludeScanningRoots = new ArrayList<>();
   private final List<PathFragment> additionalExportedHeaders = new ArrayList<>();
   private final List<CppModuleMap> additionalCppModuleMaps = new ArrayList<>();
   private final Set<CppSource> compilationUnitSources = new LinkedHashSet<>();
@@ -372,6 +375,7 @@
   private boolean useDeps = true;
   private boolean generateModuleMap = true;
   private String purpose = null;
+  private boolean generateNoPic = true;
 
   /**
    * Creates a CcLibraryHelper.
@@ -570,7 +574,7 @@
    * Adds a source to {@code compilationUnitSources} if it is a compiled file type (including
    * parsed/preprocessed header) and to {@code privateHeaders} if it is a header.
    */
-  private void addSource(Artifact source, Label label) {
+  private CcLibraryHelper addSource(Artifact source, Label label) {
     Preconditions.checkNotNull(featureConfiguration);
     boolean isHeader = CppFileTypes.CPP_HEADER.matches(source.getExecPath());
     boolean isTextualInclude = CppFileTypes.CPP_TEXTUAL_INCLUDE.matches(source.getExecPath());
@@ -582,7 +586,7 @@
       privateHeaders.add(source);
     }
     if (isTextualInclude || !isCompiledSource || (isHeader && !shouldProcessHeaders())) {
-      return;
+      return this;
     }
     boolean isClifInputProto = CppFileTypes.CLIF_INPUT_PROTO.matches(source.getExecPathString());
     CppSource.Type type;
@@ -594,6 +598,7 @@
       type = CppSource.Type.SOURCE;
     }
     compilationUnitSources.add(CppSource.create(source, label, type));
+    return this;
   }
 
   private boolean shouldProcessHeaders() {
@@ -989,6 +994,28 @@
     return this;
   }
 
+  /** non-PIC actions won't be generated. */
+  public CcLibraryHelper setGenerateNoPic(boolean generateNoPic) {
+    this.generateNoPic = generateNoPic;
+    return this;
+  }
+
+  /** Adds mandatory inputs for the compilation action. */
+  public CcLibraryHelper addCompilationMandatoryInputs(
+      Collection<Artifact> compilationMandatoryInputs) {
+    this.compilationMandatoryInputs.addAll(compilationMandatoryInputs);
+    return this;
+  }
+
+  /** Adds additional includes to be scanned. */
+  // TODO(plf): This is only needed for CLIF. Investigate whether this is strictly necessary or
+  // there is a way to avoid include scanning for CLIF rules.
+  public CcLibraryHelper addAditionalIncludeScanningRoots(
+      Collection<Artifact> additionalIncludeScanningRoots) {
+    this.additionalIncludeScanningRoots.addAll(additionalIncludeScanningRoots);
+    return this;
+  }
+
   /**
    * Create the C++ compile and link actions, and the corresponding compilation related providers.
    *
@@ -1008,7 +1035,7 @@
    *
    * @throws RuleErrorException
    */
-  public Info.CompilationInfo compile() throws RuleErrorException, InterruptedException {
+  public Info.CompilationInfo compile() throws RuleErrorException {
     if (checkDepsGenerateCpp) {
       for (LanguageDependentFragment dep :
           AnalysisUtils.getProviders(deps, LanguageDependentFragment.class)) {
@@ -1274,7 +1301,10 @@
         .setLinkTargetType(linkType)
         .setNeverLink(neverlink)
         .addLinkActionInputs(linkActionInputs)
+        .addCompilationMandatoryInputs(compilationMandatoryInputs)
+        .addAdditionalIncludeScanningRoots(additionalIncludeScanningRoots)
         .setFake(fake)
+        .setGenerateNoPic(generateNoPic)
         .setAllowInterfaceSharedObjects(emitInterfaceSharedObjects)
         .setCreateDynamicLibrary(createDynamicLibrary)
         .setCreateStaticLibraries(createStaticLibraries)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
index bc9dbef..122fc14 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
@@ -299,7 +299,8 @@
   public ConfiguredTarget create(RuleContext ruleContext)
       throws RuleErrorException, InterruptedException {
     TransitiveInfoCollection lipoContextCollector =
-        ruleContext.getPrerequisite(":lipo_context_collector", Mode.DONT_CHECK);
+        ruleContext.getPrerequisite(
+            TransitiveLipoInfoProvider.LIPO_CONTEXT_COLLECTOR, Mode.DONT_CHECK);
     if (lipoContextCollector != null
         && lipoContextCollector.getProvider(LipoContextProvider.class) == null) {
       ruleContext.ruleError("--lipo_context must point to a cc_binary or a cc_test rule");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
index 1390657..a836995 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
@@ -64,42 +64,40 @@
         .add(attr("cpu", STRING).mandatory())
         .add(attr("compiler", STRING))
         .add(attr("libc", STRING))
-        .add(attr("all_files", LABEL)
-            .legacyAllowAnyFileType()
-            .cfg(HostTransition.INSTANCE)
-            .mandatory())
-        .add(attr("compiler_files", LABEL)
-            .legacyAllowAnyFileType()
-            .cfg(HostTransition.INSTANCE)
-            .mandatory())
-        .add(attr("strip_files", LABEL)
-            .legacyAllowAnyFileType()
-            .cfg(HostTransition.INSTANCE)
-            .mandatory())
-        .add(attr("objcopy_files", LABEL)
-            .legacyAllowAnyFileType()
-            .cfg(HostTransition.INSTANCE)
-            .mandatory())
-        .add(attr("linker_files", LABEL)
-            .legacyAllowAnyFileType()
-            .cfg(HostTransition.INSTANCE)
-            .mandatory())
-        .add(attr("dwp_files", LABEL)
-            .legacyAllowAnyFileType()
-            .cfg(HostTransition.INSTANCE)
-            .mandatory())
-        .add(attr("coverage_files", LABEL)
-            .legacyAllowAnyFileType()
-            .cfg(HostTransition.INSTANCE))
-        .add(attr("static_runtime_libs", LABEL_LIST)
-            .legacyAllowAnyFileType()
-            .mandatory())
-        .add(attr("dynamic_runtime_libs", LABEL_LIST)
-            .legacyAllowAnyFileType()
-            .mandatory())
-        .add(attr("module_map", LABEL)
-            .legacyAllowAnyFileType()
-            .cfg(HostTransition.INSTANCE))
+        .add(
+            attr("all_files", LABEL)
+                .legacyAllowAnyFileType()
+                .cfg(HostTransition.INSTANCE)
+                .mandatory())
+        .add(
+            attr("compiler_files", LABEL)
+                .legacyAllowAnyFileType()
+                .cfg(HostTransition.INSTANCE)
+                .mandatory())
+        .add(
+            attr("strip_files", LABEL)
+                .legacyAllowAnyFileType()
+                .cfg(HostTransition.INSTANCE)
+                .mandatory())
+        .add(
+            attr("objcopy_files", LABEL)
+                .legacyAllowAnyFileType()
+                .cfg(HostTransition.INSTANCE)
+                .mandatory())
+        .add(
+            attr("linker_files", LABEL)
+                .legacyAllowAnyFileType()
+                .cfg(HostTransition.INSTANCE)
+                .mandatory())
+        .add(
+            attr("dwp_files", LABEL)
+                .legacyAllowAnyFileType()
+                .cfg(HostTransition.INSTANCE)
+                .mandatory())
+        .add(attr("coverage_files", LABEL).legacyAllowAnyFileType().cfg(HostTransition.INSTANCE))
+        .add(attr("static_runtime_libs", LABEL_LIST).legacyAllowAnyFileType().mandatory())
+        .add(attr("dynamic_runtime_libs", LABEL_LIST).legacyAllowAnyFileType().mandatory())
+        .add(attr("module_map", LABEL).legacyAllowAnyFileType().cfg(HostTransition.INSTANCE))
         .add(attr("supports_param_files", BOOLEAN).value(true))
         .add(attr("supports_header_parsing", BOOLEAN).value(false))
         .add(
@@ -128,7 +126,7 @@
                             cppConfig.isLLVMOptimizedFdo() ? zipper : null)))
         .add(attr(":libc_top", LABEL).value(LIBC_TOP))
         .add(
-            attr(":lipo_context_collector", LABEL)
+            attr(TransitiveLipoInfoProvider.LIPO_CONTEXT_COLLECTOR, LABEL)
                 .cfg(LipoContextCollectorTransition.INSTANCE)
                 .value(CppRuleClasses.LIPO_CONTEXT_COLLECTOR)
                 .skipPrereqValidatorCheck())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
index 70446b2..1ae9395 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java
@@ -183,7 +183,7 @@
   // A list of files to include scan that are not source files, pcm files, lipo scannables, or
   // included via a command-line "-include file.h". Actions that use non C++ files as source
   // files--such as Clif--may use this mechanism.
-  private final ImmutableList<Artifact> additionalIncludeScannables;
+  private final ImmutableList<Artifact> additionalIncludeScanningRoots;
   @VisibleForTesting public final CompileCommandLine compileCommandLine;
   private final ImmutableMap<String, String> executionInfo;
   private final ImmutableMap<String, String> environment;
@@ -249,7 +249,7 @@
    * @param actionContext TODO(bazel-team): Add parameter description.
    * @param coptsFilter regular expression to remove options from {@code copts}
    * @param lipoScannables List of artifacts to include-scan when this action is a lipo action
-   * @param additionalIncludeScannables list of additional artifacts to include-scan
+   * @param additionalIncludeScanningRoots list of additional artifacts to include-scan
    * @param actionClassId TODO(bazel-team): Add parameter description
    * @param environment TODO(bazel-team): Add parameter description
    * @param actionName a string giving the name of this action for the purpose of toolchain
@@ -282,7 +282,7 @@
       Class<? extends CppCompileActionContext> actionContext,
       Predicate<String> coptsFilter,
       Iterable<IncludeScannable> lipoScannables,
-      ImmutableList<Artifact> additionalIncludeScannables,
+      ImmutableList<Artifact> additionalIncludeScanningRoots,
       UUID actionClassId,
       ImmutableMap<String, String> executionInfo,
       ImmutableMap<String, String> environment,
@@ -340,7 +340,7 @@
     this.prunableInputs = prunableInputs;
     this.builtinIncludeFiles = builtinIncludeFiles;
     this.cppSemantics = cppSemantics;
-    this.additionalIncludeScannables = ImmutableList.copyOf(additionalIncludeScannables);
+    this.additionalIncludeScanningRoots = ImmutableList.copyOf(additionalIncludeScanningRoots);
     this.builtInIncludeDirectories =
         ImmutableList.copyOf(cppProvider.getBuiltInIncludeDirectories());
     this.gccToolPath = cppProvider.getToolPathFragment(Tool.GCC);
@@ -650,7 +650,7 @@
       builder.addAll(context.getHeaderModuleSrcs());
     } else {
       builder.add(getSourceFile());
-      builder.addAll(additionalIncludeScannables);
+      builder.addAll(additionalIncludeScanningRoots);
     }
     return builder.build().toCollection();
   }
@@ -692,15 +692,15 @@
     return getArgv(getInternalOutputFile());
   }
 
+  protected final List<String> getArgv(PathFragment outputFile) {
+    return compileCommandLine.getArgv(outputFile, overwrittenVariables);
+  }
+
   @Override
   public List<String> getArguments() {
     return getArgv();
   }
 
-  protected final List<String> getArgv(PathFragment outputFile) {
-    return compileCommandLine.getArgv(outputFile, overwrittenVariables);
-  }
-
   @Override
   public boolean canRemoveAfterExecution() {
     // Module-generating actions are needed because the action may be retrieved in
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
index 815a4a6..8cc9bf4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java
@@ -73,8 +73,7 @@
   private Class<? extends CppCompileActionContext> actionContext;
   private CppConfiguration cppConfiguration;
   private ImmutableMap<Artifact, IncludeScannable> lipoScannableMap;
-  private final ImmutableList.Builder<Artifact> additionalIncludeFiles =
-      new ImmutableList.Builder<>();
+  private final ImmutableList.Builder<Artifact> additionalIncludeScanningRoots;
   private Boolean shouldScanIncludes;
   private Map<String, String> executionInfo = new LinkedHashMap<>();
   private Map<String, String> environment = new LinkedHashMap<>();
@@ -121,6 +120,7 @@
     this.cppConfiguration = configuration.getFragment(CppConfiguration.class);
     this.lipoScannableMap = ImmutableMap.copyOf(lipoScannableMap);
     this.mandatoryInputsBuilder = NestedSetBuilder.stableOrder();
+    this.additionalIncludeScanningRoots = new ImmutableList.Builder<>();
     this.allowUsingHeaderModules = true;
     this.localShellEnvironment = configuration.getLocalShellEnvironment();
     this.codeCoverageEnabled = configuration.isCodeCoverageEnabled();
@@ -128,20 +128,6 @@
     this.ccToolchain = ccToolchain;
   }
 
-  private static ImmutableMap<Artifact, IncludeScannable> getLipoScannableMap(
-      RuleContext ruleContext, CcToolchainProvider toolchain) {
-    if (!CppHelper.isLipoOptimization(ruleContext.getFragment(CppConfiguration.class), toolchain)
-        // Rules that do not contain sources that are compiled into object files, but may
-        // contain headers, will still create CppCompileActions without providing a
-        // lipo_context_collector.
-        || ruleContext.attributes().getAttributeDefinition(":lipo_context_collector") == null) {
-      return ImmutableMap.<Artifact, IncludeScannable>of();
-    }
-    LipoContextProvider provider = ruleContext.getPrerequisite(
-        ":lipo_context_collector", Mode.DONT_CHECK, LipoContextProvider.class);
-    return provider.getIncludeScannables();
-  }
-
   /**
    * Creates a builder that is a copy of another builder.
    */
@@ -151,6 +137,8 @@
     this.sourceFile = other.sourceFile;
     this.mandatoryInputsBuilder = NestedSetBuilder.<Artifact>stableOrder()
         .addTransitive(other.mandatoryInputsBuilder.build());
+    this.additionalIncludeScanningRoots =
+        new ImmutableList.Builder<Artifact>().addAll(other.additionalIncludeScanningRoots.build());
     this.optionalSourceFile = other.optionalSourceFile;
     this.outputFile = other.outputFile;
     this.dwoFile = other.dwoFile;
@@ -179,6 +167,26 @@
     this.actionName = other.actionName;
   }
 
+  private static ImmutableMap<Artifact, IncludeScannable> getLipoScannableMap(
+      RuleContext ruleContext, CcToolchainProvider toolchain) {
+    if (!CppHelper.isLipoOptimization(ruleContext.getFragment(CppConfiguration.class), toolchain)
+        // Rules that do not contain sources that are compiled into object files, but may
+        // contain headers, will still create CppCompileActions without providing a
+        // lipo_context_collector.
+        || ruleContext
+                .attributes()
+                .getAttributeDefinition(TransitiveLipoInfoProvider.LIPO_CONTEXT_COLLECTOR)
+            == null) {
+      return ImmutableMap.<Artifact, IncludeScannable>of();
+    }
+    LipoContextProvider provider =
+        ruleContext.getPrerequisite(
+            TransitiveLipoInfoProvider.LIPO_CONTEXT_COLLECTOR,
+            Mode.DONT_CHECK,
+            LipoContextProvider.class);
+    return provider.getIncludeScannables();
+  }
+
   public PathFragment getTempOutputFile() {
     return tempOutputFile;
   }
@@ -404,7 +412,7 @@
               actionContext,
               coptsFilter,
               getLipoScannables(realMandatoryInputs),
-              additionalIncludeFiles.build(),
+              additionalIncludeScanningRoots.build(),
               actionClassId,
               ImmutableMap.copyOf(executionInfo),
               ImmutableMap.copyOf(environment),
@@ -572,8 +580,9 @@
     return this;
   }
 
-  public CppCompileActionBuilder addAdditionalIncludes(List<Artifact> includes) {
-    additionalIncludeFiles.addAll(includes);
+  public CppCompileActionBuilder addAdditionalIncludeScanningRoots(
+      Iterable<Artifact> additionalIncludeScanningRoots) {
+    this.additionalIncludeScanningRoots.addAll(additionalIncludeScanningRoots);
     return this;
   }
 
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 77aa675..dd66496 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
@@ -745,12 +745,16 @@
    * or null if such a provider doesn't exist.
    */
   public static LipoContextProvider getLipoContextProvider(RuleContext ruleContext) {
-    if (ruleContext.getRule().getAttributeDefinition(":lipo_context_collector") == null) {
+    if (ruleContext
+            .getRule()
+            .getAttributeDefinition(TransitiveLipoInfoProvider.LIPO_CONTEXT_COLLECTOR)
+        == null) {
       return null;
     }
 
     TransitiveInfoCollection dep =
-        ruleContext.getPrerequisite(":lipo_context_collector", Mode.DONT_CHECK);
+        ruleContext.getPrerequisite(
+            TransitiveLipoInfoProvider.LIPO_CONTEXT_COLLECTOR, Mode.DONT_CHECK);
     return (dep != null) ? dep.getProvider(LipoContextProvider.class) : null;
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java
index 7d983b5..aa36ab6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java
@@ -179,7 +179,8 @@
   // compile model
   private CppCompilationContext context;
   private final Set<CppSource> sourceFiles = new LinkedHashSet<>();
-  private final List<Artifact> mandatoryInputs = new ArrayList<>();
+  private final List<Artifact> compilationMandatoryInputs = new ArrayList<>();
+  private final List<Artifact> additionalIncludeScanningRoots = new ArrayList<>();
   private final ImmutableList<String> copts;
   private final Predicate<String> coptsFilter;
   private boolean fake;
@@ -202,6 +203,7 @@
   private final FdoSupportProvider fdoSupport;
   private String linkedArtifactNameSuffix = "";
   private final ImmutableSet<String> features;
+  private boolean generateNoPic = true;
 
   public CppModel(
       RuleContext ruleContext,
@@ -321,9 +323,16 @@
     return this;
   }
 
-  /** Adds mandatory inputs. */
-  public CppModel addMandatoryInputs(Collection<Artifact> artifacts) {
-    this.mandatoryInputs.addAll(artifacts);
+  /** Adds compilation mandatory inputs. */
+  public CppModel addCompilationMandatoryInputs(Collection<Artifact> compilationMandatoryInputs) {
+    this.compilationMandatoryInputs.addAll(compilationMandatoryInputs);
+    return this;
+  }
+
+  /** Adds additional includes to be scanned. */
+  public CppModel addAdditionalIncludeScanningRoots(
+      Collection<Artifact> additionalIncludeScanningRoots) {
+    this.additionalIncludeScanningRoots.addAll(additionalIncludeScanningRoots);
     return this;
   }
 
@@ -415,6 +424,12 @@
     return this;
   }
 
+  /** no-PIC actions won't be generated. */
+  public CppModel setGenerateNoPic(boolean generateNoPic) {
+    this.generateNoPic = generateNoPic;
+    return this;
+  }
+
   /**
    * @returns whether we want to provide header modules for the current target.
    */
@@ -449,6 +464,9 @@
 
   /** @return whether this target needs to generate non-pic actions. */
   private boolean getGenerateNoPicActions() {
+    if (!generateNoPic) {
+      return false;
+    }
     boolean picFeatureEnabled = featureConfiguration.isEnabled(CppRuleClasses.PIC);
     boolean usePicForBinaries = CppHelper.usePic(ruleContext, ccToolchain, true);
     boolean usePicForNonBinaries = CppHelper.usePic(ruleContext, ccToolchain, false);
@@ -739,7 +757,13 @@
           FileSystemUtils.removeExtension(sourceArtifact.getRootRelativePath()).getPathString();
       CppCompileActionBuilder builder = initializeCompileAction(sourceArtifact);
 
-      builder.setSemantics(semantics);
+      builder.setSemantics(semantics)
+          .addMandatoryInputs(compilationMandatoryInputs)
+          .addAdditionalIncludeScanningRoots(additionalIncludeScanningRoots);
+
+      boolean bitcodeOutput =
+          featureConfiguration.isEnabled(CppRuleClasses.THIN_LTO)
+              && CppFileTypes.LTO_SOURCE.matches(sourceArtifact.getFilename());
 
       if (!sourceArtifact.isTreeArtifact()) {
         switch (source.getType()) {
@@ -747,13 +771,7 @@
             createHeaderAction(
                 sourceLabel, outputName, result, env, builder, isGenerateDotdFile(sourceArtifact));
             break;
-          case CLIF_INPUT_PROTO:
-            createClifMatchAction(sourceLabel, outputName, result, env, builder);
-            break;
           default:
-            boolean bitcodeOutput =
-                featureConfiguration.isEnabled(CppRuleClasses.THIN_LTO)
-                    && CppFileTypes.LTO_SOURCE.matches(sourceArtifact.getFilename());
             createSourceAction(
                 sourceLabel,
                 outputName,
@@ -761,7 +779,12 @@
                 env,
                 sourceArtifact,
                 builder,
-                ArtifactCategory.OBJECT_FILE,
+                // TODO(plf): Continue removing CLIF logic from C++. Follow up changes would include
+                // refactoring CppSource.Type and ArtifactCategory to be classes instead of enums
+                // that could be instantiated with arbitrary values.
+                source.getType() == CppSource.Type.CLIF_INPUT_PROTO
+                    ? ArtifactCategory.CLIF_OUTPUT_PROTO
+                    : ArtifactCategory.OBJECT_FILE,
                 context.getCppModuleMap(),
                 /* addObject= */ true,
                 isCodeCoverageEnabled(),
@@ -935,38 +958,6 @@
         isGenerateDotdFile(moduleMapArtifact));
   }
 
-  private void createClifMatchAction(
-      Label sourceLabel,
-      String outputName,
-      CcCompilationOutputs.Builder result,
-      AnalysisEnvironment env,
-      CppCompileActionBuilder builder)
-      throws RuleErrorException {
-    builder
-        .setOutputs(
-            ruleContext, ArtifactCategory.CLIF_OUTPUT_PROTO, outputName, /* generateDotd= */ true)
-        .setPicMode(false)
-        // The additional headers in a clif action are both mandatory inputs and
-        // need to be include-scanned.
-        .addMandatoryInputs(mandatoryInputs)
-        .addAdditionalIncludes(mandatoryInputs);
-    setupCompileBuildVariables(
-        builder,
-        sourceLabel,
-        /* usePic= */ false,
-        /* ccRelativeName= */ null,
-        /* autoFdoImportPath= */ null,
-        /* gcnoFile= */ null,
-        /* dwoFile= */ null,
-        /* ltoIndexingFile= */ null,
-        builder.getContext().getCppModuleMap());
-    semantics.finalizeCompileActionBuilder(ruleContext, builder);
-    CppCompileAction compileAction = builder.buildOrThrowRuleError(ruleContext);
-    env.registerAction(compileAction);
-    Artifact tokenFile = compileAction.getOutputFile();
-    result.addHeaderTokenFile(tokenFile);
-  }
-
   private Collection<Artifact> createSourceAction(
       Label sourceLabel,
       String outputName,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/TransitiveLipoInfoProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/TransitiveLipoInfoProvider.java
index 73a3865..1ecdba4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/TransitiveLipoInfoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/TransitiveLipoInfoProvider.java
@@ -29,6 +29,8 @@
  */
 @Immutable
 public final class TransitiveLipoInfoProvider implements TransitiveInfoProvider {
+  
+  public static final String LIPO_CONTEXT_COLLECTOR = ":lipo_context_collector";
   public static final TransitiveLipoInfoProvider EMPTY =
       new TransitiveLipoInfoProvider(
           NestedSetBuilder.<IncludeScannable>emptySet(Order.STABLE_ORDER));
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java
index aa98d37..1aa251c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java
@@ -50,6 +50,7 @@
 import com.google.devtools.build.lib.rules.cpp.CppHelper;
 import com.google.devtools.build.lib.rules.cpp.CppRuleClasses;
 import com.google.devtools.build.lib.rules.cpp.CppSemantics;
+import com.google.devtools.build.lib.rules.cpp.TransitiveLipoInfoProvider;
 import com.google.devtools.build.lib.rules.cpp.transitions.LipoContextCollectorTransition;
 import com.google.devtools.build.lib.rules.proto.ProtoCommon;
 import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder;
@@ -119,7 +120,7 @@
                 attr(CcToolchain.CC_TOOLCHAIN_DEFAULT_ATTRIBUTE_NAME, LABEL)
                     .value(ccToolchainAttrValue))
             .add(
-                attr(":lipo_context_collector", LABEL)
+                attr(TransitiveLipoInfoProvider.LIPO_CONTEXT_COLLECTOR, LABEL)
                     .cfg(LipoContextCollectorTransition.INSTANCE)
                     .value(CppRuleClasses.LIPO_CONTEXT_COLLECTOR)
                     .skipPrereqValidatorCheck());