blob: 9b21c3278f0cbe509ee438825d3149d10427f4fb [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 (
Jingwen Chen73850672020-12-14 08:25:34 -050018 // The default `load` preamble for every generated queryview BUILD file.
Jingwen Chenb24e9702020-11-18 08:53:38 -050019 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.
Sasha Smundakfb589492022-08-04 11:13:27 -070026 soongModuleTargetTemplate = `soong_module(
Jingwen Chenb24e9702020-11-18 08:53:38 -050027 name = "%s",
Jingwen Chen288e2ba2021-01-25 04:36:04 -050028 soong_module_name = "%s",
29 soong_module_type = "%s",
30 soong_module_variant = "%s",
31 soong_module_deps = %s,
Jingwen Chenb24e9702020-11-18 08:53:38 -050032%s)`
33
Sasha Smundakfb589492022-08-04 11:13:27 -070034 ruleTargetTemplate = `%s(
Jingwen Chen73850672020-12-14 08:25:34 -050035 name = "%s",
36%s)`
37
Sasha Smundakfb589492022-08-04 11:13:27 -070038 unnamedRuleTargetTemplate = `%s(
39%s)`
40
Jingwen Chenb24e9702020-11-18 08:53:38 -050041 // A simple provider to mark and differentiate Soong module rule shims from
42 // regular Bazel rules. Every Soong module rule shim returns a
43 // SoongModuleInfo provider, and can only depend on rules returning
Jingwen Chen288e2ba2021-01-25 04:36:04 -050044 // SoongModuleInfo in the `soong_module_deps` attribute.
Jingwen Chenb24e9702020-11-18 08:53:38 -050045 providersBzl = `SoongModuleInfo = provider(
46 fields = {
47 "name": "Name of module",
48 "type": "Type of module",
49 "variant": "Variant of module",
50 },
51)
52`
53
54 // The soong_module rule implementation in a .bzl file.
55 soongModuleBzl = `
56%s
57
58load("//build/bazel/queryview_rules:providers.bzl", "SoongModuleInfo")
59
60def _generic_soong_module_impl(ctx):
61 return [
62 SoongModuleInfo(
Jingwen Chen288e2ba2021-01-25 04:36:04 -050063 name = ctx.attr.soong_module_name,
64 type = ctx.attr.soong_module_type,
65 variant = ctx.attr.soong_module_variant,
Jingwen Chenb24e9702020-11-18 08:53:38 -050066 ),
67 ]
68
69generic_soong_module = rule(
70 implementation = _generic_soong_module_impl,
71 attrs = {
Jingwen Chen288e2ba2021-01-25 04:36:04 -050072 "soong_module_name": attr.string(mandatory = True),
73 "soong_module_type": attr.string(mandatory = True),
74 "soong_module_variant": attr.string(),
75 "soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
Jingwen Chenb24e9702020-11-18 08:53:38 -050076 },
77)
78
79soong_module_rule_map = {
80%s}
81
82_SUPPORTED_TYPES = ["bool", "int", "string"]
83
84def _is_supported_type(value):
85 if type(value) in _SUPPORTED_TYPES:
86 return True
87 elif type(value) == "list":
88 supported = True
89 for v in value:
90 supported = supported and type(v) in _SUPPORTED_TYPES
91 return supported
92 else:
93 return False
94
Jingwen Chen288e2ba2021-01-25 04:36:04 -050095# soong_module is a macro that supports arbitrary kwargs, and uses soong_module_type to
Jingwen Chenb24e9702020-11-18 08:53:38 -050096# expand to the right underlying shim.
Jingwen Chen288e2ba2021-01-25 04:36:04 -050097def soong_module(name, soong_module_type, **kwargs):
98 soong_module_rule = soong_module_rule_map.get(soong_module_type)
Jingwen Chenb24e9702020-11-18 08:53:38 -050099
100 if soong_module_rule == None:
101 # This module type does not have an existing rule to map to, so use the
102 # generic_soong_module rule instead.
103 generic_soong_module(
104 name = name,
Jingwen Chen288e2ba2021-01-25 04:36:04 -0500105 soong_module_type = soong_module_type,
106 soong_module_name = kwargs.pop("soong_module_name", ""),
107 soong_module_variant = kwargs.pop("soong_module_variant", ""),
108 soong_module_deps = kwargs.pop("soong_module_deps", []),
Jingwen Chenb24e9702020-11-18 08:53:38 -0500109 )
110 else:
111 supported_kwargs = dict()
112 for key, value in kwargs.items():
113 if _is_supported_type(value):
114 supported_kwargs[key] = value
115 soong_module_rule(
116 name = name,
117 **supported_kwargs,
118 )
119`
120
121 // A rule shim for representing a Soong module type and its properties.
122 moduleRuleShim = `
123def _%[1]s_impl(ctx):
124 return [SoongModuleInfo()]
125
126%[1]s = rule(
127 implementation = _%[1]s_impl,
128 attrs = %[2]s
129)
130`
131)