diff --git a/platforms/BUILD.bazel b/platforms/BUILD.bazel index d9c7140d..d8c42a5d 100644 --- a/platforms/BUILD.bazel +++ b/platforms/BUILD.bazel @@ -45,3 +45,11 @@ platform( "@platforms//cpu:aarch64", ], ) + +platform( + name = "windows-msvc-x86_64", + constraint_values = [ + "@platforms//os:windows", + "@platforms//cpu:x86_64", + ], +) diff --git a/toolchain/BUILD.llvm_repo b/toolchain/BUILD.llvm_repo index 76cac99c..c8571977 100644 --- a/toolchain/BUILD.llvm_repo +++ b/toolchain/BUILD.llvm_repo @@ -32,6 +32,7 @@ filegroup( srcs = [ "bin/clang", "bin/clang++", + "bin/clang-cl", "bin/clang-cpp", ], ) @@ -41,6 +42,7 @@ filegroup( srcs = [ "bin/ld.lld", "bin/ld64.lld", + "bin/lld-link", ], ) diff --git a/toolchain/BUILD.toolchain.tpl b/toolchain/BUILD.toolchain.tpl index 9a7a75b0..66cab851 100644 --- a/toolchain/BUILD.toolchain.tpl +++ b/toolchain/BUILD.toolchain.tpl @@ -35,6 +35,7 @@ filegroup( name = "internal-use-wrapped-tools", srcs = [ "%{wrapper_bin_prefix}cc_wrapper.sh", + "%{wrapper_bin_prefix}cc_wrapper_msvc.sh", ], visibility = ["//visibility:private"], ) diff --git a/toolchain/cc_toolchain_config.bzl b/toolchain/cc_toolchain_config.bzl index c1b0d922..11ae4fcd 100644 --- a/toolchain/cc_toolchain_config.bzl +++ b/toolchain/cc_toolchain_config.bzl @@ -16,6 +16,10 @@ load( "@bazel_tools//tools/cpp:unix_cc_toolchain_config.bzl", unix_cc_toolchain_config = "cc_toolchain_config", ) +load( + ":windows_cc_toolchain_config.bzl", + windows_cc_toolchain_config = "cc_toolchain_config", +) load( "//toolchain/internal:common.bzl", _check_os_arch_keys = "check_os_arch_keys", @@ -89,6 +93,14 @@ def cc_toolchain_config( "clang", "glibc_unknown", ), + "windows-msvc-x86_64": ( + "clang-x86_64-windows-msvc", + "x64_windows", + "msvc", + "clang-cl", + "clang-cl", + "msvc", + ), }[target_os_arch_key] # Unfiltered compiler flags; these are placed at the end of the command @@ -105,22 +117,19 @@ def cc_toolchain_config( "-fdebug-prefix-map={}=__bazel_toolchain_llvm_repo__/".format(toolchain_path_prefix), ] - is_xcompile = not (exec_os == target_os and exec_arch == target_arch) - # Default compiler flags: compile_flags = [ "--target=" + target_system_name, # Security "-U_FORTIFY_SOURCE", # https://github.com/google/sanitizers/issues/247 - "-fstack-protector", - "-fno-omit-frame-pointer", - # Diagnostics - "-fcolor-diagnostics", - "-Wall", - "-Wthread-safety", - "-Wself-assign", ] + if target_os != "windows-msvc": + compile_flags.extend([ + "-fstack-protector", + "-fno-omit-frame-pointer", + ]) + dbg_compile_flags = ["-g", "-fstandalone-debug"] opt_compile_flags = [ @@ -134,7 +143,6 @@ def cc_toolchain_config( link_flags = [ "--target=" + target_system_name, - "-lm", "-no-canonical-prefixes", ] @@ -142,54 +150,26 @@ def cc_toolchain_config( # unused symbols are not stripped. link_libs = [] - # Flags for ar. - archive_flags = [] - - # Linker flags: - if exec_os == "darwin" and not is_xcompile: - # lld is experimental for Mach-O, so we use the native ld64 linker. - # TODO: How do we cross-compile from Linux to Darwin? - use_lld = False - link_flags.extend([ - "-headerpad_max_install_names", - "-fobjc-link-runtime", - ]) - - # Use the bundled libtool (llvm-libtool-darwin). - use_libtool = True - - # Pre-installed libtool on macOS has -static as default, but llvm-libtool-darwin needs it - # explicitly. cc_common.create_link_variables does not automatically add this either if - # output_file arg to it is None. - archive_flags.extend([ - "-static", - ]) - else: - # Note that for xcompiling from darwin to linux, the native ld64 is - # not an option because it is not a cross-linker, so lld is the - # only option. - use_lld = True - link_flags.extend([ - "-fuse-ld=lld", - "-Wl,--build-id=md5", - "-Wl,--hash-style=gnu", - "-Wl,-z,relro,-z,now", - ]) - use_libtool = False - # Flags related to C++ standard. # The linker has no way of knowing if there are C++ objects; so we # always link C++ libraries. cxx_standard = compiler_configuration["cxx_standard"] stdlib = compiler_configuration["stdlib"] + # Let's be compatible with the old way of specifying the standard library. + if stdlib == "stdc++": + print("WARNING: stdc++ is deprecated. Please use libstdc++ instead.") + stdlib = "libstdc++" sysroot_path = compiler_configuration["sysroot_path"] - if stdlib == "builtin-libc++" and is_xcompile: - stdlib = "stdc++" - if stdlib == "builtin-libc++": - cxx_flags = [ + + cxx_flags = [] + + if target_os != "windows-msvc": + cxx_flags.extend([ "-std=" + cxx_standard, - "-stdlib=libc++", - ] + "-stdlib=" + stdlib, + ]) + + if stdlib == "libc++": if major_llvm_version >= 14: # With C++20, Clang defaults to using C++ rather than Clang modules, # which breaks Bazel's `use_module_maps` feature, which is used by @@ -199,52 +179,13 @@ def cc_toolchain_config( # https://github.com/llvm/llvm-project/commit/0556138624edf48621dd49a463dbe12e7101f17d cxx_flags.append("-Xclang") cxx_flags.append("-fno-cxx-modules") - if use_lld: - # For single-platform builds, we can statically link the bundled - # libraries. - link_flags.extend([ - "-l:libc++.a", - "-l:libc++abi.a", - "-l:libunwind.a", - # Compiler runtime features. - "-rtlib=compiler-rt", - # To support libunwind. - "-lpthread", - "-ldl", - ]) - else: - # Several system libraries on macOS dynamically link libc++ and - # libc++abi, so static linking them becomes a problem. We need to - # ensure that they are dynamic linked from the system sysroot and - # not static linked from the toolchain, so explicitly have the - # sysroot directory on the search path and then add the toolchain - # directory back after we are done. - link_flags.extend([ - "-L{}/usr/lib".format(sysroot_path), - "-lc++", - "-lc++abi", - "-Bstatic", - "-lunwind", - "-Bdynamic", - "-L{}lib".format(toolchain_path_prefix), - ]) - - elif stdlib == "libc++": - cxx_flags = [ - "-std=" + cxx_standard, - "-stdlib=libc++", - ] link_flags.extend([ - "-l:c++.a", - "-l:c++abi.a", + "-l:libc++.a", + "-l:libc++abi.a", + "-l:libunwind.a", ]) - elif stdlib == "stdc++": - cxx_flags = [ - "-std=" + cxx_standard, - "-stdlib=libstdc++", - ] - + elif stdlib == "libstdc++": link_flags.extend([ "-l:libstdc++.a", ]) @@ -256,9 +197,90 @@ def cc_toolchain_config( link_flags.extend([ "-nostdlib", ]) - else: + elif target_os != "windows-msvc": + # When targetting Windows, we don't need to link against the standard + # library, as it is provided by the MSVC runtime. fail("Unknown value passed for stdlib: {stdlib}".format(stdlib = stdlib)) + archive_flags = [] + + if target_os == "darwin": + ld = "ld64.lld" + ld_path = toolchain_path_prefix + "/bin/" + ld + link_flags.extend([ + "-headerpad_max_install_names", + "-fobjc-link-runtime", + + "-fuse-ld=lld", + "--ld-path=" + ld_path, + + # Compiler runtime features. + "-rtlib=compiler-rt", + + "-lm", + "-ldl", + "-pthread", + ]) + + # Use the bundled libtool (llvm-libtool-darwin). + use_libtool = True + + # Pre-installed libtool on macOS has -static as default, but llvm-libtool-darwin needs it + # explicitly. cc_common.create_link_variables does not automatically add this either if + # output_file arg to it is None. + archive_flags.extend([ + "-static", + ]) + elif target_os == "linux": + ld = "ld.lld" + ld_path = toolchain_path_prefix + "/bin/" + ld + link_flags.extend([ + "-fuse-ld=lld", + "--ld-path=" + ld_path, + "-Wl,--build-id=md5", + "-Wl,--hash-style=gnu", + "-Wl,-z,relro,-z,now", + "-lm", + "-ldl", + "-pthread", + ]) + + use_libtool = False + elif target_os == "windows-msvc": + cxx_flags.extend([ + "/std:" + cxx_standard, + "-fms-compatibility", + "-fms-extensions", + ]) + compile_flags.extend([ + "/MT", + "/Brepro", + "/DWIN32", + "/D_WIN32", + "/D_WINDOWS", + "/clang:-isystem{}splat/VC/Tools/MSVC/14.41.17.11/include".format(sysroot_path), + "/clang:-isystem{}splat/Windows_Kits/10/include/10.0.26100/um".format(sysroot_path), + "/clang:-isystem{}splat/Windows_Kits/10/include/10.0.26100/shared".format(sysroot_path), + "/clang:-isystem{}splat/Windows_Kits/10/include/10.0.26100/ucrt".format(sysroot_path), + # Do not resolve our symlinked resource prefixes to real paths. + "-no-canonical-prefixes", + # Reproducibility + "-Wno-builtin-macro-redefined", + "/clang:-fdebug-prefix-map={}=__bazel_toolchain_llvm_repo__/".format(toolchain_path_prefix), + ]) + + ld = "lld-link" + + link_flags = [ + "/libpath:{}splat/Windows_Kits/10/lib/10.0.26100/ucrt/x64".format(sysroot_path), + "/libpath:{}splat/Windows_Kits/10/lib/10.0.26100/um/x64".format(sysroot_path), + "/libpath:{}splat/VC/Tools/MSVC/14.41.17.11/lib/x64".format(sysroot_path), + ] + + use_libtool = False + else: + fail("Unknown value passed for target_os: {}".format(target_os)) + opt_link_flags = ["-Wl,--gc-sections"] if target_os == "linux" else [] # Coverage flags: @@ -280,9 +302,9 @@ def cc_toolchain_config( "ar": tools_path_prefix + ("llvm-ar" if not use_libtool else "libtool"), "cpp": tools_path_prefix + "clang-cpp", "dwp": tools_path_prefix + "llvm-dwp", - "gcc": wrapper_bin_prefix + "cc_wrapper.sh", + "gcc": wrapper_bin_prefix + ("cc_wrapper_msvc.sh" if target_os == "windows-msvc" else "cc_wrapper.sh"), "gcov": tools_path_prefix + "llvm-profdata", - "ld": tools_path_prefix + "ld.lld" if use_lld else "/usr/bin/ld", + "ld": tools_path_prefix + ld, "llvm-cov": tools_path_prefix + "llvm-cov", "llvm-profdata": tools_path_prefix + "llvm-profdata", "nm": tools_path_prefix + "llvm-nm", @@ -291,14 +313,6 @@ def cc_toolchain_config( "strip": tools_path_prefix + "llvm-strip", } - # Start-end group linker support: - # This was added to `lld` in this patch: http://reviews.llvm.org/D18814 - # - # The oldest version of LLVM that we support is 6.0.0 which was released - # after the above patch was merged, so we just set this to `True` when - # `lld` is being used as the linker. - supports_start_end_lib = use_lld - # Replace flags with any user-provided overrides. if compiler_configuration["compile_flags"] != None: compile_flags = _fmt_flags(compiler_configuration["compile_flags"], toolchain_path_prefix) @@ -323,30 +337,55 @@ def cc_toolchain_config( if compiler_configuration["unfiltered_compile_flags"] != None: unfiltered_compile_flags = _fmt_flags(compiler_configuration["unfiltered_compile_flags"], toolchain_path_prefix) - # Source: https://cs.opensource.google/bazel/bazel/+/master:tools/cpp/unix_cc_toolchain_config.bzl - unix_cc_toolchain_config( - name = name, - cpu = target_cpu, - compiler = compiler, - toolchain_identifier = toolchain_identifier, - host_system_name = exec_arch, - target_system_name = target_system_name, - target_libc = target_libc, - abi_version = abi_version, - abi_libc_version = abi_libc_version, - cxx_builtin_include_directories = cxx_builtin_include_directories, - tool_paths = tool_paths, - compile_flags = compile_flags, - dbg_compile_flags = dbg_compile_flags, - opt_compile_flags = opt_compile_flags, - cxx_flags = cxx_flags, - link_flags = link_flags, - archive_flags = archive_flags, - link_libs = link_libs, - opt_link_flags = opt_link_flags, - unfiltered_compile_flags = unfiltered_compile_flags, - coverage_compile_flags = coverage_compile_flags, - coverage_link_flags = coverage_link_flags, - supports_start_end_lib = supports_start_end_lib, - builtin_sysroot = sysroot_path, - ) + if target_os == "windows-msvc": + windows_cc_toolchain_config( + name = name, + cpu = target_cpu, + compiler = compiler, + toolchain_identifier = toolchain_identifier, + host_system_name = exec_arch, + target_system_name = target_system_name, + target_libc = target_libc, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + cxx_builtin_include_directories = cxx_builtin_include_directories, + tool_paths = tool_paths, + archiver_flags = archive_flags, + default_compile_flags = compile_flags, + cxx_flags = cxx_flags, + default_link_flags = link_flags, + supports_parse_showincludes = False, + builtin_sysroot = sysroot_path, + msvc_cl_path = tools_path_prefix + "clang-cl", + msvc_ml_path = tools_path_prefix + "clang-cl", + msvc_link_path = tools_path_prefix + ld, + msvc_lib_path = tools_path_prefix + "llvm-lib", + ) + else: + # Source: https://cs.opensource.google/bazel/bazel/+/master:tools/cpp/unix_cc_toolchain_config.bzl + unix_cc_toolchain_config( + name = name, + cpu = target_cpu, + compiler = compiler, + toolchain_identifier = toolchain_identifier, + host_system_name = exec_arch, + target_system_name = target_system_name, + target_libc = target_libc, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + cxx_builtin_include_directories = cxx_builtin_include_directories, + tool_paths = tool_paths, + compile_flags = compile_flags, + dbg_compile_flags = dbg_compile_flags, + opt_compile_flags = opt_compile_flags, + cxx_flags = cxx_flags, + link_flags = link_flags, + archive_flags = archive_flags, + link_libs = link_libs, + opt_link_flags = opt_link_flags, + unfiltered_compile_flags = unfiltered_compile_flags, + coverage_compile_flags = coverage_compile_flags, + coverage_link_flags = coverage_link_flags, + supports_start_end_lib = True, # We only support lld, so this is always true. + builtin_sysroot = sysroot_path, + ) diff --git a/toolchain/cc_wrapper.sh.tpl b/toolchain/cc_wrapper.sh.tpl index e972d57e..181af64d 100644 --- a/toolchain/cc_wrapper.sh.tpl +++ b/toolchain/cc_wrapper.sh.tpl @@ -32,7 +32,7 @@ set -euo pipefail # See note in toolchain/internal/configure.bzl where we define # `wrapper_bin_prefix` for why this wrapper is needed. -if [[ -f %{toolchain_path_prefix}bin/clang ]]; then +if [[ -f %{toolchain_path_prefix}bin/%{clang} ]]; then execroot_path="" elif [[ ${BASH_SOURCE[0]} == "/"* ]]; then # Some consumers of `CcToolchainConfigInfo` (e.g. `cmake` from rules_foreign_cc) @@ -47,8 +47,8 @@ fi function sanitize_option() { local -r opt=$1 - if [[ ${opt} == */cc_wrapper.sh ]]; then - printf "%s" "${execroot_path}%{toolchain_path_prefix}bin/clang" + if [[ ${opt} == */cc_wrapper.sh ]] || [[ ${opt} == */cc_wrapper_msvc.sh ]]; then + printf "%s" "${execroot_path}%{toolchain_path_prefix}bin/%{clang}" elif [[ ${opt} =~ ^-fsanitize-(ignore|black)list=[^/] ]]; then # shellcheck disable=SC2206 parts=(${opt/=/ }) # Split flag name and value into array. diff --git a/toolchain/internal/common.bzl b/toolchain/internal/common.bzl index ff94bfb2..6fb989b8 100644 --- a/toolchain/internal/common.bzl +++ b/toolchain/internal/common.bzl @@ -12,7 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -SUPPORTED_TARGETS = [("linux", "x86_64"), ("linux", "aarch64"), ("darwin", "x86_64"), ("darwin", "aarch64")] +SUPPORTED_TARGETS = [ + ("darwin", "aarch64"), + ("darwin", "x86_64"), + ("linux", "aarch64"), + ("linux", "x86_64"), + ("windows-msvc", "x86_64"), +] # Map of tool name to its symlinked name in the tools directory. # See tool_paths in toolchain/cc_toolchain_config.bzl. @@ -20,11 +26,15 @@ _toolchain_tools = { name: name for name in [ "clang-cpp", + "clang-cl", "ld.lld", + "ld64.lld", + "lld-link", "llvm-ar", + "llvm-cov", "llvm-dwp", + "llvm-lib", "llvm-profdata", - "llvm-cov", "llvm-nm", "llvm-objcopy", "llvm-objdump", @@ -120,7 +130,11 @@ def os(rctx): def os_bzl(os): # Return the OS string as used in bazel platform constraints. - return {"darwin": "osx", "linux": "linux"}[os] + return { + "darwin": "osx", + "linux": "linux", + "windows-msvc": "windows", + }[os] def arch(rctx): arch = rctx.attr.exec_arch diff --git a/toolchain/internal/configure.bzl b/toolchain/internal/configure.bzl index 8731af75..ecfa4716 100644 --- a/toolchain/internal/configure.bzl +++ b/toolchain/internal/configure.bzl @@ -219,6 +219,15 @@ def llvm_config_impl(rctx): cc_wrapper_tpl, { "%{toolchain_path_prefix}": llvm_dist_path_prefix, + "%{clang}": "clang", + }, + ) + rctx.template( + "bin/cc_wrapper_msvc.sh", + rctx.attr._cc_wrapper_sh_tpl, + { + "%{toolchain_path_prefix}": llvm_dist_path_prefix, + "%{clang}": "clang-cl", }, ) @@ -315,6 +324,7 @@ def _cc_toolchain_str( "darwin-aarch64": "aarch64-apple-macosx", "linux-aarch64": "aarch64-unknown-linux-gnu", "linux-x86_64": "x86_64-unknown-linux-gnu", + "windows-msvc-x86_64": "x86_64-pc-windows-msvc", }[target_pair] cxx_builtin_include_directories = [ toolchain_path_prefix + "include/c++/v1", @@ -341,6 +351,9 @@ def _cc_toolchain_str( _join(sysroot_prefix, "/usr/include"), _join(sysroot_prefix, "/System/Library/Frameworks"), ]) + elif target_os == "windows-msvc": + # No additional include directories for MSVC. + pass else: fail("Unreachable") diff --git a/toolchain/windows_cc_toolchain_config.bzl b/toolchain/windows_cc_toolchain_config.bzl new file mode 100644 index 00000000..acfddb33 --- /dev/null +++ b/toolchain/windows_cc_toolchain_config.bzl @@ -0,0 +1,1490 @@ +# Copyright 2019 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""A Starlark cc_toolchain configuration rule for Windows""" + +load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES") +load( + "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", + "action_config", + "artifact_name_pattern", + "env_entry", + "env_set", + "feature", + "flag_group", + "flag_set", + "tool", + "tool_path", + "variable_with_value", + "with_feature_set", +) + +all_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, + ACTION_NAMES.lto_backend, +] + +all_cpp_compile_actions = [ + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, +] + +preprocessor_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.clif_match, +] + +codegen_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, +] + +all_link_actions = [ + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, +] + +def _use_msvc_toolchain(ctx): + return ctx.attr.cpu in ["x64_windows", "arm64_windows"] and (ctx.attr.compiler == "msvc-cl" or ctx.attr.compiler == "clang-cl") + +def _impl(ctx): + if _use_msvc_toolchain(ctx): + artifact_name_patterns = [ + artifact_name_pattern( + category_name = "object_file", + prefix = "", + extension = ".obj", + ), + artifact_name_pattern( + category_name = "static_library", + prefix = "", + extension = ".lib", + ), + artifact_name_pattern( + category_name = "alwayslink_static_library", + prefix = "", + extension = ".lo.lib", + ), + artifact_name_pattern( + category_name = "executable", + prefix = "", + extension = ".exe", + ), + artifact_name_pattern( + category_name = "dynamic_library", + prefix = "", + extension = ".dll", + ), + artifact_name_pattern( + category_name = "interface_library", + prefix = "", + extension = ".if.lib", + ), + ] + else: + artifact_name_patterns = [ + artifact_name_pattern( + category_name = "executable", + prefix = "", + extension = ".exe", + ), + ] + + if _use_msvc_toolchain(ctx): + cpp_link_nodeps_dynamic_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_nodeps_dynamic_library, + implies = [ + "nologo", + "shared_flag", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + "has_configured_linker_path", + "def_file", + ], + tools = [tool(path = ctx.attr.msvc_link_path)], + ) + + cpp_link_static_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_static_library, + implies = [ + "nologo", + "archiver_flags", + "input_param_flags", + "linker_param_file", + "msvc_env", + ], + tools = [tool(path = ctx.attr.msvc_lib_path)], + ) + + assemble_action = action_config( + action_name = ACTION_NAMES.assemble, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "nologo", + "msvc_env", + "sysroot", + ], + tools = [tool(path = ctx.attr.msvc_ml_path)], + ) + + preprocess_assemble_action = action_config( + action_name = ACTION_NAMES.preprocess_assemble, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "nologo", + "msvc_env", + "sysroot", + ], + tools = [tool(path = ctx.attr.msvc_ml_path)], + ) + + c_compile_action = action_config( + action_name = ACTION_NAMES.c_compile, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "nologo", + "msvc_env", + "user_compile_flags", + "sysroot", + ], + tools = [tool(path = ctx.attr.msvc_cl_path)], + ) + + linkstamp_compile_action = action_config( + action_name = ACTION_NAMES.linkstamp_compile, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "default_compile_flags", + "nologo", + "msvc_env", + "user_compile_flags", + "sysroot", + "unfiltered_compile_flags", + ], + tools = [tool(path = ctx.attr.msvc_cl_path)], + ) + + cpp_compile_action = action_config( + action_name = ACTION_NAMES.cpp_compile, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "nologo", + "msvc_env", + "user_compile_flags", + "sysroot", + ], + tools = [tool(path = ctx.attr.msvc_cl_path)], + ) + + cpp_link_executable_action = action_config( + action_name = ACTION_NAMES.cpp_link_executable, + implies = [ + "nologo", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + ], + tools = [tool(path = ctx.attr.msvc_link_path)], + ) + + cpp_link_dynamic_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_dynamic_library, + implies = [ + "nologo", + "shared_flag", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + "has_configured_linker_path", + "def_file", + ], + tools = [tool(path = ctx.attr.msvc_link_path)], + ) + + action_configs = [ + assemble_action, + preprocess_assemble_action, + c_compile_action, + linkstamp_compile_action, + cpp_compile_action, + cpp_link_executable_action, + cpp_link_dynamic_library_action, + cpp_link_nodeps_dynamic_library_action, + cpp_link_static_library_action, + ] + else: + action_configs = [] + + if _use_msvc_toolchain(ctx): + msvc_link_env_feature = feature( + name = "msvc_link_env", + env_sets = [ + env_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + env_entries = [env_entry(key = "LIB", value = ctx.attr.msvc_env_lib)], + ), + ], + ) + + shared_flag_feature = feature( + name = "shared_flag", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [flag_group(flags = ["/DLL"])], + ), + ], + ) + + determinism_feature = feature( + name = "determinism", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [ + flag_group( + flags = [ + "/wd4117", + "/D__DATE__=\"redacted\"", + "/D__TIMESTAMP__=\"redacted\"", + "/D__TIME__=\"redacted\"", + ] + (["-Wno-builtin-macro-redefined"] if ctx.attr.compiler == "clang-cl" else []), + ), + ], + ), + ], + ) + + sysroot_feature = feature( + name = "sysroot", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["/winsysroot:%{sysroot}"], + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["%{unfiltered_compile_flags}"], + iterate_over = "unfiltered_compile_flags", + expand_if_available = "unfiltered_compile_flags", + ), + ], + ), + ], + ) + + archive_param_file_feature = feature( + name = "archive_param_file", + enabled = True, + ) + + compiler_param_file_feature = feature( + name = "compiler_param_file", + enabled = True, + ) + + copy_dynamic_libraries_to_binary_feature = feature( + name = "copy_dynamic_libraries_to_binary", + ) + + input_param_flags_feature = feature( + name = "input_param_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["/IMPLIB:%{interface_library_output_path}"], + expand_if_available = "interface_library_output_path", + ), + ], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{libopts}"], + iterate_over = "libopts", + expand_if_available = "libopts", + ), + ], + ), + flag_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + iterate_over = "libraries_to_link", + flag_groups = [ + flag_group( + iterate_over = "libraries_to_link.object_files", + flag_groups = [flag_group(flags = ["%{libraries_to_link.object_files}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file_group", + ), + ), + flag_group( + flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file", + ), + ), + flag_group( + flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "interface_library", + ), + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["%{libraries_to_link.name}"], + expand_if_false = "libraries_to_link.is_whole_archive", + ), + flag_group( + flags = ["/WHOLEARCHIVE:%{libraries_to_link.name}"], + expand_if_true = "libraries_to_link.is_whole_archive", + ), + ], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "static_library", + ), + ), + ], + expand_if_available = "libraries_to_link", + ), + ], + ), + ], + ) + + fastbuild_feature = feature( + name = "fastbuild", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Od", "/Z7"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = [ctx.attr.fastbuild_mode_debug_flag, "/INCREMENTAL:NO"], + ), + ], + ), + ], + implies = ["generate_pdb_file"], + ) + + user_compile_flags_feature = feature( + name = "user_compile_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + archiver_flags_feature = feature( + name = "archiver_flags", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + flags = ["/OUT:%{output_execpath}"], + expand_if_available = "output_execpath", + ), + ], + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ctx.attr.default_link_flags)], + ), + ], + ) + + static_link_msvcrt_feature = feature( + name = "static_link_msvcrt", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MT"])], + with_features = [with_feature_set(not_features = ["dbg"])], + ), + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MTd"])], + with_features = [with_feature_set(features = ["dbg"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmt.lib"])], + with_features = [with_feature_set(not_features = ["dbg"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmtd.lib"])], + with_features = [with_feature_set(features = ["dbg"])], + ), + ], + ) + + dynamic_link_msvcrt_feature = feature( + name = "dynamic_link_msvcrt", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MD"])], + with_features = [with_feature_set(not_features = ["dbg", "static_link_msvcrt"])], + ), + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MDd"])], + with_features = [with_feature_set(features = ["dbg"], not_features = ["static_link_msvcrt"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrt.lib"])], + with_features = [with_feature_set(not_features = ["dbg", "static_link_msvcrt"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrtd.lib"])], + with_features = [with_feature_set(features = ["dbg"], not_features = ["static_link_msvcrt"])], + ), + ], + ) + + dbg_feature = feature( + name = "dbg", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Od", "/Z7"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = [ctx.attr.dbg_mode_debug_flag, "/INCREMENTAL:NO"], + ), + ], + ), + ], + implies = ["generate_pdb_file"], + ) + + opt_feature = feature( + name = "opt", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/O2"])], + ), + ], + implies = ["frame_pointer"], + ) + + supports_interface_shared_libraries_feature = feature( + name = "supports_interface_shared_libraries", + enabled = True, + ) + + user_link_flags_feature = feature( + name = "user_link_flags", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{user_link_flags}"], + iterate_over = "user_link_flags", + expand_if_available = "user_link_flags", + ), + ], + ), + ], + ) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = [ + flag_group( + flags = [ + "/DCOMPILER_MSVC", + "/DNOMINMAX", + "/D_WIN32_WINNT=0x0601", + "/D_CRT_SECURE_NO_DEPRECATE", + "/D_CRT_SECURE_NO_WARNINGS", + "/bigobj", + "/Zm500", + "/EHsc", + "/wd4351", + "/wd4291", + "/wd4250", + "/wd4996", + ], + ), + ], + ), + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = ([ + flag_group( + flags = ctx.attr.default_compile_flags, + ), + ] if ctx.attr.default_compile_flags else []), + ), + flag_set( + actions = all_cpp_compile_actions + [ACTION_NAMES.lto_backend], + flag_groups = ([ + flag_group( + flags = ctx.attr.cxx_flags, + ), + ] if ctx.attr.cxx_flags else []), + ), + ], + ) + + msvc_compile_env_feature = feature( + name = "msvc_compile_env", + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ], + env_entries = [env_entry(key = "INCLUDE", value = ctx.attr.msvc_env_include)], + ), + ], + ) + + preprocessor_defines_feature = feature( + name = "preprocessor_defines", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = [ + flag_group( + flags = ["/D%{preprocessor_defines}"], + iterate_over = "preprocessor_defines", + ), + ], + ), + ], + ) + + generate_pdb_file_feature = feature( + name = "generate_pdb_file", + ) + + generate_linkmap_feature = feature( + name = "generate_linkmap", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_executable, + ], + flag_groups = [ + flag_group( + flags = [ + "/MAP:%{output_execpath}.map", + ], + expand_if_available = "output_execpath", + ), + ], + ), + ], + ) + + output_execpath_flags_feature = feature( + name = "output_execpath_flags", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/OUT:%{output_execpath}"], + expand_if_available = "output_execpath", + ), + ], + ), + ], + ) + + disable_assertions_feature = feature( + name = "disable_assertions", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/DNDEBUG"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + has_configured_linker_path_feature = feature(name = "has_configured_linker_path") + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + no_stripping_feature = feature(name = "no_stripping") + + linker_param_file_feature = feature( + name = "linker_param_file", + flag_sets = [ + flag_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + flags = ["@%{linker_param_file}"], + expand_if_available = "linker_param_file", + ), + ], + ), + ], + ) + + ignore_noisy_warnings_feature = feature( + name = "ignore_noisy_warnings", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.cpp_link_static_library], + flag_groups = [flag_group(flags = ["/ignore:4221"])], + ), + ], + ) + + no_legacy_features_feature = feature(name = "no_legacy_features") + + parse_showincludes_feature = feature( + name = "parse_showincludes", + enabled = ctx.attr.supports_parse_showincludes, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_header_parsing, + ], + flag_groups = [flag_group(flags = ["/showIncludes"])], + ), + ], + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_header_parsing, + ], + # Force English (and thus a consistent locale) output so that Bazel can parse + # the /showIncludes output without having to guess the encoding. + env_entries = [env_entry(key = "VSLANG", value = "1033")], + ), + ], + ) + + # MSVC does not emit .d files. + no_dotd_file_feature = feature( + name = "no_dotd_file", + enabled = True, + ) + + treat_warnings_as_errors_feature = feature( + name = "treat_warnings_as_errors", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile] + all_link_actions, + flag_groups = [flag_group(flags = ["/WX"])], + ), + ], + ) + + windows_export_all_symbols_feature = feature(name = "windows_export_all_symbols") + + no_windows_export_all_symbols_feature = feature(name = "no_windows_export_all_symbols") + + include_paths_feature = feature( + name = "include_paths", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = [ + flag_group( + flags = ["/I%{quote_include_paths}"], + iterate_over = "quote_include_paths", + ), + flag_group( + flags = ["/I%{include_paths}"], + iterate_over = "include_paths", + ), + flag_group( + flags = ["/I%{system_include_paths}"], + iterate_over = "system_include_paths", + ), + ], + ), + ], + ) + + external_include_paths_feature = feature( + name = "external_include_paths", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.clif_match, + ACTION_NAMES.objc_compile, + ACTION_NAMES.objcpp_compile, + ], + flag_groups = [ + flag_group( + flags = ["/external:I%{external_include_paths}"], + iterate_over = "external_include_paths", + expand_if_available = "external_include_paths", + ), + ], + ), + ], + ) + + linkstamps_feature = feature( + name = "linkstamps", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{linkstamp_paths}"], + iterate_over = "linkstamp_paths", + expand_if_available = "linkstamp_paths", + ), + ], + ), + ], + ) + + targets_windows_feature = feature( + name = "targets_windows", + enabled = True, + implies = ["copy_dynamic_libraries_to_binary"], + ) + + linker_subsystem_flag_feature = feature( + name = "linker_subsystem_flag", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/SUBSYSTEM:CONSOLE"])], + ), + ], + ) + + frame_pointer_feature = feature( + name = "frame_pointer", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Oy-"])], + ), + ], + ) + + compiler_output_flags_feature = feature( + name = "compiler_output_flags", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.assemble], + flag_groups = [ + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fo%{output_file}", "/Zi"], + expand_if_available = "output_file", + expand_if_not_available = "output_assembly_file", + ), + ], + expand_if_not_available = "output_preprocess_file", + ), + ], + ), + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fo%{output_file}"], + expand_if_not_available = "output_preprocess_file", + ), + ], + expand_if_available = "output_file", + expand_if_not_available = "output_assembly_file", + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fa%{output_file}"], + expand_if_available = "output_assembly_file", + ), + ], + expand_if_available = "output_file", + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["/P", "/Fi%{output_file}"], + expand_if_available = "output_preprocess_file", + ), + ], + expand_if_available = "output_file", + ), + ], + ), + ], + ) + + nologo_feature = feature( + name = "nologo", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + flag_groups = [flag_group(flags = ["/nologo"])], + ), + ], + ) + + smaller_binary_feature = feature( + name = "smaller_binary", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Gy", "/Gw"])], + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/OPT:ICF", "/OPT:REF"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + compiler_input_flags_feature = feature( + name = "compiler_input_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["/c", "%{source_file}"], + expand_if_available = "source_file", + ), + ], + ), + ], + ) + + def_file_feature = feature( + name = "def_file", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/DEF:%{def_file_path}", "/ignore:4070"], + expand_if_available = "def_file_path", + ), + ], + ), + ], + ) + + msvc_env_feature = feature( + name = "msvc_env", + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + env_entries = [ + env_entry(key = "PATH", value = ctx.attr.msvc_env_path), + env_entry(key = "TMP", value = ctx.attr.msvc_env_tmp), + env_entry(key = "TEMP", value = ctx.attr.msvc_env_tmp), + ], + ), + ], + implies = ["msvc_compile_env", "msvc_link_env"], + ) + features = [ + no_legacy_features_feature, + nologo_feature, + has_configured_linker_path_feature, + no_stripping_feature, + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + default_compile_flags_feature, + msvc_env_feature, + msvc_compile_env_feature, + msvc_link_env_feature, + include_paths_feature, + external_include_paths_feature, + preprocessor_defines_feature, + parse_showincludes_feature, + no_dotd_file_feature, + generate_pdb_file_feature, + generate_linkmap_feature, + shared_flag_feature, + linkstamps_feature, + output_execpath_flags_feature, + archiver_flags_feature, + input_param_flags_feature, + linker_subsystem_flag_feature, + user_link_flags_feature, + default_link_flags_feature, + linker_param_file_feature, + static_link_msvcrt_feature, + dynamic_link_msvcrt_feature, + dbg_feature, + fastbuild_feature, + opt_feature, + frame_pointer_feature, + disable_assertions_feature, + determinism_feature, + treat_warnings_as_errors_feature, + smaller_binary_feature, + ignore_noisy_warnings_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + archive_param_file_feature, + compiler_param_file_feature, + compiler_output_flags_feature, + compiler_input_flags_feature, + def_file_feature, + windows_export_all_symbols_feature, + no_windows_export_all_symbols_feature, + supports_dynamic_linker_feature, + supports_interface_shared_libraries_feature, + ] + else: + targets_windows_feature = feature( + name = "targets_windows", + implies = ["copy_dynamic_libraries_to_binary"], + enabled = True, + ) + + copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary") + + gcc_env_feature = feature( + name = "gcc_env", + enabled = True, + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + env_entries = [ + env_entry(key = "PATH", value = ctx.attr.tool_bin_path), + ], + ), + ], + ) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = [flag_group(flags = ["-std=gnu++14"])], + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["-lstdc++"])], + ), + ], + ) + + supports_dynamic_linker_feature = feature( + name = "supports_dynamic_linker", + enabled = True, + ) + + dbg_feature = feature( + name = "dbg", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["-g", "-Og"])], + ), + ], + ) + + opt_feature = feature( + name = "opt", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = [ + "-g0", + "-O3", + "-DNDEBUG", + "-ffunction-sections", + "-fdata-sections", + ])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["-Wl,--gc-sections"])], + ), + ], + ) + + if ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "mingw-gcc": + archive_param_file_feature = feature( + name = "archive_param_file", + enabled = True, + ) + + compiler_param_file_feature = feature( + name = "compiler_param_file", + ) + + features = [ + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + gcc_env_feature, + default_compile_flags_feature, + archive_param_file_feature, + compiler_param_file_feature, + default_link_flags_feature, + supports_dynamic_linker_feature, + dbg_feature, + opt_feature, + ] + else: + supports_pic_feature = feature( + name = "supports_pic", + enabled = True, + ) + + sysroot_feature = feature( + name = "sysroot", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + fdo_optimize_feature = feature( + name = "fdo_optimize", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [ + flag_group( + flags = [ + "-fprofile-use=%{fdo_profile_path}", + "-fprofile-correction", + ], + expand_if_available = "fdo_profile_path", + ), + ], + ), + ], + provides = ["profile"], + ) + + treat_warnings_as_errors_feature = feature( + name = "treat_warnings_as_errors", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["-Werror"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["-Wl,-fatal-warnings"])], + ), + ], + ) + + user_compile_flags_feature = feature( + name = "user_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + features = [ + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + gcc_env_feature, + supports_pic_feature, + default_compile_flags_feature, + default_link_flags_feature, + fdo_optimize_feature, + supports_dynamic_linker_feature, + dbg_feature, + opt_feature, + user_compile_flags_feature, + treat_warnings_as_errors_feature, + sysroot_feature, + ] + + tool_paths = [ + tool_path(name = name, path = path) + for name, path in ctx.attr.tool_paths.items() + ] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = ctx.attr.cxx_builtin_include_directories, + toolchain_identifier = ctx.attr.toolchain_identifier, + host_system_name = ctx.attr.host_system_name, + target_system_name = ctx.attr.target_system_name, + target_cpu = ctx.attr.cpu, + target_libc = ctx.attr.target_libc, + compiler = ctx.attr.compiler, + abi_version = ctx.attr.abi_version, + abi_libc_version = ctx.attr.abi_libc_version, + tool_paths = tool_paths, + builtin_sysroot = ctx.attr.builtin_sysroot, + ) + +cc_toolchain_config = rule( + implementation = _impl, + attrs = { + "cpu": attr.string(mandatory = True), + "compiler": attr.string(), + "toolchain_identifier": attr.string(), + "host_system_name": attr.string(), + "target_system_name": attr.string(), + "target_libc": attr.string(), + "abi_version": attr.string(), + "abi_libc_version": attr.string(), + "tool_paths": attr.string_dict(), + "cxx_builtin_include_directories": attr.string_list(), + "archiver_flags": attr.string_list(default = []), + "default_compile_flags": attr.string_list(default = []), + "cxx_flags": attr.string_list(default = []), + "default_link_flags": attr.string_list(default = []), + "msvc_env_tmp": attr.string(default = "msvc_not_found"), + "msvc_env_path": attr.string(default = "msvc_not_found"), + "msvc_env_include": attr.string(default = "msvc_not_found"), + "msvc_env_lib": attr.string(default = "msvc_not_found"), + "msvc_cl_path": attr.string(default = "vc_installation_error.bat"), + "msvc_ml_path": attr.string(default = "vc_installation_error.bat"), + "msvc_link_path": attr.string(default = "vc_installation_error.bat"), + "msvc_lib_path": attr.string(default = "vc_installation_error.bat"), + "dbg_mode_debug_flag": attr.string(), + "fastbuild_mode_debug_flag": attr.string(), + "tool_bin_path": attr.string(default = "not_found"), + "supports_parse_showincludes": attr.bool(), + "builtin_sysroot": attr.string(), + }, + provides = [CcToolchainConfigInfo], +)