Overhaul CMake and Bazel CUDA support (#11651)

On the CMake side:

* Reworked SDK download so that it won't partially clobber on version
changes, etc.
* Only downloads the SDK if not already downloaded.
* Nice errors if missing deps that will keep downloads from working.
* Localized all of the CUDA special stuff into
build_tools/third_party/cuda (out of top-level CMake and leaf code
directories).
* Switched CUDA target/driver to bazel_to_cmake (and normalized
everything between the two).

On the Bazel side:

* There is now a Bazel build for CUDA :)
* SDK detection logic is primitive but functional. If the env var
IREE_CUDA_TOOLKIT_ROOT is set, then the SDK will be symlinked in and
configured.
* If the SDK is not available, then the HAL target and driver will not
be built.
* CUDA support should now be built as part of all CI actions.

I also had to fix bazel_to_cmake in a couple of unexpected ways.

This should integrate relatively cleanly into the Google systems. In
order to stage it better, I made the new BUILD files BUILD.bazel so that
they are ignored on that side. Once we get it in, we can rename them and
apply the couple of rewrites that will be needed to redirect to
Google-side SDK targets. The only thing that should be needed to make
this import is to add a rewrite for `"@iree_cuda//:enabled"` to a
private bool_flag that is hard-coded to False (until ready to enable).
Example:

```
bool_flag(
    name = "enabled",
    build_setting_default = False,
)
```

Co-authored-by: Geoffrey Martin-Noble <gcmn@google.com>
diff --git a/build_tools/bazel_to_cmake/bazel_to_cmake.py b/build_tools/bazel_to_cmake/bazel_to_cmake.py
index 1770ee2..4f8bf57 100755
--- a/build_tools/bazel_to_cmake/bazel_to_cmake.py
+++ b/build_tools/bazel_to_cmake/bazel_to_cmake.py
@@ -151,13 +151,20 @@
   if verbosity >= 1:
     log(f"Processing {rel_dir_path}")
 
-  build_file_path = os.path.join(directory_path, "BUILD")
+  # Scan for a BUILD file.
+  build_file_found = False
+  build_file_basenames = ["BUILD", "BUILD.bazel"]
+  for build_file_basename in build_file_basenames:
+    build_file_path = os.path.join(directory_path, build_file_basename)
+
+    rel_build_file_path = repo_relpath(build_file_path)
+    if os.path.isfile(build_file_path):
+      build_file_found = True
+      break
   cmakelists_file_path = os.path.join(directory_path, "CMakeLists.txt")
-
   rel_cmakelists_file_path = repo_relpath(cmakelists_file_path)
-  rel_build_file_path = repo_relpath(build_file_path)
 
-  if not os.path.isfile(build_file_path):
+  if not build_file_found:
     return Status.NO_BUILD_FILE
 
   autogeneration_tag = f"Autogenerated by {repo_relpath(os.path.abspath(__file__))}"
@@ -176,6 +183,8 @@
 
   old_lines = []
   preserved_footer_lines = ["\n" + PRESERVE_TAG + "\n"]
+
+  # Read CMakeLists.txt and check if it has the auto-generated header.
   if os.path.isfile(cmakelists_file_path):
     found_autogeneration_tag = False
     found_preserve_tag = False
@@ -195,8 +204,12 @@
       return Status.SKIPPED
   preserved_footer = "".join(preserved_footer_lines)
 
+  # Read the Bazel BUILD file and interpret it.
   with open(build_file_path, "rt") as build_file:
-    build_file_code = compile(build_file.read(), build_file_path, "exec")
+    build_file_contents = build_file.read()
+  if "bazel-to-cmake: skip" in build_file_contents:
+    return Status.SKIPPED
+  build_file_code = compile(build_file_contents, build_file_path, "exec")
   try:
     converted_build_file = bazel_to_cmake_converter.convert_build_file(
         build_file_code, allow_partial_conversion=allow_partial_conversion)