Skip to content

Commit 58627f5

Browse files
authored
Make get_host_triple public to get a triple from Bazel's repository_ctx (#1289)
I found half-baked duplicate implementations of this logic in cargo-raze, in cxx, and in rules_rust's test suite of the load_arbitrary_tool function. It seems such logic is necessary for correctly using load_arbitrary_tool from the implementation of a repository_rule.
1 parent 612f436 commit 58627f5

File tree

6 files changed

+137
-121
lines changed

6 files changed

+137
-121
lines changed

cargo/cargo_bootstrap.bzl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""The `cargo_bootstrap` rule is used for bootstrapping cargo binaries in a repository rule."""
22

3-
load("//cargo/private:cargo_utils.bzl", "get_host_triple", "get_rust_tools")
3+
load("//cargo/private:cargo_utils.bzl", "get_rust_tools")
44
load("//rust:defs.bzl", "rust_common")
5+
load("//rust/platform:triple.bzl", "get_host_triple")
56

67
_CARGO_BUILD_MODES = [
78
"release",

cargo/private/cargo_utils.bzl

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,7 @@
11
"""Utility functions for the cargo rules"""
22

3-
load("//rust/platform:triple.bzl", "triple")
43
load("//rust/platform:triple_mappings.bzl", "system_to_binary_ext")
54

6-
_CPU_ARCH_ERROR_MSG = """\
7-
Command failed with exit code '{code}': {args}
8-
----------stdout:
9-
{stdout}
10-
----------stderr:
11-
{stderr}
12-
"""
13-
14-
def _query_cpu_architecture(repository_ctx, expected_archs, is_windows = False):
15-
"""Detect the host CPU architecture
16-
17-
Args:
18-
repository_ctx (repository_ctx): The repository rule's context object
19-
expected_archs (list): A list of expected architecture strings
20-
is_windows (bool, optional): If true, the cpu lookup will use the windows method (`wmic` vs `uname`)
21-
22-
Returns:
23-
str: The host's CPU architecture
24-
"""
25-
if is_windows:
26-
arguments = ["wmic", "os", "get", "osarchitecture"]
27-
else:
28-
arguments = ["uname", "-m"]
29-
30-
result = repository_ctx.execute(arguments)
31-
32-
if result.return_code:
33-
fail(_CPU_ARCH_ERROR_MSG.format(
34-
code = result.return_code,
35-
args = arguments,
36-
stdout = result.stdout,
37-
stderr = result.stderr,
38-
))
39-
40-
if is_windows:
41-
# Example output:
42-
# OSArchitecture
43-
# 64-bit
44-
lines = result.stdout.split("\n")
45-
arch = lines[1].strip()
46-
47-
# Translate 64-bit to a compatible rust platform
48-
# https://doc.rust-lang.org/nightly/rustc/platform-support.html
49-
if arch == "64-bit":
50-
arch = "x86_64"
51-
else:
52-
arch = result.stdout.strip("\n")
53-
54-
# Correct the arm architecture for macos
55-
if "mac" in repository_ctx.os.name and arch == "arm64":
56-
arch = "aarch64"
57-
58-
if not arch in expected_archs:
59-
fail("{} is not a expected cpu architecture {}\n{}".format(
60-
arch,
61-
expected_archs,
62-
result.stdout,
63-
))
64-
65-
return arch
66-
67-
def get_host_triple(repository_ctx, abi = None):
68-
"""Query host information for the appropriate triples for the crate_universe resolver
69-
70-
Args:
71-
repository_ctx (repository_ctx): The rule's repository_ctx
72-
abi (str): Since there's no consistent way to check for ABI, this info
73-
may be explicitly provided
74-
75-
Returns:
76-
struct: A triple struct, see `@rules_rust//rust/platform:triple.bzl`
77-
"""
78-
79-
# Detect the host's cpu architecture
80-
81-
supported_architectures = {
82-
"linux": ["aarch64", "x86_64"],
83-
"macos": ["aarch64", "x86_64"],
84-
"windows": ["x86_64"],
85-
}
86-
87-
if "linux" in repository_ctx.os.name:
88-
cpu = _query_cpu_architecture(repository_ctx, supported_architectures["linux"])
89-
return triple("{}-unknown-linux-{}".format(
90-
cpu,
91-
abi or "gnu",
92-
))
93-
94-
if "mac" in repository_ctx.os.name:
95-
cpu = _query_cpu_architecture(repository_ctx, supported_architectures["macos"])
96-
return triple("{}-apple-darwin".format(cpu))
97-
98-
if "win" in repository_ctx.os.name:
99-
cpu = _query_cpu_architecture(repository_ctx, supported_architectures["windows"], True)
100-
return triple("{}-pc-windows-{}".format(
101-
cpu,
102-
abi or "msvc",
103-
))
104-
105-
fail("Unhandled host os: {}", repository_ctx.os.name)
106-
1075
def _resolve_repository_template(
1086
template,
1097
abi = None,

crate_universe/private/common_utils.bzl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
"""Common utilities useful for unifying the behavior of different parts of `cargo-bazel`."""
22

33
# buildifier: disable=bzl-visibility
4-
load(
5-
"//cargo/private:cargo_utils.bzl",
6-
_get_host_triple = "get_host_triple",
7-
_rust_get_rust_tools = "get_rust_tools",
8-
)
4+
load("//cargo/private:cargo_utils.bzl", _rust_get_rust_tools = "get_rust_tools")
5+
load("//rust/platform:triple.bzl", _get_host_triple = "get_host_triple")
96

107
get_host_triple = _get_host_triple
118

crate_universe/private/crates_repository.bzl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""`crates_repository` rule implementation"""
22

