SERVER-93265 support windows rc files in bazel (#42670)

GitOrigin-RevId: 89914241ce953fbeed384283635f3ff50bb8eee7
This commit is contained in:
Daniel Moody 2025-10-15 14:59:48 -05:00 committed by MongoDB Bot
parent 6d94d0db75
commit 96ef05984e
14 changed files with 315 additions and 45 deletions

4
MODULE.bazel.lock generated
View File

@ -61,7 +61,7 @@
"moduleExtensions": {
"//bazel:bzlmod.bzl%setup_mongo_python_toolchains": {
"general": {
"bzlTransitiveDigest": "wrUpV169g2K/B2XhHtikVJ7WDTbk2yt8p6LsJ7WH4xY=",
"bzlTransitiveDigest": "A/FPPRf/KXUGPg32SRiN/n2uOcgul1q2lPU3/Nz3Cvg=",
"usagesDigest": "bUxjq9n+hj2YwYT/lcSP4lHyQ2GVy5JpFgSmddUqUZg=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
@ -197,7 +197,7 @@
},
"//bazel/toolchains/cc/mongo_windows:mongo_toolchain.bzl%setup_mongo_windows_toolchain_extension": {
"general": {
"bzlTransitiveDigest": "n/VGK3QrOp2/taYQt3Q22FFqBudHACXuKRmYzyoG0Ic=",
"bzlTransitiveDigest": "dHLyfzMhaUTIIP7LsjQxVGJHz6n+z1RfQNYH+/O+1Iw=",
"usagesDigest": "n0o7oj+Qsfc72uhUPqYhsJpUeTzxSeQBSih56V3nmlw=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},

View File

@ -1,7 +1,7 @@
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
load("//bazel/config:configs.bzl", "sdkroot_provider")
load("//bazel:mongo_src_rules.bzl", "write_target")
load("//bazel:utils.bzl", "write_target")
def generate_config_header_impl(ctx):
cc_toolchain = find_cpp_toolchain(ctx)

View File

@ -1,4 +1,4 @@
load("//bazel:mongo_src_rules.bzl", "write_target")
load("//bazel:utils.bzl", "write_target")
def render_template_impl(ctx):
python = ctx.toolchains["@bazel_tools//tools/python:toolchain_type"].py3_runtime

View File

@ -34,6 +34,9 @@ load(
)
load("@local_host_values//:local_host_values_set.bzl", "NUM_CPUS")
load("@evergreen_variables//:evergreen_variables.bzl", "UNSAFE_COMPILE_VARIANT", "UNSAFE_VERSION_ID")
load("//bazel/toolchains/cc/mongo_windows:mongo_windows_cc_toolchain_config.bzl", "MIN_VER_MAP")
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
load("//bazel/config:generate_config_header.bzl", "generate_config_header")
# These will throw an error if the following condition is not met:
# (libunwind == on && os == linux) || libunwind == off || libunwind == auto
@ -1300,27 +1303,6 @@ idl_generator_rule = rule(
fragments = ["py"],
)
def write_target_impl(ctx):
out = ctx.actions.declare_file(ctx.label.name + ".gen_source_list")
ctx.actions.write(
out,
"//" + ctx.label.package + ":" + ctx.attr.target_name,
)
return [
DefaultInfo(
files = depset([out]),
),
]
write_target = rule(
write_target_impl,
attrs = {
"target_name": attr.string(
doc = "the name of the target to record",
),
},
)
def idl_generator(name, tags = [], **kwargs):
idl_generator_rule(
name = name,
@ -1739,3 +1721,161 @@ def mongo_cc_extension_shared_library(
"//conditions:default": ["@platforms//:incompatible"],
}),
)
def _compute_win_defines(ver):
if ver not in MIN_VER_MAP:
fail("Unsupported windows_version_minimal=%r; supported: %r" %
(ver, sorted(MIN_VER_MAP.keys())))
m = MIN_VER_MAP[ver]
return [
"_WIN32_WINNT=%s" % m["win"],
"BOOST_USE_WINAPI_VERSION=%s" % m["win"],
"NTDDI_VERSION=%s" % m["ddi"],
]
def _uniq_dirs(files):
d = {}
for f in files:
d[f.dirname] = True
return sorted(d.keys())
def _rc_impl(ctx):
# No-op on non-Windows
if not ctx.target_platform_has_constraint(
ctx.attr._os_windows[platform_common.ConstraintValueInfo],
):
li = cc_common.create_linker_input(
owner = ctx.label,
user_link_flags = [],
additional_inputs = depset(), # and declare it as a link input
)
new_cc_shared_info = CcSharedLibraryInfo(
dynamic_deps = depset(),
exports = [],
linker_input = li,
link_once_static_libs = {},
)
return [DefaultInfo(files = depset([])), CcInfo(), new_cc_shared_info]
new_cc_shared_info = CcSharedLibraryInfo(
dynamic_deps = depset(),
exports = [],
linker_input = None,
link_once_static_libs = {},
)
# On Windows we need an rc executable
if ctx.executable.rc == None:
fail("windows_rc: 'rc' tool not provided. Pass rc = '@mongo_windows_toolchain//:rc' (or your wrapper).")
out = ctx.actions.declare_file(ctx.label.name + ".res")
defines = []
if ctx.attr.windows_version_minimal:
ver = ctx.attr.windows_version_minimal[BuildSettingInfo].value
defines += _compute_win_defines(ver)
defines += ctx.attr.defines
include_dirs = ["src", ctx.file.src.dirname]
# Add $(GENDIR)/src (use backslashes for rc.exe friendliness)
gen_src = ctx.var["GENDIR"] + "\\src"
include_dirs.append(gen_src)
args = ctx.actions.args()
args.add("/nologo")
for inc in include_dirs:
args.add("/I", inc)
for d in defines:
args.add("/d", d)
args.add("/fo" + out.path) # /fo must be joined
args.add(ctx.file.src.path)
ctx.actions.run(
executable = ctx.executable.rc, # your wrapper
arguments = [args],
inputs = [ctx.file.src] + ctx.files.resources,
outputs = [out],
mnemonic = "WindowsRC",
)
li = cc_common.create_linker_input(
owner = ctx.label,
user_link_flags = [out.path], # put .res on the link line
additional_inputs = depset([out]), # and declare it as a link input
)
lc = cc_common.create_linking_context(linker_inputs = depset([li]))
new_cc_shared_info = CcSharedLibraryInfo(
dynamic_deps = depset(),
exports = [],
linker_input = li,
link_once_static_libs = {},
)
return [DefaultInfo(files = depset([out])), CcInfo(linking_context = lc), new_cc_shared_info]
windows_rc_rule = rule(
implementation = _rc_impl,
attrs = {
"src": attr.label(mandatory = True, allow_single_file = [".rc"]),
"resources": attr.label_list(allow_files = True),
"defines": attr.string_list(),
"rc": attr.label(executable = True, cfg = "exec", allow_files = True),
"windows_version_minimal": attr.label(),
"_os_windows": attr.label(
default = Label("@platforms//os:windows"),
providers = [platform_common.ConstraintValueInfo],
),
},
provides = [CcInfo],
fragments = ["cpp"],
)
def windows_rc(name, src, manifest_in = None, icon = None):
if manifest_in:
# Turn "foo.manifest.in" into "foo.manifest"
out_manifest = manifest_in[:-3] if manifest_in.endswith(".in") else manifest_in
generate_config_header(
name = name + "_manifest_gen",
checks = "//src/mongo/util:version_constants_gen.py",
cpp_defines = [],
cpp_linkflags = [],
cpp_opts = [],
extra_definitions = {
"MONGO_DISTMOD": "$(MONGO_DISTMOD)",
"MONGO_VERSION": "$(MONGO_VERSION)",
"GIT_COMMIT_HASH": "$(GIT_COMMIT_HASH)",
} | select({
"//bazel/config:js_engine_mozjs": {"js_engine_ver": "mozjs"},
"//conditions:default": {"js_engine_ver": "none"},
}) | select({
"//bazel/config:tcmalloc_google_enabled": {"MONGO_ALLOCATOR": "tcmalloc-google"},
"//bazel/config:tcmalloc_gperf_enabled": {"MONGO_ALLOCATOR": "tcmalloc-gperf"},
"//conditions:default": {"MONGO_ALLOCATOR": "system"},
}) | select({
"//bazel/config:build_enterprise_enabled": {"build_enterprise_enabled": "1"},
"//conditions:default": {},
}),
logfile = name + "_manifest_gen.log",
output = out_manifest,
template = manifest_in,
)
resources = ["//src/mongo/util:rc_constants_gen"]
if manifest_in:
resources.append(name + "_manifest_gen")
if icon:
resources.append(icon)
windows_rc_rule(
name = name,
src = src,
resources = resources,
rc = select({
"@platforms//os:windows": "@mongo_windows_toolchain//:rc",
"//conditions:default": None,
}),
windows_version_minimal = "//bazel/config:win_min_version",
)

View File

@ -69,6 +69,14 @@ mongo_windows_cc_toolchain_config(
smaller_binary = SMALLER_BINARY,
)
exports_files(["rc_wrapper.cmd"])
alias(
name = "rc",
actual = "rc_wrapper.cmd",
visibility = ["//visibility:public"]
)
cc_toolchain(
name = "mongo_win_cc_toolchain",
all_files = ":all_files",

View File

@ -11,6 +11,41 @@ load(
"setup_vc_env_vars",
)
def _compute_rc_path(ctx, env_vars):
# Allow an explicit override from CI/dev
rc_path = ctx.os.environ.get("RC_PATH")
if rc_path and ctx.path(rc_path).exists:
return rc_path.replace("\\", "/")
winsdkdir = (env_vars.get("WINDOWSSDKDIR") or "").rstrip("\\/")
sdkver = (env_vars.get("WindowsSDKVersion") or "").strip("\\/")
# Typical locations in recent SDKs
candidates = []
if winsdkdir:
if sdkver:
candidates += [
"%s\\bin\\%s\\x64\\rc.exe" % (winsdkdir, sdkver),
"%s\\bin\\%s\\x86\\rc.exe" % (winsdkdir, sdkver),
]
candidates += [
"%s\\bin\\x64\\rc.exe" % winsdkdir,
"%s\\bin\\x86\\rc.exe" % winsdkdir,
]
# Fallback to LLVM if present
llvm = ctx.os.environ.get("BAZEL_LLVM")
if llvm:
candidates += [
"%s\\bin\\llvm-rc.exe" % llvm,
"%s\\bin\\rc.exe" % llvm, # some layouts
]
for c in candidates:
if ctx.path(c).exists:
return c.replace("\\", "/")
return None
def _impl_gen_windows_toolchain_build_file(ctx):
if "windows" not in ctx.os.name:
ctx.file(
@ -85,6 +120,21 @@ def _impl_gen_windows_toolchain_build_file(ctx):
# purpose.
ctx.file("windows_toolchain_config.json", json.encode(substitutions), executable = False)
# --- expose rc.exe/llvm-rc.exe as a stable label in this repo ---
# Ask VS env for SDK location/version (setup_vc_env_vars already did that).
# Add WindowsSDKVersion to your setup_vc_env_vars() if not already included.
rc_path = _compute_rc_path(ctx, vars)
if not rc_path:
auto_configure_fail(
"Could not locate rc.exe (or llvm-rc.exe). Set RC_PATH or ensure Windows SDK is installed and WindowsSDKVersion is exported.",
)
ctx.file(
"rc_wrapper.cmd",
"@echo off\r\nsetlocal\r\nset \"INCLUDE=%s\"\r\nset \"PATH=%s\"\r\n\"%s\" %%*\r\n" % (vars["INCLUDE"], vars["PATH"], rc_path),
executable = True,
)
ctx.report_progress("Generating toolchain build file")
ctx.template(
"BUILD.bazel",

View File

@ -36,6 +36,16 @@ load(
"with_feature_set",
)
# The values are populated from the following link:
# https://learn.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt?view=msvc-170
# For future versions, please add it in the map.
MIN_VER_MAP = {
"10": {
"win": "0x0A00",
"ddi": "0x0A000000",
},
}
all_compile_actions = [
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
@ -85,25 +95,15 @@ all_link_actions = [
]
def get_windows_mimimun_version_feature(ctx):
# The values are populated from the following link:
# https://learn.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt?view=msvc-170
# For future versions, please add it in the map.
min_ver_map = {
"10": {
"win": "0x0A00",
"ddi": "0x0A000000",
},
}
if BuildSettingInfo not in ctx.attr.windows_version_minimal:
fail("windows_version_minimal attribute value is not a build flag.")
ver = ctx.attr.windows_version_minimal[BuildSettingInfo].value
if ver not in min_ver_map:
error_msg = "Windows mininum version {} does not exist. These are the minimum versions that are supported: {}".format(ver, min_ver_map.keys())
if ver not in MIN_VER_MAP:
error_msg = "Windows mininum version {} does not exist. These are the minimum versions that are supported: {}".format(ver, MIN_VER_MAP.keys())
fail(error_msg)
min_ver = min_ver_map[ver]
min_ver = MIN_VER_MAP[ver]
return feature(
name = "windows_version_minimum",
enabled = True,

View File

@ -351,7 +351,7 @@ def setup_vc_env_vars(repository_ctx, vc_path, envvars = [], allow_empty = False
dictionary of the envvars
"""
if not envvars:
envvars = ["PATH", "INCLUDE", "LIB", "WINDOWSSDKDIR"]
envvars = ["PATH", "INCLUDE", "LIB", "WINDOWSSDKDIR", "WindowsSDKVersion"]
vcvars_script = _find_vcvars_bat_script(repository_ctx, vc_path)
if not vcvars_script:

View File

@ -1,6 +1,27 @@
# General starlark utility functions
load("//bazel/platforms:normalize.bzl", "ARCH_NORMALIZE_MAP")
def write_target_impl(ctx):
out = ctx.actions.declare_file(ctx.label.name + ".gen_source_list")
ctx.actions.write(
out,
"//" + ctx.label.package + ":" + ctx.attr.target_name,
)
return [
DefaultInfo(
files = depset([out]),
),
]
write_target = rule(
write_target_impl,
attrs = {
"target_name": attr.string(
doc = "the name of the target to record",
),
},
)
def retry_download_and_extract(ctx, tries, **kwargs):
sleep_time = 1
for attempt in range(tries):

View File

@ -49,6 +49,9 @@ def main():
if not atlas_mod.exists():
args += ["--//bazel/config:build_atlas=False"]
if any(arg.startswith("--include_mongot") for arg in args):
os.makedirs("mongot-localdev", exist_ok=True)
engflow_auth(args)
write_workstation_bazelrc(args)
write_mongo_variables_bazelrc(args)

View File

@ -1,5 +1,5 @@
load("@poetry//:dependencies.bzl", "dependency")
load("//bazel:mongo_src_rules.bzl", "idl_generator", "mongo_cc_benchmark", "mongo_cc_binary", "mongo_cc_fuzzer_test", "mongo_cc_integration_test", "mongo_cc_library", "mongo_cc_unit_test", "mongo_idl_library")
load("//bazel:mongo_src_rules.bzl", "idl_generator", "mongo_cc_benchmark", "mongo_cc_binary", "mongo_cc_fuzzer_test", "mongo_cc_integration_test", "mongo_cc_library", "mongo_cc_unit_test", "mongo_idl_library", "windows_rc")
load("//bazel/config:render_template.bzl", "render_template")
package(default_visibility = ["//visibility:public"])
@ -8,6 +8,7 @@ exports_files(
glob([
"*.h",
"*.cpp",
"*.ico",
]),
)
@ -3511,6 +3512,13 @@ mongo_cc_binary(
],
)
windows_rc(
name = "mongod_res",
src = "mongod.rc",
icon = "mongo.ico",
manifest_in = "mongod.manifest.in",
)
mongo_cc_binary(
name = "mongod",
srcs = [
@ -3563,7 +3571,6 @@ mongo_cc_binary(
"devcore",
"dist_test",
],
#+ env.WindowsResourceFile("mongod.rc"),
deps = [
# NOTE: Do not add new deps here unless required by the linker to
# satisfy symbol dependencies from the files listed above in `sources`. If you need to add a
@ -3571,6 +3578,7 @@ mongo_cc_binary(
# dep of mongod_initializers.
"mongod_main",
"server_base",
"mongod_res",
],
)

View File

@ -1,4 +1,4 @@
load("//bazel:mongo_src_rules.bzl", "idl_generator", "mongo_cc_benchmark", "mongo_cc_binary", "mongo_cc_library", "mongo_cc_unit_test")
load("//bazel:mongo_src_rules.bzl", "idl_generator", "mongo_cc_benchmark", "mongo_cc_binary", "mongo_cc_library", "mongo_cc_unit_test", "windows_rc")
package(default_visibility = ["//visibility:public"])
@ -908,6 +908,13 @@ mongo_cc_library(
}),
)
windows_rc(
name = "mongos_res",
src = "mongos.rc",
icon = "//src/mongo/db:mongo.ico",
manifest_in = "mongos.manifest.in",
)
mongo_cc_binary(
name = "mongos",
srcs = [
@ -924,7 +931,6 @@ mongo_cc_binary(
"devcore",
"dist_test",
],
#+ env.WindowsResourceFile("mongos.rc"),
deps = [
# NOTE: Do not add new deps here unless required by the linker to
# satisfy symbol dependencies from the files listed above in `sources`. If you need to add a
@ -932,6 +938,7 @@ mongo_cc_binary(
# dep of mongos_initializers.
"mongos_main",
"//src/mongo/db:server_base",
"mongos_res",
],
)

View File

@ -1,6 +1,6 @@
load("@bazel_skylib//lib:selects.bzl", "selects")
load("@poetry//:dependencies.bzl", "dependency")
load("//bazel:mongo_src_rules.bzl", "idl_generator", "mongo_cc_binary", "mongo_cc_library", "mongo_cc_unit_test")
load("//bazel:mongo_src_rules.bzl", "idl_generator", "mongo_cc_binary", "mongo_cc_library", "mongo_cc_unit_test", "windows_rc")
load("//bazel/config:render_template.bzl", "render_template")
package(default_visibility = ["//visibility:public"])
@ -484,6 +484,13 @@ mongo_cc_library(
],
)
windows_rc(
name = "mongo_res",
src = "mongo.rc",
icon = "mongo.ico",
manifest_in = "mongo.manifest.in",
)
mongo_cc_binary(
name = "mongo",
srcs = [
@ -504,7 +511,6 @@ mongo_cc_binary(
"dist_test",
"jstestshell",
],
#+ env.WindowsResourceFile("mongo.rc"),
deps = [
# NOTE: Do not add new deps here unless required by the linker to
# satisfy symbol dependencies from the files listed above in `sources`. If you need to add a
@ -512,6 +518,7 @@ mongo_cc_binary(
# dep of mongos_initializers.
"mongo_main",
"//src/mongo/db:server_base",
"mongo_res",
],
)

View File

@ -803,6 +803,32 @@ generate_config_header(
template = "version_impl.tpl.cpp",
)
generate_config_header(
name = "rc_constants_gen",
checks = "//src/mongo/util:version_constants_gen.py",
cpp_defines = MONGO_GLOBAL_DEFINES,
cpp_linkflags = MONGO_GLOBAL_LINKFLAGS,
cpp_opts = MONGO_GLOBAL_COPTS,
extra_definitions = {
"MONGO_DISTMOD": "$(MONGO_DISTMOD)",
"MONGO_VERSION": "$(MONGO_VERSION)",
"GIT_COMMIT_HASH": "$(GIT_COMMIT_HASH)",
} | select({
"//bazel/config:js_engine_mozjs": {"js_engine_ver": "mozjs"},
"//conditions:default": {"js_engine_ver": "none"},
}) | select({
"//bazel/config:tcmalloc_google_enabled": {"MONGO_ALLOCATOR": "tcmalloc-google"},
"//bazel/config:tcmalloc_gperf_enabled": {"MONGO_ALLOCATOR": "tcmalloc-gperf"},
"//conditions:default": {"MONGO_ALLOCATOR": "system"},
}) | select({
"//bazel/config:build_enterprise_enabled": {"build_enterprise_enabled": "1"},
"//conditions:default": {},
}),
logfile = "rc_constants_gen.log",
output = "resource_constants.h",
template = "resource_constants.h.in",
)
mongo_cc_unit_test(
name = "concurrent_shared_values_map_test",
srcs = ["concurrent_shared_values_map_test.cpp"],