1# Copyright (C) 2023 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15load("@bazel_skylib//lib:paths.bzl", "paths")
16load("//build/bazel/rules/aconfig:aconfig_declarations.bzl", "AconfigDeclarationsInfo")
17load("//build/bazel/rules/cc:cc_library_shared.bzl", "cc_library_shared")
18load("//build/bazel/rules/cc:cc_library_static.bzl", "cc_library_static")
19
20def _cc_aconfig_code_gen_rule_impl(ctx):
21    gen_dir_str = paths.join(ctx.label.name, "gen")
22    header_dir_str = paths.join(gen_dir_str, "include")
23
24    aconfig_declarations = ctx.attr.aconfig_declarations[AconfigDeclarationsInfo]
25    basename = aconfig_declarations.package.replace(".", "_")
26    gen_cpp = ctx.actions.declare_file(paths.join(gen_dir_str, basename + ".cc"))
27    gen_header = ctx.actions.declare_file(paths.join(header_dir_str, basename + ".h"))
28    intermediate_path = aconfig_declarations.intermediate_path
29
30    args = ctx.actions.args()
31    args.add("create-cpp-lib")
32    args.add_all(["--cache", intermediate_path])
33    args.add_all(["--out", gen_cpp.dirname])
34
35    outputs = [gen_cpp, gen_header]
36
37    ctx.actions.run(
38        inputs = [intermediate_path],
39        executable = ctx.executable._aconfig,
40        outputs = outputs,
41        arguments = [args],
42        tools = [
43            ctx.executable._aconfig,
44        ],
45        mnemonic = "AconfigCreateCppLib",
46    )
47
48    compilation_context = cc_common.create_compilation_context(
49        headers = depset([gen_header]),
50        includes = depset([gen_header.dirname]),
51    )
52
53    return [
54        DefaultInfo(files = depset(direct = outputs)),
55        CcInfo(compilation_context = compilation_context),
56    ]
57
58_cc_aconfig_code_gen = rule(
59    implementation = _cc_aconfig_code_gen_rule_impl,
60    attrs = {
61        "aconfig_declarations": attr.label(
62            providers = [AconfigDeclarationsInfo],
63            mandatory = True,
64        ),
65        "_aconfig": attr.label(
66            allow_single_file = True,
67            executable = True,
68            cfg = "exec",
69            default = Label("//build/make/tools/aconfig:aconfig"),
70        ),
71    },
72    provides = [CcInfo],
73)
74
75def cc_aconfig_library(
76        name,
77        aconfig_declarations,
78        **kwargs):
79    gen_name = name + "_gen"
80
81    _cc_aconfig_code_gen(
82        name = gen_name,
83        aconfig_declarations = aconfig_declarations,
84        tags = ["manual"],
85    )
86
87    common_attrs = dict(
88        kwargs,
89        srcs = [":" + gen_name],
90        deps = [":" + gen_name],
91    )
92
93    cc_library_shared(
94        name = name,
95        **common_attrs
96    )
97
98    cc_library_static(
99        name = name + "_bp2build_cc_library_static",
100        **common_attrs
101    )
102