3-
load("//crate_universe/private:common_utils.bzl", "get_host_triple", "get_rust_tools")
3+
load("//crate_universe/private:common_utils.bzl", "get_rust_tools")
44
load(
55
"//crate_universe/private:generate_utils.bzl",
66
"CRATES_REPOSITORY_ENVIRON",
@@ -17,6 +17,7 @@ load(
1717
)
1818
load("//crate_universe/private:urls.bzl", "CARGO_BAZEL_SHA256S", "CARGO_BAZEL_URLS")
1919
load("//rust:defs.bzl", "rust_common")
20+
load("//rust/platform:triple.bzl", "get_host_triple")
2021
load("//rust/platform:triple_mappings.bzl", "SUPPORTED_PLATFORM_TRIPLES")
2122

2223
def _crates_repository_impl(repository_ctx):

rust/platform/triple.bzl

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Triples are a way to define information about a platform/system. This module provides
22
a way to convert a triple string into a well structured object to avoid constant string
3-
parsing in starlark code.
3+
parsing in starlark code, and a way for a repository_rule to extract the target triple
4+
of the host platform.
45
56
Triples can be described at the following link:
67
https://clang.llvm.org/docs/CrossCompilation.html#target-triple
@@ -18,14 +19,16 @@ def triple(triple):
1819
- vendor (str): The vendor of the system
1920
- system (str): The name of the system
2021
- abi (str, optional): The abi to use or None if abi does not apply.
21-
- triple (str): The original triple
22+
- str (str): Original string representation of the triple
23+
- triple (str): Deprecated; same as str
2224
"""
2325
if triple == "wasm32-wasi":
2426
return struct(
2527
arch = "wasm32",
2628
system = "wasi",
2729
vendor = "wasi",
2830
abi = None,
31+
str = triple,
2932
triple = triple,
3033
)
3134

@@ -50,5 +53,126 @@ def triple(triple):
5053
vendor = vendor,
5154
system = system,
5255
abi = abi,
56+
str = triple,
5357
triple = triple,
5458
)
59+
60+
_CPU_ARCH_ERROR_MSG = """\
61+
Command failed with exit code '{code}': {args}
62+
----------stdout:
63+
{stdout}
64+
----------stderr:
65+
{stderr}
66+
"""
67+
68+
def _query_cpu_architecture(repository_ctx, expected_archs, is_windows = False):
69+
"""Detect the host CPU architecture
70+
71+
Args:
72+
repository_ctx (repository_ctx): The repository_rule's context object
73+
expected_archs (list): A list of expected architecture strings
74+
is_windows (bool, optional): If true, the cpu lookup will use the windows method (`wmic` vs `uname`)
75+
76+
Returns:
77+
str: The host's CPU architecture
78+
"""
79+
if is_windows:
80+
arguments = ["wmic", "os", "get", "osarchitecture"]
81+
else:
82+
arguments = ["uname", "-m"]
83+
84+
result = repository_ctx.execute(arguments)
85+
86+
if result.return_code:
87+
fail(_CPU_ARCH_ERROR_MSG.format(
88+
code = result.return_code,
89+
args = arguments,
90+
stdout = result.stdout,
91+
stderr = result.stderr,
92+
))
93+
94+
if is_windows:
95+
# Example output:
96+
# OSArchitecture
97+
# 64-bit
98+
lines = result.stdout.split("\n")
99+
arch = lines[1].strip()
100+
101+
# Translate 64-bit to a compatible rust platform
102+
# https://doc.rust-lang.org/nightly/rustc/platform-support.html
103+
if arch == "64-bit":
104+
arch = "x86_64"
105+
else:
106+
arch = result.stdout.strip("\n")
107+
108+
# Correct the arm architecture for macos
109+
if "mac" in repository_ctx.os.name and arch == "arm64":
110+
arch = "aarch64"
111+
112+
if not arch in expected_archs:
113+
fail("{} is not a expected cpu architecture {}\n{}".format(
114+
arch,
115+
expected_archs,
116+
result.stdout,
117+
))
118+
119+
return arch
120+
121+
def get_host_triple(repository_ctx, abi = None):
122+
"""Query host information for the appropriate triple to use with load_arbitrary_tool or the crate_universe resolver
123+
124+
Example:
125+
126+
```python
127+
load("@rules_rust//rust:repositories.bzl", "load_arbitrary_tool")
128+
load("@rules_rust//rust/platform:triple.bzl", "get_host_triple")
129+
130+
def _impl(repository_ctx):
131+
host_triple = get_host_triple(repository_ctx)
132+
133+
load_arbitrary_tool(
134+
ctx = repository_ctx,
135+
tool_name = "cargo",
136+
tool_subdirectories = ["cargo"],
137+
target_triple = host_triple.str,
138+
)
139+
140+
example = repository_rule(implementation = _impl)
141+
```
142+
143+
Args:
144+
repository_ctx (repository_ctx): The repository_rule's context object
145+
abi (str): Since there's no consistent way to check for ABI, this info
146+
may be explicitly provided
147+
148+
Returns:
149+
struct: A triple struct; see the `triple` function in this module
150+
"""
151+
152+
# Detect the host's cpu architecture
153+
154+
supported_architectures = {
155+
"linux": ["aarch64", "x86_64"],
156+
"macos": ["aarch64", "x86_64"],
157+
"windows": ["x86_64"],
158+
}
159+
160+
if "linux" in repository_ctx.os.name:
161+
cpu = _query_cpu_architecture(repository_ctx, supported_architectures["linux"])
162+
return triple("{}-unknown-linux-{}".format(
163+
cpu,
164+
abi or "gnu",
165+
))
166+
167+
if "mac" in repository_ctx.os.name:
168+
cpu = _query_cpu_architecture(repository_ctx, supported_architectures["macos"])
169+
return triple("{}-apple-darwin".format(cpu))
170+
171+
if "win" in repository_ctx.os.name:
172+
cpu = _query_cpu_architecture(repository_ctx, supported_architectures["windows"], True)
173+
return triple("{}-pc-windows-{}".format(
174+
cpu,
175+
abi or "msvc",
176+
))
177+
178+
fail("Unhandled host os: {}", repository_ctx.os.name)

test/load_arbitrary_tool/load_arbitrary_tool_test.bzl

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
# buildifier: disable=module-docstring
22
load("//rust:repositories.bzl", "load_arbitrary_tool")
3+
load("//rust/platform:triple.bzl", "get_host_triple")
4+
load("//rust/platform:triple_mappings.bzl", "system_to_binary_ext")
35

46
def _load_arbitrary_tool_test_impl(repository_ctx):
5-
if "mac" in repository_ctx.os.name:
6-
target_triple = "x86_64-apple-darwin"
7-
cargo_bin = "bin/cargo"
8-
elif "windows" in repository_ctx.os.name:
9-
target_triple = "x86_64-pc-windows-msvc"
10-
cargo_bin = "bin/cargo.exe"
11-
else:
12-
target_triple = "x86_64-unknown-linux-gnu"
13-
cargo_bin = "bin/cargo"
7+
host_triple = get_host_triple(repository_ctx)
8+
cargo_bin = "bin/cargo" + system_to_binary_ext(host_triple.system)
149

1510
# Download cargo
1611
load_arbitrary_tool(
@@ -19,7 +14,7 @@ def _load_arbitrary_tool_test_impl(repository_ctx):
1914
tool_subdirectories = ["cargo"],
2015
version = "1.53.0",
2116
iso_date = None,
22-
target_triple = target_triple,
17+
target_triple = host_triple.str,
2318
)
2419

2520
repo_path = repository_ctx.path(".")

0 commit comments

Comments
 (0)