diff options
author | John Hughes <john.hughes@fernride.com> | 2024-02-02 10:51:49 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-02 09:51:49 +0000 |
commit | c06564d1bbd164b0f0561a4a450cb3460f1d5a93 (patch) | |
tree | 9a0fd6dd3c5e5f6ace267d2ee8aeca639ff467ab | |
parent | 0f777e198309a1bc2e5e9c4e71d3e586f6c13530 (diff) | |
download | bazelbuild-rules_rust-c06564d1bbd164b0f0561a4a450cb3460f1d5a93.tar.gz |
Make cross-compiling with bzlmod possible, added example (#2419)
Before it wasn't possible to add your desired cross-compilation targets
to `extra_target_triples` if they also happened to be in
`DEFAULT_TOOLCHAIN_TRIPLES`.
-rw-r--r-- | examples/bzlmod/cross_compile/.bazelrc | 1 | ||||
-rw-r--r-- | examples/bzlmod/cross_compile/.gitignore | 2 | ||||
-rw-r--r-- | examples/bzlmod/cross_compile/BUILD.bazel | 54 | ||||
-rw-r--r-- | examples/bzlmod/cross_compile/MODULE.bazel | 39 | ||||
-rw-r--r-- | examples/bzlmod/cross_compile/README.md | 6 | ||||
-rw-r--r-- | examples/bzlmod/cross_compile/WORKSPACE.bazel | 1 | ||||
-rw-r--r-- | examples/bzlmod/cross_compile/WORKSPACE.bzlmod | 17 | ||||
-rwxr-xr-x | examples/bzlmod/cross_compile/hello_world_test.sh | 38 | ||||
-rw-r--r-- | examples/bzlmod/cross_compile/src/main.rs | 17 | ||||
-rw-r--r-- | examples/bzlmod/hello_world/MODULE.bazel | 1 | ||||
-rw-r--r-- | rust/repositories.bzl | 2 |
11 files changed, 177 insertions, 1 deletions
diff --git a/examples/bzlmod/cross_compile/.bazelrc b/examples/bzlmod/cross_compile/.bazelrc new file mode 100644 index 00000000..e2ece0c3 --- /dev/null +++ b/examples/bzlmod/cross_compile/.bazelrc @@ -0,0 +1 @@ +build --experimental_enable_bzlmod diff --git a/examples/bzlmod/cross_compile/.gitignore b/examples/bzlmod/cross_compile/.gitignore new file mode 100644 index 00000000..2f0f755d --- /dev/null +++ b/examples/bzlmod/cross_compile/.gitignore @@ -0,0 +1,2 @@ +/bazel-* +/MODULE.bazel.lock diff --git a/examples/bzlmod/cross_compile/BUILD.bazel b/examples/bzlmod/cross_compile/BUILD.bazel new file mode 100644 index 00000000..e12afa89 --- /dev/null +++ b/examples/bzlmod/cross_compile/BUILD.bazel @@ -0,0 +1,54 @@ +load("@rules_rust//rust:defs.bzl", "rust_binary") + +package(default_visibility = ["//visibility:public"]) + +rust_binary( + name = "hello_world_aarch64", + srcs = ["src/main.rs"], + platform = ":linux-aarch64", + deps = [], +) + +rust_binary( + name = "hello_world_x86_64", + srcs = ["src/main.rs"], + platform = ":linux-x86_64", + deps = [], +) + +[ + sh_test( + name = "hello_world_{}_test".format(target), + srcs = ["hello_world_test.sh"], + args = [ + "$(rlocationpath :hello_world_{})".format(target), + arch_string, + ], + data = [ + ":hello_world_{}".format(target), + ], + deps = [ + "@bazel_tools//tools/bash/runfiles", + ], + ) + for (target, arch_string) in [ + ("aarch64", "AArch64"), + ("x86_64", "X86-64"), + ] +] + +platform( + name = "linux-aarch64", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + ], +) + +platform( + name = "linux-x86_64", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], +) diff --git a/examples/bzlmod/cross_compile/MODULE.bazel b/examples/bzlmod/cross_compile/MODULE.bazel new file mode 100644 index 00000000..90ed67dc --- /dev/null +++ b/examples/bzlmod/cross_compile/MODULE.bazel @@ -0,0 +1,39 @@ +"""bazelbuild/rules_rust - bzlmod cross-compilation example""" + +module( + name = "cross_compile_example", + version = "0.0.0", +) + +bazel_dep(name = "bazel_skylib", version = "1.5.0") +bazel_dep(name = "platforms", version = "0.0.8") +bazel_dep(name = "toolchains_llvm", version = "0.10.3") + +# rules_rust still needs a cpp toolchain, so provide a cross-compiling one here +llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm") +llvm.toolchain( + name = "llvm_toolchain", + llvm_version = "16.0.0", + sysroot = {"linux-aarch64": "@@org_chromium_sysroot_linux_aarch64//:sysroot"}, +) +use_repo(llvm, "llvm_toolchain", "llvm_toolchain_llvm") + +register_toolchains("@llvm_toolchain//:all") + +bazel_dep(name = "rules_rust", version = "0.0.0") +local_path_override( + module_name = "rules_rust", + path = "../../..", +) + +rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") +rust.toolchain( + edition = "2021", + extra_target_triples = [ + "aarch64-unknown-linux-gnu", + "x86_64-unknown-linux-gnu", + ], +) +use_repo(rust, "rust_toolchains") + +register_toolchains("@rust_toolchains//:all") diff --git a/examples/bzlmod/cross_compile/README.md b/examples/bzlmod/cross_compile/README.md new file mode 100644 index 00000000..14171f31 --- /dev/null +++ b/examples/bzlmod/cross_compile/README.md @@ -0,0 +1,6 @@ +# bzlmod cross-compile example + +This example shows how to use `rules_rust` through bzlmod to invoke Rust cross-compilation. + +It should be possible to `bazel build //:hello_world_aarch64` and `bazel build //:hello_world_x86_64` regardless of your +host platform (as long as it is supported by Bazel and rustc). diff --git a/examples/bzlmod/cross_compile/WORKSPACE.bazel b/examples/bzlmod/cross_compile/WORKSPACE.bazel new file mode 100644 index 00000000..b543b79e --- /dev/null +++ b/examples/bzlmod/cross_compile/WORKSPACE.bazel @@ -0,0 +1 @@ +# Intentionally blank; using bzlmod diff --git a/examples/bzlmod/cross_compile/WORKSPACE.bzlmod b/examples/bzlmod/cross_compile/WORKSPACE.bzlmod new file mode 100644 index 00000000..a32aab23 --- /dev/null +++ b/examples/bzlmod/cross_compile/WORKSPACE.bzlmod @@ -0,0 +1,17 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +_BUILD_FILE_CONTENT = """filegroup( + name = "{name}", + srcs = glob(["*/**"]), + visibility = ["//visibility:public"], +) +""" + +http_archive( + name = "org_chromium_sysroot_linux_aarch64", + sha256 = "902d1a40a5fd8c3764a36c8d377af5945a92e3d264c6252855bda4d7ef81d3df", + url = "https://commondatastorage.googleapis.com/chrome-linux-sysroot/toolchain/{}".format( + "41a6c8dec4c4304d6509e30cbaf9218dffb4438e/debian_bullseye_arm64_sysroot.tar.xz", + ), + build_file_content = _BUILD_FILE_CONTENT.format(name = "sysroot"), +)
\ No newline at end of file diff --git a/examples/bzlmod/cross_compile/hello_world_test.sh b/examples/bzlmod/cross_compile/hello_world_test.sh new file mode 100755 index 00000000..a5b887c7 --- /dev/null +++ b/examples/bzlmod/cross_compile/hello_world_test.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# --- begin runfiles.bash initialization v3 --- +# Copy-pasted from the Bazel Bash runfiles library v3. +set -uo pipefail; set +e; f=bazel_tools/tools/bash/runfiles/runfiles.bash +source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \ + source "$0.runfiles/$f" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \ + { echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e +# --- end runfiles.bash initialization v3 --- + + +set -euo pipefail + +# MARK - Functions + +fail() { + echo >&2 "$@" + exit 1 +} + +# MARK - Args + +if [[ "$#" -ne 2 ]]; then + fail "Usage: $0 /path/to/hello_world expected_arch" +fi +HELLO_WORLD="$(rlocation "$1")" +ARCH_STRING="$2" + +# MARK - Test + +OUTPUT="$(readelf -h "${HELLO_WORLD}")" + +# Match the architecture string with grep. +echo "${OUTPUT}" | grep -E "Machine:(.+)${ARCH_STRING}" || + fail "Expected '${ARCH_STRING}' in ${OUTPUT}" diff --git a/examples/bzlmod/cross_compile/src/main.rs b/examples/bzlmod/cross_compile/src/main.rs new file mode 100644 index 00000000..317f5645 --- /dev/null +++ b/examples/bzlmod/cross_compile/src/main.rs @@ -0,0 +1,17 @@ +// Copyright 2015 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +fn main() { + println!("Hello, world!"); +} diff --git a/examples/bzlmod/hello_world/MODULE.bazel b/examples/bzlmod/hello_world/MODULE.bazel index fdf6a748..121281c5 100644 --- a/examples/bzlmod/hello_world/MODULE.bazel +++ b/examples/bzlmod/hello_world/MODULE.bazel @@ -5,6 +5,7 @@ module( version = "0.0.0", ) +bazel_dep(name = "platforms", version = "0.0.8") bazel_dep( name = "bazel_skylib", version = "1.5.0", diff --git a/rust/repositories.bzl b/rust/repositories.bzl index 610baa79..2a9738e6 100644 --- a/rust/repositories.bzl +++ b/rust/repositories.bzl @@ -858,7 +858,7 @@ rust_toolchain_set_repository = repository_rule( def _get_toolchain_repositories(name, exec_triple, extra_target_triples, versions, iso_date): toolchain_repos = [] - for target_triple in [exec_triple] + extra_target_triples: + for target_triple in depset([exec_triple] + extra_target_triples).to_list(): # Parse all provided versions while checking for duplicates channels = {} for version in versions: |