1# Copyright (C) 2023 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15load("@gbl_llvm_prebuilts//:info.bzl", "LLVM_PREBUILTS_C_INCLUDE") 16load("@rules_rust//bindgen:defs.bzl", "rust_bindgen") 17load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test") 18 19package( 20 default_visibility = ["//visibility:public"], 21) 22 23# Newer version of `rust_bindgen` requires a `cc_library` target that actually produces a static 24# library and instead of only headers. Thus we generate a placeholder source file to meet the 25# requirement. 26genrule( 27 name = "bindgen_noop_cc", 28 outs = ["bindgen_noop_cc.cc"], 29 cmd = "touch $(OUTS)", 30) 31 32cc_library( 33 name = "efi_c_headers", 34 srcs = [":bindgen_noop_cc"], 35 hdrs = [ 36 "defs/boot_service.h", 37 "defs/efi.h", 38 "defs/protocols/android_boot_protocol.h", 39 "defs/protocols/block_io_protocol.h", 40 "defs/protocols/device_path_protocol.h", 41 "defs/protocols/loaded_image_protocol.h", 42 "defs/protocols/riscv_efi_boot_protocol.h", 43 "defs/protocols/simple_network_protocol.h", 44 "defs/protocols/simple_text_input_protocol.h", 45 "defs/protocols/simple_text_output_protocol.h", 46 "defs/runtime_service.h", 47 "defs/system_table.h", 48 "defs/types.h", 49 ], 50 includes = ["defs"], 51) 52 53# Side note: function pointers for UEFI interfaces need to specify the "efiapi" ABI. i.e. 54# "unsafe extern "efiapi" fn(...)". bindgen uses "extern "C"" by default. We are currently fine 55# because for x86_64/x86_32/aarch64, we use dedicated rust UEFI compiler which uses EFIAPI ABI by 56# default. For riscv64 which we use ELF compiler, the efiapi calling convention is the same as C 57# calling convention according to the UEFI spec at the time of writing. If we do eventually run 58# into problems, we need to use a newer version of bindgen 0.65.0 or above, which offers 59# "--override-abi" with "efiapi" option. 60rust_bindgen( 61 name = "efi_defs_bindgen", 62 bindgen_flags = [ 63 "--ctypes-prefix", 64 "core::ffi", 65 "--use-core", 66 "--with-derive-partialeq", 67 "--with-derive-default", 68 "--with-derive-custom-struct=EfiMemoryDescriptor=AsBytes,FromBytes,FromZeroes", 69 "--allowlist-type", 70 "(Efi.*)", 71 "--raw-line", 72 """ 73#![allow(non_camel_case_types)] 74#![allow(non_snake_case)] 75use zerocopy::{AsBytes, FromBytes, FromZeroes};""", 76 ], 77 cc_lib = ":efi_c_headers", 78 # For x86_32, we need to explicitly specify 32bit architecture. 79 clang_flags = select({ 80 "@gbl//toolchain:gbl_rust_uefi_x86_32": ["-m32"], 81 "//conditions:default": ["-m64"], 82 }) + [ 83 "-I{}".format(LLVM_PREBUILTS_C_INCLUDE), 84 "-nostdinc", 85 ], 86 header = "defs/efi.h", 87) 88 89# Copy the generated source to "src/defs.rs" in the output assembly, so that libefi can include it 90# as a source. 91genrule( 92 name = "efi_defs_genrule", 93 srcs = [":efi_defs_bindgen"], 94 outs = ["src/defs.rs"], 95 cmd = "cat $(location :efi_defs_bindgen) > $@", 96) 97 98rust_library( 99 name = "libefi", 100 srcs = [ 101 "src/allocation.rs", 102 "src/defs.rs", # Generated by :efi_defs_genrule 103 "src/lib.rs", 104 "src/protocol.rs", 105 "src/protocol/android_boot.rs", 106 "src/protocol/block_io.rs", 107 "src/protocol/device_path.rs", 108 "src/protocol/loaded_image.rs", 109 "src/protocol/riscv.rs", 110 "src/protocol/simple_network.rs", 111 "src/protocol/simple_text_input.rs", 112 "src/protocol/simple_text_output.rs", 113 ], 114 crate_name = "efi", 115 data = [":efi_defs_genrule"], 116 deps = ["@zerocopy"], 117) 118 119rust_test( 120 name = "libefi_test", 121 crate = ":libefi", 122) 123