Put include paths into action
diff --git a/cc/private/toolchain/BUILD.tpl b/cc/private/toolchain/BUILD.tpl
index d40f7f5..9241326 100644
--- a/cc/private/toolchain/BUILD.tpl
+++ b/cc/private/toolchain/BUILD.tpl
@@ -38,7 +38,7 @@
 
 filegroup(
     name = "compiler_deps",
-    srcs = glob(["extra_tools/**"], allow_empty = True) + ["%{cc_compiler_deps}"],
+    srcs = glob(["extra_tools/**"], allow_empty = True) + [%{cc_compiler_deps}],
 )
 
 # This is the entry point for --crosstool_top.  Toolchains are found
diff --git a/cc/private/toolchain/BUILD.windows.tpl b/cc/private/toolchain/BUILD.windows.tpl
index 7295700..66dbafd 100644
--- a/cc/private/toolchain/BUILD.windows.tpl
+++ b/cc/private/toolchain/BUILD.windows.tpl
@@ -28,6 +28,21 @@
     srcs = [],
 )
 
+filegroup(
+    name = "mingw_compiler_files",
+    srcs = [":builtin_include_directory_paths_mingw"]
+)
+
+filegroup(
+    name = "clangcl_compiler_files",
+    srcs = [":builtin_include_directory_paths_clangcl"]
+)
+
+filegroup(
+    name = "msvc_compiler_files",
+    srcs = [":builtin_include_directory_paths_msvc"]
+)
+
 # Hardcoded toolchain, legacy behaviour.
 cc_toolchain_suite(
     name = "toolchain",
@@ -49,8 +64,8 @@
     toolchain_config = ":msys_x64",
     all_files = ":empty",
     ar_files = ":empty",
-    as_files = ":empty",
-    compiler_files = ":empty",
+    as_files = ":mingw_compiler_files",
+    compiler_files = ":mingw_compiler_files",
     dwp_files = ":empty",
     linker_files = ":empty",
     objcopy_files = ":empty",
@@ -95,8 +110,8 @@
     toolchain_config = ":msys_x64_mingw",
     all_files = ":empty",
     ar_files = ":empty",
-    as_files = ":empty",
-    compiler_files = ":empty",
+    as_files = ":mingw_compiler_files",
+    compiler_files = ":mingw_compiler_files",
     dwp_files = ":empty",
     linker_files = ":empty",
     objcopy_files = ":empty",
@@ -141,8 +156,8 @@
     toolchain_config = ":msvc_x64",
     all_files = ":empty",
     ar_files = ":empty",
-    as_files = ":empty",
-    compiler_files = ":empty",
+    as_files = ":msvc_compiler_files",
+    compiler_files = ":msvc_compiler_files",
     dwp_files = ":empty",
     linker_files = ":empty",
     objcopy_files = ":empty",
@@ -206,8 +221,8 @@
     toolchain_config = ":clang_cl_x64",
     all_files = ":empty",
     ar_files = ":empty",
-    as_files = ":empty",
-    compiler_files = ":empty",
+    as_files = ":clangcl_compiler_files",
+    compiler_files = ":clangcl_compiler_files",
     dwp_files = ":empty",
     linker_files = ":empty",
     objcopy_files = ":empty",
diff --git a/cc/private/toolchain/cc_configure.bzl b/cc/private/toolchain/cc_configure.bzl
index 3ef32bf..1c25484 100644
--- a/cc/private/toolchain/cc_configure.bzl
+++ b/cc/private/toolchain/cc_configure.bzl
@@ -82,6 +82,7 @@
         "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN",
     ],
     implementation = cc_autoconf_toolchains_impl,
+    configure = True,
 )
 
 def cc_autoconf_impl(repository_ctx, overriden_tools = dict()):
@@ -158,6 +159,7 @@
         "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN",
         "BAZEL_USE_LLVM_NATIVE_COVERAGE",
         "BAZEL_LLVM",
+        "BAZEL_IGNORE_SYSTEM_HEADERS_VERSIONS",
         "USE_CLANG_CL",
         "CC",
         "CC_CONFIGURE_DEBUG",
@@ -168,6 +170,7 @@
         "SYSTEMROOT",
     ] + MSVC_ENVVARS,
     implementation = cc_autoconf_impl,
+    configure = True,
 )
 
 def cc_configure():
diff --git a/cc/private/toolchain/lib_cc_configure.bzl b/cc/private/toolchain/lib_cc_configure.bzl
index 789018f..fbce23b 100644
--- a/cc/private/toolchain/lib_cc_configure.bzl
+++ b/cc/private/toolchain/lib_cc_configure.bzl
@@ -209,6 +209,7 @@
     return "\n".join(["        flag: '" + flag + "'" for flag in flags])
 
 def get_starlark_list(values):
+    """Convert a list of string into a string that can be passed to a rule attribute."""
     if not values:
         return ""
     return "\"" + "\",\n    \"".join(values) + "\""
