diff --git a/MODULE.bazel b/MODULE.bazel index 4574b44d3..21aef3160 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -9,6 +9,7 @@ module( bazel_dep(name = "bazel_skylib", version = "1.8.2") bazel_dep(name = "pigweed") bazel_dep(name = "platforms", version = "1.0.0") +bazel_dep(name = "rules_cc", version = "0.2.22") bazel_dep(name = "rules_rust", version = "0.70.0") bazel_dep(name = "rules_rust_mdbook", version = "0.70.0") bazel_dep(name = "rules_platform", version = "0.1.0") @@ -36,9 +37,27 @@ git_override( pw_rust = use_extension("@pigweed//pw_toolchain/rust:extensions.bzl", "pw_rust") pw_rust.toolchain(cipd_tag = "git_revisions:fe5c95d4ae33ec9d7831921e448e2daf8264ea42,7b074fc9362a4a6a5f172dd8936a22fb25eff96b") -use_repo(pw_rust, "pw_rust_toolchains") +use_repo( + pw_rust, + "pw_rust_toolchains", + # Used by //toolcain/aarch64_linux + "rust_toolchain_host_linux_x86_64", + "rust_toolchain_target_aarch64-unknown-linux-gnu_aarch64", +) + +# Used by //toolcain/aarch64_linux +pw_cxx_toolchain = use_extension("@pigweed//pw_toolchain/cc:pw_cxx_toolchain.bzl", "pw_cxx_toolchain") +use_repo(pw_cxx_toolchain, "llvm_toolchain") + +pw_cipd = use_extension("@pigweed//pw_env_setup/bazel/cipd:defs.bzl", "cipd") +use_repo(pw_cipd, linux_sysroot = "pigweed.linux_sysroot") register_toolchains( + # Must precede host_cc_toolchain_linux and @pw_rust_toolchains//:all, which + # matches any Linux target CPU or any aarch64 platform respectively + "//toolchain/aarch64_linux:cc_toolchain_aarch64_linux", + "//toolchain/aarch64_linux:rust_toolchain_aarch64_linux_nightly", + "//toolchain/aarch64_linux:rust_toolchain_aarch64_linux_stable", "@pigweed//pw_toolchain/host_clang:host_cc_toolchain_linux", "@pigweed//pw_toolchain/host_clang:host_cc_toolchain_macos", "@pigweed//pw_toolchain/arm_clang:arm_clang_cc_toolchain_cortex-m4", diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 5fe9190e9..a1996f911 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1335,7 +1335,7 @@ "@@pigweed+//pw_toolchain/cc:pw_cxx_toolchain.bzl%pw_cxx_toolchain": { "general": { "bzlTransitiveDigest": "8IpVszWptocnteXbMdzhsEBLTUDLy29Js900DGnv/58=", - "usagesDigest": "WXs9NNUE6j/rwQgRuduoROGS4zlVtgtsBGW7DJbiggU=", + "usagesDigest": "rCfTS5VNU7HRJcLhj80f4vFq8+9o7N/Vd2jYmRu8e5w=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, diff --git a/toolchain/aarch64_linux/BUILD.bazel b/toolchain/aarch64_linux/BUILD.bazel new file mode 100644 index 000000000..4bc20d7db --- /dev/null +++ b/toolchain/aarch64_linux/BUILD.bazel @@ -0,0 +1,187 @@ +# Licensed under the Apache-2.0 license +# SPDX-License-Identifier: Apache-2.0 + +# Cross toolchain for aarch64-unknown-linux-gnu, built on x86_64 Linux. +# +# Used for programs that run on the Linux side of the VCK190 FPGA boards +# (e.g. FPGA test binaries that drive the hardware model). Pigweed's toolchains +# only provide aarch64 Linux as a native host (aarch64 exec), so this package +# adds the x86_64 -> aarch64 Linux cross path: +# +# * C/C++ (used to link Rust code): Pigweed's LLVM toolchain with +# `--target=aarch64-unknown-linux-gnu` against Pigweed's multiarch +# linux_sysroot, which already ships aarch64 glibc (2.27) libraries and +# headers. +# * Rust: the x86_64 host rustc from Pigweed's CIPD toolchain, paired with the +# matching aarch64-unknown-linux-gnu standard library from the same CIPD tag. +# +# Build for it with `--platforms=//toolchain/aarch64_linux`. + +load("@rules_cc//cc/toolchains:args.bzl", "cc_args") +load("@rules_cc//cc/toolchains:feature.bzl", "cc_feature") +load("@rules_cc//cc/toolchains:toolchain.bzl", "cc_toolchain") +load("@rules_rust//rust:toolchain.bzl", "rust_toolchain") + +package(default_visibility = ["//visibility:public"]) + +platform( + name = "aarch64_linux", + constraint_values = [ + "@platforms//cpu:aarch64", + "@platforms//os:linux", + ], +) + +_EXEC_CONSTRAINTS = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", +] + +_TARGET_CONSTRAINTS = [ + "@platforms//cpu:aarch64", + "@platforms//os:linux", +] + +# --------------------------------------------------------------------------- +# C/C++ +# --------------------------------------------------------------------------- + +cc_args( + name = "target_triple", + actions = [ + "@rules_cc//cc/toolchains/actions:assembly_actions", + "@rules_cc//cc/toolchains/actions:c_compile_actions", + "@rules_cc//cc/toolchains/actions:cpp_compile_actions", + "@rules_cc//cc/toolchains/actions:link_actions", + ], + args = ["--target=aarch64-unknown-linux-gnu"], +) + +cc_args( + name = "link_with_lld", + actions = ["@rules_cc//cc/toolchains/actions:link_actions"], + args = ["-fuse-ld=lld"], +) + +# Same runtime selection as Pigweed's host_clang Linux toolchain: link the +# LLVM toolchain's libc++/compiler-rt/libunwind instead of libstdc++/libgcc, +# which the sysroot doesn't provide. +cc_args( + name = "link_libs", + actions = ["@rules_cc//cc/toolchains/actions:link_actions"], + args = [ + "-pthread", + "-stdlib=libc++", + "--rtlib=compiler-rt", + "--unwindlib=libunwind", + ], +) + +cc_feature( + name = "supports_pic", + feature_name = "supports_pic", +) + +cc_toolchain( + name = "cc_toolchain", + args = [ + ":target_triple", + "@linux_sysroot//:sysroot", + ":link_libs", + ":link_with_lld", + "@pigweed//pw_toolchain/cc/args:debugging", + "@pigweed//pw_toolchain/cc/args:reduced_size", + "@pigweed//pw_toolchain/cc/args:no_canonical_prefixes", + ], + enabled_features = [ + ":supports_pic", + "@pigweed//pw_toolchain/cc/capability:compiler_is_clang", + "@pigweed//pw_toolchain/cc/capability:linker_is_clang", + "@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features", + ], + known_features = [ + "@pigweed//pw_toolchain/cc/args:dbg_feature", + "@pigweed//pw_toolchain/cc/args:fastbuild_feature", + "@pigweed//pw_toolchain/cc/args:opt_feature", + ], + tool_map = "@llvm_toolchain//:all_tools", +) + +toolchain( + name = "cc_toolchain_aarch64_linux", + exec_compatible_with = _EXEC_CONSTRAINTS, + target_compatible_with = _TARGET_CONSTRAINTS, + toolchain = ":cc_toolchain", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +# --------------------------------------------------------------------------- +# Rust +# --------------------------------------------------------------------------- + +# Mirrors Pigweed's per-channel rustc flags (pw_toolchain/rust/toolchains.bzl) +# so code builds the same way here as for the other targets. +_CHANNELS = { + "nightly": [ + "-Dwarnings", + "-Zemit-stack-sizes", + "-Zmacro-backtrace", + ], + "stable": [ + "-Dwarnings", + "-Zallow-features=core_intrinsics,error_generic_member_access,proc_macro_span,rustc_attrs", + "-Zemit-stack-sizes", + "-Zmacro-backtrace", + ], +} + +[ + rust_toolchain( + name = "rust_toolchain_{}_impl".format(channel), + binary_ext = "", + cargo = "@rust_toolchain_host_linux_x86_64//:bin/cargo", + clippy_driver = "@rust_toolchain_host_linux_x86_64//:bin/clippy-driver", + debug_info = { + "dbg": "2", + "fastbuild": "2", + "opt": "2", + }, + dylib_ext = ".so", + exec_triple = "x86_64-unknown-linux-gnu", + extra_exec_rustc_flags = flags, + extra_rustc_flags = flags, + opt_level = { + "dbg": "s", + "fastbuild": "s", + "opt": "s", + }, + rust_doc = "@rust_toolchain_host_linux_x86_64//:bin/rustdoc", + rust_std = "@rust_toolchain_target_aarch64-unknown-linux-gnu_aarch64//:rust_std", + rustc = "@rust_toolchain_host_linux_x86_64//:bin/rustc", + rustc_lib = "@rust_toolchain_host_linux_x86_64//:rustc_lib", + staticlib_ext = ".a", + stdlib_linkflags = [], + strip_level = { + "dbg": "none", + "fastbuild": "none", + "opt": "none", + }, + # rust_toolchain's own target_compatible_with is confusing (see + # https://pwbug.dev/342695883); constraints live on toolchain() below. + tags = ["manual"], + target_triple = "aarch64-unknown-linux-gnu", + ) + for channel, flags in _CHANNELS.items() +] + +[ + toolchain( + name = "rust_toolchain_aarch64_linux_{}".format(channel), + exec_compatible_with = _EXEC_CONSTRAINTS, + target_compatible_with = _TARGET_CONSTRAINTS, + target_settings = ["@rules_rust//rust/toolchain/channel:{}".format(channel)], + toolchain = ":rust_toolchain_{}_impl".format(channel), + toolchain_type = "@rules_rust//rust:toolchain", + ) + for channel in _CHANNELS.keys() +]