120 lines
3.8 KiB
Python
120 lines
3.8 KiB
Python
|
|
# Copyright (C) 2022 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//lib:paths.bzl", "paths")
|
||
|
|
|
||
|
|
LANGUAGE_CC_HEADERS = "c++-headers"
|
||
|
|
LANGUAGE_CC_SOURCES = "c++-sources"
|
||
|
|
INTERFACE_HEADER_PREFIXES = ["I", "Bs", "BnHw", "BpHw", "IHw"]
|
||
|
|
TYPE_HEADER_PREFIXES = ["", "hw"]
|
||
|
|
|
||
|
|
def _generate_hidl_action(
|
||
|
|
hidl_info,
|
||
|
|
language,
|
||
|
|
ctx):
|
||
|
|
""" Utility function for generating code for the given language from HIDL interface."""
|
||
|
|
|
||
|
|
output_dir = paths.join(ctx.bin_dir.path, ctx.label.package)
|
||
|
|
|
||
|
|
args = ctx.actions.args()
|
||
|
|
|
||
|
|
args.add("-R")
|
||
|
|
args.add_all(["-p", "."])
|
||
|
|
args.add_all(["-o", output_dir])
|
||
|
|
args.add_all(["-L", language])
|
||
|
|
for root in hidl_info.transitive_roots.to_list():
|
||
|
|
args.add_all(["-r", root])
|
||
|
|
|
||
|
|
args.add(hidl_info.fq_name)
|
||
|
|
|
||
|
|
hidl_srcs = hidl_info.srcs.to_list()
|
||
|
|
inputs = depset(
|
||
|
|
direct = hidl_srcs,
|
||
|
|
# These are needed for hidl-gen to correctly generate the code.
|
||
|
|
transitive = [hidl_info.transitive_srcs, hidl_info.transitive_root_interface_files],
|
||
|
|
)
|
||
|
|
|
||
|
|
outputs = _generate_and_declare_output_files(
|
||
|
|
ctx,
|
||
|
|
hidl_info.fq_name,
|
||
|
|
language,
|
||
|
|
hidl_srcs,
|
||
|
|
)
|
||
|
|
|
||
|
|
ctx.actions.run(
|
||
|
|
inputs = inputs,
|
||
|
|
executable = ctx.executable._hidl_gen,
|
||
|
|
outputs = outputs,
|
||
|
|
arguments = [args],
|
||
|
|
mnemonic = "HidlGen" + _get_language_string(language),
|
||
|
|
)
|
||
|
|
|
||
|
|
return outputs
|
||
|
|
|
||
|
|
def _get_language_string(language):
|
||
|
|
if language == LANGUAGE_CC_HEADERS:
|
||
|
|
return "CcHeader"
|
||
|
|
elif language == LANGUAGE_CC_SOURCES:
|
||
|
|
return "Cc"
|
||
|
|
|
||
|
|
def _generate_and_declare_output_files(
|
||
|
|
ctx,
|
||
|
|
fq_name,
|
||
|
|
language,
|
||
|
|
hidl_srcs):
|
||
|
|
files = []
|
||
|
|
|
||
|
|
# Break FQ name such as android.hardware.neuralnetworks@1.3 into
|
||
|
|
# android/hardware/neuralnetworks/1.3 which is the directory structure
|
||
|
|
# that hidl-gen uses to generate files.
|
||
|
|
parts = fq_name.split("@")
|
||
|
|
dirname = paths.join(parts[0].replace(".", "/"), parts[1])
|
||
|
|
|
||
|
|
for src in hidl_srcs:
|
||
|
|
filename = src.basename
|
||
|
|
|
||
|
|
# "I" prefix indicates that this file is a interface file, the rest are
|
||
|
|
# files that define types. Interface files and type files are treated
|
||
|
|
# differently when generating code using hidl-gen.
|
||
|
|
basename = filename.removeprefix("I").removesuffix(".hal")
|
||
|
|
interface = _is_interface(filename)
|
||
|
|
if language == LANGUAGE_CC_HEADERS:
|
||
|
|
if interface:
|
||
|
|
prefixes = INTERFACE_HEADER_PREFIXES
|
||
|
|
else:
|
||
|
|
prefixes = TYPE_HEADER_PREFIXES
|
||
|
|
for prefix in prefixes:
|
||
|
|
out_name = paths.join(dirname, prefix + basename + ".h")
|
||
|
|
declared = ctx.actions.declare_file(out_name)
|
||
|
|
files.append(declared)
|
||
|
|
elif language == LANGUAGE_CC_SOURCES:
|
||
|
|
if interface:
|
||
|
|
out_name = paths.join(dirname, basename + "All.cpp")
|
||
|
|
else:
|
||
|
|
out_name = paths.join(dirname, basename + ".cpp")
|
||
|
|
declared = ctx.actions.declare_file(out_name)
|
||
|
|
files.append(declared)
|
||
|
|
|
||
|
|
return files
|
||
|
|
|
||
|
|
def _is_interface(filename):
|
||
|
|
if not filename.endswith(".hal"):
|
||
|
|
fail("HIDL source file must be a .hal file: %s" % filename)
|
||
|
|
|
||
|
|
return filename.startswith("I")
|
||
|
|
|
||
|
|
hidl_file_utils = struct(
|
||
|
|
generate_hidl_action = _generate_hidl_action,
|
||
|
|
)
|