plugin.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // 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. package android
  15. import (
  16. "encoding/json"
  17. "fmt"
  18. "io/ioutil"
  19. "os"
  20. "strings"
  21. "github.com/google/blueprint"
  22. )
  23. func init() {
  24. RegisterPluginSingletonBuildComponents(InitRegistrationContext)
  25. }
  26. func RegisterPluginSingletonBuildComponents(ctx RegistrationContext) {
  27. ctx.RegisterParallelSingletonType("plugins", pluginSingletonFactory)
  28. }
  29. // pluginSingleton is a singleton to handle allowlisting of the final Android-<product_name>.mk file
  30. // output.
  31. func pluginSingletonFactory() Singleton {
  32. return &pluginSingleton{}
  33. }
  34. type pluginSingleton struct{}
  35. var allowedPluginsByName = map[string]bool{
  36. "aidl-soong-rules": true,
  37. "arm_compute_library_nn_driver": true,
  38. "cuttlefish-soong-rules": true,
  39. "gki-soong-rules": true,
  40. "hidl-soong-rules": true,
  41. "kernel-config-soong-rules": true,
  42. "soong-angle-codegen": true,
  43. "soong-api": true,
  44. "soong-art": true,
  45. "soong-ca-certificates": true,
  46. "soong-ca-certificates-apex": true,
  47. "soong-clang": true,
  48. "soong-clang-prebuilts": true,
  49. "soong-csuite": true,
  50. "soong-fluoride": true,
  51. "soong-fs_config": true,
  52. "soong-icu": true,
  53. "soong-java-config-error_prone": true,
  54. "soong-libchrome": true,
  55. "soong-llvm": true,
  56. "soong-robolectric": true,
  57. "soong-rust-prebuilts": true,
  58. "soong-selinux": true,
  59. "soong-wayland-protocol-codegen": true,
  60. "treble_report_app": true,
  61. "treble_report_local": true,
  62. "treble_report_module": true,
  63. "vintf-compatibility-matrix-soong-rules": true,
  64. "xsdc-soong-rules": true,
  65. }
  66. const (
  67. internalPluginsPath = "vendor/google/build/soong/internal_plugins.json"
  68. )
  69. type pluginProvider interface {
  70. IsPluginFor(string) bool
  71. }
  72. func maybeAddInternalPluginsToAllowlist(ctx SingletonContext) {
  73. if path := ExistentPathForSource(ctx, internalPluginsPath); path.Valid() {
  74. ctx.AddNinjaFileDeps(path.String())
  75. absPath := absolutePath(path.String())
  76. var moreAllowed map[string]bool
  77. data, err := ioutil.ReadFile(absPath)
  78. if err != nil {
  79. ctx.Errorf("Failed to open internal plugins path %q %q", internalPluginsPath, err)
  80. }
  81. if err := json.Unmarshal(data, &moreAllowed); err != nil {
  82. fmt.Fprintf(os.Stderr, "Internal plugins file %q did not parse correctly: %q", data, err)
  83. }
  84. for k, v := range moreAllowed {
  85. allowedPluginsByName[k] = v
  86. }
  87. }
  88. }
  89. func (p *pluginSingleton) GenerateBuildActions(ctx SingletonContext) {
  90. for _, p := range ctx.DeviceConfig().BuildBrokenPluginValidation() {
  91. allowedPluginsByName[p] = true
  92. }
  93. maybeAddInternalPluginsToAllowlist(ctx)
  94. disallowedPlugins := map[string]bool{}
  95. ctx.VisitAllModulesBlueprint(func(module blueprint.Module) {
  96. if ctx.ModuleType(module) != "bootstrap_go_package" {
  97. return
  98. }
  99. p, ok := module.(pluginProvider)
  100. if !ok || !p.IsPluginFor("soong_build") {
  101. return
  102. }
  103. name := ctx.ModuleName(module)
  104. if _, ok := allowedPluginsByName[name]; ok {
  105. return
  106. }
  107. dir := ctx.ModuleDir(module)
  108. // allow use of plugins within Soong to not allowlist everything
  109. if strings.HasPrefix(dir, "build/soong") {
  110. return
  111. }
  112. // allow third party users outside of external to create new plugins, i.e. non-google paths
  113. // under vendor or hardware
  114. if !strings.HasPrefix(dir, "external/") && IsThirdPartyPath(dir) {
  115. return
  116. }
  117. disallowedPlugins[name] = true
  118. })
  119. if len(disallowedPlugins) > 0 {
  120. 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))
  121. }
  122. }