Prechádzať zdrojové kódy

Adding Windows support for building Carbon with Bazel. (#1754)

This PR fixes issue #298. I am attempting to build Carbon using Bazel on Windows, without the need to go through WSL. This is still a work in progress, below is a list of issues I have discovered and my fixes for them.

- Windows does not support Homebrew; however, I was able to properly install all of the required packages through [Chocolatey](https://chocolatey.org/). This was my first time using the Chocolatey package manager, yet it was fairly easy to use. I believe there are other options as well for Windows.
- As is mentioned in issue #298, your Windows installation must be running in [Developer Mode](https://docs.microsoft.com/en-us/windows/apps/get-started/enable-your-device-for-development). This will allow unprivileged users to create symlinks during the build process.
- As it currently stands in trunk, clang_configuration.bzl will fail when attempting to run the method `_compute_clang_cpp_include_search_paths` on Windows. I have discovered that this is because Clang++.exe fails to execute if you provide it with an input file that does not exist. Thus, I have the build script generate an empty temp file in the Bazel repo for Clang to use when running the above method. 
- A cc toolchain specifically for Windows was created in clang_toolchain.BUILD. I simply mimicked what was done for other platforms, I apologize if this is incorrect since I am fairly new to Bazel.

As I understand it, the next step is to configure clang_cc_toolchain_config.bzl to support the new Windows toolchain. I intend to continue working on this, however as I stated I am quite new so help is seriously appreciated!

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
ethang 3 rokov pred
rodič
commit
2f3ff12704

+ 21 - 10
bazel/cc_toolchains/clang_cc_toolchain_config.bzl

@@ -97,6 +97,11 @@ def _impl(ctx):
         for name in [ACTION_NAMES.strip]
     ]
 
+    std_compile_flags = ["-std=c++17"]
+    # libc++ is only used on non-Windows platforms.
+    if ctx.attr.target_cpu != "x64_windows":
+        std_compile_flags.append("-stdlib=libc++")
+
     default_flags_feature = feature(
         name = "default_flags",
         enabled = True,
@@ -153,10 +158,7 @@ def _impl(ctx):
                 actions = all_cpp_compile_actions + all_link_actions,
                 flag_groups = ([
                     flag_group(
-                        flags = [
-                            "-std=c++17",
-                            "-stdlib=libc++",
-                        ],
+                        flags = std_compile_flags,
                     ),
                 ]),
             ),
@@ -312,12 +314,16 @@ def _impl(ctx):
     # minimal settings if both are enabled.
     minimal_debug_info_flags = feature(
         name = "minimal_debug_info_flags",
-        flag_sets = [flag_set(
-            actions = codegen_compile_actions,
-            flag_groups = [flag_group(flags = [
-                "-gmlt",
-            ])],
-        )],
+        flag_sets = [
+            flag_set(
+                actions = codegen_compile_actions,
+                flag_groups = [
+                    flag_group(
+                        flags = ["-gmlt"],
+                    ),
+                ],
+            ),
+        ],
     )
     default_debug_info_flags = feature(
         name = "default_debug_info_flags",
@@ -782,6 +788,11 @@ def _impl(ctx):
     if ctx.attr.target_cpu == "k8":
         features += [linux_flags_feature]
         sysroot = None
+    elif ctx.attr.target_cpu == "x64_windows":
+        # TODO: Need to figure out if we need to add windows specific features
+        # I think the .pdb debug files will need to be handled differently,
+        # so that might be an example where a feature must be added.
+        sysroot = None
     elif ctx.attr.target_cpu in ["darwin", "darwin_arm64"]:
         sysroot = sysroot_dir
     else:

+ 22 - 1
bazel/cc_toolchains/clang_configuration.bzl

@@ -64,6 +64,19 @@ def _compute_clang_cpp_include_search_paths(repository_ctx, clang, sysroot):
     Returns the resulting paths as a list of strings.
     """
 
+    # Create an empty temp file for Clang to use
+    if repository_ctx.os.name.lower().startswith("windows"):
+        repository_ctx.file('_temp', '')
+
+    # Read in an empty input file. If we are building from
+    # Windows, then we create an empty temp file. Clang
+    # on Windows does not like it when you pass a non-existent file.
+    if repository_ctx.os.name.lower().startswith("windows"):
+        repository_ctx.file('_temp', '')
+        input_file = repository_ctx.path('_temp')
+    else:
+        input_file = "/dev/null"
+
     # The only way to get this out of Clang currently is to parse the verbose
     # output of the compiler when it is compiling C++ code.
     cmd = [
@@ -78,7 +91,7 @@ def _compute_clang_cpp_include_search_paths(repository_ctx, clang, sysroot):
         "-x",
         "c++",
         # Read in an empty input file.
-        "/dev/null",
+        input_file,
         # Always use libc++.
         "-stdlib=libc++",
     ]
@@ -98,6 +111,7 @@ def _compute_clang_cpp_include_search_paths(repository_ctx, clang, sysroot):
     # space from each path.
     include_begin = output.index("#include <...> search starts here:") + 1
     include_end = output.index("End of search list.", include_begin)
+
     return [
         repository_ctx.path(s.lstrip(" "))
         for s in output[include_begin:include_end]
@@ -139,6 +153,13 @@ def _configure_clang_toolchain_impl(repository_ctx):
         if not arpath:
             fail("`llvm-ar` not found in PATH or adjacent to clang")
 
+    # By default Windows uses '\' in its paths. These will be
+    # interpreted as escape characters and fail the build, thus
+    # we must manually replace the backslashes with '/'
+    if repository_ctx.os.name.lower().startswith("windows"):
+        resource_dir = resource_dir.replace("\\", "/")
+        include_dirs = [str(s).replace("\\", "/") for s in include_dirs]
+
     repository_ctx.template(
         "clang_detected_variables.bzl",
         repository_ctx.attr._clang_detected_variables_template,

+ 21 - 0
bazel/cc_toolchains/clang_toolchain.BUILD

@@ -23,6 +23,7 @@ cc_toolchain_suite(
         "darwin": ":cc-compiler-darwin",
         "darwin_arm64": ":cc-compiler-darwin-arm64",
         "k8": ":cc-compiler-k8",
+        "x64_windows": ":cc-compiler-x64-windows",
     },
 )
 
@@ -85,3 +86,23 @@ cc_toolchain_config(
     name = "local-darwin-arm64",
     target_cpu = "darwin_arm64",
 )
+
+cc_toolchain(
+    name = "cc-compiler-x64-windows",
+    all_files = ":empty",
+    ar_files = ":empty",
+    as_files = ":empty",
+    compiler_files = ":empty",
+    dwp_files = ":empty",
+    linker_files = ":empty",
+    objcopy_files = ":empty",
+    strip_files = ":empty",
+    supports_param_files = 1,
+    toolchain_config = ":local-x64-windows",
+    toolchain_identifier = "local-x64-windows",
+)
+
+cc_toolchain_config(
+    name = "local-x64-windows",
+    target_cpu = "x64_windows",
+)