blob: 75c3ccb9adf5f80d19155f1c8649b37ba04f52d8 [file] [log] [blame]
Jingwen Chenb24e9702020-11-18 08:53:38 -05001// Copyright 2020 Google Inc. All rights reserved.
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
Liz Kammer2dd9ca42020-11-25 16:06:39 -080015package bp2build
Jingwen Chenb24e9702020-11-18 08:53:38 -050016
17const (
18 // The default `load` preamble for every generated BUILD file.
19 soongModuleLoad = `package(default_visibility = ["//visibility:public"])
20load("//build/bazel/queryview_rules:soong_module.bzl", "soong_module")
21
22`
23
24 // A macro call in the BUILD file representing a Soong module, with space
25 // for expanding more attributes.
26 soongModuleTarget = `soong_module(
27 name = "%s",
28 module_name = "%s",
29 module_type = "%s",
30 module_variant = "%s",
31 module_deps = %s,
32%s)`
33
34 // A simple provider to mark and differentiate Soong module rule shims from
35 // regular Bazel rules. Every Soong module rule shim returns a
36 // SoongModuleInfo provider, and can only depend on rules returning
37 // SoongModuleInfo in the `module_deps` attribute.
38 providersBzl = `SoongModuleInfo = provider(
39 fields = {
40 "name": "Name of module",
41 "type": "Type of module",
42 "variant": "Variant of module",
43 },
44)
45`
46
47 // The soong_module rule implementation in a .bzl file.
48 soongModuleBzl = `
49%s
50
51load("//build/bazel/queryview_rules:providers.bzl", "SoongModuleInfo")
52
53def _generic_soong_module_impl(ctx):
54 return [
55 SoongModuleInfo(
56 name = ctx.attr.module_name,
57 type = ctx.attr.module_type,
58 variant = ctx.attr.module_variant,
59 ),
60 ]
61
62generic_soong_module = rule(
63 implementation = _generic_soong_module_impl,
64 attrs = {
65 "module_name": attr.string(mandatory = True),
66 "module_type": attr.string(mandatory = True),
67 "module_variant": attr.string(),
68 "module_deps": attr.label_list(providers = [SoongModuleInfo]),
69 },
70)
71
72soong_module_rule_map = {
73%s}
74
75_SUPPORTED_TYPES = ["bool", "int", "string"]
76
77def _is_supported_type(value):
78 if type(value) in _SUPPORTED_TYPES:
79 return True
80 elif type(value) == "list":
81 supported = True
82 for v in value:
83 supported = supported and type(v) in _SUPPORTED_TYPES
84 return supported
85 else:
86 return False
87
88# soong_module is a macro that supports arbitrary kwargs, and uses module_type to
89# expand to the right underlying shim.
90def soong_module(name, module_type, **kwargs):
91 soong_module_rule = soong_module_rule_map.get(module_type)
92
93 if soong_module_rule == None:
94 # This module type does not have an existing rule to map to, so use the
95 # generic_soong_module rule instead.
96 generic_soong_module(
97 name = name,
98 module_type = module_type,
99 module_name = kwargs.pop("module_name", ""),
100 module_variant = kwargs.pop("module_variant", ""),
101 module_deps = kwargs.pop("module_deps", []),
102 )
103 else:
104 supported_kwargs = dict()
105 for key, value in kwargs.items():
106 if _is_supported_type(value):
107 supported_kwargs[key] = value
108 soong_module_rule(
109 name = name,
110 **supported_kwargs,
111 )
112`
113
114 // A rule shim for representing a Soong module type and its properties.
115 moduleRuleShim = `
116def _%[1]s_impl(ctx):
117 return [SoongModuleInfo()]
118
119%[1]s = rule(
120 implementation = _%[1]s_impl,
121 attrs = %[2]s
122)
123`
124)