xref: /aosp_15_r20/external/bazelbuild-rules_rust/rust/platform/triple_mappings.bzl (revision d4726bddaa87cc4778e7472feed243fa4b6c267f)
1"""Helpers for constructing supported Rust platform triples"""
2
3load("//rust/platform:triple.bzl", "triple")
4
5# All T1 Platforms should be supported, but aren't, see inline notes.
6SUPPORTED_T1_PLATFORM_TRIPLES = [
7    "aarch64-unknown-linux-gnu",
8    "aarch64-unknown-nixos-gnu",  # Same as `aarch64-unknown-linux-gnu` but with `@platforms//os:nixos`.
9    "i686-apple-darwin",
10    "i686-pc-windows-msvc",
11    "i686-unknown-linux-gnu",
12    "x86_64-apple-darwin",
13    "x86_64-pc-windows-msvc",
14    "x86_64-unknown-linux-gnu",
15    "x86_64-unknown-nixos-gnu",  # Same as `x86_64-unknown-linux-gnu` but with `@platforms//os:nixos`.
16    # N.B. These "alternative" envs are not supported, as bazel cannot distinguish between them
17    # and others using existing @platforms// config_values
18    #
19    #"i686-pc-windows-gnu",
20    #"x86_64-pc-windows-gnu",
21]
22
23# Some T2 Platforms are supported, provided we have mappings to @platforms// entries.
24# See @rules_rust//rust/platform:triple_mappings.bzl for the complete list.
25SUPPORTED_T2_PLATFORM_TRIPLES = [
26    "aarch64-apple-darwin",
27    "aarch64-apple-ios-sim",
28    "aarch64-apple-ios",
29    "aarch64-fuchsia",
30    "aarch64-linux-android",
31    "aarch64-pc-windows-msvc",
32    "arm-unknown-linux-gnueabi",
33    "armv7-linux-androideabi",
34    "armv7-unknown-linux-gnueabi",
35    "i686-linux-android",
36    "i686-unknown-freebsd",
37    "powerpc-unknown-linux-gnu",
38    "riscv32imc-unknown-none-elf",
39    "riscv64gc-unknown-none-elf",
40    "s390x-unknown-linux-gnu",
41    "thumbv7em-none-eabi",
42    "thumbv8m.main-none-eabi",
43    "wasm32-unknown-unknown",
44    "wasm32-wasi",
45    "x86_64-apple-ios",
46    "x86_64-fuchsia",
47    "x86_64-linux-android",
48    "x86_64-unknown-freebsd",
49    "x86_64-unknown-none",
50]
51
52SUPPORTED_T3_PLATFORM_TRIPLES = [
53    "aarch64-unknown-nto-qnx710",
54]
55
56SUPPORTED_PLATFORM_TRIPLES = SUPPORTED_T1_PLATFORM_TRIPLES + SUPPORTED_T2_PLATFORM_TRIPLES + SUPPORTED_T3_PLATFORM_TRIPLES
57
58# CPUs that map to a "@platforms//cpu entry
59_CPU_ARCH_TO_BUILTIN_PLAT_SUFFIX = {
60    "aarch64": "aarch64",
61    "arm": "arm",
62    "armv7": "armv7",
63    "armv7s": None,
64    "asmjs": None,
65    "i386": "i386",
66    "i586": None,
67    "i686": "x86_32",
68    "le32": None,
69    "mips": None,
70    "mipsel": None,
71    "powerpc": "ppc",
72    "powerpc64": None,
73    "powerpc64le": None,
74    "riscv32": "riscv32",
75    "riscv32imc": "riscv32",
76    "riscv64": "riscv64",
77    "riscv64gc": "riscv64",
78    "s390": None,
79    "s390x": "s390x",
80    "thumbv6m": "armv6-m",
81    "thumbv7em": "armv7e-m",
82    "thumbv7m": "armv7-m",
83    "thumbv8m.main": "armv8-m",
84    "wasm32": None,
85    "x86_64": "x86_64",
86}
87
88# Systems that map to a "@platforms//os entry
89_SYSTEM_TO_BUILTIN_SYS_SUFFIX = {
90    "android": "android",
91    "bitrig": None,
92    "darwin": "osx",
93    "dragonfly": None,
94    "eabi": "none",
95    "eabihf": "none",
96    "emscripten": None,
97    "freebsd": "freebsd",
98    "fuchsia": "fuchsia",
99    "ios": "ios",
100    "linux": "linux",
101    "nacl": None,
102    "netbsd": None,
103    "nixos": "nixos",
104    "none": "none",
105    "nto": "qnx",
106    "openbsd": "openbsd",
107    "solaris": None,
108    "unknown": None,
109    "wasi": None,
110    "windows": "windows",
111}
112
113_SYSTEM_TO_BINARY_EXT = {
114    "android": "",
115    "darwin": "",
116    "eabi": "",
117    "eabihf": "",
118    "emscripten": ".js",
119    "freebsd": "",
120    "fuchsia": "",
121    "ios": "",
122    "linux": "",
123    "nixos": "",
124    "none": "",
125    "nto": "",
126    # This is currently a hack allowing us to have the proper
127    # generated extension for the wasm target, similarly to the
128    # windows target
129    "unknown": ".wasm",
130    "wasi": ".wasm",
131    "windows": ".exe",
132}
133
134_SYSTEM_TO_STATICLIB_EXT = {
135    "android": ".a",
136    "darwin": ".a",
137    "eabi": ".a",
138    "eabihf": ".a",
139    "emscripten": ".js",
140    "freebsd": ".a",
141    "fuchsia": ".a",
142    "ios": ".a",
143    "linux": ".a",
144    "nixos": ".a",
145    "none": ".a",
146    "nto": ".a",
147    "unknown": "",
148    "wasi": "",
149    "windows": ".lib",
150}
151
152_SYSTEM_TO_DYLIB_EXT = {
153    "android": ".so",
154    "darwin": ".dylib",
155    "eabi": ".so",
156    "eabihf": ".so",
157    "emscripten": ".js",
158    "freebsd": ".so",
159    "fuchsia": ".so",
160    "ios": ".dylib",
161    "linux": ".so",
162    "nixos": ".so",
163    "none": ".so",
164    "nto": ".a",
165    "unknown": ".wasm",
166    "wasi": ".wasm",
167    "windows": ".dll",
168}
169
170# See https://github.com/rust-lang/rust/blob/master/src/libstd/build.rs
171_SYSTEM_TO_STDLIB_LINKFLAGS = {
172    # NOTE: Rust stdlib `build.rs` treats android as a subset of linux, rust rules treat android
173    # as its own system.
174    "android": ["-ldl", "-llog"],
175    "bitrig": [],
176    # TODO(gregbowyer): If rust stdlib is compiled for cloudabi with the backtrace feature it
177    # includes `-lunwind` but this might not actually be required.
178    # I am not sure which is the common configuration or how we encode it as a link flag.
179    "cloudabi": ["-lunwind", "-lc", "-lcompiler_rt"],
180    "darwin": ["-lSystem", "-lresolv"],
181    "dragonfly": ["-lpthread"],
182    "eabi": [],
183    "eabihf": [],
184    "emscripten": [],
185    # TODO(bazelbuild/rules_cc#75):
186    #
187    # Right now bazel cc rules does not specify the exact flag setup needed for calling out system
188    # libs, that is we dont know given a toolchain if it should be, for example,
189    # `-lxxx` or `/Lxxx` or `xxx.lib` etc.
190    #
191    # We include the flag setup as they are _commonly seen_ on various platforms with a cc_rules
192    # style override for people doing things like gnu-mingw on windows.
193    #
194    # If you are reading this ... sorry! set the env var `BAZEL_RUST_STDLIB_LINKFLAGS` to
195    # what you need for your specific setup, for example like so
196    # `BAZEL_RUST_STDLIB_LINKFLAGS="-ladvapi32:-lws2_32:-luserenv"`
197    "freebsd": ["-lexecinfo", "-lpthread"],
198    "fuchsia": ["-lzircon", "-lfdio"],
199    "illumos": ["-lsocket", "-lposix4", "-lpthread", "-lresolv", "-lnsl", "-lumem"],
200    "ios": ["-lSystem", "-lobjc", "-Wl,-framework,Security", "-Wl,-framework,Foundation", "-lresolv"],
201    # TODO: This ignores musl. Longer term what does Bazel think about musl?
202    "linux": ["-ldl", "-lpthread"],
203    "nacl": [],
204    "netbsd": ["-lpthread", "-lrt"],
205    "nixos": ["-ldl", "-lpthread"],  # Same as `linux`.
206    "none": [],
207    "nto": [],
208    "openbsd": ["-lpthread"],
209    "solaris": ["-lsocket", "-lposix4", "-lpthread", "-lresolv"],
210    "unknown": [],
211    "uwp": ["ws2_32.lib"],
212    "wasi": [],
213    "windows": ["advapi32.lib", "ws2_32.lib", "userenv.lib", "Bcrypt.lib"],
214}
215
216def cpu_arch_to_constraints(cpu_arch, *, system = None):
217    """Returns a list of contraint values which represents a triple's CPU.
218
219    Args:
220        cpu_arch (str): The architecture to match constraints for
221        system (str, optional): The system for the associated ABI value.
222
223    Returns:
224        List: A list of labels to constraint values
225    """
226    if cpu_arch not in _CPU_ARCH_TO_BUILTIN_PLAT_SUFFIX:
227        fail("CPU architecture \"{}\" is not supported by rules_rust".format(cpu_arch))
228
229    plat_suffix = _CPU_ARCH_TO_BUILTIN_PLAT_SUFFIX[cpu_arch]
230
231    # Patch armv7e-m to mf if hardfloat abi is selected
232    if plat_suffix == "armv7e-m" and system == "eabihf":
233        plat_suffix = "armv7e-mf"
234
235    return ["@platforms//cpu:{}".format(plat_suffix)]
236
237def vendor_to_constraints(_vendor):
238    # TODO(acmcarther): Review:
239    #
240    # My current understanding is that vendors can't have a material impact on
241    # constraint sets.
242    return []
243
244def system_to_constraints(system):
245    if system not in _SYSTEM_TO_BUILTIN_SYS_SUFFIX:
246        fail("System \"{}\" is not supported by rules_rust".format(system))
247
248    sys_suffix = _SYSTEM_TO_BUILTIN_SYS_SUFFIX[system]
249
250    return ["@platforms//os:{}".format(sys_suffix)]
251
252def abi_to_constraints(abi, *, arch = None, system = None):
253    """Return a list of constraint values which represents a triple's ABI.
254
255    Note that some ABI values require additional info to accurately match a set of constraints.
256
257    Args:
258        abi (str): The abi value to match constraints for
259        arch (str, optional): The architecture for the associated ABI value.
260        system (str, optional): The system for the associated ABI value.
261
262    Returns:
263        List: A list of labels to constraint values
264    """
265
266    all_abi_constraints = []
267
268    # add constraints for MUSL static compilation and linking
269    # to separate the MUSL from the non-MUSL toolchain on x86_64
270    # if abi == "musl" and system == "linux" and arch == "x86_64":
271    # all_abi_constraints.append("//rust/platform/constraints:musl_on")
272
273    # add constraints for iOS + watchOS simulator and device triples
274    if system in ["ios", "watchos"]:
275        if arch == "x86_64" or abi == "sim":
276            all_abi_constraints.append("@build_bazel_apple_support//constraints:simulator")
277        else:
278            all_abi_constraints.append("@build_bazel_apple_support//constraints:device")
279
280    # TODO(bazelbuild/platforms#38): Implement when C++ toolchain is more mature and we
281    # figure out how they're doing this
282    return all_abi_constraints
283
284def triple_to_system(target_triple):
285    """Returns a system name for a given platform triple
286
287    **Deprecated**: Use triple() from triple.bzl directly.
288
289    Args:
290        target_triple (str): A platform triple. eg: `x86_64-unknown-linux-gnu`
291
292    Returns:
293        str: A system name
294    """
295    if type(target_triple) == "string":
296        target_triple = triple(target_triple)
297    return target_triple.system
298
299def triple_to_arch(target_triple):
300    """Returns a system architecture name for a given platform triple
301
302    **Deprecated**: Use triple() from triple.bzl directly.
303
304    Args:
305        target_triple (str): A platform triple. eg: `x86_64-unknown-linux-gnu`
306
307    Returns:
308        str: A cpu architecture
309    """
310    if type(target_triple) == "string":
311        target_triple = triple(target_triple)
312    return target_triple.arch
313
314def triple_to_abi(target_triple):
315    """Returns a system abi name for a given platform triple
316
317    **Deprecated**: Use triple() from triple.bzl directly.
318
319    Args:
320        target_triple (str): A platform triple. eg: `x86_64-unknown-linux-gnu`
321
322    Returns:
323        str: The triple's abi
324    """
325    if type(target_triple) == "string":
326        target_triple = triple(target_triple)
327    return target_triple.system
328
329def system_to_dylib_ext(system):
330    return _SYSTEM_TO_DYLIB_EXT[system]
331
332def system_to_staticlib_ext(system):
333    return _SYSTEM_TO_STATICLIB_EXT[system]
334
335def system_to_binary_ext(system):
336    return _SYSTEM_TO_BINARY_EXT[system]
337
338def system_to_stdlib_linkflags(system):
339    return _SYSTEM_TO_STDLIB_LINKFLAGS[system]
340
341def triple_to_constraint_set(target_triple):
342    """Returns a set of constraints for a given platform triple
343
344    Args:
345        target_triple (str): A platform triple. eg: `x86_64-unknown-linux-gnu`
346
347    Returns:
348        list: A list of constraints (each represented by a list of strings)
349    """
350    if target_triple == "wasm32-wasi":
351        return [
352            "@platforms//cpu:wasm32",
353            "@platforms//os:wasi",
354        ]
355    if target_triple == "wasm32-unknown-unknown":
356        return [
357            "@platforms//cpu:wasm32",
358            "@platforms//os:none",
359        ]
360
361    triple_struct = triple(target_triple)
362
363    constraint_set = []
364    constraint_set += cpu_arch_to_constraints(
365        triple_struct.arch,
366        system = triple_struct.system,
367    )
368    constraint_set += vendor_to_constraints(triple_struct.vendor)
369    constraint_set += system_to_constraints(triple_struct.system)
370    constraint_set += abi_to_constraints(
371        triple_struct.abi,
372        arch = triple_struct.arch,
373        system = triple_struct.system,
374    )
375
376    return constraint_set
377