@@ -217,3 +218,26 @@
     """Output warning message when CC_CONFIGURE_DEBUG is enabled."""
     if is_cc_configure_debug(repository_ctx):
         auto_configure_warning(msg)
+
+def write_builtin_include_directory_paths(repository_ctx, cc, directories, file_suffix = ""):
+    """Generate output file named 'builtin_include_directory_paths' in the root of the repository."""
+    if get_env_var(repository_ctx, "BAZEL_IGNORE_SYSTEM_HEADERS_VERSIONS", "0", False) == "1":
+        repository_ctx.file(
+            "builtin_include_directory_paths" + file_suffix,
+            """This file is generated by cc_configure and normally contains builtin include directories
+that C++ compiler reported. But because BAZEL_IGNORE_SYSTEM_HEADERS_VERSIONS was set to 1,
+header include directory paths are intentionally not put there.
+""",
+        )
+    else:
+        repository_ctx.file(
+            "builtin_include_directory_paths" + file_suffix,
+            """This file is generated by cc_configure and contains builtin include directories
+that %s reported. This file is a dependency of every compilation action and
+changes to it will be reflected in the action cache key. When some of these
+paths change, Bazel will make sure to rerun the action, even though none of
+declared action inputs or the action commandline changes.
+
+%s
+""" % (cc, "\n".join(directories)),
+        )
diff --git a/cc/private/toolchain/osx_cc_configure.bzl b/cc/private/toolchain/osx_cc_configure.bzl
index e40b4e4..716d5b2 100644
--- a/cc/private/toolchain/osx_cc_configure.bzl
+++ b/cc/private/toolchain/osx_cc_configure.bzl
@@ -19,6 +19,7 @@
     "@rules_cc//cc/private/toolchain:lib_cc_configure.bzl",
     "escape_string",
     "resolve_labels",
+    "write_builtin_include_directory_paths",
 )
 load(
     "@rules_cc//cc/private/toolchain:unix_cc_configure.bzl",
@@ -134,6 +135,7 @@
                  error_msg)
 
         escaped_include_paths = _get_escaped_xcode_cxx_inc_directories(repository_ctx, cc, xcode_toolchains)
+        write_builtin_include_directory_paths(repository_ctx, cc, escaped_include_paths)
         escaped_cxx_include_directories = []
         for path in escaped_include_paths:
             escaped_cxx_include_directories.append(("        \"%s\"," % path))
diff --git a/cc/private/toolchain/unix_cc_configure.bzl b/cc/private/toolchain/unix_cc_configure.bzl
index 58b31bb..a62afd9 100644
--- a/cc/private/toolchain/unix_cc_configure.bzl
+++ b/cc/private/toolchain/unix_cc_configure.bzl
@@ -25,6 +25,7 @@
     "resolve_labels",
     "split_escaped",
     "which",
+    "write_builtin_include_directory_paths",
 )
 
 def _field(name, value):
@@ -388,7 +389,24 @@
         bin_search_flag = []
 
     coverage_compile_flags, coverage_link_flags = _coverage_flags(repository_ctx, darwin)
+    builtin_include_directories = _uniq(
+        get_escaped_cxx_inc_directories(repository_ctx, cc, "-xc") +
+        get_escaped_cxx_inc_directories(repository_ctx, cc, "-xc++", cxx_opts) +
+        get_escaped_cxx_inc_directories(
+            repository_ctx,
+            cc,
+            "-xc",
+            _get_no_canonical_prefixes_opt(repository_ctx, cc),
+        ) +
+        get_escaped_cxx_inc_directories(
+            repository_ctx,
+            cc,
+            "-xc++",
+            cxx_opts + _get_no_canonical_prefixes_opt(repository_ctx, cc),
+        ),
+    )
 
