aboutsummaryrefslogtreecommitdiff
path: root/core/cc/library.py
blob: fb3576b6a3675d8039c6ce7078c16d1b116cefb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/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.

"""A module for compiling and linking cc artifacts."""

from ninja_tools import Ninja
from ninja_syntax import BuildAction, Rule

from functools import lru_cache
from typing import List

class CompileContext():

    def __init__(self, src: str, flags:str, out: str, frontend: str):
        self.src = src
        self.flags = flags
        self.out = out
        self.frontend = frontend

class Compiler():

    @lru_cache(maxsize=None)
    def _create_compile_rule(self, ninja: Ninja) -> Rule:
        rule = Rule("cc")
        rule.add_variable("description", "compile source to object file using clang/clang++")
        rule.add_variable("command", "${cFrontend} -c ${cFlags} -o ${out} ${in}")
        ninja.add_rule(rule)
        return rule

    def compile(self, ninja: Ninja, compile_context: CompileContext) -> None:
        compile_rule = self._create_compile_rule(ninja)

        compile_action = BuildAction(output=compile_context.out,
                    inputs=compile_context.src,
                    rule=compile_rule.name,
                    implicits=[compile_context.frontend]
                    )
        compile_action.add_variable("cFrontend", compile_context.frontend)
        compile_action.add_variable("cFlags", compile_context.flags)
        ninja.add_build_action(compile_action)

class LinkContext():

    def __init__(self, objs: List[str], flags: str, out: str, frontend: str):
        self.objs = objs
        self.flags = flags
        self.out = out
        self.frontend = frontend
        self.implicits = [frontend]

    def add_implicits(self, implicits: List[str]):
        self.implicits.extend(implicits)

class Linker():

    @lru_cache(maxsize=None)
    def _create_link_rule(self, ninja: Ninja) -> Rule:
        rule = Rule("ld")
        rule.add_variable("description", "link object files using clang/clang++")
        rule.add_variable("command", "${ldFrontend} ${ldFlags} -o ${out} ${in}")
        ninja.add_rule(rule)
        return rule

    def link(self, ninja: Ninja, link_context: LinkContext) -> None:
        link_rule = self._create_link_rule(ninja)

        link_action = BuildAction(output=link_context.out,
                inputs=link_context.objs,
                rule=link_rule.name,
                implicits=link_context.implicits,
                )
        link_action.add_variable("ldFrontend", link_context.frontend)
        link_action.add_variable("ldFlags", link_context.flags)
        ninja.add_build_action(link_action)