Create sysprop_library soong module

A newly introduced sysprop_library soong module will generate a
java_sdk_library and a cc_library from .sysprop description files.
Both Java modules and C++ modules can link against sysprop_library
module, thus giving consistency for using generated sysprop API.

As Java controls accessibility of Internal / System properties with
@hide and @SystemApi, 2 different header files will be created. And
build system will selectively expose depending on the property owner
and the place where the client libraries go into.

Bug: 80125326
Bug: 122170616
Test: 1) Create sysprop_library module.
Test: 2) Create empty txt files under prebuilts/sdk.
Test: 3) Create api directory, make update-api, and see changes.
Test: 4) Try to link against sysprop_library with various clients.
Test: 5) Soc_specific, Device_specific, Product_specific, recovery flags
work as intended.
Change-Id: I78dc5780ccfbb4b69e5c61dec26b94e92d43c333
This commit is contained in:
Inseob Kim 2019-02-08 21:00:45 +09:00
parent 58b31ad33a
commit c0907f191a
15 changed files with 895 additions and 231 deletions

View file

@ -148,6 +148,7 @@ bootstrap_go_package {
"cc/sabi.go",
"cc/stl.go",
"cc/strip.go",
"cc/sysprop.go",
"cc/tidy.go",
"cc/util.go",
"cc/vndk.go",
@ -178,6 +179,8 @@ bootstrap_go_package {
"cc/genrule.go",
"cc/vendor_public_library.go",
"cc/testing.go",
],
testSrcs: [
"cc/cc_test.go",
@ -378,6 +381,25 @@ bootstrap_go_package {
pluginFor: ["soong_build"],
}
bootstrap_go_package {
name: "soong-sysprop",
pkgPath: "android/soong/sysprop",
deps: [
"blueprint",
"soong",
"soong-android",
"soong-cc",
"soong-java",
],
srcs: [
"sysprop/sysprop_library.go",
],
testSrcs: [
"sysprop/sysprop_test.go",
],
pluginFor: ["soong_build"],
}
//
// Defaults to enable various configurations of host bionic
//

View file

@ -123,7 +123,7 @@ type hooks struct {
install []func(InstallHookContext)
}
func loadHookMutator(ctx TopDownMutatorContext) {
func LoadHookMutator(ctx TopDownMutatorContext) {
if m, ok := ctx.Module().(Module); ok {
// Cast through *androidTopDownMutatorContext because AppendProperties is implemented
// on *androidTopDownMutatorContext but not exposed through TopDownMutatorContext

View file

@ -74,7 +74,7 @@ type RegisterMutatorFunc func(RegisterMutatorsContext)
var preArch = []RegisterMutatorFunc{
func(ctx RegisterMutatorsContext) {
ctx.TopDown("load_hooks", loadHookMutator).Parallel()
ctx.TopDown("load_hooks", LoadHookMutator).Parallel()
},
RegisterNamespaceMutator,
RegisterPrebuiltsPreArchMutators,

View file

@ -41,6 +41,7 @@ func init() {
ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel()
ctx.BottomUp("version", VersionMutator).Parallel()
ctx.BottomUp("begin", BeginMutator).Parallel()
ctx.BottomUp("sysprop", SyspropMutator).Parallel()
})
android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
@ -1211,11 +1212,18 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
{Mutator: "link", Variation: "static"},
}, wholeStaticDepTag, deps.WholeStaticLibs...)
syspropImplLibraries := syspropImplLibraries(actx.Config())
for _, lib := range deps.StaticLibs {
depTag := staticDepTag
if inList(lib, deps.ReexportStaticLibHeaders) {
depTag = staticExportDepTag
}
if impl, ok := syspropImplLibraries[lib]; ok {
lib = impl
}
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
}, depTag, lib)
@ -1253,12 +1261,18 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
var sharedLibNames []string
for _, lib := range deps.SharedLibs {
name, version := stubsLibNameAndVersion(lib)
sharedLibNames = append(sharedLibNames, name)
depTag := sharedDepTag
if inList(lib, deps.ReexportSharedLibHeaders) {
depTag = sharedExportDepTag
}
if impl, ok := syspropImplLibraries[lib]; ok {
lib = impl
}
name, version := stubsLibNameAndVersion(lib)
sharedLibNames = append(sharedLibNames, name)
addSharedLibDependencies(depTag, name, version)
}

View file

@ -51,165 +51,6 @@ func TestMain(m *testing.M) {
os.Exit(run())
}
func gatherRequiredDeps(os android.OsType) string {
ret := `
toolchain_library {
name: "libatomic",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libcompiler_rt-extras",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libclang_rt.builtins-arm-android",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libclang_rt.builtins-aarch64-android",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libclang_rt.builtins-i686-android",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libclang_rt.builtins-x86_64-android",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libgcc",
vendor_available: true,
recovery_available: true,
src: "",
}
cc_library {
name: "libc",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
recovery_available: true,
}
llndk_library {
name: "libc",
symbol_file: "",
}
cc_library {
name: "libm",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
recovery_available: true,
}
llndk_library {
name: "libm",
symbol_file: "",
}
cc_library {
name: "libdl",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
recovery_available: true,
}
llndk_library {
name: "libdl",
symbol_file: "",
}
cc_library {
name: "libc++_static",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
vendor_available: true,
recovery_available: true,
}
cc_library {
name: "libc++",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
vendor_available: true,
recovery_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
}
cc_library {
name: "libunwind_llvm",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
vendor_available: true,
recovery_available: true,
}
cc_object {
name: "crtbegin_so",
recovery_available: true,
vendor_available: true,
}
cc_object {
name: "crtbegin_static",
recovery_available: true,
vendor_available: true,
}
cc_object {
name: "crtend_so",
recovery_available: true,
vendor_available: true,
}
cc_object {
name: "crtend_android",
recovery_available: true,
vendor_available: true,
}
cc_library {
name: "libprotobuf-cpp-lite",
}
`
if os == android.Fuchsia {
ret += `
cc_library {
name: "libbioniccompat",
stl: "none",
}
cc_library {
name: "libcompiler_rt",
stl: "none",
}
`
}
return ret
}
func createTestContext(t *testing.T, config android.Config, bp string, os android.OsType) *android.TestContext {
ctx := android.NewTestArchContext()
ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(BinaryFactory))
@ -233,7 +74,7 @@ func createTestContext(t *testing.T, config android.Config, bp string, os androi
ctx.Register()
// add some modules that are required by the compiler and/or linker
bp = bp + gatherRequiredDeps(os)
bp = bp + GatherRequiredDepsForTest(os)
ctx.MockFileSystem(map[string][]byte{
"Android.bp": []byte(bp),

View file

@ -56,10 +56,11 @@ var (
sysprop = pctx.AndroidStaticRule("sysprop",
blueprint.RuleParams{
Command: "$syspropCmd --header-output-dir=$headerOutDir --source-output-dir=$srcOutDir --include-name=$includeName $in",
Command: "$syspropCmd --header-dir=$headerOutDir --system-header-dir=$systemOutDir " +
"--source-dir=$srcOutDir --include-name=$includeName $in",
CommandDeps: []string{"$syspropCmd"},
},
"headerOutDir", "srcOutDir", "includeName")
"headerOutDir", "systemOutDir", "srcOutDir", "includeName")
windmc = pctx.AndroidStaticRule("windmc",
blueprint.RuleParams{
@ -114,6 +115,7 @@ func genLex(ctx android.ModuleContext, lexFile android.Path, outFile android.Mod
func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Path, android.Path) {
headerFile := android.PathForModuleGen(ctx, "sysprop", "include", syspropFile.Rel()+".h")
systemHeaderFile := android.PathForModuleGen(ctx, "sysprop/system", "include", syspropFile.Rel()+".h")
cppFile := android.PathForModuleGen(ctx, "sysprop", syspropFile.Rel()+".cpp")
ctx.Build(pctx, android.BuildParams{
@ -124,6 +126,7 @@ func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Pa
Input: syspropFile,
Args: map[string]string{
"headerOutDir": filepath.Dir(headerFile.String()),
"systemOutDir": filepath.Dir(systemHeaderFile.String()),
"srcOutDir": filepath.Dir(cppFile.String()),
"includeName": syspropFile.Rel() + ".h",
},

View file

@ -67,6 +67,11 @@ type LibraryProperties struct {
Export_proto_headers *bool
}
Sysprop struct {
// Whether platform owns this sysprop library.
Platform *bool
}
Static_ndk_lib *bool
Stubs struct {
@ -836,9 +841,27 @@ func (library *libraryDecorator) link(ctx ModuleContext,
}
if library.baseCompiler.hasSrcExt(".sysprop") {
flags := []string{
internalFlags := []string{
"-I" + android.PathForModuleGen(ctx, "sysprop", "include").String(),
}
systemFlags := []string{
"-I" + android.PathForModuleGen(ctx, "sysprop/system", "include").String(),
}
flags := internalFlags
if library.Properties.Sysprop.Platform != nil {
isProduct := ctx.ProductSpecific() && !ctx.useVndk()
isVendor := ctx.useVndk()
isOwnerPlatform := Bool(library.Properties.Sysprop.Platform)
useSystem := isProduct || (isOwnerPlatform == isVendor)
if useSystem {
flags = systemFlags
}
}
library.reexportFlags(flags)
library.reexportDeps(library.baseCompiler.pathDeps)
library.reuseExportedFlags = append(library.reuseExportedFlags, flags...)

47
cc/sysprop.go Normal file
View file

@ -0,0 +1,47 @@
// Copyright (C) 2019 The Android Open Source Project
//
// 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 cc
import (
"sync"
"android/soong/android"
)
type syspropLibraryInterface interface {
CcModuleName() string
}
var (
syspropImplLibrariesKey = android.NewOnceKey("syspropImplLibirares")
syspropImplLibrariesLock sync.Mutex
)
func syspropImplLibraries(config android.Config) map[string]string {
return config.Once(syspropImplLibrariesKey, func() interface{} {
return make(map[string]string)
}).(map[string]string)
}
// gather list of sysprop libraries
func SyspropMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(syspropLibraryInterface); ok {
syspropImplLibraries := syspropImplLibraries(mctx.Config())
syspropImplLibrariesLock.Lock()
defer syspropImplLibrariesLock.Unlock()
syspropImplLibraries[mctx.ModuleName()] = m.CcModuleName()
}
}

188
cc/testing.go Normal file
View file

@ -0,0 +1,188 @@
// Copyright (C) 2019 The Android Open Source Project
//
// 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 cc
import (
"android/soong/android"
)
func GatherRequiredDepsForTest(os android.OsType) string {
ret := `
toolchain_library {
name: "libatomic",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libcompiler_rt-extras",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libclang_rt.builtins-arm-android",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libclang_rt.builtins-aarch64-android",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libclang_rt.builtins-i686-android",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libclang_rt.builtins-x86_64-android",
vendor_available: true,
recovery_available: true,
src: "",
}
toolchain_library {
name: "libgcc",
vendor_available: true,
recovery_available: true,
src: "",
}
cc_library {
name: "libbase",
no_libgcc: true,
nocrt: true,
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
}
}
cc_library {
name: "libc",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
recovery_available: true,
}
llndk_library {
name: "libc",
symbol_file: "",
}
cc_library {
name: "libm",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
recovery_available: true,
}
llndk_library {
name: "libm",
symbol_file: "",
}
cc_library {
name: "libdl",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
recovery_available: true,
}
llndk_library {
name: "libdl",
symbol_file: "",
}
cc_library {
name: "libc++_static",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
vendor_available: true,
recovery_available: true,
}
cc_library {
name: "libc++",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
vendor_available: true,
recovery_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
}
cc_library {
name: "libunwind_llvm",
no_libgcc: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
vendor_available: true,
recovery_available: true,
}
cc_object {
name: "crtbegin_so",
recovery_available: true,
vendor_available: true,
}
cc_object {
name: "crtbegin_static",
recovery_available: true,
vendor_available: true,
}
cc_object {
name: "crtend_so",
recovery_available: true,
vendor_available: true,
}
cc_object {
name: "crtend_android",
recovery_available: true,
vendor_available: true,
}
cc_library {
name: "libprotobuf-cpp-lite",
}
`
if os == android.Fuchsia {
ret += `
cc_library {
name: "libbioniccompat",
stl: "none",
}
cc_library {
name: "libcompiler_rt",
stl: "none",
}
`
}
return ret
}

View file

@ -599,6 +599,9 @@ func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
case ".aidl":
javaFile := genAidl(ctx, srcFile, flags.aidlFlags)
outSrcFiles = append(outSrcFiles, javaFile)
case ".sysprop":
javaFile := genSysprop(ctx, srcFile)
outSrcFiles = append(outSrcFiles, javaFile)
default:
outSrcFiles = append(outSrcFiles, srcFile)
}

View file

@ -90,14 +90,14 @@ func testContext(config android.Config, bp string,
ctx.RegisterModuleType("droiddoc", android.ModuleFactoryAdaptor(DroiddocFactory))
ctx.RegisterModuleType("droiddoc_host", android.ModuleFactoryAdaptor(DroiddocHostFactory))
ctx.RegisterModuleType("droiddoc_template", android.ModuleFactoryAdaptor(ExportedDroiddocDirFactory))
ctx.RegisterModuleType("java_sdk_library", android.ModuleFactoryAdaptor(sdkLibraryFactory))
ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(prebuiltApisFactory))
ctx.RegisterModuleType("java_sdk_library", android.ModuleFactoryAdaptor(SdkLibraryFactory))
ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(PrebuiltApisFactory))
ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
ctx.TopDown("prebuilt_apis", prebuiltApisMutator).Parallel()
ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
ctx.TopDown("java_sdk_library", SdkLibraryMutator).Parallel()
})
ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
ctx.RegisterPreSingletonType("sdk", android.SingletonFactoryAdaptor(sdkSingletonFactory))

View file

@ -30,10 +30,10 @@ import (
// It also creates <module>-api.<scope>.latest for the lastest <ver>.
//
func init() {
android.RegisterModuleType("prebuilt_apis", prebuiltApisFactory)
android.RegisterModuleType("prebuilt_apis", PrebuiltApisFactory)
android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
ctx.TopDown("prebuilt_apis", prebuiltApisMutator).Parallel()
ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
})
}
@ -176,14 +176,14 @@ func prebuiltApiFiles(mctx android.TopDownMutatorContext) {
}
}
func prebuiltApisMutator(mctx android.TopDownMutatorContext) {
func PrebuiltApisMutator(mctx android.TopDownMutatorContext) {
if _, ok := mctx.Module().(*prebuiltApis); ok {
prebuiltApiFiles(mctx)
prebuiltSdkStubs(mctx)
}
}
func prebuiltApisFactory() android.Module {
func PrebuiltApisFactory() android.Module {
module := &prebuiltApis{}
module.AddProperties(&module.properties)
android.InitAndroidModule(module)

View file

@ -42,6 +42,10 @@ type stubsLibraryDependencyTag struct {
name string
}
type syspropLibraryInterface interface {
SyspropJavaModule() *SdkLibrary
}
var (
publicApiStubsTag = dependencyTag{name: "public"}
systemApiStubsTag = dependencyTag{name: "system"}
@ -74,10 +78,10 @@ var (
// 2) HTML generation
func init() {
android.RegisterModuleType("java_sdk_library", sdkLibraryFactory)
android.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
ctx.TopDown("java_sdk_library", SdkLibraryMutator).Parallel()
})
android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
@ -133,7 +137,7 @@ type sdkLibraryProperties struct {
//Html_doc *bool
}
type sdkLibrary struct {
type SdkLibrary struct {
Library
sdkLibraryProperties sdkLibraryProperties
@ -151,10 +155,10 @@ type sdkLibrary struct {
testApiFilePath android.Path
}
var _ Dependency = (*sdkLibrary)(nil)
var _ SdkLibraryDependency = (*sdkLibrary)(nil)
var _ Dependency = (*SdkLibrary)(nil)
var _ SdkLibraryDependency = (*SdkLibrary)(nil)
func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies to the stubs library
ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
@ -169,7 +173,7 @@ func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
module.Library.deps(ctx)
}
func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
module.Library.GenerateAndroidBuildActions(ctx)
// Record the paths to the header jars of the library (stubs and impl).
@ -207,7 +211,7 @@ func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
})
}
func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
func (module *SdkLibrary) AndroidMk() android.AndroidMkData {
data := module.Library.AndroidMk()
data.Required = append(data.Required, module.xmlFileName())
@ -267,7 +271,7 @@ func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
}
// Module name of the stubs library
func (module *sdkLibrary) stubsName(apiScope apiScope) string {
func (module *SdkLibrary) stubsName(apiScope apiScope) string {
stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
switch apiScope {
case apiScopeSystem:
@ -279,7 +283,7 @@ func (module *sdkLibrary) stubsName(apiScope apiScope) string {
}
// Module name of the docs
func (module *sdkLibrary) docsName(apiScope apiScope) string {
func (module *SdkLibrary) docsName(apiScope apiScope) string {
docsName := module.BaseModuleName() + sdkDocsSuffix
switch apiScope {
case apiScopeSystem:
@ -291,12 +295,12 @@ func (module *sdkLibrary) docsName(apiScope apiScope) string {
}
// Module name of the runtime implementation library
func (module *sdkLibrary) implName() string {
func (module *SdkLibrary) implName() string {
return module.BaseModuleName()
}
// File path to the runtime implementation library
func (module *sdkLibrary) implPath() string {
func (module *SdkLibrary) implPath() string {
partition := "system"
if module.SocSpecific() {
partition = "vendor"
@ -309,14 +313,14 @@ func (module *sdkLibrary) implPath() string {
}
// Module name of the XML file for the lib
func (module *sdkLibrary) xmlFileName() string {
func (module *SdkLibrary) xmlFileName() string {
return module.BaseModuleName() + sdkXmlFileSuffix
}
// SDK version that the stubs library is built against. Note that this is always
// *current. Older stubs library built with a numberd SDK version is created from
// the prebuilt jar.
func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
func (module *SdkLibrary) sdkVersion(apiScope apiScope) string {
switch apiScope {
case apiScopePublic:
return "current"
@ -332,7 +336,7 @@ func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
// api file for the current source
// TODO: remove this when apicheck is done in soong
func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
func (module *SdkLibrary) apiTagName(apiScope apiScope) string {
apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
switch apiScope {
case apiScopeSystem:
@ -343,7 +347,7 @@ func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
return apiTagName
}
func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
func (module *SdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
name := ":" + module.BaseModuleName() + ".api."
switch apiScope {
case apiScopePublic:
@ -357,7 +361,7 @@ func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
return name
}
func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
name := ":" + module.BaseModuleName() + "-removed.api."
switch apiScope {
case apiScopePublic:
@ -372,7 +376,7 @@ func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) strin
}
// Creates a static java library that has API stubs
func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
func (module *SdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
props := struct {
Name *string
Srcs []string
@ -431,7 +435,7 @@ func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext,
// Creates a droiddoc module that creates stubs source files from the given full source
// files
func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
func (module *SdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
props := struct {
Name *string
Srcs []string
@ -528,7 +532,7 @@ func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScop
}
// Creates the xml file that publicizes the runtime library
func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
func (module *SdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
template := `
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project
@ -587,7 +591,7 @@ func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
}
func (module *sdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
func (module *SdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
var api, v string
if sdkVersion == "" {
api = "system"
@ -607,7 +611,7 @@ func (module *sdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion strin
}
// to satisfy SdkLibraryDependency interface
func (module *sdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
// This module is just a wrapper for the stubs.
if ctx.Config().UnbundledBuildPrebuiltSdks() {
return module.PrebuiltJars(ctx, sdkVersion)
@ -623,7 +627,7 @@ func (module *sdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion stri
}
// to satisfy SdkLibraryDependency interface
func (module *sdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
// This module is just a wrapper for the stubs.
if ctx.Config().UnbundledBuildPrebuiltSdks() {
return module.PrebuiltJars(ctx, sdkVersion)
@ -649,42 +653,47 @@ func javaSdkLibraries(config android.Config) *[]string {
// For a java_sdk_library module, create internal modules for stubs, docs,
// runtime libs and xml file. If requested, the stubs and docs are created twice
// once for public API level and once for system API level
func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
if module, ok := mctx.Module().(*sdkLibrary); ok {
if module.Library.Module.properties.Srcs == nil {
mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
}
if module.sdkLibraryProperties.Api_packages == nil {
mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
}
// for public API stubs
module.createStubsLibrary(mctx, apiScopePublic)
module.createDocs(mctx, apiScopePublic)
if !Bool(module.properties.No_standard_libs) {
// for system API stubs
module.createStubsLibrary(mctx, apiScopeSystem)
module.createDocs(mctx, apiScopeSystem)
// for test API stubs
module.createStubsLibrary(mctx, apiScopeTest)
module.createDocs(mctx, apiScopeTest)
// for runtime
module.createXmlFile(mctx)
}
// record java_sdk_library modules so that they are exported to make
javaSdkLibraries := javaSdkLibraries(mctx.Config())
javaSdkLibrariesLock.Lock()
defer javaSdkLibrariesLock.Unlock()
*javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
func SdkLibraryMutator(mctx android.TopDownMutatorContext) {
if module, ok := mctx.Module().(*SdkLibrary); ok {
module.createInternalModules(mctx)
} else if module, ok := mctx.Module().(syspropLibraryInterface); ok {
module.SyspropJavaModule().createInternalModules(mctx)
}
}
func sdkLibraryFactory() android.Module {
module := &sdkLibrary{}
func (module *SdkLibrary) createInternalModules(mctx android.TopDownMutatorContext) {
if module.Library.Module.properties.Srcs == nil {
mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
}
if module.sdkLibraryProperties.Api_packages == nil {
mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
}
// for public API stubs
module.createStubsLibrary(mctx, apiScopePublic)
module.createDocs(mctx, apiScopePublic)
if !Bool(module.properties.No_standard_libs) {
// for system API stubs
module.createStubsLibrary(mctx, apiScopeSystem)
module.createDocs(mctx, apiScopeSystem)
// for test API stubs
module.createStubsLibrary(mctx, apiScopeTest)
module.createDocs(mctx, apiScopeTest)
// for runtime
module.createXmlFile(mctx)
}
// record java_sdk_library modules so that they are exported to make
javaSdkLibraries := javaSdkLibraries(mctx.Config())
javaSdkLibrariesLock.Lock()
defer javaSdkLibrariesLock.Unlock()
*javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
}
func (module *SdkLibrary) InitSdkLibraryProperties() {
module.AddProperties(
&module.sdkLibraryProperties,
&module.Library.Module.properties,
@ -695,7 +704,11 @@ func sdkLibraryFactory() android.Module {
module.Library.Module.properties.Installable = proptools.BoolPtr(true)
module.Library.Module.deviceProperties.IsSDKLibrary = true
}
func SdkLibraryFactory() android.Module {
module := &SdkLibrary{}
module.InitSdkLibraryProperties()
InitJavaModule(module, android.HostAndDeviceSupported)
return module
}

130
sysprop/sysprop_library.go Normal file
View file

@ -0,0 +1,130 @@
// Copyright (C) 2019 The Android Open Source Project
//
// 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 sysprop
import (
"android/soong/android"
"android/soong/cc"
"android/soong/java"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
type dependencyTag struct {
blueprint.BaseDependencyTag
name string
}
type syspropLibrary struct {
java.SdkLibrary
commonProperties commonProperties
syspropLibraryProperties syspropLibraryProperties
}
type syspropLibraryProperties struct {
// Determine who owns this sysprop library. Possible values are
// "Platform", "Vendor", or "Odm"
Property_owner string
Api_packages []string
}
type commonProperties struct {
Srcs []string
Recovery *bool
Vendor_available *bool
}
var (
Bool = proptools.Bool
syspropCcTag = dependencyTag{name: "syspropCc"}
)
func init() {
android.RegisterModuleType("sysprop_library", syspropLibraryFactory)
}
func (m *syspropLibrary) CcModuleName() string {
return "lib" + m.Name()
}
func (m *syspropLibrary) SyspropJavaModule() *java.SdkLibrary {
return &m.SdkLibrary
}
func syspropLibraryFactory() android.Module {
m := &syspropLibrary{}
m.AddProperties(
&m.commonProperties,
&m.syspropLibraryProperties,
)
m.InitSdkLibraryProperties()
android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, "common")
android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) })
return m
}
func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) {
if m.syspropLibraryProperties.Api_packages == nil {
ctx.PropertyErrorf("api_packages", "sysprop_library must specify api_packages")
}
socSpecific := ctx.SocSpecific()
deviceSpecific := ctx.DeviceSpecific()
productSpecific := ctx.ProductSpecific()
owner := m.syspropLibraryProperties.Property_owner
switch owner {
case "Platform":
// Every partition can access platform-defined properties
break
case "Vendor":
// System can't access vendor's properties
if !socSpecific && !deviceSpecific && !productSpecific {
ctx.ModuleErrorf("None of soc_specific, device_specific, product_specific is true. " +
"System can't access sysprop_library owned by Vendor")
}
case "Odm":
// Only vendor can access Odm-defined properties
if !socSpecific && !deviceSpecific {
ctx.ModuleErrorf("Neither soc_speicifc nor device_specific is true. " +
"Odm-defined properties should be accessed only in Vendor or Odm")
}
default:
ctx.PropertyErrorf("property_owner",
"Unknown value %s: must be one of Platform, Vendor or Odm", owner)
}
ccProps := struct {
Name *string
Soc_specific *bool
Device_specific *bool
Product_specific *bool
Sysprop struct {
Platform *bool
}
}{}
ccProps.Name = proptools.StringPtr(m.CcModuleName())
ccProps.Soc_specific = proptools.BoolPtr(socSpecific)
ccProps.Device_specific = proptools.BoolPtr(deviceSpecific)
ccProps.Product_specific = proptools.BoolPtr(productSpecific)
ccProps.Sysprop.Platform = proptools.BoolPtr(owner == "Platform")
ctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &m.commonProperties, &ccProps)
}

380
sysprop/sysprop_test.go Normal file
View file

@ -0,0 +1,380 @@
// Copyright (C) 2019 The Android Open Source Project
//
// 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 sysprop
import (
"android/soong/android"
"android/soong/cc"
"android/soong/java"
"fmt"
"io/ioutil"
"os"
"strings"
"testing"
"github.com/google/blueprint/proptools"
)
var buildDir string
func setUp() {
var err error
buildDir, err = ioutil.TempDir("", "soong_sysprop_test")
if err != nil {
panic(err)
}
}
func tearDown() {
os.RemoveAll(buildDir)
}
func TestMain(m *testing.M) {
run := func() int {
setUp()
defer tearDown()
return m.Run()
}
os.Exit(run())
}
func testContext(config android.Config, bp string,
fs map[string][]byte) *android.TestContext {
ctx := android.NewTestArchContext()
ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(java.AndroidAppFactory))
ctx.RegisterModuleType("droiddoc_template", android.ModuleFactoryAdaptor(java.ExportedDroiddocDirFactory))
ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(java.LibraryFactory))
ctx.RegisterModuleType("java_system_modules", android.ModuleFactoryAdaptor(java.SystemModulesFactory))
ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(java.PrebuiltApisFactory))
ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
ctx.TopDown("load_hooks", android.LoadHookMutator).Parallel()
})
ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
ctx.TopDown("prebuilt_apis", java.PrebuiltApisMutator).Parallel()
ctx.TopDown("java_sdk_library", java.SdkLibraryMutator).Parallel()
})
ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))
ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory))
ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory))
ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("image", cc.ImageMutator).Parallel()
ctx.BottomUp("link", cc.LinkageMutator).Parallel()
ctx.BottomUp("vndk", cc.VndkMutator).Parallel()
ctx.BottomUp("version", cc.VersionMutator).Parallel()
ctx.BottomUp("begin", cc.BeginMutator).Parallel()
ctx.BottomUp("sysprop", cc.SyspropMutator).Parallel()
})
ctx.RegisterModuleType("sysprop_library", android.ModuleFactoryAdaptor(syspropLibraryFactory))
ctx.Register()
extraModules := []string{
"core-lambda-stubs",
"framework",
"ext",
"updatable_media_stubs",
"android_stubs_current",
"android_system_stubs_current",
"android_test_stubs_current",
"core.current.stubs",
"core.platform.api.stubs",
}
for _, extra := range extraModules {
bp += fmt.Sprintf(`
java_library {
name: "%s",
srcs: ["a.java"],
no_standard_libs: true,
sdk_version: "core_current",
system_modules: "core-platform-api-stubs-system-modules",
}
`, extra)
}
bp += `
android_app {
name: "framework-res",
no_framework_libs: true,
}
`
systemModules := []string{
"core-system-modules",
"core-platform-api-stubs-system-modules",
"android_stubs_current_system_modules",
"android_system_stubs_current_system_modules",
"android_test_stubs_current_system_modules",
}
for _, extra := range systemModules {
bp += fmt.Sprintf(`
java_system_modules {
name: "%s",
}
`, extra)
}
bp += cc.GatherRequiredDepsForTest(android.Android)
mockFS := map[string][]byte{
"Android.bp": []byte(bp),
"a.java": nil,
"b.java": nil,
"c.java": nil,
"d.cpp": nil,
"api/current.txt": nil,
"api/removed.txt": nil,
"api/system-current.txt": nil,
"api/system-removed.txt": nil,
"api/test-current.txt": nil,
"api/test-removed.txt": nil,
"prebuilts/sdk/current/core/android.jar": nil,
"prebuilts/sdk/current/public/android.jar": nil,
"prebuilts/sdk/current/public/framework.aidl": nil,
"prebuilts/sdk/current/public/core.jar": nil,
"prebuilts/sdk/current/system/android.jar": nil,
"prebuilts/sdk/current/test/android.jar": nil,
"prebuilts/sdk/28/public/api/sysprop-platform.txt": nil,
"prebuilts/sdk/28/system/api/sysprop-platform.txt": nil,
"prebuilts/sdk/28/test/api/sysprop-platform.txt": nil,
"prebuilts/sdk/28/public/api/sysprop-platform-removed.txt": nil,
"prebuilts/sdk/28/system/api/sysprop-platform-removed.txt": nil,
"prebuilts/sdk/28/test/api/sysprop-platform-removed.txt": nil,
"prebuilts/sdk/28/public/api/sysprop-platform-on-product.txt": nil,
"prebuilts/sdk/28/system/api/sysprop-platform-on-product.txt": nil,
"prebuilts/sdk/28/test/api/sysprop-platform-on-product.txt": nil,
"prebuilts/sdk/28/public/api/sysprop-platform-on-product-removed.txt": nil,
"prebuilts/sdk/28/system/api/sysprop-platform-on-product-removed.txt": nil,
"prebuilts/sdk/28/test/api/sysprop-platform-on-product-removed.txt": nil,
"prebuilts/sdk/28/public/api/sysprop-vendor.txt": nil,
"prebuilts/sdk/28/system/api/sysprop-vendor.txt": nil,
"prebuilts/sdk/28/test/api/sysprop-vendor.txt": nil,
"prebuilts/sdk/28/public/api/sysprop-vendor-removed.txt": nil,
"prebuilts/sdk/28/system/api/sysprop-vendor-removed.txt": nil,
"prebuilts/sdk/28/test/api/sysprop-vendor-removed.txt": nil,
"prebuilts/sdk/tools/core-lambda-stubs.jar": nil,
"prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["28", "current"],}`),
// For framework-res, which is an implicit dependency for framework
"AndroidManifest.xml": nil,
"build/target/product/security/testkey": nil,
"build/soong/scripts/jar-wrapper.sh": nil,
"build/make/core/proguard.flags": nil,
"build/make/core/proguard_basic_keeps.flags": nil,
"jdk8/jre/lib/jce.jar": nil,
"jdk8/jre/lib/rt.jar": nil,
"jdk8/lib/tools.jar": nil,
"bar-doc/a.java": nil,
"bar-doc/b.java": nil,
"bar-doc/IFoo.aidl": nil,
"bar-doc/known_oj_tags.txt": nil,
"external/doclava/templates-sdk": nil,
"cert/new_cert.x509.pem": nil,
"cert/new_cert.pk8": nil,
"android/sysprop/PlatformProperties.sysprop": nil,
"com/android/VendorProperties.sysprop": nil,
}
for k, v := range fs {
mockFS[k] = v
}
ctx.MockFileSystem(mockFS)
return ctx
}
func run(t *testing.T, ctx *android.TestContext, config android.Config) {
t.Helper()
_, errs := ctx.ParseFileList(".", []string{"Android.bp", "prebuilts/sdk/Android.bp"})
android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs)
}
func testConfig(env map[string]string) android.Config {
if env == nil {
env = make(map[string]string)
}
if env["ANDROID_JAVA8_HOME"] == "" {
env["ANDROID_JAVA8_HOME"] = "jdk8"
}
config := android.TestArchConfig(buildDir, env)
config.TestProductVariables.DeviceSystemSdkVersions = []string{"28"}
config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
config.TestProductVariables.Platform_vndk_version = proptools.StringPtr("VER")
return config
}
func test(t *testing.T, bp string) *android.TestContext {
t.Helper()
config := testConfig(nil)
ctx := testContext(config, bp, nil)
run(t, ctx, config)
return ctx
}
func TestSyspropLibrary(t *testing.T) {
ctx := test(t, `
sysprop_library {
name: "sysprop-platform",
srcs: ["android/sysprop/PlatformProperties.sysprop"],
api_packages: ["android.sysprop"],
property_owner: "Platform",
vendor_available: true,
}
sysprop_library {
name: "sysprop-platform-on-product",
srcs: ["android/sysprop/PlatformProperties.sysprop"],
api_packages: ["android.sysprop"],
property_owner: "Platform",
product_specific: true,
}
sysprop_library {
name: "sysprop-vendor",
srcs: ["com/android/VendorProperties.sysprop"],
api_packages: ["com.android"],
property_owner: "Vendor",
product_specific: true,
vendor_available: true,
}
java_library {
name: "java-platform",
srcs: ["c.java"],
sdk_version: "system_current",
libs: ["sysprop-platform"],
}
java_library {
name: "java-product",
srcs: ["c.java"],
sdk_version: "system_current",
product_specific: true,
libs: ["sysprop-platform", "sysprop-vendor"],
}
java_library {
name: "java-vendor",
srcs: ["c.java"],
sdk_version: "system_current",
soc_specific: true,
libs: ["sysprop-platform", "sysprop-vendor"],
}
cc_library {
name: "cc-client-platform",
srcs: ["d.cpp"],
static_libs: ["sysprop-platform"],
}
cc_library {
name: "cc-client-product",
srcs: ["d.cpp"],
product_specific: true,
static_libs: ["sysprop-platform-on-product", "sysprop-vendor"],
}
cc_library {
name: "cc-client-vendor",
srcs: ["d.cpp"],
soc_specific: true,
static_libs: ["sysprop-platform", "sysprop-vendor"],
}
`)
for _, variant := range []string{
"android_arm_armv7-a-neon_core_shared",
"android_arm_armv7-a-neon_core_static",
"android_arm_armv7-a-neon_vendor_shared",
"android_arm_armv7-a-neon_vendor_static",
"android_arm64_armv8-a_core_shared",
"android_arm64_armv8-a_core_static",
"android_arm64_armv8-a_vendor_shared",
"android_arm64_armv8-a_vendor_static",
} {
// Check for generated cc_library
ctx.ModuleForTests("libsysprop-platform", variant)
ctx.ModuleForTests("libsysprop-vendor", variant)
}
ctx.ModuleForTests("sysprop-platform", "android_common")
ctx.ModuleForTests("sysprop-vendor", "android_common")
// Check for exported includes
coreVariant := "android_arm64_armv8-a_core_static"
vendorVariant := "android_arm64_armv8-a_vendor_static"
platformInternalPath := "libsysprop-platform/android_arm64_armv8-a_core_static/gen/sysprop/include"
platformSystemCorePath := "libsysprop-platform/android_arm64_armv8-a_core_static/gen/sysprop/system/include"
platformSystemVendorPath := "libsysprop-platform/android_arm64_armv8-a_vendor_static/gen/sysprop/system/include"
platformOnProductPath := "libsysprop-platform-on-product/android_arm64_armv8-a_core_static/gen/sysprop/system/include"
vendorInternalPath := "libsysprop-vendor/android_arm64_armv8-a_vendor_static/gen/sysprop/include"
vendorSystemPath := "libsysprop-vendor/android_arm64_armv8-a_core_static/gen/sysprop/system/include"
platformClient := ctx.ModuleForTests("cc-client-platform", coreVariant)
platformFlags := platformClient.Rule("cc").Args["cFlags"]
// Platform should use platform's internal header
if !strings.Contains(platformFlags, platformInternalPath) {
t.Errorf("flags for platform must contain %#v, but was %#v.",
platformInternalPath, platformFlags)
}
productClient := ctx.ModuleForTests("cc-client-product", coreVariant)
productFlags := productClient.Rule("cc").Args["cFlags"]
// Product should use platform's and vendor's system headers
if !strings.Contains(productFlags, platformOnProductPath) ||
!strings.Contains(productFlags, vendorSystemPath) {
t.Errorf("flags for product must contain %#v and %#v, but was %#v.",
platformSystemCorePath, vendorSystemPath, productFlags)
}
vendorClient := ctx.ModuleForTests("cc-client-vendor", vendorVariant)
vendorFlags := vendorClient.Rule("cc").Args["cFlags"]
// Vendor should use platform's system header and vendor's internal header
if !strings.Contains(vendorFlags, platformSystemVendorPath) ||
!strings.Contains(vendorFlags, vendorInternalPath) {
t.Errorf("flags for vendor must contain %#v and %#v, but was %#v.",
platformSystemVendorPath, vendorInternalPath, vendorFlags)
}
}