From 2f3ff1270433c82ecabc2410c38f88b5c7c4f20d Mon Sep 17 00:00:00 2001 From: ethang Date: Tue, 23 Aug 2022 17:28:47 -0300 Subject: [PATCH] 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 --- .../clang_cc_toolchain_config.bzl | 31 +++++++++++++------ bazel/cc_toolchains/clang_configuration.bzl | 23 +++++++++++++- bazel/cc_toolchains/clang_toolchain.BUILD | 21 +++++++++++++ 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/bazel/cc_toolchains/clang_cc_toolchain_config.bzl b/bazel/cc_toolchains/clang_cc_toolchain_config.bzl index 16e50f06acc6..6050760fbcd2 100644 --- a/bazel/cc_toolchains/clang_cc_toolchain_config.bzl +++ b/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: diff --git a/bazel/cc_toolchains/clang_configuration.bzl b/bazel/cc_toolchains/clang_configuration.bzl index 88be63aa91d7..fb67a4ebb3c2 100644 --- a/bazel/cc_toolchains/clang_configuration.bzl +++ b/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, diff --git a/bazel/cc_toolchains/clang_toolchain.BUILD b/bazel/cc_toolchains/clang_toolchain.BUILD index dc45b926983d..b6ec41596203 100644 --- a/bazel/cc_toolchains/clang_toolchain.BUILD +++ b/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", +)