xref: /aosp_15_r20/external/bazelbuild-rules_rust/rust/platform/triple.bzl (revision d4726bddaa87cc4778e7472feed243fa4b6c267f)
1*d4726bddSHONG Yifan"""Triples are a way to define information about a platform/system. This module provides
2*d4726bddSHONG Yifana way to convert a triple string into a well structured object to avoid constant string
3*d4726bddSHONG Yifanparsing in starlark code, and a way for a repository_rule to extract the target triple
4*d4726bddSHONG Yifanof the host platform.
5*d4726bddSHONG Yifan
6*d4726bddSHONG YifanTriples can be described at the following link:
7*d4726bddSHONG Yifanhttps://clang.llvm.org/docs/CrossCompilation.html#target-triple
8*d4726bddSHONG Yifan"""
9*d4726bddSHONG Yifan
10*d4726bddSHONG Yifandef triple(triple):
11*d4726bddSHONG Yifan    """Constructs a struct containing each component of the provided triple
12*d4726bddSHONG Yifan
13*d4726bddSHONG Yifan    Args:
14*d4726bddSHONG Yifan        triple (str): A platform triple. eg: `x86_64-unknown-linux-gnu`
15*d4726bddSHONG Yifan
16*d4726bddSHONG Yifan    Returns:
17*d4726bddSHONG Yifan        struct:
18*d4726bddSHONG Yifan            - arch (str): The triple's CPU architecture
19*d4726bddSHONG Yifan            - vendor (str): The vendor of the system
20*d4726bddSHONG Yifan            - system (str): The name of the system
21*d4726bddSHONG Yifan            - abi (str, optional): The abi to use or None if abi does not apply.
22*d4726bddSHONG Yifan            - str (str): Original string representation of the triple
23*d4726bddSHONG Yifan    """
24*d4726bddSHONG Yifan    if triple == "wasm32-wasi":
25*d4726bddSHONG Yifan        return struct(
26*d4726bddSHONG Yifan            arch = "wasm32",
27*d4726bddSHONG Yifan            system = "wasi",
28*d4726bddSHONG Yifan            vendor = "wasi",
29*d4726bddSHONG Yifan            abi = None,
30*d4726bddSHONG Yifan            str = triple,
31*d4726bddSHONG Yifan        )
32*d4726bddSHONG Yifan    elif triple in ("aarch64-fuchsia", "x86_64-fuchsia"):
33*d4726bddSHONG Yifan        return struct(
34*d4726bddSHONG Yifan            arch = triple.split("-")[0],
35*d4726bddSHONG Yifan            system = "fuchsia",
36*d4726bddSHONG Yifan            vendor = "fuchsia",
37*d4726bddSHONG Yifan            abi = None,
38*d4726bddSHONG Yifan            str = triple,
39*d4726bddSHONG Yifan        )
40*d4726bddSHONG Yifan
41*d4726bddSHONG Yifan    component_parts = triple.split("-")
42*d4726bddSHONG Yifan    if len(component_parts) < 3:
43*d4726bddSHONG Yifan        fail("Expected target triple to contain at least three sections separated by '-'")
44*d4726bddSHONG Yifan
45*d4726bddSHONG Yifan    cpu_arch = component_parts[0]
46*d4726bddSHONG Yifan    vendor = component_parts[1]
47*d4726bddSHONG Yifan    system = component_parts[2]
48*d4726bddSHONG Yifan    abi = None
49*d4726bddSHONG Yifan
50*d4726bddSHONG Yifan    if cpu_arch.startswith(("thumbv8m", "thumbv7m", "thumbv7e", "thumbv6m")):
51*d4726bddSHONG Yifan        abi = system
52*d4726bddSHONG Yifan        system = vendor
53*d4726bddSHONG Yifan        vendor = None
54*d4726bddSHONG Yifan
55*d4726bddSHONG Yifan    if system == "androideabi":
56*d4726bddSHONG Yifan        system = "android"
57*d4726bddSHONG Yifan        abi = "eabi"
58*d4726bddSHONG Yifan
59*d4726bddSHONG Yifan    if len(component_parts) == 4:
60*d4726bddSHONG Yifan        abi = component_parts[3]
61*d4726bddSHONG Yifan
62*d4726bddSHONG Yifan    return struct(
63*d4726bddSHONG Yifan        arch = cpu_arch,
64*d4726bddSHONG Yifan        vendor = vendor,
65*d4726bddSHONG Yifan        system = system,
66*d4726bddSHONG Yifan        abi = abi,
67*d4726bddSHONG Yifan        str = triple,
68*d4726bddSHONG Yifan    )
69*d4726bddSHONG Yifan
70*d4726bddSHONG Yifandef _validate_cpu_architecture(arch, expected_archs):
71*d4726bddSHONG Yifan    """Validate the host CPU architecture
72*d4726bddSHONG Yifan
73*d4726bddSHONG Yifan    Args:
74*d4726bddSHONG Yifan        arch (string): a CPU architecture
75*d4726bddSHONG Yifan        expected_archs (list): A list of expected architecture strings
76*d4726bddSHONG Yifan    """
77*d4726bddSHONG Yifan    if arch not in expected_archs:
78*d4726bddSHONG Yifan        fail("{} is not a expected cpu architecture {}".format(
79*d4726bddSHONG Yifan            arch,
80*d4726bddSHONG Yifan            expected_archs,
81*d4726bddSHONG Yifan        ))
82*d4726bddSHONG Yifan
83*d4726bddSHONG Yifandef get_host_triple(repository_ctx, abi = None):
84*d4726bddSHONG Yifan    """Query host information for the appropriate triple to use with load_arbitrary_tool or the crate_universe resolver
85*d4726bddSHONG Yifan
86*d4726bddSHONG Yifan    Example:
87*d4726bddSHONG Yifan
88*d4726bddSHONG Yifan    ```python
89*d4726bddSHONG Yifan    load("@rules_rust//rust:repositories.bzl", "load_arbitrary_tool")
90*d4726bddSHONG Yifan    load("@rules_rust//rust/platform:triple.bzl", "get_host_triple")
91*d4726bddSHONG Yifan
92*d4726bddSHONG Yifan    def _impl(repository_ctx):
93*d4726bddSHONG Yifan        host_triple = get_host_triple(repository_ctx)
94*d4726bddSHONG Yifan
95*d4726bddSHONG Yifan        load_arbitrary_tool(
96*d4726bddSHONG Yifan            ctx = repository_ctx,
97*d4726bddSHONG Yifan            tool_name = "cargo",
98*d4726bddSHONG Yifan            tool_subdirectories = ["cargo"],
99*d4726bddSHONG Yifan            target_triple = host_triple.str,
100*d4726bddSHONG Yifan        )
101*d4726bddSHONG Yifan
102*d4726bddSHONG Yifan    example = repository_rule(implementation = _impl)
103*d4726bddSHONG Yifan    ```
104*d4726bddSHONG Yifan
105*d4726bddSHONG Yifan    Args:
106*d4726bddSHONG Yifan        repository_ctx (repository_ctx): The repository_rule's context object
107*d4726bddSHONG Yifan        abi (str): Since there's no consistent way to check for ABI, this info
108*d4726bddSHONG Yifan            may be explicitly provided
109*d4726bddSHONG Yifan
110*d4726bddSHONG Yifan    Returns:
111*d4726bddSHONG Yifan        struct: A triple struct; see the `triple` function in this module
112*d4726bddSHONG Yifan    """
113*d4726bddSHONG Yifan
114*d4726bddSHONG Yifan    # Detect the host's cpu architecture
115*d4726bddSHONG Yifan
116*d4726bddSHONG Yifan    supported_architectures = {
117*d4726bddSHONG Yifan        "linux": ["aarch64", "x86_64"],
118*d4726bddSHONG Yifan        "macos": ["aarch64", "x86_64"],
119*d4726bddSHONG Yifan        "windows": ["aarch64", "x86_64"],
120*d4726bddSHONG Yifan    }
121*d4726bddSHONG Yifan
122*d4726bddSHONG Yifan    arch = repository_ctx.os.arch
123*d4726bddSHONG Yifan    if arch == "amd64":
124*d4726bddSHONG Yifan        arch = "x86_64"
125*d4726bddSHONG Yifan
126*d4726bddSHONG Yifan    if "linux" in repository_ctx.os.name:
127*d4726bddSHONG Yifan        _validate_cpu_architecture(arch, supported_architectures["linux"])
128*d4726bddSHONG Yifan        return triple("{}-unknown-linux-{}".format(
129*d4726bddSHONG Yifan            arch,
130*d4726bddSHONG Yifan            abi or "gnu",
131*d4726bddSHONG Yifan        ))
132*d4726bddSHONG Yifan
133*d4726bddSHONG Yifan    if "mac" in repository_ctx.os.name:
134*d4726bddSHONG Yifan        _validate_cpu_architecture(arch, supported_architectures["macos"])
135*d4726bddSHONG Yifan        return triple("{}-apple-darwin".format(arch))
136*d4726bddSHONG Yifan
137*d4726bddSHONG Yifan    if "win" in repository_ctx.os.name:
138*d4726bddSHONG Yifan        _validate_cpu_architecture(arch, supported_architectures["windows"])
139*d4726bddSHONG Yifan        return triple("{}-pc-windows-{}".format(
140*d4726bddSHONG Yifan            arch,
141*d4726bddSHONG Yifan            abi or "msvc",
142*d4726bddSHONG Yifan        ))
143*d4726bddSHONG Yifan
144*d4726bddSHONG Yifan    fail("Unhandled host os: {}", repository_ctx.os.name)
145