• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3
2#
3# Copyright (C) 2022 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""A module for writing ninja rules that generate C stubs."""
18
19import os
20
21from typing import NamedTuple
22
23from ninja_tools import Ninja
24from ninja_syntax import Variable, Rule, BuildAction
25
26# This is the path relative to outer tree root
27NDKSTUBGEN = "orchestrator/build/orchestrator/core/cc/ndkstubgen_runner.sh"
28
29class GenCcStubsInput:
30
31    def __init__(self, arch: str, version: str, api: str, version_map: str, additional_args=""):
32        self.arch = arch  # target device arch (e.g. x86)
33        self.version = version  # numeric API level (e.g. 33)
34        self.version_map = version_map # path to API level map (e.g. Q-->29)
35        self.api = api  # path to map.txt
36        self.additional_args = additional_args  # additional args to ndkstubgen (e.g. --llndk)
37
38class GenCcStubsOutput(NamedTuple):
39    stub: str
40    version_script: str
41    symbol_list: str
42
43class StubGenerator:
44
45    def __init__(self):
46        self._stubgen_rule = None
47
48    def _add_stubgen_rule(self, ninja: Ninja):
49        """This adds a ninja rule to run ndkstubgen
50
51        Running ndkstubgen creates C stubs from API .map.txt files
52        """
53        # Create a variable name for the binary.
54        ninja.add_variable(Variable("ndkstubgen", NDKSTUBGEN))
55
56        # Add a rule to the ninja file.
57        rule = Rule("genCcStubsRule")
58        rule.add_variable(
59            "description",
60            "Generate stub .c files from .map.txt API description files")
61        rule.add_variable(
62            "command",
63            "${ndkstubgen} --arch ${arch} --api ${apiLevel} --api-map ${apiMap} ${additionalArgs} ${in} ${out}"
64        )
65        ninja.add_rule(rule)
66        self._stubgen_rule = rule
67
68    def add_stubgen_action(self, ninja: Ninja, stub_input: GenCcStubsInput,
69                           work_dir: str) -> GenCcStubsOutput:
70        """This adds a ninja build action to generate stubs using `genCcStubsRule`"""
71        # Add stubgen rule if it has not been added yet.
72        if not self._stubgen_rule:
73            self._add_stubgen_rule(ninja)
74
75        outputs = GenCcStubsOutput(
76            stub=os.path.join(work_dir, stub_input.arch, "stub.c"),
77            version_script=os.path.join(work_dir, stub_input.arch, "stub.map"),
78            symbol_list=os.path.join(work_dir, stub_input.arch,
79                                     "abi_symbol_list.txt")
80        )
81
82        # Create the ninja build action.
83        stubgen_action = BuildAction(
84            output=list(outputs),
85            inputs=stub_input.api,
86            rule=self._stubgen_rule.name,
87            implicits=[
88                    NDKSTUBGEN,
89                    stub_input.version_map,
90            ],
91        )
92        stubgen_action.add_variable("arch", stub_input.arch)
93        stubgen_action.add_variable("apiLevel", stub_input.version)
94        stubgen_action.add_variable("apiMap", stub_input.version_map)
95        stubgen_action.add_variable("additionalArgs",
96                                           stub_input.additional_args)
97
98        # Add the build action to the ninja file.
99        ninja.add_build_action(stubgen_action)
100        return outputs
101