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