1# Copyright (C) 2022 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# 15 16# Generate Rust bindings for C headers 17# 18# Bindgen reads C headers and generates compatible Rust declarations of types 19# and APIs. This allows us to keep Rust code in sync with C code that it depends 20# on. 21# 22# Input variables: 23# MODULE_BINDGEN_ALLOW_FILES 24# MODULE_BINDGEN_ALLOW_FUNCTIONS 25# MODULE_BINDGEN_ALLOW_TYPES 26# MODULE_BINDGEN_ALLOW_VARS 27# MODULE_BINDGEN_BLOCK_TYPES 28# MODULE_BINDGEN_CTYPES_PREFIX 29# MODULE_BINDGEN_FLAGS 30# MODULE_BINDGEN_OUTPUT_ENV_VAR 31# MODULE_BINDGEN_SRC_HEADER 32# MODULE_BINDGEN_OUTPUT_FILE_NAME 33 34ifeq ($(strip $(MODULE_BINDGEN_SRC_HEADER)),) 35$(error $(MODULE): MODULE_BINDGEN_SRC_HEADER is required to use bindgen.mk) 36endif 37 38BINDGEN := $(CLANG_TOOLS_BINDIR)/bindgen 39 40ifeq ($(strip $(MODULE_BINDGEN_OUTPUT_FILE_NAME)),) 41MODULE_BINDGEN_OUTPUT_FILE := $(call TOBUILDDIR,$(patsubst %.h,%.rs,$(MODULE_BINDGEN_SRC_HEADER))) 42else 43MODULE_BINDGEN_OUTPUT_FILE := $(call TOBUILDDIR,$(dir $(MODULE_BINDGEN_SRC_HEADER))$(MODULE_BINDGEN_OUTPUT_FILE_NAME).rs) 44endif 45 46# Trusty rust is all no_std 47ifeq ($(MODULE_IS_KERNEL),true) 48MODULE_BINDGEN_FLAGS += --use-core --ctypes-prefix 'core::ffi' 49else 50MODULE_BINDGEN_FLAGS += --use-core --ctypes-prefix 'trusty_sys' 51endif 52 53ifneq ($(strip $(MODULE_BINDGEN_CTYPES_PREFIX)),) 54MODULE_BINDGEN_FLAGS += --ctypes-prefix $(MODULE_BINDGEN_CTYPES_PREFIX) 55endif 56 57MODULE_BINDGEN_FLAGS += $(addprefix --allowlist-var ,$(MODULE_BINDGEN_ALLOW_VARS)) 58MODULE_BINDGEN_FLAGS += $(addprefix --allowlist-type ,$(MODULE_BINDGEN_ALLOW_TYPES)) 59MODULE_BINDGEN_FLAGS += $(addprefix --blocklist-type ,$(MODULE_BINDGEN_BLOCK_TYPES)) 60MODULE_BINDGEN_FLAGS += $(addprefix --allowlist-function ,$(MODULE_BINDGEN_ALLOW_FUNCTIONS)) 61MODULE_BINDGEN_FLAGS += $(addprefix --allowlist-file ,$(MODULE_BINDGEN_ALLOW_FILES)) 62# other sanitizer flags if present will cause bindgen to fail unless we pass 63# -fno-sanitize-ignorelist, see https://issues.chromium.org/issues/40265121 64BINDGEN_MODULE_COMPILEFLAGS := $(MODULE_COMPILEFLAGS) -fvisibility=default -fno-sanitize-ignorelist 65 66ifeq ($(call TOBOOL,$(TRUSTY_USERSPACE)),true) 67# library.mk overrides GLOBAL_COMPILEFLAGS and GLOBAL_INCLUDES for the .o, so we 68# must do the same here for bindgen 69$(MODULE_BINDGEN_OUTPUT_FILE): GLOBAL_COMPILEFLAGS := $(GLOBAL_SHARED_COMPILEFLAGS) $(GLOBAL_USER_COMPILEFLAGS) $(GLOBAL_USER_IN_TREE_COMPILEFLAGS) $(GLOBAL_USER_IN_TREE_CPPFLAGS) 70$(MODULE_BINDGEN_OUTPUT_FILE): GLOBAL_INCLUDES := $(addprefix -I,$(GLOBAL_UAPI_INCLUDES) $(GLOBAL_SHARED_INCLUDES) $(GLOBAL_USER_INCLUDES)) 71endif 72 73-include $(MODULE_BINDGEN_OUTPUT_FILE).d 74 75MODULE_BINDGEN_DEFINES := $(MODULE_DEFINES) 76MODULE_BINDGEN_DEFINES += MODULE_BINDGEN_FLAGS=\"$(call clean_defines,$(MODULE_BINDGEN_FLAGS))\" 77MODULE_BINDGEN_DEFINES += BINDGEN_MODULE_COMPILEFLAGS=\"$(call clean_defines,$(BINDGEN_MODULE_COMPILEFLAGS))\" 78MODULE_BINDGEN_DEFINES += BINDGEN_MODULE_INCLUDES=\"$(call clean_defines,$(BINDGEN_MODULE_INCLUDES))\" 79 80MODULE_BINDGEN_CONFIG := $(call TOBUILDDIR,$(dir $(MODULE_BINDGEN_SRC_HEADER))/module_bindgen_config.h) 81$(MODULE_BINDGEN_CONFIG): MODULE_BINDGEN_DEFINES:=$(MODULE_BINDGEN_DEFINES) 82$(MODULE_BINDGEN_CONFIG): MODULE:=$(MODULE) 83$(MODULE_BINDGEN_CONFIG): configheader 84 @$(call INFO_DONE,$(MODULE),generating bindgen config header, $@) 85 @$(call MAKECONFIGHEADER,$@,MODULE_BINDGEN_DEFINES) 86 87$(MODULE_BINDGEN_OUTPUT_FILE): BINDGEN := $(BINDGEN) 88$(MODULE_BINDGEN_OUTPUT_FILE): BINDGEN_MODULE_COMPILEFLAGS := $(BINDGEN_MODULE_COMPILEFLAGS) 89$(MODULE_BINDGEN_OUTPUT_FILE): BINDGEN_MODULE_INCLUDES := $(addprefix -I,$(MODULE_INCLUDES)) 90$(MODULE_BINDGEN_OUTPUT_FILE): ARCH_COMPILEFLAGS := $(ARCH_$(ARCH)_COMPILEFLAGS) 91$(MODULE_BINDGEN_OUTPUT_FILE): DEFINES := $(addprefix -D,$(MODULE_DEFINES)) 92$(MODULE_BINDGEN_OUTPUT_FILE): MODULE_BINDGEN_FLAGS := $(MODULE_BINDGEN_FLAGS) 93$(MODULE_BINDGEN_OUTPUT_FILE): RUSTFMT_PATH := $(RUST_BINDIR)/rustfmt 94$(MODULE_BINDGEN_OUTPUT_FILE): $(MODULE_BINDGEN_SRC_HEADER) $(BINDGEN) $(MODULE_SRCDEPS) $(CONFIGHEADER) $(MODULE_BINDGEN_CONFIG) 95 @$(MKDIR) 96 $(NOECHO) 97 CLANG_PATH=$(BINDGEN_CLANG_PATH) \ 98 LIBCLANG_PATH=$(BINDGEN_LIBCLANG_PATH) \ 99 RUSTFMT=$(RUSTFMT_PATH) \ 100 $(BINDGEN) $< -o $@.tmp $(MODULE_BINDGEN_FLAGS) --depfile $@.d -- $(GLOBAL_COMPILEFLAGS) $(ARCH_COMPILEFLAGS) $(BINDGEN_MODULE_COMPILEFLAGS) $(BINDGEN_MODULE_INCLUDES) $(GLOBAL_INCLUDES) $(DEFINES) 101 @$(call TESTANDREPLACEFILE,$@.tmp,$@) 102 103MODULE_SRCDEPS += $(MODULE_BINDGEN_OUTPUT_FILE) 104 105ifeq ($(MODULE_BINDGEN_OUTPUT_ENV_VAR),) 106MODULE_BINDGEN_OUTPUT_ENV_VAR := BINDGEN_INC_FILE 107endif 108 109# MODULE_BINDGEN_OUTPUT_ENV_VAR is not compatible with Soong as Soong does not allow 110# custom `envflags`. bindgen modules should resort to using `MODULE_BINDGEN_OUTPUT_FILE` 111# and `include!(concat!(env!("OUT_DIR"), "/{MODULE_BINDGEN_OUTPUT_FILE}"))` to include 112# the generated bindgen file. 113MODULE_RUST_ENV := $(MODULE_RUST_ENV) $(MODULE_BINDGEN_OUTPUT_ENV_VAR)=$(MODULE_BINDGEN_OUTPUT_FILE) OUT_DIR=$(dir $(MODULE_BINDGEN_OUTPUT_FILE)) 114 115$(info $(MODULE_BINDGEN_OUTPUT_FILE)) 116 117MODULE_BINDGEN_ALLOW_FILES := 118MODULE_BINDGEN_ALLOW_FUNCTIONS := 119MODULE_BINDGEN_ALLOW_TYPES := 120MODULE_BINDGEN_ALLOW_VARS := 121MODULE_BINDGEN_BLOCK_TYPES := 122MODULE_BINDGEN_CONFIG := 123MODULE_BINDGEN_CTYPES_PREFIX := 124MODULE_BINDGEN_DEFINES := 125MODULE_BINDGEN_OUTPUT_ENV_VAR := 126MODULE_BINDGEN_OUTPUT_FILE_NAME := 127MODULE_BINDGEN_SRC_HEADER := 128 129BINDGEN := 130MODULE_BINDGEN_FLAGS := 131BINDGEN_MODULE_COMPILEFLAGS := 132MODULE_BINDGEN_OUTPUT_FILE := 133