• 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 compiling and linking cc artifacts."""
18
19from ninja_tools import Ninja
20from ninja_syntax import BuildAction, Rule
21
22from functools import lru_cache
23from typing import List
24
25class CompileContext():
26
27    def __init__(self, src: str, flags:str, out: str, frontend: str):
28        self.src = src
29        self.flags = flags
30        self.out = out
31        self.frontend = frontend
32
33class Compiler():
34
35    @lru_cache(maxsize=None)
36    def _create_compile_rule(self, ninja: Ninja) -> Rule:
37        rule = Rule("cc")
38        rule.add_variable("description", "compile source to object file using clang/clang++")
39        rule.add_variable("command", "${cFrontend} -c ${cFlags} -o ${out} ${in}")
40        ninja.add_rule(rule)
41        return rule
42
43    def compile(self, ninja: Ninja, compile_context: CompileContext) -> None:
44        compile_rule = self._create_compile_rule(ninja)
45
46        compile_action = BuildAction(output=compile_context.out,
47                    inputs=compile_context.src,
48                    rule=compile_rule.name,
49                    implicits=[compile_context.frontend]
50                    )
51        compile_action.add_variable("cFrontend", compile_context.frontend)
52        compile_action.add_variable("cFlags", compile_context.flags)
53        ninja.add_build_action(compile_action)
54
55class LinkContext():
56
57    def __init__(self, objs: List[str], flags: str, out: str, frontend: str):
58        self.objs = objs
59        self.flags = flags
60        self.out = out
61        self.frontend = frontend
62        self.implicits = [frontend]
63
64    def add_implicits(self, implicits: List[str]):
65        self.implicits.extend(implicits)
66
67class Linker():
68
69    @lru_cache(maxsize=None)
70    def _create_link_rule(self, ninja: Ninja) -> Rule:
71        rule = Rule("ld")
72        rule.add_variable("description", "link object files using clang/clang++")
73        rule.add_variable("command", "${ldFrontend} ${ldFlags} -o ${out} ${in}")
74        ninja.add_rule(rule)
75        return rule
76
77    def link(self, ninja: Ninja, link_context: LinkContext) -> None:
78        link_rule = self._create_link_rule(ninja)
79
80        link_action = BuildAction(output=link_context.out,
81                inputs=link_context.objs,
82                rule=link_rule.name,
83                implicits=link_context.implicits,
84                )
85        link_action.add_variable("ldFrontend", link_context.frontend)
86        link_action.add_variable("ldFlags", link_context.flags)
87        ninja.add_build_action(link_action)
88