Loading Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ bootstrap_go_package { "android/notices.go", "android/onceper.go", "android/override_module.go", "android/package.go", "android/package_ctx.go", "android/path_properties.go", "android/paths.go", Loading Loading @@ -88,6 +89,7 @@ bootstrap_go_package { "android/namespace_test.go", "android/neverallow_test.go", "android/onceper_test.go", "android/package_test.go", "android/path_properties_test.go", "android/paths_test.go", "android/prebuilt_test.go", Loading README.md +37 −9 Original line number Diff line number Diff line Loading @@ -133,6 +133,25 @@ directory) there are two packages, `my/app`, and the subpackage `my/app/tests`. This is based on the Bazel package concept. The `package` module type allows information to be specified about a package. Only a single `package` module can be specified per package and in the case where there are multiple `.bp` files in the same package directory it is highly recommended that the `package` module (if required) is specified in the `Android.bp` file. Unlike most module type `package` does not have a `name` property. Instead the name is set to the name of the package, e.g. if the package is in `top/intermediate/package` then the package name is `//top/intermediate/package`. E.g. The following will set the default visibility for all the modules defined in the package and any subpackages that do not set their own default visibility (irrespective of whether they are in the same `.bp` file as the `package` module) to be visible to all the subpackages by default. ``` package { default_visibility: [":__subpackages"] } ``` ### Name resolution Soong provides the ability for modules in different directories to specify Loading Loading @@ -191,7 +210,7 @@ this module. For example, `//project:rule`, `//project/library:lib` or `//independent:evil`) * `["//project"]`: This is shorthand for `["//project:__pkg__"]` * `[":__subpackages__"]`: This is shorthand for `["//project:__subpackages__"]` where `//project` is the module's package. e.g. using `[":__subpackages__"]` in where `//project` is the module's package, e.g. using `[":__subpackages__"]` in `packages/apps/Settings/Android.bp` is equivalent to `//packages/apps/Settings:__subpackages__`. * `["//visibility:legacy_public"]`: The default visibility, behaves as Loading @@ -207,13 +226,22 @@ in `vendor/`, e.g. a module in `libcore` cannot declare that it is visible to say `vendor/google`, instead it must make itself visible to all packages within `vendor/` using `//vendor:__subpackages__`. If a module does not specify the `visibility` property the module is `//visibility:legacy_public`. Once the build has been completely switched over to soong it is possible that a global refactoring will be done to change this to `//visibility:private` at which point all modules that do not currently specify a `visibility` property will be updated to have `visibility = [//visibility:legacy_public]` added. It will then be the owner's responsibility to replace that with a more appropriate visibility. If a module does not specify the `visibility` property then it uses the `default_visibility` property of the `package` module in the module's package. If the `default_visibility` property is not set for the module's package then it will use the `default_visibility` of its closest ancestor package for which a `default_visibility` property is specified. If no `default_visibility` property can be found then the module uses the global default of `//visibility:legacy_public`. Once the build has been completely switched over to soong it is possible that a global refactoring will be done to change this to `//visibility:private` at which point all packages that do not currently specify a `default_visibility` property will be updated to have `default_visibility = [//visibility:legacy_public]` added. It will then be the owner's responsibility to replace that with a more appropriate visibility. ### Formatter Loading android/module.go +75 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,55 @@ type Module interface { BuildParamsForTests() []BuildParams RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams VariablesForTests() map[string]string // Get the qualified module id for this module. qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName // Get information about the properties that can contain visibility rules. visibilityProperties() []visibilityProperty } // Qualified id for a module type qualifiedModuleName struct { // The package (i.e. directory) in which the module is defined, without trailing / pkg string // The name of the module, empty string if package. name string } func (q qualifiedModuleName) String() string { if q.name == "" { return "//" + q.pkg } return "//" + q.pkg + ":" + q.name } func (q qualifiedModuleName) isRootPackage() bool { return q.pkg == "" && q.name == "" } // Get the id for the package containing this module. func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName { pkg := q.pkg if q.name == "" { if pkg == "" { panic(fmt.Errorf("Cannot get containing package id of root package")) } index := strings.LastIndex(pkg, "/") if index == -1 { pkg = "" } else { pkg = pkg[:index] } } return newPackageId(pkg) } func newPackageId(pkg string) qualifiedModuleName { // A qualified id for a package module has no name. return qualifiedModuleName{pkg: pkg, name: ""} } type nameProperties struct { Loading Loading @@ -236,6 +285,20 @@ type commonProperties struct { // //packages/apps/Settings:__subpackages__. // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public // for now. It is an error if it is used in a module. // // If a module does not specify the `visibility` property then it uses the // `default_visibility` property of the `package` module in the module's package. // // If a module does not specify the `visibility` property then it uses the // `default_visibility` property of the `package` module in the module's package. // // If the `default_visibility` property is not set for the module's package then // it will use the `default_visibility` of its closest ancestor package for which // a `default_visibility` property is specified. // // If no `default_visibility` property can be found then the module uses the // global default of `//visibility:legacy_public`. // // See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for // more details. Visibility []string Loading Loading @@ -571,6 +634,18 @@ func (m *ModuleBase) base() *ModuleBase { return m } func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()} } func (m *ModuleBase) visibilityProperties() []visibilityProperty { return []visibilityProperty{ newVisibilityProperty("visibility", func() []string { return m.base().commonProperties.Visibility }), } } func (m *ModuleBase) SetTarget(target Target, multiTargets []Target, primary bool) { m.commonProperties.CompileTarget = target m.commonProperties.CompileMultiTargets = multiTargets Loading android/mutator.go +2 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,8 @@ type RegisterMutatorFunc func(RegisterMutatorsContext) var preArch = []RegisterMutatorFunc{ registerLoadHookMutator, RegisterNamespaceMutator, // Rename package module types. registerPackageRenamer, RegisterPrebuiltsPreArchMutators, registerVisibilityRuleChecker, RegisterDefaultsPreArchMutators, Loading android/package.go 0 → 100644 +194 −0 Original line number Diff line number Diff line // Copyright 2019 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 ( "fmt" "sync/atomic" "github.com/google/blueprint" ) func init() { RegisterModuleType("package", PackageFactory) } // The information maintained about each package. type packageInfo struct { // The module from which this information was populated. If `duplicated` = true then this is the // module that has been renamed and must be used to report errors. module *packageModule // If true this indicates that there are two package statements in the same package which is not // allowed and will cause the build to fail. This flag is set by packageRenamer and checked in // packageErrorReporter duplicated bool } type packageProperties struct { Name string `blueprint:"mutated"` // Specifies the default visibility for all modules defined in this package. Default_visibility []string } type packageModule struct { ModuleBase properties packageProperties packageInfo *packageInfo } func (p *packageModule) GenerateAndroidBuildActions(ModuleContext) { // Nothing to do. } func (p *packageModule) GenerateBuildActions(ctx blueprint.ModuleContext) { // Nothing to do. } func (p *packageModule) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { // Override to create a package id. return newPackageId(ctx.ModuleDir()) } // Override to ensure that the default_visibility rules are checked by the visibility module during // its checking phase. func (p *packageModule) visibilityProperties() []visibilityProperty { return []visibilityProperty{ newVisibilityProperty("default_visibility", func() []string { return p.properties.Default_visibility }), } } func (p *packageModule) Name() string { return p.properties.Name } func (p *packageModule) setName(name string) { p.properties.Name = name } // Counter to ensure package modules are created with a unique name within whatever namespace they // belong. var packageCount uint32 = 0 func PackageFactory() Module { module := &packageModule{} // Get a unique if for the package. Has to be done atomically as the creation of the modules are // done in parallel. id := atomic.AddUint32(&packageCount, 1) name := fmt.Sprintf("soong_package_%d", id) module.properties.Name = name module.AddProperties(&module.properties) return module } // Registers the function that renames the packages. func registerPackageRenamer(ctx RegisterMutatorsContext) { ctx.BottomUp("packageRenamer", packageRenamer).Parallel() ctx.BottomUp("packageErrorReporter", packageErrorReporter).Parallel() } // Renames the package to match the package directory. // // This also creates a PackageInfo object for each package and uses that to detect and remember // duplicates for later error reporting. func packageRenamer(ctx BottomUpMutatorContext) { m, ok := ctx.Module().(*packageModule) if !ok { return } packageName := "//" + ctx.ModuleDir() pi := newPackageInfo(ctx, packageName, m) if pi.module != m { // Remember that the package was duplicated but do not rename as that will cause an error to // be logged with the generated name. Similarly, reporting the error here will use the generated // name as renames are only processed after this phase. pi.duplicated = true } else { // This is the first package module in this package so rename it to match the package name. m.setName(packageName) ctx.Rename(packageName) // Store a package info reference in the module. m.packageInfo = pi } } // Logs any deferred errors. func packageErrorReporter(ctx BottomUpMutatorContext) { m, ok := ctx.Module().(*packageModule) if !ok { return } packageDir := ctx.ModuleDir() packageName := "//" + packageDir // Get the PackageInfo for the package. Should have been populated in the packageRenamer phase. pi := findPackageInfo(ctx, packageName) if pi == nil { ctx.ModuleErrorf("internal error, expected package info to be present for package '%s'", packageName) return } if pi.module != m { // The package module has been duplicated but this is not the module that has been renamed so // ignore it. An error will be logged for the renamed module which will ensure that the error // message uses the correct name. return } // Check to see whether there are duplicate package modules in the package. if pi.duplicated { ctx.ModuleErrorf("package {...} specified multiple times") return } } type defaultPackageInfoKey string func newPackageInfo( ctx BaseModuleContext, packageName string, module *packageModule) *packageInfo { key := NewCustomOnceKey(defaultPackageInfoKey(packageName)) return ctx.Config().Once(key, func() interface{} { return &packageInfo{module: module} }).(*packageInfo) } // Get the PackageInfo for the package name (starts with //, no trailing /), is nil if no package // module type was specified. func findPackageInfo(ctx BaseModuleContext, packageName string) *packageInfo { key := NewCustomOnceKey(defaultPackageInfoKey(packageName)) pi := ctx.Config().Once(key, func() interface{} { return nil }) if pi == nil { return nil } else { return pi.(*packageInfo) } } Loading
Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,7 @@ bootstrap_go_package { "android/notices.go", "android/onceper.go", "android/override_module.go", "android/package.go", "android/package_ctx.go", "android/path_properties.go", "android/paths.go", Loading Loading @@ -88,6 +89,7 @@ bootstrap_go_package { "android/namespace_test.go", "android/neverallow_test.go", "android/onceper_test.go", "android/package_test.go", "android/path_properties_test.go", "android/paths_test.go", "android/prebuilt_test.go", Loading
README.md +37 −9 Original line number Diff line number Diff line Loading @@ -133,6 +133,25 @@ directory) there are two packages, `my/app`, and the subpackage `my/app/tests`. This is based on the Bazel package concept. The `package` module type allows information to be specified about a package. Only a single `package` module can be specified per package and in the case where there are multiple `.bp` files in the same package directory it is highly recommended that the `package` module (if required) is specified in the `Android.bp` file. Unlike most module type `package` does not have a `name` property. Instead the name is set to the name of the package, e.g. if the package is in `top/intermediate/package` then the package name is `//top/intermediate/package`. E.g. The following will set the default visibility for all the modules defined in the package and any subpackages that do not set their own default visibility (irrespective of whether they are in the same `.bp` file as the `package` module) to be visible to all the subpackages by default. ``` package { default_visibility: [":__subpackages"] } ``` ### Name resolution Soong provides the ability for modules in different directories to specify Loading Loading @@ -191,7 +210,7 @@ this module. For example, `//project:rule`, `//project/library:lib` or `//independent:evil`) * `["//project"]`: This is shorthand for `["//project:__pkg__"]` * `[":__subpackages__"]`: This is shorthand for `["//project:__subpackages__"]` where `//project` is the module's package. e.g. using `[":__subpackages__"]` in where `//project` is the module's package, e.g. using `[":__subpackages__"]` in `packages/apps/Settings/Android.bp` is equivalent to `//packages/apps/Settings:__subpackages__`. * `["//visibility:legacy_public"]`: The default visibility, behaves as Loading @@ -207,13 +226,22 @@ in `vendor/`, e.g. a module in `libcore` cannot declare that it is visible to say `vendor/google`, instead it must make itself visible to all packages within `vendor/` using `//vendor:__subpackages__`. If a module does not specify the `visibility` property the module is `//visibility:legacy_public`. Once the build has been completely switched over to soong it is possible that a global refactoring will be done to change this to `//visibility:private` at which point all modules that do not currently specify a `visibility` property will be updated to have `visibility = [//visibility:legacy_public]` added. It will then be the owner's responsibility to replace that with a more appropriate visibility. If a module does not specify the `visibility` property then it uses the `default_visibility` property of the `package` module in the module's package. If the `default_visibility` property is not set for the module's package then it will use the `default_visibility` of its closest ancestor package for which a `default_visibility` property is specified. If no `default_visibility` property can be found then the module uses the global default of `//visibility:legacy_public`. Once the build has been completely switched over to soong it is possible that a global refactoring will be done to change this to `//visibility:private` at which point all packages that do not currently specify a `default_visibility` property will be updated to have `default_visibility = [//visibility:legacy_public]` added. It will then be the owner's responsibility to replace that with a more appropriate visibility. ### Formatter Loading
android/module.go +75 −0 Original line number Diff line number Diff line Loading @@ -202,6 +202,55 @@ type Module interface { BuildParamsForTests() []BuildParams RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams VariablesForTests() map[string]string // Get the qualified module id for this module. qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName // Get information about the properties that can contain visibility rules. visibilityProperties() []visibilityProperty } // Qualified id for a module type qualifiedModuleName struct { // The package (i.e. directory) in which the module is defined, without trailing / pkg string // The name of the module, empty string if package. name string } func (q qualifiedModuleName) String() string { if q.name == "" { return "//" + q.pkg } return "//" + q.pkg + ":" + q.name } func (q qualifiedModuleName) isRootPackage() bool { return q.pkg == "" && q.name == "" } // Get the id for the package containing this module. func (q qualifiedModuleName) getContainingPackageId() qualifiedModuleName { pkg := q.pkg if q.name == "" { if pkg == "" { panic(fmt.Errorf("Cannot get containing package id of root package")) } index := strings.LastIndex(pkg, "/") if index == -1 { pkg = "" } else { pkg = pkg[:index] } } return newPackageId(pkg) } func newPackageId(pkg string) qualifiedModuleName { // A qualified id for a package module has no name. return qualifiedModuleName{pkg: pkg, name: ""} } type nameProperties struct { Loading Loading @@ -236,6 +285,20 @@ type commonProperties struct { // //packages/apps/Settings:__subpackages__. // ["//visibility:legacy_public"]: The default visibility, behaves as //visibility:public // for now. It is an error if it is used in a module. // // If a module does not specify the `visibility` property then it uses the // `default_visibility` property of the `package` module in the module's package. // // If a module does not specify the `visibility` property then it uses the // `default_visibility` property of the `package` module in the module's package. // // If the `default_visibility` property is not set for the module's package then // it will use the `default_visibility` of its closest ancestor package for which // a `default_visibility` property is specified. // // If no `default_visibility` property can be found then the module uses the // global default of `//visibility:legacy_public`. // // See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for // more details. Visibility []string Loading Loading @@ -571,6 +634,18 @@ func (m *ModuleBase) base() *ModuleBase { return m } func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { return qualifiedModuleName{pkg: ctx.ModuleDir(), name: ctx.ModuleName()} } func (m *ModuleBase) visibilityProperties() []visibilityProperty { return []visibilityProperty{ newVisibilityProperty("visibility", func() []string { return m.base().commonProperties.Visibility }), } } func (m *ModuleBase) SetTarget(target Target, multiTargets []Target, primary bool) { m.commonProperties.CompileTarget = target m.commonProperties.CompileMultiTargets = multiTargets Loading
android/mutator.go +2 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,8 @@ type RegisterMutatorFunc func(RegisterMutatorsContext) var preArch = []RegisterMutatorFunc{ registerLoadHookMutator, RegisterNamespaceMutator, // Rename package module types. registerPackageRenamer, RegisterPrebuiltsPreArchMutators, registerVisibilityRuleChecker, RegisterDefaultsPreArchMutators, Loading
android/package.go 0 → 100644 +194 −0 Original line number Diff line number Diff line // Copyright 2019 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 ( "fmt" "sync/atomic" "github.com/google/blueprint" ) func init() { RegisterModuleType("package", PackageFactory) } // The information maintained about each package. type packageInfo struct { // The module from which this information was populated. If `duplicated` = true then this is the // module that has been renamed and must be used to report errors. module *packageModule // If true this indicates that there are two package statements in the same package which is not // allowed and will cause the build to fail. This flag is set by packageRenamer and checked in // packageErrorReporter duplicated bool } type packageProperties struct { Name string `blueprint:"mutated"` // Specifies the default visibility for all modules defined in this package. Default_visibility []string } type packageModule struct { ModuleBase properties packageProperties packageInfo *packageInfo } func (p *packageModule) GenerateAndroidBuildActions(ModuleContext) { // Nothing to do. } func (p *packageModule) GenerateBuildActions(ctx blueprint.ModuleContext) { // Nothing to do. } func (p *packageModule) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleName { // Override to create a package id. return newPackageId(ctx.ModuleDir()) } // Override to ensure that the default_visibility rules are checked by the visibility module during // its checking phase. func (p *packageModule) visibilityProperties() []visibilityProperty { return []visibilityProperty{ newVisibilityProperty("default_visibility", func() []string { return p.properties.Default_visibility }), } } func (p *packageModule) Name() string { return p.properties.Name } func (p *packageModule) setName(name string) { p.properties.Name = name } // Counter to ensure package modules are created with a unique name within whatever namespace they // belong. var packageCount uint32 = 0 func PackageFactory() Module { module := &packageModule{} // Get a unique if for the package. Has to be done atomically as the creation of the modules are // done in parallel. id := atomic.AddUint32(&packageCount, 1) name := fmt.Sprintf("soong_package_%d", id) module.properties.Name = name module.AddProperties(&module.properties) return module } // Registers the function that renames the packages. func registerPackageRenamer(ctx RegisterMutatorsContext) { ctx.BottomUp("packageRenamer", packageRenamer).Parallel() ctx.BottomUp("packageErrorReporter", packageErrorReporter).Parallel() } // Renames the package to match the package directory. // // This also creates a PackageInfo object for each package and uses that to detect and remember // duplicates for later error reporting. func packageRenamer(ctx BottomUpMutatorContext) { m, ok := ctx.Module().(*packageModule) if !ok { return } packageName := "//" + ctx.ModuleDir() pi := newPackageInfo(ctx, packageName, m) if pi.module != m { // Remember that the package was duplicated but do not rename as that will cause an error to // be logged with the generated name. Similarly, reporting the error here will use the generated // name as renames are only processed after this phase. pi.duplicated = true } else { // This is the first package module in this package so rename it to match the package name. m.setName(packageName) ctx.Rename(packageName) // Store a package info reference in the module. m.packageInfo = pi } } // Logs any deferred errors. func packageErrorReporter(ctx BottomUpMutatorContext) { m, ok := ctx.Module().(*packageModule) if !ok { return } packageDir := ctx.ModuleDir() packageName := "//" + packageDir // Get the PackageInfo for the package. Should have been populated in the packageRenamer phase. pi := findPackageInfo(ctx, packageName) if pi == nil { ctx.ModuleErrorf("internal error, expected package info to be present for package '%s'", packageName) return } if pi.module != m { // The package module has been duplicated but this is not the module that has been renamed so // ignore it. An error will be logged for the renamed module which will ensure that the error // message uses the correct name. return } // Check to see whether there are duplicate package modules in the package. if pi.duplicated { ctx.ModuleErrorf("package {...} specified multiple times") return } } type defaultPackageInfoKey string func newPackageInfo( ctx BaseModuleContext, packageName string, module *packageModule) *packageInfo { key := NewCustomOnceKey(defaultPackageInfoKey(packageName)) return ctx.Config().Once(key, func() interface{} { return &packageInfo{module: module} }).(*packageInfo) } // Get the PackageInfo for the package name (starts with //, no trailing /), is nil if no package // module type was specified. func findPackageInfo(ctx BaseModuleContext, packageName string) *packageInfo { key := NewCustomOnceKey(defaultPackageInfoKey(packageName)) pi := ctx.Config().Once(key, func() interface{} { return nil }) if pi == nil { return nil } else { return pi.(*packageInfo) } }