| # Copyright (C) 2023 The Android Open Source Project |
| # |
| # 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. |
| |
| load("@bazel_skylib//rules:common_settings.bzl", "bool_setting") |
| load( |
| "@gbl_llvm_prebuilts//:info.bzl", |
| "LINUX_SYSROOT_INCLUDES", |
| "LLVM_PREBUILTS_CPP_INCLUDE", |
| "LLVM_PREBUILTS_C_INCLUDE", |
| "gbl_llvm_tool_path", |
| ) |
| load("@rules_rust//bindgen:defs.bzl", "rust_bindgen_toolchain") |
| load( |
| "@rules_rust//rust:toolchain.bzl", |
| "rust_stdlib_filegroup", |
| "rust_toolchain", |
| "rustfmt_toolchain", |
| ) |
| load( |
| ":gbl_toolchain.bzl", |
| "build_with_no_rust_sysroot", |
| "gbl_clang_cc_toolchain", |
| "prebuilt_binary", |
| ) |
| |
| package( |
| default_visibility = ["//visibility:public"], |
| ) |
| |
| # The following constraint/settings will be used in our newly defined |
| # toolchains, so that they only get selected by bazel when we configure |
| # to build GBL. |
| constraint_setting(name = "firmware_image_type") |
| |
| constraint_value( |
| name = "uefi", |
| constraint_setting = ":firmware_image_type", |
| ) |
| |
| constraint_value( |
| name = "elf", |
| constraint_setting = ":firmware_image_type", |
| ) |
| |
| uefi_x86_64_constraint_values = [ |
| ":uefi", |
| "@platforms//os:none", |
| "@platforms//cpu:x86_64", |
| ] |
| |
| uefi_x86_32_constraint_values = [ |
| ":uefi", |
| "@platforms//os:none", |
| "@platforms//cpu:x86_32", |
| ] |
| |
| uefi_aarch64_constraint_values = [ |
| ":uefi", |
| "@platforms//os:none", |
| "@platforms//cpu:aarch64", |
| ] |
| |
| elf_riscv64_constraint_values = [ |
| ":elf", |
| "@platforms//os:none", |
| "@platforms//cpu:riscv64", |
| ] |
| |
| config_setting( |
| name = "gbl_rust_uefi_x86_64", |
| constraint_values = uefi_x86_64_constraint_values, |
| ) |
| |
| config_setting( |
| name = "gbl_rust_uefi_x86_32", |
| constraint_values = uefi_x86_32_constraint_values, |
| ) |
| |
| config_setting( |
| name = "gbl_rust_uefi_aarch64", |
| constraint_values = uefi_aarch64_constraint_values, |
| ) |
| |
| config_setting( |
| name = "gbl_rust_elf_riscv64", |
| constraint_values = elf_riscv64_constraint_values, |
| ) |
| |
| # The following will be passed to "bazel build --platform=<>" argument to |
| # configure building for specific architecture and image type. |
| platform( |
| name = "gbl_uefi_x86_64", |
| constraint_values = uefi_x86_64_constraint_values, |
| ) |
| |
| platform( |
| name = "gbl_uefi_x86_32", |
| constraint_values = uefi_x86_32_constraint_values, |
| ) |
| |
| platform( |
| name = "gbl_uefi_aarch64", |
| constraint_values = uefi_aarch64_constraint_values, |
| ) |
| |
| platform( |
| name = "gbl_elf_riscv64", |
| constraint_values = elf_riscv64_constraint_values, |
| ) |
| |
| bool_setting( |
| name = "rust_no_sysroot", |
| build_setting_default = False, |
| visibility = ["//visibility:public"], |
| ) |
| |
| config_setting( |
| name = "rust_no_sysroot_true", |
| flag_values = {":rust_no_sysroot": "True"}, |
| ) |
| |
| # Linux host LLVM toolchain. |
| # The toolchain is mainly used for building/linking host tools, i.e. bindgen pre-processing |
| gbl_clang_cc_toolchain( |
| name = "x86_64-unknown-linux-gnu", |
| # Host LLVM toolchain has additional C++ stdlib. |
| builtin_includes = [ |
| LLVM_PREBUILTS_CPP_INCLUDE, # C++ headers must come first. |
| LLVM_PREBUILTS_C_INCLUDE, |
| ] + LINUX_SYSROOT_INCLUDES, |
| ld_flags = [ |
| "-stdlib=libc++", |
| "-static-libstdc++", |
| ], |
| target_cpu = "x86_64", |
| target_system_triple = "x86_64-unknown-linux-gnu", |
| ) |
| |
| toolchain( |
| name = "x86_64-unknown-linux-gnu_toolchain", |
| exec_compatible_with = ["@platforms//os:linux"], |
| target_compatible_with = [ |
| "@platforms//os:linux", |
| "@platforms//cpu:x86_64", |
| ], |
| toolchain = ":x86_64-unknown-linux-gnu", |
| toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", |
| ) |
| |
| # The following defines LLVM C++ toolchains for UEFI/ELF targets. They are mostly used for the |
| # final step of linking Rust executables, but may also be used for compiling mixed C/C++ code. |
| |
| cc_flags_common = [ |
| "-ffreestanding", |
| "-fno-common", |
| "-fno-exceptions", |
| "-fno-rtti", |
| ] |
| |
| # x86_64 UEFI targets |
| gbl_clang_cc_toolchain( |
| name = "x86_64_uefi_clang_cc_toolchain", |
| cc_flags = cc_flags_common, |
| target_cpu = "x86_64", |
| target_system_triple = "x86_64-unknown-windows-msvc", |
| ) |
| |
| toolchain( |
| name = "x86_64_uefi_clang", |
| exec_compatible_with = ["@platforms//os:linux"], |
| target_compatible_with = uefi_x86_64_constraint_values, |
| toolchain = ":x86_64_uefi_clang_cc_toolchain", |
| toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", |
| ) |
| |
| # x86_32 UEFI targets |
| gbl_clang_cc_toolchain( |
| name = "x86_32_uefi_clang_cc_toolchain", |
| cc_flags = cc_flags_common + [ |
| "-m32", |
| # Adding this prevents the compiler from generating mmx, sse instructions such as |
| # "movsd (%esp),%xmm0" which likely isn't enabled during the bootloader stage and causes |
| # crash as a result. |
| "-march=i686", |
| ], |
| # Safe Exception Handlers is not applicable to EFI systems. |
| ld_flags = ["/SAFESEH:no"], |
| target_cpu = "x86_32", |
| target_system_triple = "i686-unknown-windows-gnu", |
| ) |
| |
| toolchain( |
| name = "x86_32_uefi_clang", |
| exec_compatible_with = ["@platforms//os:linux"], |
| target_compatible_with = uefi_x86_32_constraint_values, |
| toolchain = ":x86_32_uefi_clang_cc_toolchain", |
| toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", |
| ) |
| |
| # aarch64 UEFI targets |
| gbl_clang_cc_toolchain( |
| name = "aarch64_uefi_clang_cc_toolchain", |
| cc_flags = cc_flags_common, |
| target_cpu = "aarch64", |
| target_system_triple = "aarch64-windows-msvc", |
| ) |
| |
| toolchain( |
| name = "aarch64_uefi_clang", |
| exec_compatible_with = ["@platforms//os:linux"], |
| target_compatible_with = uefi_aarch64_constraint_values, |
| toolchain = ":aarch64_uefi_clang_cc_toolchain", |
| toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", |
| ) |
| |
| # riscv64 ELF targets |
| gbl_clang_cc_toolchain( |
| name = "riscv64_elf_clang_cc_toolchain", |
| cc_flags = cc_flags_common + ["-fpie"], |
| target_cpu = "riscv64", |
| target_system_triple = "riscv64-unknown-linux", |
| ) |
| |
| toolchain( |
| name = "riscv64_elf_clang", |
| exec_compatible_with = ["@platforms//os:linux"], |
| target_compatible_with = elf_riscv64_constraint_values, |
| toolchain = ":riscv64_elf_clang_cc_toolchain", |
| toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", |
| ) |
| |
| # Rust toolchains |
| |
| # An empty rust std file group used as placeholder when building rust sysroot. |
| rust_stdlib_filegroup( |
| name = "rust_stdlib_empty", |
| srcs = [], |
| ) |
| |
| # A rule for building sysroot from source. |
| build_with_no_rust_sysroot( |
| name = "rust_sysroot_source_build", |
| deps = [ |
| "@rust_prebuilts//:liballoc", |
| "@rust_prebuilts//:libcompiler_builtins", |
| "@rust_prebuilts//:libcore", |
| ], |
| ) |
| |
| rust_stdlib_filegroup( |
| name = "rust_std_source_build", |
| srcs = [":rust_sysroot_source_build"], |
| ) |
| |
| common_lint_opts = [ |
| "-A", |
| "deprecated", |
| # external/rust/crates/spin doesn't pass this lint check and there is not a way to make an |
| # exemption. Disable it until upstream is fixed or we figure out a workaround. |
| #"-D", |
| #"unsafe_op_in_unsafe_fn", |
| "-D", |
| "warnings", |
| "-D", |
| "clippy::undocumented_unsafe_blocks", |
| "-D", |
| "clippy::too-many-arguments", |
| ] |
| |
| # Linux x86_64 Host toolchain |
| rust_toolchain( |
| name = "x86_64_unknown_linux_gnu", |
| allocator_library = None, |
| binary_ext = "", |
| default_edition = "2021", |
| dylib_ext = ".so", |
| exec_triple = "x86_64-unknown-linux-gnu", |
| global_allocator_library = None, |
| rust_doc = "@rust_prebuilts//:bin/rustdoc", |
| rust_std = "@rust_prebuilts//:prebuilt_stdlibs", |
| rustc = "@rust_prebuilts//:bin/rustc", |
| staticlib_ext = ".a", |
| stdlib_linkflags = [], |
| target_triple = "x86_64-unknown-linux-gnu", |
| ) |
| |
| toolchain( |
| name = "x86_64_unknown_linux_gnu_toolchain", |
| exec_compatible_with = ["@platforms//os:linux"], |
| target_compatible_with = [ |
| "@platforms//os:linux", |
| "@platforms//cpu:x86_64", |
| ], |
| toolchain = ":x86_64_unknown_linux_gnu", |
| toolchain_type = "@rules_rust//rust:toolchain", |
| ) |
| |
| # x86_64 UEFI toolchain |
| rust_toolchain( |
| name = "x86_64-unknown-uefi", |
| allocator_library = None, |
| binary_ext = ".efi", |
| default_edition = "2021", |
| dylib_ext = ".so", |
| exec_triple = "x86_64-unknown-linux-gnu", |
| extra_rustc_flags = common_lint_opts + [ |
| # The linker options generated by rustc assumes `lld` as the linker. For windows platforms, |
| # the lld args style is different than that of clang++, i.e. for library search path, lld |
| # uses "/L<path>" while clang++ uses "-L<path>". Thus we need to use lld directly instead |
| # of `clang++`. |
| "--codegen=linker={}".format(gbl_llvm_tool_path("lld")), |
| # Disable default sysroot. We'll pass sysroot explicitly via the `rust_std` field below. |
| "--sysroot", |
| "/dev/null", |
| ], |
| global_allocator_library = None, |
| rust_doc = "@rust_prebuilts//:bin/rustdoc", |
| rust_std = "@rust_prebuilts//:x86_64-unknown-uefi_prebuilt_stdlibs", |
| rustc = "@rust_prebuilts//:bin/rustc", |
| staticlib_ext = ".a", |
| stdlib_linkflags = [], |
| target_triple = "x86_64-unknown-uefi", |
| ) |
| |
| toolchain( |
| name = "x86_64-unknown-uefi_toolchain", |
| exec_compatible_with = ["@platforms//os:linux"], |
| target_settings = [":gbl_rust_uefi_x86_64"], |
| toolchain = ":x86_64-unknown-uefi", |
| toolchain_type = "@rules_rust//rust:toolchain", |
| ) |
| |
| # i686 UEFI toolchain |
| rust_toolchain( |
| name = "i686-unknown-uefi", |
| allocator_library = None, |
| binary_ext = ".efi", |
| default_edition = "2021", |
| dylib_ext = ".so", |
| exec_triple = "x86_64-unknown-linux-gnu", |
| extra_rustc_flags = common_lint_opts + [ |
| "--codegen=linker={}".format(gbl_llvm_tool_path("lld")), |
| # Disable default sysroot. We'll pass sysroot explicitly via the `rust_std` field below. |
| "--sysroot", |
| "/dev/null", |
| ], |
| global_allocator_library = None, |
| rust_doc = "@rust_prebuilts//:bin/rustdoc", |
| # Need to use our own sysroot because we have a custom patch that needs to be applied for std |
| # in order to enable compiler builtin for chkstk(), alloca(). Once the fix is upstreamed, we |
| # can use the prebuilt. |
| rust_std = select({ |
| ":rust_no_sysroot_true": ":rust_stdlib_empty", |
| "//conditions:default": ":rust_std_source_build", |
| }), |
| #rust_std = "@rust_prebuilts//:i686-unknown-uefi_prebuilt_stdlibs", |
| rustc = "@rust_prebuilts//:bin/rustc", |
| staticlib_ext = ".a", |
| stdlib_linkflags = [], |
| target_triple = "i686-unknown-uefi", |
| ) |
| |
| toolchain( |
| name = "i686-unknown-uefi_toolchain", |
| exec_compatible_with = ["@platforms//os:linux"], |
| target_settings = [":gbl_rust_uefi_x86_32"], |
| toolchain = ":i686-unknown-uefi", |
| toolchain_type = "@rules_rust//rust:toolchain", |
| ) |
| |
| # aarch64 UEFI toolchain |
| rust_toolchain( |
| name = "aarch64-unknown-uefi", |
| allocator_library = None, |
| binary_ext = ".efi", |
| default_edition = "2021", |
| dylib_ext = ".so", |
| exec_triple = "x86_64-unknown-linux-gnu", |
| extra_rustc_flags = common_lint_opts + [ |
| "--codegen=linker={}".format(gbl_llvm_tool_path("lld")), |
| # Disable default sysroot. We'll pass sysroot explicitly via the `rust_std` field below. |
| "--sysroot", |
| "/dev/null", |
| ], |
| global_allocator_library = None, |
| rust_doc = "@rust_prebuilts//:bin/rustdoc", |
| rust_std = "@rust_prebuilts//:aarch64-unknown-uefi_prebuilt_stdlibs", |
| rustc = "@rust_prebuilts//:bin/rustc", |
| staticlib_ext = ".a", |
| stdlib_linkflags = [], |
| target_triple = "aarch64-unknown-uefi", |
| ) |
| |
| toolchain( |
| name = "aarch64-unknown-uefi_toolchain", |
| exec_compatible_with = ["@platforms//os:linux"], |
| target_settings = [":gbl_rust_uefi_aarch64"], |
| toolchain = ":aarch64-unknown-uefi", |
| toolchain_type = "@rules_rust//rust:toolchain", |
| ) |
| |
| # riscv64 PIE ELF toolchain |
| rust_toolchain( |
| name = "riscv64gc-unknown-none-pie_elf", |
| allocator_library = None, |
| binary_ext = "", |
| default_edition = "2021", |
| dylib_ext = ".so", |
| exec_triple = "x86_64-unknown-linux-gnu", |
| extra_rustc_flags = common_lint_opts + [ |
| "--codegen=linker={}".format(gbl_llvm_tool_path("lld")), |
| # Disable default sysroot. We'll pass sysroot explicitly via the `rust_std` field below. |
| "--sysroot", |
| "/dev/null", |
| ], |
| global_allocator_library = None, |
| rust_doc = "@rust_prebuilts//:bin/rustdoc", |
| # Need to use our own built sysroot because we are using a custom spec below. |
| rust_std = select({ |
| ":rust_no_sysroot_true": ":rust_stdlib_empty", |
| "//conditions:default": ":rust_std_source_build", |
| }), |
| rustc = "@rust_prebuilts//:bin/rustc", |
| staticlib_ext = ".a", |
| stdlib_linkflags = [], |
| # The custom spec is based on builtin target "riscv64gc-unknown-none-elf" but with the |
| # following changes for enabling PIE: |
| # |
| # 1. "relocation-model" config entry changed from "static" to "pic". |
| # 2. Added "position-independent-executables": true. |
| # |
| # The original spec can be obtained by: |
| # |
| # rustc +nightly -Z unstable-options --print target-spec-json \ |
| # --target riscv64gc-unknown-none-elf |
| target_json = """ |
| { |
| "arch": "riscv64", |
| "code-model": "medium", |
| "cpu": "generic-rv64", |
| "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128", |
| "eh-frame-header": false, |
| "emit-debug-gdb-scripts": false, |
| "features": "+m,+a,+f,+d,+c", |
| "is-builtin": false, |
| "linker": "rust-lld", |
| "linker-flavor": "ld.lld", |
| "llvm-abiname": "lp64d", |
| "llvm-target": "riscv64-unknown-linux", |
| "max-atomic-width": 64, |
| "os": "none", |
| "panic-strategy": "abort", |
| "relocation-model": "pic", |
| "position-independent-executables": true, |
| "supported-sanitizers": [ |
| "kernel-address" |
| ], |
| "target-pointer-width": "64" |
| } |
| """, |
| ) |
| |
| toolchain( |
| name = "riscv64gc-unknown-none-pie_elf_toolchain", |
| exec_compatible_with = ["@platforms//os:linux"], |
| target_settings = ["@gbl//toolchain:gbl_rust_elf_riscv64"], |
| toolchain = ":riscv64gc-unknown-none-pie_elf", |
| toolchain_type = "@rules_rust//rust:toolchain", |
| ) |
| |
| # rustfmt toolchain |
| rustfmt_toolchain( |
| name = "rustfmt", |
| rustfmt = "@rust_prebuilts//:bin/rustfmt", |
| ) |
| |
| toolchain( |
| name = "rustfmt_toolchain", |
| exec_compatible_with = ["@platforms//os:linux"], |
| toolchain = ":rustfmt", |
| toolchain_type = "@rules_rust//rust/rustfmt:toolchain_type", |
| ) |
| |
| # Rust bindgen toolchain |
| |
| prebuilt_binary( |
| name = "bindgen_prebuilt", |
| bin = "@bindgen//:bindgen", |
| ) |
| |
| rust_bindgen_toolchain( |
| name = "bindgen_toolchain_impl", |
| bindgen = ":bindgen_prebuilt", |
| clang = "@gbl_llvm_prebuilts//:clang-bin", |
| libclang = "@gbl_llvm_prebuilts//:libclang", |
| libstdcxx = "@gbl_llvm_prebuilts//:libc++", |
| ) |
| |
| toolchain( |
| name = "bindgen_toolchain", |
| toolchain = "bindgen_toolchain_impl", |
| toolchain_type = "@rules_rust//bindgen:toolchain_type", |
| ) |