From 5d43040c90b2c50b9ef3a1864e27256353c3858e Mon Sep 17 00:00:00 2001 From: Zach Yu Date: Fri, 23 Jun 2023 18:15:46 -0700 Subject: Add repository rule for Windows SDK. Due to how the SDK directory is structured (/include/), the BUILD file is expanded from a template with version string substituted. The BUILD file template contains an import target for all SDK libraries of the selected version. Bug: 288495471 Change-Id: I4d0c85f42210349f9a81e80b20b6fc09770d0d9d --- rules/repository_utils.bzl | 14 ++++++-- toolchains/cc/repository_rules.bzl | 59 +++++++++++++++++++++++++++++++ toolchains/cc/windows_clang/sdk.BUILD.tpl | 27 ++++++++++++++ toplevel.WORKSPACE | 7 ++++ 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 toolchains/cc/windows_clang/sdk.BUILD.tpl diff --git a/rules/repository_utils.bzl b/rules/repository_utils.bzl index e614b65e..3c2c297f 100644 --- a/rules/repository_utils.bzl +++ b/rules/repository_utils.bzl @@ -60,13 +60,15 @@ def relative_path(path_str, root): """ return path_str.removeprefix(root).lstrip("/\\") -def create_build_file(build_file, repo_ctx): +def create_build_file(build_file, repo_ctx, substitutions = None): """Create a BUILD.bazel file at root of the repository. Args: build_file: A path string to the BUILD file. Relative path is resolved relative to the workspace root. repo_ctx: The repository context. + substitutions: If specified, substitutions to make when expanding + build_file as a template. """ repo_ctx.delete("BUILD.bazel") build_file = resolve_workspace_path(build_file, repo_ctx) @@ -78,7 +80,15 @@ def create_build_file(build_file, repo_ctx): build_file, "is not found.", ) - repo_ctx.symlink(build_file, "BUILD.bazel") + if not substitutions: + repo_ctx.symlink(build_file, "BUILD.bazel") + else: + repo_ctx.template( + "BUILD.bazel", + build_file, + substitutions, + executable = False, + ) def create_workspace_file(workspace_file, repo_ctx, default_content = None): """Create a WORKSPACE file at root of the repository. At least one of workspace_file and default_content must be passed. diff --git a/toolchains/cc/repository_rules.bzl b/toolchains/cc/repository_rules.bzl index 78120cc5..cf42a547 100644 --- a/toolchains/cc/repository_rules.bzl +++ b/toolchains/cc/repository_rules.bzl @@ -134,3 +134,62 @@ msvc_tools_repository = repository_rule( ), }, ) + +def _get_all_win_sdk_versions(sdk_path): + sdk_versions = [] + for versioned_sdk_include in sdk_path.get_child("Include").readdir(): + if versioned_sdk_include.get_child("um", "winsdkver.h").exists: + sdk_versions.append(versioned_sdk_include.basename) + return sdk_versions + +def _windows_sdk_repository_impl(repo_ctx): + """Creates a local repository for a Windows SDK.""" + sdk_path = repo_ctx.path(repo_ctx.attr.sdk_path) + all_versions = {v: None for v in _get_all_win_sdk_versions(sdk_path)} + want_versions = repo_ctx.attr.sdk_versions if repo_ctx.attr.sdk_versions else [""] + selected_version = _select_version(all_versions, want_versions) + if not selected_version: + fail( + "None of the following Windows SDK versions are found in", + str(sdk_path), + ":", + want_versions, + "; available versions are:", + all_versions.keys(), + ) + for entry in sdk_path.readdir(): + repo_ctx.symlink(entry, relative_path(str(entry), str(sdk_path))) + create_build_file( + repo_ctx.attr.build_file_template, + repo_ctx, + substitutions = {"%{sdk_version}": selected_version}, + ) + create_workspace_file(None, repo_ctx, default_workspace_file_content( + repo_ctx.name, + "windows_sdk_repository", + )) + +windows_sdk_repository = repository_rule( + implementation = _windows_sdk_repository_impl, + local = True, + doc = "Creates a local repository for host installed Windows SDK.", + attrs = { + "build_file_template": attr.string( + doc = "A file to be expanded as a BUILD file for this directory, " + + "relative to the main workspace. The template can contain " + + "'%{sdk_version}' tags that will be replaced with exact " + + "SDK version.", + mandatory = True, + ), + "sdk_path": attr.string( + doc = "The installation path of Windows SDKs.", + mandatory = True, + ), + "sdk_versions": attr.string_list( + doc = "The SDK versions to look for (e.g. 10.0.19041.0). " + + "The first version found will be used. An empty " + + "string can be added at the end for the latest version.", + default = [""], + ), + }, +) diff --git a/toolchains/cc/windows_clang/sdk.BUILD.tpl b/toolchains/cc/windows_clang/sdk.BUILD.tpl new file mode 100644 index 00000000..3b528870 --- /dev/null +++ b/toolchains/cc/windows_clang/sdk.BUILD.tpl @@ -0,0 +1,27 @@ +"""Exports Windows SDK libraries from the "Windows Kits\\" directory.""" + +load("@//build/bazel/toolchains/cc:rules.bzl", "cc_toolchain_import") + +package(default_visibility = ["@//build/bazel/toolchains/cc:__subpackages__"]) + +cc_toolchain_import( + name = "sdk_libs_x64", + include_paths = [ + ":include/%{sdk_version}/ucrt", + ":include/%{sdk_version}/shared", + ":include/%{sdk_version}/um", + ":include/%{sdk_version}/winrt", + ":include/%{sdk_version}/cppwinrt", + ], + lib_search_paths = [ + ":lib/%{sdk_version}/ucrt/x64", + ":lib/%{sdk_version}/um/x64", + ], + support_files = glob( + [ + "include/%{sdk_version}/**", + "lib/%{sdk_version}/ucrt/x64/**", + "lib/%{sdk_version}/um/x64/**", + ], + ), +) diff --git a/toplevel.WORKSPACE b/toplevel.WORKSPACE index b04b8ce1..9d87eff0 100644 --- a/toplevel.WORKSPACE +++ b/toplevel.WORKSPACE @@ -118,6 +118,7 @@ load( "//build/bazel/toolchains/cc:repository_rules.bzl", "macos_sdk_repository", "msvc_tools_repository", + "windows_sdk_repository", ) # Repository that provides the clang compilers @@ -156,6 +157,12 @@ msvc_tools_repository( build_file = "build/bazel/toolchains/cc/windows_clang/vctools.BUILD", ) +windows_sdk_repository( + name = "windows_sdk", + build_file_template = "build\\bazel\\toolchains\\cc\\windows_clang\\sdk.BUILD.tpl", + sdk_path = "C:\\Program Files (x86)\\Windows Kits\\10", +) + register_toolchains( "//build/bazel/toolchains/cc/linux_clang:x64_toolchain", "//build/bazel/toolchains/cc/mac_clang:x64_toolchain", -- cgit v1.2.3