+    write_builtin_include_directory_paths(repository_ctx, cc, builtin_include_directories)
     repository_ctx.template(
         "BUILD",
         paths["@rules_cc//cc/private/toolchain:BUILD.tpl"],
@@ -396,7 +414,9 @@
             "%{cc_toolchain_identifier}": cc_toolchain_identifier,
             "%{name}": cpu_value,
             "%{supports_param_files}": "0" if darwin else "1",
-            "%{cc_compiler_deps}": ":cc_wrapper" if darwin else ":empty",
+            "%{cc_compiler_deps}": get_starlark_list([":builtin_include_directory_paths"] + (
+                [":cc_wrapper"] if darwin else []
+            )),
             "%{compiler}": escape_string(get_env_var(
                 repository_ctx,
                 "BAZEL_COMPILER",
@@ -442,24 +462,7 @@
             "%{tool_paths}": ",\n        ".join(
                 ['"%s": "%s"' % (k, v) for k, v in tool_paths.items()],
             ),
-            "%{cxx_builtin_include_directories}": get_starlark_list(
-                _uniq(
-                    get_escaped_cxx_inc_directories(repository_ctx, cc, "-xc") +
-                    get_escaped_cxx_inc_directories(repository_ctx, cc, "-xc++", cxx_opts) +
-                    get_escaped_cxx_inc_directories(
-                        repository_ctx,
-                        cc,
-                        "-xc",
-                        _get_no_canonical_prefixes_opt(repository_ctx, cc),
-                    ) +
-                    get_escaped_cxx_inc_directories(
-                        repository_ctx,
-                        cc,
-                        "-xc++",
-                        cxx_opts + _get_no_canonical_prefixes_opt(repository_ctx, cc),
-                    ),
-                ),
-            ),
+            "%{cxx_builtin_include_directories}": get_starlark_list(builtin_include_directories),
             "%{compile_flags}": get_starlark_list(
                 [
                     # Security hardening requires optimization.
diff --git a/cc/private/toolchain/windows_cc_configure.bzl b/cc/private/toolchain/windows_cc_configure.bzl
index a151beb..bd2c72e 100644
--- a/cc/private/toolchain/windows_cc_configure.bzl
+++ b/cc/private/toolchain/windows_cc_configure.bzl
@@ -22,6 +22,7 @@
     "escape_string",
     "execute",
     "resolve_labels",
+    "write_builtin_include_directory_paths",
 )
 
 def _get_path_env_var(repository_ctx, name):
@@ -476,6 +477,7 @@
     """Get the variables we need to populate the msys/mingw toolchains."""
     tool_paths, tool_bin_path, inc_dir_msys = _get_escaped_windows_msys_starlark_content(repository_ctx)
     tool_paths_mingw, tool_bin_path_mingw, inc_dir_mingw = _get_escaped_windows_msys_starlark_content(repository_ctx, use_mingw = True)
+    write_builtin_include_directory_paths(repository_ctx, "mingw", [inc_dir_mingw], file_suffix = "_mingw")
     msys_mingw_vars = {
         "%{cxx_builtin_include_directories}": inc_dir_msys,
         "%{mingw_cxx_builtin_include_directories}": inc_dir_mingw,
@@ -514,6 +516,7 @@
             )
 
     if not vc_path or missing_tools:
+        write_builtin_include_directory_paths(repository_ctx, "msvc", [], file_suffix = "_msvc")
         msvc_vars = {
             "%{msvc_env_tmp}": "msvc_not_found",
             "%{msvc_env_path}": "msvc_not_found",
@@ -569,6 +572,7 @@
 
     support_debug_fastlink = _is_support_debug_fastlink(repository_ctx, link_path)
 
+    write_builtin_include_directory_paths(repository_ctx, "msvc", escaped_cxx_include_directories, file_suffix = "_msvc")
     msvc_vars = {
         "%{msvc_env_tmp}": escaped_tmp_dir,
         "%{msvc_env_path}": escaped_paths,
@@ -609,12 +613,13 @@
             ])
             repository_ctx.template(
                 "clang_installation_error.bat",
-                paths["@rules_cc//cc/private/toolchain:clang_installation_error.bat.tpl"],
+                paths["@bazel_tools//tools/cpp:clang_installation_error.bat.tpl"],
                 {"%{clang_error_message}": message},
             )
             error_script = "clang_installation_error.bat"
 
     if error_script:
+        write_builtin_include_directory_paths(repository_ctx, "clang-cl", [], file_suffix = "_clangcl")
         clang_cl_vars = {
             "%{clang_cl_env_tmp}": "clang_cl_not_found",
             "%{clang_cl_env_path}": "clang_cl_not_found",
@@ -639,12 +644,14 @@
     clang_include_path = (clang_dir + "\\include").replace("\\", "\\\\")
     clang_lib_path = (clang_dir + "\\lib\\windows").replace("\\", "\\\\")
 
+    clang_cl_include_directories = msvc_vars["%{msvc_cxx_builtin_include_directories}"] + (",\n        \"%s\"" % clang_include_path)
+    write_builtin_include_directory_paths(repository_ctx, "clang-cl", [clang_cl_include_directories], file_suffix = "_clangcl")
     clang_cl_vars = {
         "%{clang_cl_env_tmp}": msvc_vars["%{msvc_env_tmp}"],
         "%{clang_cl_env_path}": msvc_vars["%{msvc_env_path}"],
         "%{clang_cl_env_include}": msvc_vars["%{msvc_env_include}"] + ";" + clang_include_path,
         "%{clang_cl_env_lib}": msvc_vars["%{msvc_env_lib}"] + ";" + clang_lib_path,
-        "%{clang_cl_cxx_builtin_include_directories}": msvc_vars["%{msvc_cxx_builtin_include_directories}"] + (",\n        \"%s\"" % clang_include_path),
+        "%{clang_cl_cxx_builtin_include_directories}": clang_cl_include_directories,
         "%{clang_cl_cl_path}": clang_cl_path,
         "%{clang_cl_link_path}": lld_link_path,
         "%{clang_cl_lib_path}": llvm_lib_path,