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( 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 @@ filegroup( 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 @@ cc_toolchain( 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 @@ cc_toolchain( 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 @@ cc_toolchain( 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 @@ cc_toolchain( 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 @@ cc_autoconf_toolchains = repository_rule( "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 @@ cc_autoconf = repository_rule( "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 @@ cc_autoconf = repository_rule( "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 @@ def build_flags(flags): 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 @@ def auto_configure_warning_maybe(repository_ctx, msg): """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 @@ load( "@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 @@ def configure_osx_toolchain(repository_ctx, overriden_tools): 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 @@ load( "resolve_labels", "split_escaped", "which", + "write_builtin_include_directory_paths", ) def _field(name, value): @@ -388,7 +389,24 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools): 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 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools): "%{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 @@ def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools): "%{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 @@ load( "escape_string", "execute", "resolve_labels", + "write_builtin_include_directory_paths", ) def _get_path_env_var(repository_ctx, name): @@ -476,6 +477,7 @@ def _get_msys_mingw_vars(repository_ctx): """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 @@ def _get_msvc_vars(repository_ctx, paths): ) 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 @@ def _get_msvc_vars(repository_ctx, paths): 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 @@ def _get_clang_cl_vars(repository_ctx, paths, msvc_vars): ]) 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 @@ def _get_clang_cl_vars(repository_ctx, paths, msvc_vars): 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,