Skip to content

Commit 92d42c4

Browse files
committed
remaining
1 parent d3ff092 commit 92d42c4

File tree

6 files changed

+277
-19
lines changed

6 files changed

+277
-19
lines changed

rust/platform/BUILD.bazel

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ constraint_value(
2121
constraint_setting = ":wasi_version",
2222
)
2323

24+
# ABI constraint settings
25+
constraint_setting(
26+
name = "abi",
27+
default_constraint_value = ":gnu",
28+
)
29+
30+
constraint_value(
31+
name = "gnu",
32+
constraint_setting = ":abi",
33+
)
34+
35+
constraint_value(
36+
name = "musl",
37+
constraint_setting = ":abi",
38+
)
39+
2440
package_group(
2541
name = "function_transition_allowlist",
2642
packages = [

rust/platform/triple_mappings.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ SUPPORTED_T2_PLATFORM_TRIPLES = {
6969
"x86_64-linux-android": _support(std = True, host_tools = False),
7070
"x86_64-unknown-freebsd": _support(std = True, host_tools = True),
7171
"x86_64-unknown-fuchsia": _support(std = True, host_tools = False),
72+
"x86_64-unknown-linux-musl": _support(std = True, host_tools = True),
7273
"x86_64-unknown-none": _support(std = True, host_tools = False),
7374
"x86_64-unknown-uefi": _support(std = True, host_tools = False),
7475
}

rust/private/repository_utils.bzl

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ load(":semver.bzl", "semver")
2020
DEFAULT_TOOLCHAIN_NAME_PREFIX = "toolchain_for"
2121
DEFAULT_STATIC_RUST_URL_TEMPLATES = ["https://static.rust-lang.org/dist/{}.tar.xz"]
2222
DEFAULT_NIGHTLY_VERSION = "nightly/{}".format(DEFAULT_NIGHTLY_ISO_DATE)
23-
DEFAULT_EXTRA_TARGET_TRIPLES = ["wasm32-unknown-unknown", "wasm32-wasip1", "wasm32-wasip2"]
23+
DEFAULT_EXTRA_TARGET_TRIPLES = [
24+
"wasm32-unknown-unknown",
25+
"wasm32-wasip1",
26+
"wasm32-wasip2",
27+
"x86_64-unknown-linux-musl",
28+
"aarch64-unknown-linux-musl",
29+
]
2430

2531
TINYJSON_KWARGS = dict(
2632
name = "rules_rust_tinyjson",
@@ -446,9 +452,36 @@ def BUILD_for_toolchain(
446452
toolchain,
447453
toolchain_type,
448454
target_settings,
455+
target_settings_select,
449456
target_compatible_with,
450457
exec_compatible_with):
451-
target_settings_value = "target_settings = {},".format(json.encode(target_settings)) if target_settings else "# target_settings = []"
458+
"""Generates BUILD file content for a Bazel toolchain target.
459+
460+
Args:
461+
name (str): The name of the toolchain target.
462+
toolchain (str): Label of the toolchain implementation (e.g., rust_toolchain target).
463+
toolchain_type (str): The toolchain type label (e.g., "@rules_rust//rust:toolchain").
464+
target_settings (list): A list of config_setting labels that must be satisfied for
465+
this toolchain to be selected.
466+
target_settings_select (dict): A dictionary mapping config_setting labels to lists of
467+
additional target_settings, used to generate a select() statement. If empty, no
468+
select() is generated.
469+
target_compatible_with (list): A list of constraint values for the target platform.
470+
exec_compatible_with (list): A list of constraint values for the execution platform.
471+
472+
Returns:
473+
str: The generated BUILD file content as a string.
474+
"""
475+
target_settings_value = "# target_settings = []"
476+
477+
if target_settings or target_settings_select:
478+
target_settings_value = "target_settings = {}".format(
479+
json.encode(target_settings),
480+
)
481+
if target_settings_select:
482+
target_settings_value += " + select({})".format(
483+
json.encode(target_settings_select),
484+
)
452485

453486
return _build_file_for_toolchain_template.format(
454487
name = name,
@@ -1035,6 +1068,7 @@ def BUILD_for_toolchain_hub(
10351068
toolchain_labels,
10361069
toolchain_types,
10371070
target_settings,
1071+
target_settings_select,
10381072
target_compatible_with,
10391073
exec_compatible_with):
10401074
"""Generates BUILD file content for a toolchain hub repository.
@@ -1072,11 +1106,15 @@ def _toolchain_repository_hub_impl(repository_ctx):
10721106
repository_ctx.name,
10731107
))
10741108

1109+
# Decode the JSON-encoded target_settings_select
1110+
target_settings_select = json.decode(repository_ctx.attr.target_settings_select)
1111+
10751112
repository_ctx.file("BUILD.bazel", BUILD_for_toolchain_hub(
10761113
toolchain_names = repository_ctx.attr.toolchain_names,
10771114
toolchain_labels = repository_ctx.attr.toolchain_labels,
10781115
toolchain_types = repository_ctx.attr.toolchain_types,
10791116
target_settings = repository_ctx.attr.target_settings,
1117+
target_settings_select = target_settings_select,
10801118
target_compatible_with = repository_ctx.attr.target_compatible_with,
10811119
exec_compatible_with = repository_ctx.attr.exec_compatible_with,
10821120
))
@@ -1099,6 +1137,10 @@ toolchain_repository_hub = repository_rule(
10991137
doc = "A list of config_settings that must be satisfied by the target configuration in order for this toolchain to be selected during toolchain resolution, keyed by toolchain name.",
11001138
mandatory = True,
11011139
),
1140+
"target_settings_select": attr.string(
1141+
doc = "JSON-encoded dictionary mapping toolchain name to a dict of config_setting labels to lists of additional target_settings, used to generate select() statements. For internal use only.",
1142+
default = "{}",
1143+
),
11021144
"toolchain_labels": attr.string_dict(
11031145
doc = "The name of the toolchain implementation target, keyed by toolchain name.",
11041146
mandatory = True,

rust/private/rust.bzl

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,38 +1348,103 @@ def _common_attrs_for_binary_without_process_wrapper(attrs):
13481348

13491349
return new_attr
13501350

1351+
def _rust_binary_without_process_wrapper_transition_impl(_settings, _attr):
1352+
# For process wrapper bootstrapping, we force musl on Linux for better portability
1353+
# and set the linker preference to use Rust's linker
1354+
return {
1355+
str(Label("//rust/settings:toolchain_linker_preference")): "rust",
1356+
str(Label("//rust/settings:platform_linux_musl")): True,
1357+
}
1358+
1359+
_rust_binary_without_process_wrapper_transition = transition(
1360+
implementation = _rust_binary_without_process_wrapper_transition_impl,
1361+
inputs = [],
1362+
outputs = [
1363+
str(Label("//rust/settings:toolchain_linker_preference")),
1364+
str(Label("//rust/settings:platform_linux_musl")),
1365+
],
1366+
)
1367+
1368+
_RustBuiltWithoutProcessWrapperInfo = provider(
1369+
doc = "A provider identifying the target having been built using a `*_without_process_wrapper` rule variant.",
1370+
fields = {},
1371+
)
1372+
1373+
def _rust_binary_without_process_wrapper_impl(ctx):
1374+
providers = _rust_binary_impl(ctx)
1375+
return providers + [_RustBuiltWithoutProcessWrapperInfo()]
1376+
13511377
# Provides an internal rust_{binary,library} to use that we can use to build the process
13521378
# wrapper, this breaks the dependency of rust_* on the process wrapper by
13531379
# setting it to None, which the functions in rustc detect and build accordingly.
13541380
rust_binary_without_process_wrapper = rule(
1355-
implementation = _rust_binary_impl,
1356-
provides = COMMON_PROVIDERS,
1357-
attrs = _common_attrs_for_binary_without_process_wrapper(_common_attrs | _rust_binary_attrs | {
1358-
"platform": attr.label(
1359-
doc = "Optional platform to transition the binary to.",
1360-
default = None,
1361-
),
1362-
"_allowlist_function_transition": attr.label(
1363-
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
1364-
),
1365-
}),
1381+
implementation = _rust_binary_without_process_wrapper_impl,
1382+
doc = "A variant of `rust_binary` that uses a minimal process wrapper for `Rustc` actions.",
1383+
provides = COMMON_PROVIDERS + [_RustBuiltWithoutProcessWrapperInfo],
1384+
attrs = _common_attrs_for_binary_without_process_wrapper(_common_attrs | _rust_binary_attrs),
1385+
cfg = _rust_binary_without_process_wrapper_transition,
13661386
executable = True,
13671387
fragments = ["cpp"],
1368-
cfg = _rust_binary_transition,
13691388
toolchains = [
13701389
str(Label("//rust:toolchain_type")),
1371-
"@bazel_tools//tools/cpp:toolchain_type",
1390+
config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False),
13721391
],
13731392
)
13741393

1394+
def _rust_library_without_process_wrapper_impl(ctx):
1395+
providers = _rust_library_impl(ctx)
1396+
return providers + [_RustBuiltWithoutProcessWrapperInfo()]
1397+
13751398
rust_library_without_process_wrapper = rule(
1376-
implementation = _rust_library_impl,
1377-
provides = COMMON_PROVIDERS,
1399+
implementation = _rust_library_without_process_wrapper_impl,
1400+
doc = "A variant of `rust_library` that uses a minimal process wrapper for `Rustc` actions.",
1401+
provides = COMMON_PROVIDERS + [_RustBuiltWithoutProcessWrapperInfo],
13781402
attrs = dict(_common_attrs_for_binary_without_process_wrapper(_common_attrs).items()),
13791403
fragments = ["cpp"],
13801404
toolchains = [
13811405
str(Label("//rust:toolchain_type")),
1382-
"@bazel_tools//tools/cpp:toolchain_type",
1406+
config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False),
1407+
],
1408+
)
1409+
1410+
def _test_attrs_for_binary_without_process_wrapper(attrs):
1411+
new_attrs = {}
1412+
new_attrs.update(attrs)
1413+
1414+
# Require that `crate` has the correct internal provider.
1415+
new_attrs["crate"] = attr.label(
1416+
mandatory = False,
1417+
providers = [_RustBuiltWithoutProcessWrapperInfo],
1418+
doc = dedent("""\
1419+
Target inline tests declared in the given crate
1420+
1421+
These tests are typically those that would be held out under
1422+
`#[cfg(test)]` declarations.
1423+
"""),
1424+
)
1425+
1426+
return new_attrs
1427+
1428+
def _rust_test_without_process_wrapper_test_impl(ctx):
1429+
if ctx.attr.srcs:
1430+
fail("`rust_test_without_process_wrapper_test.srcs` is not allowed. Remove it from {}".format(
1431+
ctx.label,
1432+
))
1433+
providers = _rust_test_impl(ctx)
1434+
return providers
1435+
1436+
rust_test_without_process_wrapper_test = rule(
1437+
implementation = _rust_test_without_process_wrapper_test_impl,
1438+
doc = "Unlike other `*_without_process_wrapper` rules, this rule does use the process wrapper but requires it's dependencies were not built with one.",
1439+
provides = COMMON_PROVIDERS,
1440+
attrs = _test_attrs_for_binary_without_process_wrapper(_common_attrs | _rust_test_attrs),
1441+
executable = True,
1442+
cfg = _rust_binary_without_process_wrapper_transition,
1443+
fragments = ["cpp"],
1444+
test = True,
1445+
toolchains = [
1446+
str(Label("//rust:toolchain_type")),
1447+
config_common.toolchain_type("@bazel_tools//tools/cpp:toolchain_type", mandatory = False),
13831448
],
13841449
)
13851450

rust/repositories.bzl

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,18 @@ load_arbitrary_tool = _load_arbitrary_tool
4343
# Note: Code in `.github/workflows/crate_universe.yaml` looks for this line, if you remove it or change its format, you will also need to update that code.
4444
DEFAULT_TOOLCHAIN_TRIPLES = {
4545
"aarch64-apple-darwin": "rust_macos_aarch64",
46+
# "aarch64-pc-windows-gnu": "rust_windows_aarch64_gnu",
4647
"aarch64-pc-windows-msvc": "rust_windows_aarch64",
4748
"aarch64-unknown-linux-gnu": "rust_linux_aarch64",
49+
# "aarch64-unknown-linux-musl": "rust_linux_aarch64_gnu",
4850
"powerpc64le-unknown-linux-gnu": "rust_linux_powerpc64le",
4951
"s390x-unknown-linux-gnu": "rust_linux_s390x",
5052
"x86_64-apple-darwin": "rust_macos_x86_64",
53+
# "x86_64-pc-windows-gnu": "rust_windows_x86_64_gnu",
5154
"x86_64-pc-windows-msvc": "rust_windows_x86_64",
5255
"x86_64-unknown-freebsd": "rust_freebsd_x86_64",
5356
"x86_64-unknown-linux-gnu": "rust_linux_x86_64",
57+
# "x86_64-unknown-linux-musl": "rust_linux_x86_64_musl",
5458
}
5559

5660
_COMPACT_WINDOWS_NAMES = True
@@ -234,6 +238,7 @@ def rust_register_toolchains(
234238
toolchain_names = []
235239
toolchain_labels = {}
236240
toolchain_target_settings = {}
241+
toolchain_target_settings_select = {}
237242
toolchain_types = {}
238243
exec_compatible_with_by_toolchain = {}
239244
target_compatible_with_by_toolchain = {}
@@ -295,6 +300,7 @@ def rust_register_toolchains(
295300
target_compatible_with_by_toolchain[toolchain.name] = toolchain.target_constraints
296301
toolchain_types[toolchain.name] = "@rules_rust//rust:toolchain"
297302
toolchain_target_settings[toolchain.name] = ["@rules_rust//rust/toolchain/channel:{}".format(toolchain.channel.name)] + target_settings
303+
toolchain_target_settings_select[toolchain.name] = _get_abi_target_settings_select(toolchain.target_triple)
298304

299305
for exec_triple, name in rustfmt_toolchain_triples.items():
300306
rustfmt_repo_name = "rustfmt_{}__{}".format(rustfmt_version.replace("/", "-"), exec_triple)
@@ -319,6 +325,7 @@ def rust_register_toolchains(
319325
toolchain_labels[rustfmt_repo_name] = "@{}_tools//:rustfmt_toolchain".format(rustfmt_repo_name)
320326
exec_compatible_with_by_toolchain[rustfmt_repo_name] = triple_to_constraint_set(exec_triple)
321327
target_compatible_with_by_toolchain[rustfmt_repo_name] = []
328+
toolchain_target_settings_select[rustfmt_repo_name] = {}
322329
toolchain_types[rustfmt_repo_name] = "@rules_rust//rust/rustfmt:toolchain_type"
323330

324331
if aliases:
@@ -332,6 +339,7 @@ def rust_register_toolchains(
332339
exec_compatible_with_by_toolchain[name] = info["exec_compatible_with"]
333340
target_compatible_with_by_toolchain[name] = info["target_compatible_with"]
334341
toolchain_target_settings[name] = info["target_settings"]
342+
toolchain_target_settings_select[name] = info["target_settings_select"]
335343
toolchain_types[name] = info["toolchain_type"]
336344

337345
toolchain_repository_hub(
@@ -340,6 +348,7 @@ def rust_register_toolchains(
340348
toolchain_labels = toolchain_labels,
341349
toolchain_types = toolchain_types,
342350
target_settings = toolchain_target_settings,
351+
target_settings_select = json.encode(toolchain_target_settings_select),
343352
exec_compatible_with = exec_compatible_with_by_toolchain,
344353
target_compatible_with = target_compatible_with_by_toolchain,
345354
)
@@ -590,6 +599,7 @@ def _toolchain_repository_proxy_impl(repository_ctx):
590599
name = "toolchain",
591600
toolchain = repository_ctx.attr.toolchain,
592601
target_settings = repository_ctx.attr.target_settings,
602+
target_settings_select = repository_ctx.attr.target_settings_select,
593603
toolchain_type = repository_ctx.attr.toolchain_type,
594604
target_compatible_with = repository_ctx.attr.target_compatible_with,
595605
exec_compatible_with = repository_ctx.attr.exec_compatible_with,
@@ -610,6 +620,9 @@ toolchain_repository_proxy = repository_rule(
610620
"target_settings": attr.string_list(
611621
doc = "A list of config_settings that must be satisfied by the target configuration in order for this toolchain to be selected during toolchain resolution.",
612622
),
623+
"target_settings_select": attr.string_list_dict(
624+
doc = "A dictionary mapping config_setting labels to lists of additional target_settings, used to generate a select() statement. If empty, no select() is generated.",
625+
),
613626
"toolchain": attr.string(
614627
doc = "The name of the toolchain implementation target.",
615628
mandatory = True,
@@ -625,6 +638,42 @@ toolchain_repository_proxy = repository_rule(
625638
# For legacy support
626639
rust_toolchain_repository_proxy = toolchain_repository_proxy
627640

641+
def _get_abi_target_settings_select(target_triple):
642+
"""Returns the ABI-specific config_settings for use in a select() statement.
643+
644+
Args:
645+
target_triple (str): The target triple to check
646+
647+
Returns:
648+
dict: A dictionary mapping config_setting labels to lists of target_settings,
649+
for use in a select() statement. Empty dict if no ABI-specific settings apply.
650+
"""
651+
triple_struct = triple(target_triple)
652+
653+
# Check for linux + musl combination
654+
if triple_struct.system == "linux":
655+
return {
656+
"@rules_rust//rust/settings:experimental_use_platform_abi_settings_enabled": [
657+
"@rules_rust//rust/settings:platform_linux_musl_{}".format(
658+
"enabled" if triple_struct.abi == "musl" else "disabled",
659+
),
660+
],
661+
"//conditions:default": [],
662+
}
663+
664+
# Check for windows + gnu combination
665+
if triple_struct.system == "windows":
666+
return {
667+
"@rules_rust//rust/settings:experimental_use_platform_abi_settings_enabled": [
668+
"@rules_rust//rust/settings:platform_windows_gnu_{}".format(
669+
"enabled" if triple_struct.abi == "gnu" else "disabled",
670+
),
671+
],
672+
"//conditions:default": [],
673+
}
674+
675+
return {}
676+
628677
# N.B. A "proxy repository" is needed to allow for registering the toolchain (with constraints)
629678
# without actually downloading the toolchain.
630679
def rust_toolchain_repository(
@@ -718,6 +767,7 @@ def rust_toolchain_repository(
718767
)
719768

720769
channel_target_settings = ["@rules_rust//rust/toolchain/channel:{}".format(channel)] if channel else []
770+
abi_target_settings_select = _get_abi_target_settings_select(target_triple)
721771

722772
tools_toolchain_label = "@{}//:rust_toolchain".format(tools_repo_name)
723773

@@ -727,6 +777,7 @@ def rust_toolchain_repository(
727777
name = name,
728778
toolchain = tools_toolchain_label,
729779
target_settings = channel_target_settings + target_settings,
780+
target_settings_select = abi_target_settings_select,
730781
toolchain_type = toolchain_type,
731782
exec_compatible_with = exec_compatible_with,
732783
target_compatible_with = target_compatible_with,
@@ -736,7 +787,8 @@ def rust_toolchain_repository(
736787
"exec_compatible_with": exec_compatible_with,
737788
"name": name,
738789
"target_compatible_with": target_compatible_with,
739-
"target_settings": target_settings,
790+
"target_settings": channel_target_settings + target_settings,
791+
"target_settings_select": abi_target_settings_select,
740792
"toolchain_label": "@{name}//:toolchain".format(name = name),
741793
"toolchain_type": toolchain_type,
742794
"tools_toolchain_label": tools_toolchain_label,

0 commit comments

Comments
 (0)