Refactor Windows C++ toolchain selection

We used to have --cpu=x64_windows_msys for selecting msys gcc toolchain,
this is a misuse of --cpu flag.

Instead, we should use --compiler flag to select C++ toolchain.
For example, --compiler=msvc-cl, --compiler=msys-gcc, --compiler=mingw-gcc

After this change, we can use mingw gcc toolchain by following steps:
1. In MSYS, install mingw by `pacman -S mingw-w64-x86_64-gcc`
2. Add /mingw64:/mingw64/bin into PATH
3. build with --compiler=mingw-gcc

Related:
https://github.com/bazelbuild/rules_go/issues/736

Change-Id: I4b5f77ce0698cfcafefe5d2ab17657f9c9e295d3
PiperOrigin-RevId: 180678829
diff --git a/tools/cpp/BUILD.static b/tools/cpp/BUILD.static
index eb5f113..92cefaa 100644
--- a/tools/cpp/BUILD.static
+++ b/tools/cpp/BUILD.static
@@ -19,9 +19,9 @@
     toolchains = {
         "armeabi-v7a|compiler": ":cc-compiler-armeabi-v7a",
         "freebsd|compiler": ":cc-compiler-freebsd",
-        "x64_windows|cl": ":cc-compiler-x64_windows",
-        "x64_windows_msvc|cl": ":cc-compiler-x64_windows",
-        "x64_windows_msys|windows_msys64": ":cc-compiler-x64_windows_msys",
+        "x64_windows|msvc-cl": ":cc-compiler-x64_windows",
+        "x64_windows|msys-gcc": ":cc-compiler-x64_windows_msys",
+        "x64_windows|mingw-gcc": ":cc-compiler-x64_windows_mingw",
         "ios_x86_64|compiler": ":cc-compiler-ios_x86_64",
     },
 )
@@ -69,6 +69,20 @@
 )
 
 cc_toolchain(
+    name = "cc-compiler-x64_windows_mingw",
+    all_files = ":empty",
+    compiler_files = ":empty",
+    cpu = "x64_windows",
+    dwp_files = ":empty",
+    dynamic_runtime_libs = [":empty"],
+    linker_files = ":empty",
+    objcopy_files = ":empty",
+    static_runtime_libs = [":empty"],
+    strip_files = ":empty",
+    supports_param_files = 1,
+)
+
+cc_toolchain(
     name = "cc-compiler-x64_windows",
     all_files = ":every-file-x64_windows",
     compiler_files = ":compile-x64_windows",
diff --git a/tools/cpp/CROSSTOOL.tpl b/tools/cpp/CROSSTOOL.tpl
index 2b86bbb..2f224e6 100644
--- a/tools/cpp/CROSSTOOL.tpl
+++ b/tools/cpp/CROSSTOOL.tpl
@@ -149,6 +149,23 @@
 }
 
 toolchain {
+  toolchain_identifier: "msys_x64_mingw"
+  abi_version: "local"
+  abi_libc_version: "local"
+  builtin_sysroot: ""
+  compiler: "mingw-gcc"
+  host_system_name: "local"
+  needsPic: false
+  target_libc: "mingw"
+  target_cpu: "x64_windows"
+  target_system_name: "local"
+
+%{msys_x64_mingw_content}
+
+  linking_mode_flags { mode: DYNAMIC }
+}
+
+toolchain {
   toolchain_identifier: "msvc_x64"
   host_system_name: "local"
   target_system_name: "local"
@@ -156,8 +173,8 @@
   abi_version: "local"
   abi_libc_version: "local"
   target_cpu: "x64_windows"
-  compiler: "cl"
-  target_libc: "msvcrt140"
+  compiler: "msvc-cl"
+  target_libc: "msvcrt"
   default_python_version: "python2.7"
 
 %{cxx_builtin_include_directory}
diff --git a/tools/cpp/unix_cc_configure.bzl b/tools/cpp/unix_cc_configure.bzl
index 82f47f8..4657ba4 100644
--- a/tools/cpp/unix_cc_configure.bzl
+++ b/tools/cpp/unix_cc_configure.bzl
@@ -461,6 +461,7 @@
       "%{msvc_ml_path}": "",
       "%{msvc_link_path}": "",
       "%{msvc_lib_path}": "",
+      "%{msys_x64_mingw_content}": "",
       "%{dbg_mode_debug}": "",
       "%{fastbuild_mode_debug}": "",
       "%{compilation_mode_content}": "",
diff --git a/tools/cpp/windows_cc_configure.bzl b/tools/cpp/windows_cc_configure.bzl
index da13691..23b150c 100644
--- a/tools/cpp/windows_cc_configure.bzl
+++ b/tools/cpp/windows_cc_configure.bzl
@@ -28,11 +28,11 @@
 )
 
 
-# TODO(pcloudy): Remove this after MSVC CROSSTOOL becomes default on Windows
-def _get_escaped_windows_msys_crosstool_content(repository_ctx):
+def _get_escaped_windows_msys_crosstool_content(repository_ctx, use_mingw = False):
   """Return the content of msys crosstool which is still the default CROSSTOOL on Windows."""
   bazel_sh = get_env_var(repository_ctx, "BAZEL_SH").replace("\\", "/").lower()
   tokens = bazel_sh.rsplit("/", 1)
