blob: 2c7f9ff8ecb13b641ae72b5129245a2a68c7db62 [file] [log] [blame]
Liz Kammer33cc80e2023-05-18 18:20:28 +00001// Copyright 2022 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 android
16
17import (
18 "encoding/json"
Liz Kammer33cc80e2023-05-18 18:20:28 +000019 "os"
20 "strings"
21
22 "github.com/google/blueprint"
23)
24
25func init() {
26 RegisterPluginSingletonBuildComponents(InitRegistrationContext)
27}
28
29func RegisterPluginSingletonBuildComponents(ctx RegistrationContext) {
LaMont Jones9b44c2a2023-05-22 19:06:56 +000030 ctx.RegisterParallelSingletonType("plugins", pluginSingletonFactory)
Liz Kammer33cc80e2023-05-18 18:20:28 +000031}
32
33// pluginSingleton is a singleton to handle allowlisting of the final Android-<product_name>.mk file
34// output.
35func pluginSingletonFactory() Singleton {
36 return &pluginSingleton{}
37}
38
39type pluginSingleton struct{}
40
41var allowedPluginsByName = map[string]bool{
42 "aidl-soong-rules": true,
43 "arm_compute_library_nn_driver": true,
44 "cuttlefish-soong-rules": true,
45 "gki-soong-rules": true,
46 "hidl-soong-rules": true,
47 "kernel-config-soong-rules": true,
48 "soong-angle-codegen": true,
49 "soong-api": true,
50 "soong-art": true,
51 "soong-ca-certificates": true,
52 "soong-ca-certificates-apex": true,
53 "soong-clang": true,
54 "soong-clang-prebuilts": true,
55 "soong-csuite": true,
56 "soong-fluoride": true,
57 "soong-fs_config": true,
58 "soong-icu": true,
59 "soong-java-config-error_prone": true,
60 "soong-libchrome": true,
61 "soong-llvm": true,
62 "soong-robolectric": true,
63 "soong-rust-prebuilts": true,
64 "soong-selinux": true,
65 "soong-wayland-protocol-codegen": true,
66 "treble_report_app": true,
67 "treble_report_local": true,
68 "treble_report_module": true,
69 "vintf-compatibility-matrix-soong-rules": true,
70 "xsdc-soong-rules": true,
71}
72
Cole Faust97e19032023-10-20 11:51:33 -070073var internalPluginsPaths = []string{
74 "vendor/google/build/soong/internal_plugins.json",
75 "vendor/google_clockwork/build/internal_plugins.json",
76}
Liz Kammer33cc80e2023-05-18 18:20:28 +000077
78type pluginProvider interface {
79 IsPluginFor(string) bool
80}
81
82func maybeAddInternalPluginsToAllowlist(ctx SingletonContext) {
Cole Faust97e19032023-10-20 11:51:33 -070083 for _, internalPluginsPath := range internalPluginsPaths {
84 if path := ExistentPathForSource(ctx, internalPluginsPath); path.Valid() {
85 ctx.AddNinjaFileDeps(path.String())
86 absPath := absolutePath(path.String())
87 var moreAllowed map[string]bool
88 data, err := os.ReadFile(absPath)
89 if err != nil {
90 ctx.Errorf("Failed to open internal plugins path %q %q", internalPluginsPath, err)
91 }
92 if err := json.Unmarshal(data, &moreAllowed); err != nil {
93 ctx.Errorf("Internal plugins file %q did not parse correctly: %q", data, err)
94 }
95 for k, v := range moreAllowed {
96 allowedPluginsByName[k] = v
97 }
Liz Kammer33cc80e2023-05-18 18:20:28 +000098 }
99 }
100}
101
102func (p *pluginSingleton) GenerateBuildActions(ctx SingletonContext) {
103 for _, p := range ctx.DeviceConfig().BuildBrokenPluginValidation() {
104 allowedPluginsByName[p] = true
105 }
106 maybeAddInternalPluginsToAllowlist(ctx)
107
108 disallowedPlugins := map[string]bool{}
109 ctx.VisitAllModulesBlueprint(func(module blueprint.Module) {
110 if ctx.ModuleType(module) != "bootstrap_go_package" {
111 return
112 }
113
114 p, ok := module.(pluginProvider)
115 if !ok || !p.IsPluginFor("soong_build") {
116 return
117 }
118
119 name := ctx.ModuleName(module)
120 if _, ok := allowedPluginsByName[name]; ok {
121 return
122 }
123
124 dir := ctx.ModuleDir(module)
125
126 // allow use of plugins within Soong to not allowlist everything
127 if strings.HasPrefix(dir, "build/soong") {
128 return
129 }
130
131 // allow third party users outside of external to create new plugins, i.e. non-google paths
132 // under vendor or hardware
133 if !strings.HasPrefix(dir, "external/") && IsThirdPartyPath(dir) {
134 return
135 }
136 disallowedPlugins[name] = true
137 })
138 if len(disallowedPlugins) > 0 {
139 ctx.Errorf("New plugins are not supported; however %q were found. Please reach out to the build team or use BUILD_BROKEN_PLUGIN_VALIDATION (see Changes.md for more info).", SortedStringKeys(disallowedPlugins))
140 }
141}