| """Triples are a way to define information about a platform/system. This module provides |
| a way to convert a triple string into a well structured object to avoid constant string |
| parsing in starlark code, and a way for a repository_rule to extract the target triple |
| of the host platform. |
| |
| Triples can be described at the following link: |
| https://clang.llvm.org/docs/CrossCompilation.html#target-triple |
| """ |
| |
| def triple(triple): |
| """Constructs a struct containing each component of the provided triple |
| |
| Args: |
| triple (str): A platform triple. eg: `x86_64-unknown-linux-gnu` |
| |
| Returns: |
| struct: |
| - arch (str): The triple's CPU architecture |
| - vendor (str): The vendor of the system |
| - system (str): The name of the system |
| - abi (str, optional): The abi to use or None if abi does not apply. |
| - str (str): Original string representation of the triple |
| """ |
| if triple == "wasm32-wasi": |
| return struct( |
| arch = "wasm32", |
| system = "wasi", |
| vendor = "wasi", |
| abi = None, |
| str = triple, |
| ) |
| elif triple in ("aarch64-fuchsia", "x86_64-fuchsia"): |
| return struct( |
| arch = triple.split("-")[0], |
| system = "fuchsia", |
| vendor = "fuchsia", |
| abi = None, |
| str = triple, |
| ) |
| |
| component_parts = triple.split("-") |
| if len(component_parts) < 3: |
| fail("Expected target triple to contain at least three sections separated by '-'") |
| |
| cpu_arch = component_parts[0] |
| vendor = component_parts[1] |
| system = component_parts[2] |
| abi = None |
| |
| if cpu_arch.startswith(("thumbv8m", "thumbv7m", "thumbv7e", "thumbv6m")): |
| abi = system |
| system = vendor |
| vendor = None |
| |
| if system == "androideabi": |
| system = "android" |
| abi = "eabi" |
| |
| if len(component_parts) == 4: |
| abi = component_parts[3] |
| |
| return struct( |
| arch = cpu_arch, |
| vendor = vendor, |
| system = system, |
| abi = abi, |
| str = triple, |
| ) |
| |
| def _validate_cpu_architecture(arch, expected_archs): |
| """Validate the host CPU architecture |
| |
| Args: |
| arch (string): a CPU architecture |
| expected_archs (list): A list of expected architecture strings |
| """ |
| if arch not in expected_archs: |
| fail("{} is not a expected cpu architecture {}".format( |
| arch, |
| expected_archs, |
| )) |
| |
| def get_host_triple(repository_ctx, abi = None): |
| """Query host information for the appropriate triple to use with load_arbitrary_tool or the crate_universe resolver |
| |
| Example: |
| |
| ```python |
| load("@rules_rust//rust:repositories.bzl", "load_arbitrary_tool") |
| load("@rules_rust//rust/platform:triple.bzl", "get_host_triple") |
| |
| def _impl(repository_ctx): |
| host_triple = get_host_triple(repository_ctx) |
| |
| load_arbitrary_tool( |
| ctx = repository_ctx, |
| tool_name = "cargo", |
| tool_subdirectories = ["cargo"], |
| target_triple = host_triple.str, |
| ) |
| |
| example = repository_rule(implementation = _impl) |
| ``` |
| |
| Args: |
| repository_ctx (repository_ctx): The repository_rule's context object |
| abi (str): Since there's no consistent way to check for ABI, this info |
| may be explicitly provided |
| |
| Returns: |
| struct: A triple struct; see the `triple` function in this module |
| """ |
| |
| # Detect the host's cpu architecture |
| |
| supported_architectures = { |
| "linux": ["aarch64", "x86_64", "s390x"], |
| "macos": ["aarch64", "x86_64"], |
| "windows": ["aarch64", "x86_64"], |
| } |
| |
| arch = repository_ctx.os.arch |
| if arch == "amd64": |
| arch = "x86_64" |
| |
| if "linux" in repository_ctx.os.name: |
| _validate_cpu_architecture(arch, supported_architectures["linux"]) |
| return triple("{}-unknown-linux-{}".format( |
| arch, |
| abi or "gnu", |
| )) |
| |
| if "mac" in repository_ctx.os.name: |
| _validate_cpu_architecture(arch, supported_architectures["macos"]) |
| return triple("{}-apple-darwin".format(arch)) |
| |
| if "win" in repository_ctx.os.name: |
| _validate_cpu_architecture(arch, supported_architectures["windows"]) |
| return triple("{}-pc-windows-{}".format( |
| arch, |
| abi or "msvc", |
| )) |
| |
| fail("Unhandled host os: {}", repository_ctx.os.name) |