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