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>
This commit is contained in:
ethang
2022-08-23 13:28:47 -07:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent 065d5224be
commit 2f3ff12704
3 changed files with 64 additions and 11 deletions
@@ -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
View File
@@ -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
View File
@@ -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",
)