332 lines
14 KiB
Python
332 lines
14 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("//build/bazel/rules/aidl:aidl_library.bzl", "aidl_library")
|
|
load("//build/bazel/rules/cc:cc_aidl_library.bzl", "cc_aidl_library")
|
|
load("//build/bazel/rules/java:java_aidl_library.bzl", "java_aidl_library")
|
|
|
|
JAVA = "java"
|
|
CPP = "cpp"
|
|
NDK = "ndk"
|
|
#TODO(b/246803961) Add support for rust backend
|
|
|
|
def _hash_file(name, version):
|
|
return "aidl_api/{}/{}/.hash".format(name, version)
|
|
|
|
def _check_versions_with_info(versions_with_info):
|
|
for version_with_info in versions_with_info:
|
|
for dep in version_with_info.get("deps", []):
|
|
parts = dep.split("-V")
|
|
if len(parts) < 2 or not parts[-1].isdigit():
|
|
fail("deps in versions_with_info must specify its version, but", dep)
|
|
|
|
versions = []
|
|
|
|
# ensure that all versions are ints
|
|
for info in versions_with_info:
|
|
version = info["version"]
|
|
if version.isdigit() == False:
|
|
fail("version %s is not an integer".format(version))
|
|
|
|
versions.append(int(version))
|
|
|
|
if versions != sorted(versions):
|
|
fail("versions should be sorted")
|
|
|
|
for i, v in enumerate(versions):
|
|
if i > 0:
|
|
if v == versions[i - 1]:
|
|
fail("duplicate version found:", v)
|
|
if v <= 0:
|
|
fail("all versions should be > 0, but found version:", v)
|
|
|
|
def _create_latest_version_aliases(name, last_version_name, backend_configs, **kwargs):
|
|
latest_name = name + "-latest"
|
|
native.alias(
|
|
name = latest_name,
|
|
actual = ":" + last_version_name,
|
|
**kwargs
|
|
)
|
|
for lang in backend_configs.keys():
|
|
language_binding_name = last_version_name + "-" + lang
|
|
native.alias(
|
|
name = latest_name + "-" + lang,
|
|
actual = ":" + language_binding_name,
|
|
**kwargs
|
|
)
|
|
|
|
def _versioned_name(name, version):
|
|
if version == "":
|
|
return name
|
|
|
|
return name + "-V" + version
|
|
|
|
# https://cs.android.com/android/platform/superproject/+/master:system/tools/aidl/build/aidl_interface.go;l=782-799;drc=5390d9a42f5e4f99ccb3a84068f554d948cb62b9
|
|
def _next_version(versions_with_info, unstable):
|
|
if unstable:
|
|
return ""
|
|
|
|
if versions_with_info == None or len(versions_with_info) == 0:
|
|
return "1"
|
|
|
|
return str(int(versions_with_info[-1]["version"]) + 1)
|
|
|
|
def _is_config_enabled(config):
|
|
if config == None:
|
|
return False
|
|
|
|
for key in config:
|
|
if key not in ["enabled", "min_sdk_version", "tags"]:
|
|
fail("unknown property in aidl configuration: " + str(key))
|
|
|
|
return config.get("enabled", False) == True
|
|
|
|
def aidl_interface(
|
|
name,
|
|
deps = [],
|
|
strip_import_prefix = "",
|
|
srcs = None,
|
|
flags = None,
|
|
java_config = None,
|
|
cpp_config = None,
|
|
ndk_config = None,
|
|
stability = None,
|
|
versions_with_info = [],
|
|
unstable = False,
|
|
tags = [],
|
|
# TODO(b/261208761): Support frozen attr
|
|
frozen = False,
|
|
**kwargs):
|
|
"""aidl_interface creates a versioned aidl_libraries and language-specific *_aidl_libraries
|
|
|
|
This macro loops over the list of required versions and searches for all
|
|
*.aidl source files located under the path `aidl_api/<version label/`.
|
|
For each version, an `aidl_library` is created with the corresponding sources.
|
|
For each `aidl_library`, a language-binding library *_aidl_library is created
|
|
based on the values passed to the `backends` argument.
|
|
|
|
Arguments:
|
|
name: string, base name of generated targets: <module-name>-V<version number>-<language-type>
|
|
deps: List[AidlGenInfo], a list of other aidl_libraries that all versions of this interface depend on
|
|
strip_import_prefix: str, a local directory to pass to the AIDL compiler to satisfy imports
|
|
srcs: List[file], a list of files to include in the development (unversioned) version of the aidl_interface
|
|
flags: List[string], a list of flags to pass to the AIDL compiler
|
|
java_config: Dict{"enabled": bool}, config for java backend
|
|
cpp_config: Dict{"enabled": bool, "min_sdk_version": string}, config for cpp backend
|
|
ndk_config: Dict{"enabled": bool, "min_sdk_version": string}, config for ndk backend
|
|
stability: string, stability promise of the interface. Currently, only supports "vintf"
|
|
backends: List[string], a list of the languages to generate bindings for
|
|
"""
|
|
|
|
# When versions_with_info is set, versions is no-op.
|
|
# TODO(b/244349745): Modify bp2build to skip convert versions if versions_with_info is set
|
|
if (len(versions_with_info) == 0 and srcs == None):
|
|
fail("must specify at least versions_with_info or srcs")
|
|
|
|
if len(versions_with_info) == 0:
|
|
if frozen == True:
|
|
fail("frozen cannot be set without versions_with_info attr being set")
|
|
elif unstable == True:
|
|
# https://cs.android.com/android/platform/superproject/+/master:system/tools/aidl/build/aidl_interface.go;l=872;drc=5390d9a42f5e4f99ccb3a84068f554d948cb62b9
|
|
fail("cannot have versions for unstable interface")
|
|
|
|
aidl_flags = ["--structured"]
|
|
if flags != None:
|
|
aidl_flags.extend(flags)
|
|
|
|
enabled_backend_configs = {}
|
|
if _is_config_enabled(java_config):
|
|
enabled_backend_configs[JAVA] = java_config
|
|
if _is_config_enabled(cpp_config):
|
|
enabled_backend_configs[CPP] = cpp_config
|
|
if _is_config_enabled(ndk_config):
|
|
enabled_backend_configs[NDK] = ndk_config
|
|
|
|
if stability != None:
|
|
if unstable == True:
|
|
fail("stability must be unset when unstable is true")
|
|
if stability == "vintf":
|
|
aidl_flags.append("--stability=" + stability)
|
|
|
|
# TODO(b/245738285): Add support for vintf stability in java backend
|
|
if JAVA in enabled_backend_configs:
|
|
enabled_backend_configs.pop(JAVA)
|
|
else:
|
|
# https://cs.android.com/android/platform/superproject/+/master:system/tools/aidl/build/aidl_interface.go;l=329;drc=e88d9a9b14eafb064a234d555a5cd96de97ca9e2
|
|
# only vintf is allowed currently
|
|
fail("stability must be unset or \"vintf\"")
|
|
|
|
# next_version will be the last specified version + 1.
|
|
# https://cs.android.com/android/platform/superproject/+/master:system/tools/aidl/build/aidl_interface.go;l=791?q=system%2Ftools%2Faidl%2Fbuild%2Faidl_interface.go
|
|
next_version = None
|
|
|
|
if len(versions_with_info) > 0:
|
|
_check_versions_with_info(versions_with_info)
|
|
next_version = _next_version(versions_with_info, False)
|
|
|
|
for version_with_info in versions_with_info:
|
|
deps_for_version = version_with_info.get("deps", [])
|
|
|
|
create_aidl_binding_for_backends(
|
|
name = name,
|
|
version = version_with_info["version"],
|
|
deps = deps_for_version,
|
|
aidl_flags = aidl_flags,
|
|
backend_configs = enabled_backend_configs,
|
|
tags = tags,
|
|
**kwargs
|
|
)
|
|
|
|
_create_latest_version_aliases(
|
|
name,
|
|
_versioned_name(name, versions_with_info[-1]["version"]),
|
|
enabled_backend_configs,
|
|
tags = tags,
|
|
**kwargs
|
|
)
|
|
else:
|
|
next_version = _next_version(versions_with_info, unstable)
|
|
|
|
# https://cs.android.com/android/platform/superproject/+/master:system/tools/aidl/build/aidl_interface.go;l=941;drc=5390d9a42f5e4f99ccb3a84068f554d948cb62b9
|
|
# Create aidl binding for next_version with srcs
|
|
if srcs and len(srcs) > 0:
|
|
create_aidl_binding_for_backends(
|
|
name = name,
|
|
version = next_version,
|
|
srcs = srcs,
|
|
strip_import_prefix = strip_import_prefix,
|
|
deps = deps,
|
|
aidl_flags = aidl_flags,
|
|
backend_configs = enabled_backend_configs,
|
|
tags = tags,
|
|
**kwargs
|
|
)
|
|
|
|
def create_aidl_binding_for_backends(
|
|
name,
|
|
version = None,
|
|
srcs = None,
|
|
strip_import_prefix = "",
|
|
deps = None,
|
|
aidl_flags = [],
|
|
backend_configs = {},
|
|
tags = [],
|
|
**kwargs):
|
|
"""
|
|
Create aidl_library target and corrending <backend>_aidl_library target for a given version
|
|
|
|
Arguments:
|
|
name: string, base name of the aidl interface
|
|
version: string, version of the aidl interface
|
|
srcs: List[Label] list of unversioned AIDL srcs
|
|
strip_import_prefix string, the prefix to strip the paths of the .aidl files in srcs
|
|
deps: List[AidlGenInfo], a list of other aidl_libraries that the version depends on
|
|
the label of the targets have format <aidl-interface>-V<version_number>
|
|
aidl_flags: List[string], a list of flags to pass to the AIDL compiler
|
|
backends: List[string], a list of the languages to generate bindings for
|
|
"""
|
|
aidl_library_name = _versioned_name(name, version)
|
|
|
|
# srcs is None when create_aidl_binding_for_backends is called with a
|
|
# frozen version specified via versions or versions_with_info.
|
|
# next_version being equal to "" means this is an unstable version and
|
|
# we should use srcs instead
|
|
if version != "":
|
|
aidl_flags = aidl_flags + ["--version=" + version]
|
|
|
|
hash_file = None
|
|
|
|
if srcs == None:
|
|
if version == "":
|
|
fail("need srcs for unversioned interface")
|
|
strip_import_prefix = "aidl_api/{}/{}".format(name, version)
|
|
srcs = native.glob([strip_import_prefix + "/**/*.aidl"])
|
|
hash_file = _hash_file(name, version)
|
|
|
|
aidl_library(
|
|
name = aidl_library_name,
|
|
deps = deps,
|
|
hash_file = hash_file,
|
|
version = version,
|
|
strip_import_prefix = strip_import_prefix,
|
|
srcs = srcs,
|
|
flags = aidl_flags,
|
|
# The language-specific backends will set more appropriate apex_available values.
|
|
tags = tags + ["apex_available=//apex_available:anyapex"],
|
|
**kwargs
|
|
)
|
|
|
|
for lang, config in backend_configs.items():
|
|
# https://cs.android.com/android/platform/superproject/+/master:system/tools/aidl/build/aidl_gen_rule.go;l=207;drc=a858ae7039b876a30002a1130f24196915a859a4
|
|
min_sdk_version = "current"
|
|
if "min_sdk_version" in config:
|
|
min_sdk_version = config["min_sdk_version"]
|
|
|
|
if lang == JAVA:
|
|
java_aidl_library(
|
|
name = aidl_library_name + "-java",
|
|
deps = [":" + aidl_library_name],
|
|
tags = tags + config.get("tags", []),
|
|
# TODO(b/249276008): Pass min_sdk_version to java_aidl_library
|
|
**(kwargs | {"target_compatible_with": ["//build/bazel/platforms/os:android"]})
|
|
)
|
|
elif lang == CPP or lang == NDK:
|
|
dynamic_deps = []
|
|
cppflags = []
|
|
|
|
# https://cs.android.com/android/platform/superproject/+/master:system/tools/aidl/build/aidl_interface_backends.go;l=564;drc=0517d97079d4b08f909e7f35edfa33b88fcc0d0e
|
|
if deps != None:
|
|
# For each aidl_library target label versioned_name, there's an
|
|
# associated cc_library_shared target with label versioned_name-<cpp|ndk>
|
|
dynamic_deps.extend(["{}-{}".format(dep, lang) for dep in deps])
|
|
|
|
# https://cs.android.com/android/platform/superproject/+/master:system/tools/aidl/build/aidl_interface_backends.go;l=111;drc=ef9f1352a1a8fec7bb134b1c713e13fc3ccee651
|
|
if lang == CPP:
|
|
dynamic_deps.extend([
|
|
"//frameworks/native/libs/binder:libbinder",
|
|
"//system/core/libutils:libutils",
|
|
])
|
|
elif lang == NDK:
|
|
dynamic_deps = dynamic_deps + select({
|
|
"//build/bazel/rules/apex:android-in_apex": ["//frameworks/native/libs/binder/ndk:libbinder_ndk_stub_libs_current"],
|
|
"//conditions:default": ["//frameworks/native/libs/binder/ndk:libbinder_ndk"],
|
|
})
|
|
|
|
# https://source.corp.google.com/android/system/tools/aidl/build/aidl_interface_backends.go;l=120;rcl=18dd931bde35b502545b7a52987e2363042c151c
|
|
cppflags = ["-DBINDER_STABILITY_SUPPORT"]
|
|
|
|
if hasattr(kwargs, "tidy_checks_as_errors"):
|
|
fail("tidy_checks_as_errors cannot be overriden for aidl_interface cc_libraries")
|
|
tidy_checks_as_errors = [
|
|
"*",
|
|
"-clang-analyzer-deadcode.DeadStores", # b/253079031
|
|
"-clang-analyzer-cplusplus.NewDeleteLeaks", # b/253079031
|
|
"-clang-analyzer-optin.performance.Padding", # b/253079031
|
|
]
|
|
|
|
cc_aidl_library(
|
|
name = "{}-{}".format(aidl_library_name, lang),
|
|
make_shared = True,
|
|
cppflags = cppflags,
|
|
deps = [":" + aidl_library_name],
|
|
dynamic_deps = dynamic_deps,
|
|
lang = lang,
|
|
min_sdk_version = min_sdk_version,
|
|
tidy = "local",
|
|
tidy_checks_as_errors = tidy_checks_as_errors,
|
|
tidy_gen_header_filter = True,
|
|
tags = tags + config.get("tags", []),
|
|
**kwargs
|
|
)
|