From 5efa371c639be5e06bdc797a9deef1dc53048f58 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Tue, 25 Jun 2024 04:27:32 +0000 Subject: [PATCH] Add a rule to build Windows executables w/ custom build configs This CL adds a custom rule `mozc_win_build_rule` to build Windows executables with the given build configurations. This rule is necessary to build Windows executables with the correct build configurations, such as the CPU architecture and the CRT library. For instance, the following build rule tells Bazel to have "custom_action" target with "x64_windows" CPU architecture and with statically linking to MSVC C++ runtime. mozc_win_build_rule( name = "custom_action", target = "//win32/custom_action:custom_action", cpu = "x64_windows", static_crt = True, ) This CL is a part of the effort to migrate the Windows build system from GYP to Bazel (#948). #codehealth PiperOrigin-RevId: 646324022 --- src/.bazelrc | 8 +++++ src/build_defs.bzl | 82 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/src/.bazelrc b/src/.bazelrc index d0dc988e5..bd1a787f6 100644 --- a/src/.bazelrc +++ b/src/.bazelrc @@ -50,6 +50,14 @@ build:windows --define TARGET=oss_windows --build_tag_filters=-nowin build:oss_windows --define TARGET=oss_windows --build_tag_filters=-nowin build:prod_windows --define TARGET=prod_windows --build_tag_filters=-nowin +# A temporary workaround to make "mozc_win_build_rule" work. +# Note that "incompatible_enable_cc_toolchain_resolution" is now enabled by +# default. See https://github.com/bazelbuild/bazel/issues/7260 +# TODO: Re-enable "incompatible_enable_cc_toolchain_resolution" +build:windows --noincompatible_enable_cc_toolchain_resolution +build:oss_macos --noincompatible_enable_cc_toolchain_resolution +build:prod_macos --noincompatible_enable_cc_toolchain_resolution + # Android / OSS Android (same configurations) build:android --define TARGET=oss_android --copt "-DOS_ANDROID" build:android --android_crosstool_top=@androidndk//:toolchain diff --git a/src/build_defs.bzl b/src/build_defs.bzl index 434c62afc..0057f9571 100644 --- a/src/build_defs.bzl +++ b/src/build_defs.bzl @@ -43,7 +43,13 @@ See also: https://bazel.build/rules/bzl-style#rules """ load("@build_bazel_rules_apple//apple:macos.bzl", "macos_application", "macos_bundle", "macos_unit_test") -load("//:config.bzl", "BRANDING", "MACOS_BUNDLE_ID_PREFIX", "MACOS_MIN_OS_VER") +load( + "//:config.bzl", + "BAZEL_TOOLS_PREFIX", + "BRANDING", + "MACOS_BUNDLE_ID_PREFIX", + "MACOS_MIN_OS_VER", +) load("//bazel:run_build_tool.bzl", "mozc_run_build_tool") load("//bazel:stubs.bzl", "pytype_strict_binary", "pytype_strict_library", "register_extension_info") @@ -434,6 +440,80 @@ def mozc_macos_bundle(name, bundle_name, infoplists, strings = [], bundle_id = N **kwargs ) +def _win_executable_transition_impl( + settings, # @unused + attr): + features = [] + if attr.static_crt: + features = ["static_link_msvcrt"] + return { + "//command_line_option:features": features, + "//command_line_option:cpu": attr.cpu, + } + +_win_executable_transition = transition( + implementation = _win_executable_transition_impl, + inputs = [], + outputs = [ + "//command_line_option:features", + "//command_line_option:cpu", + ], +) + +def _mozc_win_build_rule_impl(ctx): + input_file = ctx.file.target + output = ctx.actions.declare_file( + ctx.label.name + "." + input_file.extension, + ) + if input_file.path == output.path: + fail("input=%d and output=%d are the same." % (input_file.path, output.path)) + + # Create a symlink as we do not need to create an actual copy. + ctx.actions.symlink( + output = output, + target_file = input_file, + is_executable = True, + ) + return [DefaultInfo( + files = depset([output]), + executable = output, + )] + +# A custom rule to reference the given build target with the given build configurations. +# +# For instance, the following rule creates a target "my_target" with setting "cpu" as "x64_windows" +# and setting "static_link_msvcrt" feature. +# +# mozc_win_build_rule( +# name = "my_target", +# cpu = "x64_windows", +# static_crt = True, +# target = "//bath/to/target:my_target", +# ) +# +# See the following page for the details on transition. +# https://bazel.build/rules/lib/builtins/transition +mozc_win_build_rule = rule( + implementation = _mozc_win_build_rule_impl, + cfg = _win_executable_transition, + attrs = { + "_allowlist_function_transition": attr.label( + default = BAZEL_TOOLS_PREFIX + "//tools/allowlists/function_transition_allowlist", + ), + "target": attr.label( + allow_single_file = [".dll", ".exe"], + doc = "the actual Bazel target to be built.", + mandatory = True, + ), + "static_crt": attr.bool( + default = False, + ), + "cpu": attr.string( + default = "x64_windows", + ), + }, +) + def _get_value(args): for arg in args: if arg != None: