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 15load("@bazel_skylib//lib:paths.bzl", "paths") 16 17LANGUAGE_CC_HEADERS = "c++-headers" 18LANGUAGE_CC_SOURCES = "c++-sources" 19INTERFACE_HEADER_PREFIXES = ["I", "Bs", "BnHw", "BpHw", "IHw"] 20TYPE_HEADER_PREFIXES = ["", "hw"] 21 22def _generate_hidl_action( 23 hidl_info, 24 language, 25 ctx): 26 """ Utility function for generating code for the given language from HIDL interface.""" 27 28 output_dir = paths.join(ctx.bin_dir.path, ctx.label.package) 29 30 args = ctx.actions.args() 31 32 args.add("-R") 33 args.add_all(["-p", "."]) 34 args.add_all(["-o", output_dir]) 35 args.add_all(["-L", language]) 36 for root in hidl_info.transitive_roots.to_list(): 37 args.add_all(["-r", root]) 38 39 args.add(hidl_info.fq_name) 40 41 hidl_srcs = hidl_info.srcs.to_list() 42 inputs = depset( 43 direct = hidl_srcs, 44 # These are needed for hidl-gen to correctly generate the code. 45 transitive = [hidl_info.transitive_srcs, hidl_info.transitive_root_interface_files], 46 ) 47 48 outputs = _generate_and_declare_output_files( 49 ctx, 50 hidl_info.fq_name, 51 language, 52 hidl_srcs, 53 ) 54 55 ctx.actions.run( 56 inputs = inputs, 57 executable = ctx.executable._hidl_gen, 58 outputs = outputs, 59 arguments = [args], 60 mnemonic = "HidlGen" + _get_language_string(language), 61 ) 62 63 return outputs 64 65def _get_language_string(language): 66 if language == LANGUAGE_CC_HEADERS: 67 return "CcHeader" 68 elif language == LANGUAGE_CC_SOURCES: 69 return "Cc" 70 71def _generate_and_declare_output_files( 72 ctx, 73 fq_name, 74 language, 75 hidl_srcs): 76 files = [] 77 78 # Break FQ name such as [email protected] into 79 # android/hardware/neuralnetworks/1.3 which is the directory structure 80 # that hidl-gen uses to generate files. 81 parts = fq_name.split("@") 82 dirname = paths.join(parts[0].replace(".", "/"), parts[1]) 83 84 for src in hidl_srcs: 85 filename = src.basename 86 87 # "I" prefix indicates that this file is a interface file, the rest are 88 # files that define types. Interface files and type files are treated 89 # differently when generating code using hidl-gen. 90 basename = filename.removeprefix("I").removesuffix(".hal") 91 interface = _is_interface(filename) 92 if language == LANGUAGE_CC_HEADERS: 93 if interface: 94 prefixes = INTERFACE_HEADER_PREFIXES 95 else: 96 prefixes = TYPE_HEADER_PREFIXES 97 for prefix in prefixes: 98 out_name = paths.join(dirname, prefix + basename + ".h") 99 declared = ctx.actions.declare_file(out_name) 100 files.append(declared) 101 elif language == LANGUAGE_CC_SOURCES: 102 if interface: 103 out_name = paths.join(dirname, basename + "All.cpp") 104 else: 105 out_name = paths.join(dirname, basename + ".cpp") 106 declared = ctx.actions.declare_file(out_name) 107 files.append(declared) 108 109 return files 110 111def _is_interface(filename): 112 if not filename.endswith(".hal"): 113 fail("HIDL source file must be a .hal file: %s" % filename) 114 115 return filename.startswith("I") 116 117hidl_file_utils = struct( 118 generate_hidl_action = _generate_hidl_action, 119) 120