Gracefully handle if Windows DEF-file-specific cc_<rule> attributes are missing.

PiperOrigin-RevId: 244362486
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
index 2ebcd2c..5a08694 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
@@ -436,12 +436,12 @@
           }
         }
 
-        generatedDefFile =
-            CppHelper.createDefFileActions(
-                ruleContext,
-                ruleContext.getPrerequisiteArtifact("$def_parser", Mode.HOST),
-                objectFiles.build(),
-                binary.getFilename());
+        Artifact defParser = common.getDefParser();
+        if (defParser != null) {
+          generatedDefFile =
+              CppHelper.createDefFileActions(
+                  ruleContext, defParser, objectFiles.build(), binary.getFilename());
+        }
         customDefFile = common.getWinDefFile();
       }
     }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
index bedea9a..1a9ad14 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
@@ -13,6 +13,8 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules.cpp;
 
+import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
@@ -708,9 +710,25 @@
   /** Returns the Windows DEF file specified in win_def_file attribute of the rule. */
   @Nullable
   Artifact getWinDefFile() {
+    if (!ruleContext.isAttrDefined("win_def_file", LABEL)) {
+      return null;
+    }
+
     return ruleContext.getPrerequisiteArtifact("win_def_file", Mode.TARGET);
   }
 
+  /**
+   * Returns the parser & Windows DEF file generator specified in $def_parser attribute of the rule.
+   */
+  @Nullable
+  Artifact getDefParser() {
+    if (!ruleContext.isAttrDefined("$def_parser", LABEL)) {
+      return null;
+    }
+
+    return ruleContext.getPrerequisiteArtifact("$def_parser", Mode.HOST);
+  }
+
   /** Provides support for instrumentation. */
   public InstrumentedFilesInfo getInstrumentedFilesProvider(
       Iterable<Artifact> files, boolean withBaselineCoverage) throws RuleErrorException {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
index 712b5e8..ced185c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcLibrary.java
@@ -14,8 +14,6 @@
 
 package com.google.devtools.build.lib.rules.cpp;
 
-import static com.google.devtools.build.lib.packages.BuildType.LABEL;
-
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSortedMap;
@@ -305,34 +303,35 @@
     if (ruleContext.getRule().getImplicitOutputsFunction() != ImplicitOutputsFunction.NONE
         || !ccCompilationOutputs.isEmpty()) {
       if (featureConfiguration.isEnabled(CppRuleClasses.TARGETS_WINDOWS)) {
-        // If windows_export_all_symbols feature is enabled, bazel parses object files to generate
-        // DEF file and use it to export symbols. The generated DEF file won't be used if a custom
-        // DEF file is specified by win_def_file attribute.
-        if (CppHelper.shouldUseGeneratedDefFile(ruleContext, featureConfiguration)) {
-          try {
-            Artifact generatedDefFile =
-                CppHelper.createDefFileActions(
-                    ruleContext,
-                    ruleContext.getPrerequisiteArtifact("$def_parser", Mode.HOST),
-                    ccCompilationOutputs.getObjectFiles(false),
-                    ccToolchain
-                        .getFeatures()
-                        .getArtifactNameForCategory(
-                            ArtifactCategory.DYNAMIC_LIBRARY, ruleContext.getLabel().getName()));
-            linkingHelper.setDefFile(generatedDefFile);
-          } catch (EvalException e) {
-            ruleContext.throwWithRuleError(e.getMessage());
-            throw new IllegalStateException("Should not be reached");
+        // If user specifies a custom DEF file, then we use it.
+        Artifact defFile = common.getWinDefFile();
+
+        // If no DEF file is specified and the windows_export_all_symbols feature is enabled, parse
+        // object files to generate DEF file and use it to export symbols - if we have a parser.
+        // Otherwise, use no DEF file.
+        if (defFile == null
+            && CppHelper.shouldUseGeneratedDefFile(ruleContext, featureConfiguration)) {
+          Artifact defParser = common.getDefParser();
+          if (defParser != null) {
+            try {
+              defFile =
+                  CppHelper.createDefFileActions(
+                      ruleContext,
+                      defParser,
+                      ccCompilationOutputs.getObjectFiles(false),
+                      ccToolchain
+                          .getFeatures()
+                          .getArtifactNameForCategory(
+                              ArtifactCategory.DYNAMIC_LIBRARY, ruleContext.getLabel().getName()));
+            } catch (EvalException e) {
+              ruleContext.throwWithRuleError(e.getMessage());
+              throw new IllegalStateException("Should not be reached");
+            }
           }
         }
 
-        // If user specifies a custom DEF file, then we use this one instead of the generated one.
-        Artifact customDefFile = null;
-        if (ruleContext.isAttrDefined("win_def_file", LABEL)) {
-          customDefFile = ruleContext.getPrerequisiteArtifact("win_def_file", Mode.TARGET);
-          if (customDefFile != null) {
-            linkingHelper.setDefFile(customDefFile);
-          }
+        if (defFile != null) {
+          linkingHelper.setDefFile(defFile);
         }
       }
       ccLinkingOutputs = linkingHelper.link(ccCompilationOutputs);