blob: 9d55e7041a79c4912db8fd6fe7300d52215a775b [file] [log] [blame]
#!/usr/bin/python3
#
# 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.
from functools import lru_cache
import os
from build_file_generator import AndroidBpFile, AndroidBpModule, BuildFileGenerator, ConfigAxis
from utils import ASSEMBLE_PHONY_TARGET, Context
class JavaApiAssemblyContext(object):
"""Context object for managing global state of Java API Assembly."""
def get_java_api_assembler(self):
"""Return a callback to assemble Java APIs.
The callback is a member of the context object,
and therefore has access to its state."""
return self.assemble_java_api_library
@lru_cache(maxsize=None)
def _java_api_library_module(self, context: Context,
build_file_generator: BuildFileGenerator,
surface_name: str,
surface_version: str) -> AndroidBpModule:
"""Initializes the java_api_library AndroidBpModule for an API surface stub
Args:
context: Container for global state.
build_file_generator: Container for registering Android.bp files.
surface_name: API surface name (e.g. publicapi).
surface_version: API surface version (e.g. 29, 30, current).
Returns:
AndroidBpModule object
"""
# Create Android.bp module.
# There should be one stub library per (api_surface, version).
name = f"{surface_name}_{surface_version}"
api_library_module = AndroidBpModule(name=name,
module_type="java_api_library")
staging_dir = context.out.api_library_dir(surface_name,
surface_version, "")
# Create Android.bp file
bp_file = AndroidBpFile(directory=staging_dir)
bp_file.add_comment_string("WARNING: THIS IS AN AUTOGENERATED FILE.")
bp_file.add_module(api_library_module)
build_file_generator.add_android_bp_file(bp_file)
return api_library_module
def assemble_java_api_library(self, context: Context, ninja,
build_file_generator: BuildFileGenerator,
stub_library) -> None:
"""Assembles the API .txt files in the output directory.
Args:
context: Container for global state.
ninja: Ninja writer object. ninja_tools.Ninja instance.
build_file_generator: Container for registering Android.bp files.
stub_library: Container for APIs provided by a library an API surface
at a specific version. api_assembly.StubLibrary instance.
Returns:
None
"""
staging_dir = context.out.api_library_dir(
stub_library.api_surface,
stub_library.api_surface_version,
"",
)
# Create one java_api_library for the api surface. This should be
# idempotent.
api_library_module = self._java_api_library_module(
context, build_file_generator, stub_library.api_surface,
stub_library.api_surface_version)
api_deps = []
for c in stub_library.contributions:
# (A single API domain can provide multiple java libraries)
# Proposed layout
# out/api_surfaces/
# publicapi/current/
# <contribution1>/current.txt
# <contribution2>/current.txt
# ...
# systemapi/current/
# <contribution1>/current.txt
# <contribution1>/system-current.txt
# <contribution2>/current.txt
# <contribution2>/system-current.txt
# ...
name = c.library_contribution["name"]
api = c.library_contribution["api"]
api_out = os.path.join(staging_dir, name, os.path.basename(api))
ninja.add_copy_file(api_out, os.path.join(
c.inner_tree.root,
api,
))
# TODO: Short term hack to make the files in outer tree available to files
# in inner tree. This is needed because chdir'd trees cannot reach
# into outer tree's scope.
# The list of inner trees is hardcoded for now.
for inner_tree in ["system", "vendor", "apexes"]:
path_in_inner_tree = api_out.replace(
context.out.api_surfaces_dir(),
os.path.join(inner_tree, context.out.root(),
"api_surfaces"))
ninja.add_phony(path_in_inner_tree, api_out)
# Add the api file to java_api_library
api_library_module.extend_property(
prop="api_files",
val=[os.path.join(name, os.path.basename(api))])
api_deps.append(api_out)
# Add the api files as deps of the phony assembly target
ninja.add_global_phony(ASSEMBLE_PHONY_TARGET, api_deps)