2023-05-18 20:20:28 +02:00
// Copyright 2022 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package android
import (
"encoding/json"
"os"
"strings"
"github.com/google/blueprint"
)
func init ( ) {
RegisterPluginSingletonBuildComponents ( InitRegistrationContext )
}
func RegisterPluginSingletonBuildComponents ( ctx RegistrationContext ) {
2023-05-22 21:06:56 +02:00
ctx . RegisterParallelSingletonType ( "plugins" , pluginSingletonFactory )
2023-05-18 20:20:28 +02:00
}
// pluginSingleton is a singleton to handle allowlisting of the final Android-<product_name>.mk file
// output.
func pluginSingletonFactory ( ) Singleton {
return & pluginSingleton { }
}
type pluginSingleton struct { }
var allowedPluginsByName = map [ string ] bool {
"aidl-soong-rules" : true ,
"arm_compute_library_nn_driver" : true ,
"cuttlefish-soong-rules" : true ,
"gki-soong-rules" : true ,
"hidl-soong-rules" : true ,
"kernel-config-soong-rules" : true ,
"soong-angle-codegen" : true ,
"soong-api" : true ,
"soong-art" : true ,
"soong-ca-certificates" : true ,
"soong-ca-certificates-apex" : true ,
"soong-clang" : true ,
"soong-clang-prebuilts" : true ,
"soong-csuite" : true ,
"soong-fluoride" : true ,
"soong-fs_config" : true ,
"soong-icu" : true ,
"soong-java-config-error_prone" : true ,
"soong-libchrome" : true ,
"soong-llvm" : true ,
"soong-robolectric" : true ,
"soong-rust-prebuilts" : true ,
"soong-selinux" : true ,
"soong-wayland-protocol-codegen" : true ,
"treble_report_app" : true ,
"treble_report_local" : true ,
"treble_report_module" : true ,
"vintf-compatibility-matrix-soong-rules" : true ,
"xsdc-soong-rules" : true ,
}
2023-10-20 20:51:33 +02:00
var internalPluginsPaths = [ ] string {
"vendor/google/build/soong/internal_plugins.json" ,
"vendor/google_clockwork/build/internal_plugins.json" ,
}
2023-05-18 20:20:28 +02:00
type pluginProvider interface {
IsPluginFor ( string ) bool
}
func maybeAddInternalPluginsToAllowlist ( ctx SingletonContext ) {
2023-10-20 20:51:33 +02:00
for _ , internalPluginsPath := range internalPluginsPaths {
if path := ExistentPathForSource ( ctx , internalPluginsPath ) ; path . Valid ( ) {
ctx . AddNinjaFileDeps ( path . String ( ) )
absPath := absolutePath ( path . String ( ) )
var moreAllowed map [ string ] bool
data , err := os . ReadFile ( absPath )
if err != nil {
ctx . Errorf ( "Failed to open internal plugins path %q %q" , internalPluginsPath , err )
}
if err := json . Unmarshal ( data , & moreAllowed ) ; err != nil {
ctx . Errorf ( "Internal plugins file %q did not parse correctly: %q" , data , err )
}
for k , v := range moreAllowed {
allowedPluginsByName [ k ] = v
}
2023-05-18 20:20:28 +02:00
}
}
}
func ( p * pluginSingleton ) GenerateBuildActions ( ctx SingletonContext ) {
for _ , p := range ctx . DeviceConfig ( ) . BuildBrokenPluginValidation ( ) {
allowedPluginsByName [ p ] = true
}
maybeAddInternalPluginsToAllowlist ( ctx )
disallowedPlugins := map [ string ] bool { }
ctx . VisitAllModulesBlueprint ( func ( module blueprint . Module ) {
if ctx . ModuleType ( module ) != "bootstrap_go_package" {
return
}
p , ok := module . ( pluginProvider )
if ! ok || ! p . IsPluginFor ( "soong_build" ) {
return
}
name := ctx . ModuleName ( module )
if _ , ok := allowedPluginsByName [ name ] ; ok {
return
}
dir := ctx . ModuleDir ( module )
// allow use of plugins within Soong to not allowlist everything
if strings . HasPrefix ( dir , "build/soong" ) {
return
}
// allow third party users outside of external to create new plugins, i.e. non-google paths
// under vendor or hardware
if ! strings . HasPrefix ( dir , "external/" ) && IsThirdPartyPath ( dir ) {
return
}
disallowedPlugins [ name ] = true
} )
if len ( disallowedPlugins ) > 0 {
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 ) )
}
}