diff --git a/cargo/cargo_bootstrap.bzl b/cargo/cargo_bootstrap.bzl index bbe35c0548..a839aad08a 100644 --- a/cargo/cargo_bootstrap.bzl +++ b/cargo/cargo_bootstrap.bzl @@ -1,7 +1,8 @@ """The `cargo_bootstrap` rule is used for bootstrapping cargo binaries in a repository rule.""" -load("//cargo/private:cargo_utils.bzl", "get_host_triple", "get_rust_tools") +load("//cargo/private:cargo_utils.bzl", "get_rust_tools") load("//rust:defs.bzl", "rust_common") +load("//rust/platform:triple.bzl", "get_host_triple") _CARGO_BUILD_MODES = [ "release", diff --git a/cargo/private/cargo_utils.bzl b/cargo/private/cargo_utils.bzl index d519576087..2aa26a3928 100644 --- a/cargo/private/cargo_utils.bzl +++ b/cargo/private/cargo_utils.bzl @@ -1,109 +1,7 @@ """Utility functions for the cargo rules""" -load("//rust/platform:triple.bzl", "triple") load("//rust/platform:triple_mappings.bzl", "system_to_binary_ext") -_CPU_ARCH_ERROR_MSG = """\ -Command failed with exit code '{code}': {args} -----------stdout: -{stdout} -----------stderr: -{stderr} -""" - -def _query_cpu_architecture(repository_ctx, expected_archs, is_windows = False): - """Detect the host CPU architecture - - Args: - repository_ctx (repository_ctx): The repository rule's context object - expected_archs (list): A list of expected architecture strings - is_windows (bool, optional): If true, the cpu lookup will use the windows method (`wmic` vs `uname`) - - Returns: - str: The host's CPU architecture - """ - if is_windows: - arguments = ["wmic", "os", "get", "osarchitecture"] - else: - arguments = ["uname", "-m"] - - result = repository_ctx.execute(arguments) - - if result.return_code: - fail(_CPU_ARCH_ERROR_MSG.format( - code = result.return_code, - args = arguments, - stdout = result.stdout, - stderr = result.stderr, - )) - - if is_windows: - # Example output: - # OSArchitecture - # 64-bit - lines = result.stdout.split("\n") - arch = lines[1].strip() - - # Translate 64-bit to a compatible rust platform - # https://doc.rust-lang.org/nightly/rustc/platform-support.html - if arch == "64-bit": - arch = "x86_64" - else: - arch = result.stdout.strip("\n") - - # Correct the arm architecture for macos - if "mac" in repository_ctx.os.name and arch == "arm64": - arch = "aarch64" - - if not arch in expected_archs: - fail("{} is not a expected cpu architecture {}\n{}".format( - arch, - expected_archs, - result.stdout, - )) - - return arch - -def get_host_triple(repository_ctx, abi = None): - """Query host information for the appropriate triples for the crate_universe resolver - - Args: - repository_ctx (repository_ctx): The rule's repository_ctx - abi (str): Since there's no consistent way to check for ABI, this info - may be explicitly provided - - Returns: - struct: A triple struct, see `@rules_rust//rust/platform:triple.bzl` - """ - - # Detect the host's cpu architecture - - supported_architectures = { - "linux": ["aarch64", "x86_64"], - "macos": ["aarch64", "x86_64"], - "windows": ["x86_64"], - } - - if "linux" in repository_ctx.os.name: - cpu = _query_cpu_architecture(repository_ctx, supported_architectures["linux"]) - return triple("{}-unknown-linux-{}".format( - cpu, - abi or "gnu", - )) - - if "mac" in repository_ctx.os.name: - cpu = _query_cpu_architecture(repository_ctx, supported_architectures["macos"]) - return triple("{}-apple-darwin".format(cpu)) - - if "win" in repository_ctx.os.name: - cpu = _query_cpu_architecture(repository_ctx, supported_architectures["windows"], True) - return triple("{}-pc-windows-{}".format( - cpu, - abi or "msvc", - )) - - fail("Unhandled host os: {}", repository_ctx.os.name) - def _resolve_repository_template( template, abi = None, diff --git a/crate_universe/private/common_utils.bzl b/crate_universe/private/common_utils.bzl index ae65b6337a..bf10b213f2 100644 --- a/crate_universe/private/common_utils.bzl +++ b/crate_universe/private/common_utils.bzl @@ -1,11 +1,8 @@ """Common utilities useful for unifying the behavior of different parts of `cargo-bazel`.""" # buildifier: disable=bzl-visibility -load( - "//cargo/private:cargo_utils.bzl", - _get_host_triple = "get_host_triple", - _rust_get_rust_tools = "get_rust_tools", -) +load("//cargo/private:cargo_utils.bzl", _rust_get_rust_tools = "get_rust_tools") +load("//rust/platform:triple.bzl", _get_host_triple = "get_host_triple") get_host_triple = _get_host_triple diff --git a/crate_universe/private/crates_repository.bzl b/crate_universe/private/crates_repository.bzl index a25e3a06e5..a6ebb954ee 100644 --- a/crate_universe/private/crates_repository.bzl +++ b/crate_universe/private/crates_repository.bzl @@ -1,6 +1,6 @@ """`crates_repository` rule implementation""" -load("//crate_universe/private:common_utils.bzl", "get_host_triple", "get_rust_tools") +load("//crate_universe/private:common_utils.bzl", "get_rust_tools") load( "//crate_universe/private:generate_utils.bzl", "CRATES_REPOSITORY_ENVIRON", @@ -17,6 +17,7 @@ load( ) load("//crate_universe/private:urls.bzl", "CARGO_BAZEL_SHA256S", "CARGO_BAZEL_URLS") load("//rust:defs.bzl", "rust_common") +load("//rust/platform:triple.bzl", "get_host_triple") load("//rust/platform:triple_mappings.bzl", "SUPPORTED_PLATFORM_TRIPLES") def _crates_repository_impl(repository_ctx): diff --git a/rust/platform/triple.bzl b/rust/platform/triple.bzl index 13a59a4cab..13a335911c 100644 --- a/rust/platform/triple.bzl +++ b/rust/platform/triple.bzl @@ -1,6 +1,7 @@ """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. +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 @@ -18,7 +19,8 @@ def triple(triple): - 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. - - triple (str): The original triple + - str (str): Original string representation of the triple + - triple (str): Deprecated; same as str """ if triple == "wasm32-wasi": return struct( @@ -26,6 +28,7 @@ def triple(triple): system = "wasi", vendor = "wasi", abi = None, + str = triple, triple = triple, ) @@ -50,5 +53,126 @@ def triple(triple): vendor = vendor, system = system, abi = abi, + str = triple, triple = triple, ) + +_CPU_ARCH_ERROR_MSG = """\ +Command failed with exit code '{code}': {args} +----------stdout: +{stdout} +----------stderr: +{stderr} +""" + +def _query_cpu_architecture(repository_ctx, expected_archs, is_windows = False): + """Detect the host CPU architecture + + Args: + repository_ctx (repository_ctx): The repository_rule's context object + expected_archs (list): A list of expected architecture strings + is_windows (bool, optional): If true, the cpu lookup will use the windows method (`wmic` vs `uname`) + + Returns: + str: The host's CPU architecture + """ + if is_windows: + arguments = ["wmic", "os", "get", "osarchitecture"] + else: + arguments = ["uname", "-m"] + + result = repository_ctx.execute(arguments) + + if result.return_code: + fail(_CPU_ARCH_ERROR_MSG.format( + code = result.return_code, + args = arguments, + stdout = result.stdout, + stderr = result.stderr, + )) + + if is_windows: + # Example output: + # OSArchitecture + # 64-bit + lines = result.stdout.split("\n") + arch = lines[1].strip() + + # Translate 64-bit to a compatible rust platform + # https://doc.rust-lang.org/nightly/rustc/platform-support.html + if arch == "64-bit": + arch = "x86_64" + else: + arch = result.stdout.strip("\n") + + # Correct the arm architecture for macos + if "mac" in repository_ctx.os.name and arch == "arm64": + arch = "aarch64" + + if not arch in expected_archs: + fail("{} is not a expected cpu architecture {}\n{}".format( + arch, + expected_archs, + result.stdout, + )) + + return arch + +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"], + "macos": ["aarch64", "x86_64"], + "windows": ["x86_64"], + } + + if "linux" in repository_ctx.os.name: + cpu = _query_cpu_architecture(repository_ctx, supported_architectures["linux"]) + return triple("{}-unknown-linux-{}".format( + cpu, + abi or "gnu", + )) + + if "mac" in repository_ctx.os.name: + cpu = _query_cpu_architecture(repository_ctx, supported_architectures["macos"]) + return triple("{}-apple-darwin".format(cpu)) + + if "win" in repository_ctx.os.name: + cpu = _query_cpu_architecture(repository_ctx, supported_architectures["windows"], True) + return triple("{}-pc-windows-{}".format( + cpu, + abi or "msvc", + )) + + fail("Unhandled host os: {}", repository_ctx.os.name) diff --git a/test/load_arbitrary_tool/load_arbitrary_tool_test.bzl b/test/load_arbitrary_tool/load_arbitrary_tool_test.bzl index 8906329ff7..495b6bb89a 100644 --- a/test/load_arbitrary_tool/load_arbitrary_tool_test.bzl +++ b/test/load_arbitrary_tool/load_arbitrary_tool_test.bzl @@ -1,16 +1,11 @@ # buildifier: disable=module-docstring load("//rust:repositories.bzl", "load_arbitrary_tool") +load("//rust/platform:triple.bzl", "get_host_triple") +load("//rust/platform:triple_mappings.bzl", "system_to_binary_ext") def _load_arbitrary_tool_test_impl(repository_ctx): - if "mac" in repository_ctx.os.name: - target_triple = "x86_64-apple-darwin" - cargo_bin = "bin/cargo" - elif "windows" in repository_ctx.os.name: - target_triple = "x86_64-pc-windows-msvc" - cargo_bin = "bin/cargo.exe" - else: - target_triple = "x86_64-unknown-linux-gnu" - cargo_bin = "bin/cargo" + host_triple = get_host_triple(repository_ctx) + cargo_bin = "bin/cargo" + system_to_binary_ext(host_triple.system) # Download cargo load_arbitrary_tool( @@ -19,7 +14,7 @@ def _load_arbitrary_tool_test_impl(repository_ctx): tool_subdirectories = ["cargo"], version = "1.53.0", iso_date = None, - target_triple = target_triple, + target_triple = host_triple.str, ) repo_path = repository_ctx.path(".")