+  prefix = "mingw64" if use_mingw else "usr"
   msys_root = None
   if tokens[0].endswith("/usr/bin"):
     msys_root = tokens[0][:len(tokens[0]) - len("usr/bin")]
@@ -42,32 +42,34 @@
     auto_configure_fail(
         "Could not determine MSYS/Cygwin root from BAZEL_SH (%s)" % bazel_sh)
   escaped_msys_root = escape_string(msys_root)
-  return (
+  return (((
       '   abi_version: "local"\n' +
       '   abi_libc_version: "local"\n' +
       '   builtin_sysroot: ""\n' +
-      '   compiler: "windows_msys64"\n' +
+      '   compiler: "msys-gcc"\n' +
       '   host_system_name: "local"\n' +
-      "   needsPic: false\n" +
-      '   target_libc: "local"\n' +
-      '   target_cpu: "x64_windows_msys"\n' +
-      '   target_system_name: "local"\n' +
-      '   tool_path { name: "ar" path: "%susr/bin/ar" }\n' % escaped_msys_root +
-      '   tool_path { name: "compat-ld" path: "%susr/bin/ld" }\n' % escaped_msys_root +
-      '   tool_path { name: "cpp" path: "%susr/bin/cpp" }\n' % escaped_msys_root +
-      '   tool_path { name: "dwp" path: "%susr/bin/dwp" }\n' % escaped_msys_root +
-      '   tool_path { name: "gcc" path: "%susr/bin/gcc" }\n' % escaped_msys_root +
+      '   needsPic: false\n' +
+      '   target_libc: "msys"\n' +
+      '   target_cpu: "x64_windows"\n' +
+      '   target_system_name: "local"\n') if not use_mingw else '') +
+      '   tool_path { name: "ar" path: "%s%s/bin/ar" }\n' % (escaped_msys_root, prefix) +
+      '   tool_path { name: "compat-ld" path: "%s%s/bin/ld" }\n' % (escaped_msys_root, prefix) +
+      '   tool_path { name: "cpp" path: "%s%s/bin/cpp" }\n' % (escaped_msys_root, prefix) +
+      '   tool_path { name: "dwp" path: "%s%s/bin/dwp" }\n' % (escaped_msys_root, prefix) +
+      '   tool_path { name: "gcc" path: "%s%s/bin/gcc" }\n' % (escaped_msys_root, prefix) +
       '   cxx_flag: "-std=gnu++0x"\n' +
       '   linker_flag: "-lstdc++"\n' +
-      '   cxx_builtin_include_directory: "%susr/"\n' % escaped_msys_root +
-      '   tool_path { name: "gcov" path: "%susr/bin/gcov" }\n' % escaped_msys_root +
-      '   tool_path { name: "ld" path: "%susr/bin/ld" }\n' % escaped_msys_root +
-      '   tool_path { name: "nm" path: "%susr/bin/nm" }\n' % escaped_msys_root +
-      '   tool_path { name: "objcopy" path: "%susr/bin/objcopy" }\n' % escaped_msys_root +
+      '   cxx_builtin_include_directory: "%s%s/"\n' % (escaped_msys_root, prefix) +
+      '   tool_path { name: "gcov" path: "%s%s/bin/gcov" }\n' % (escaped_msys_root, prefix) +
+      '   tool_path { name: "ld" path: "%s%s/bin/ld" }\n' % (escaped_msys_root, prefix) +
+      '   tool_path { name: "nm" path: "%s%s/bin/nm" }\n' % (escaped_msys_root, prefix) +
+      '   tool_path { name: "objcopy" path: "%s%s/bin/objcopy" }\n' % (escaped_msys_root, prefix) +
       '   objcopy_embed_flag: "-I"\n' +
       '   objcopy_embed_flag: "binary"\n' +
-      '   tool_path { name: "objdump" path: "%susr/bin/objdump" }\n' % escaped_msys_root +
-      '   tool_path { name: "strip" path: "%susr/bin/strip" }'% escaped_msys_root )
+      '   tool_path { name: "objdump" path: "%s%s/bin/objdump" }\n' % (escaped_msys_root, prefix) +
+      '   tool_path { name: "strip" path: "%s%s/bin/strip" }'% (escaped_msys_root, prefix) +
+      '   feature { name: "targets_windows" implies: "copy_dynamic_libraries_to_binary" enabled: true }' +
+      '   feature { name: "copy_dynamic_libraries_to_binary" }' )
 
 
 def _get_system_root(repository_ctx):
@@ -310,6 +312,7 @@
         "%{msvc_lib_path}": vc_path_error_script,
         "%{compilation_mode_content}": "",
         "%{content}": _get_escaped_windows_msys_crosstool_content(repository_ctx),
+        "%{msys_x64_mingw_content}": _get_escaped_windows_msys_crosstool_content(repository_ctx, use_mingw = True),
         "%{opt_content}": "",
         "%{dbg_content}": "",
         "%{link_content}": "",
@@ -387,6 +390,7 @@
       "%{fastbuild_mode_debug}": "/DEBUG:FASTLINK" if support_debug_fastlink else "/DEBUG",
       "%{compilation_mode_content}": compilation_mode_content,
       "%{content}": _get_escaped_windows_msys_crosstool_content(repository_ctx),
+      "%{msys_x64_mingw_content}": _get_escaped_windows_msys_crosstool_content(repository_ctx, use_mingw = True),
       "%{opt_content}": "",
       "%{dbg_content}": "",
       "%{link_content}": "",