From 07def12d502d2f8c7156435ec5e8dd173a33ad28 Mon Sep 17 00:00:00 2001 From: Inseob Kim Date: Mon, 23 Nov 2020 14:43:02 +0900 Subject: [PATCH] Add comments about sysprop_library Bug: 173473767 Test: m nothing Change-Id: I96395742ae369baf9d54be8f92b01860ee0351ab --- cc/cc.go | 5 +++++ cc/library.go | 12 ++++++++--- cc/sysprop.go | 25 ++++++++++++++++++++-- java/sysprop.go | 4 ++++ sysprop/sysprop_library.go | 43 +++++++++++++++++++++++++++----------- 5 files changed, 72 insertions(+), 17 deletions(-) diff --git a/cc/cc.go b/cc/cc.go index bd6e5d532..ed7ca244f 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1841,6 +1841,11 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { return } + // sysprop_library has to support both C++ and Java. So sysprop_library internally creates one + // C++ implementation library and one Java implementation library. When a module links against + // sysprop_library, the C++ implementation library has to be linked. syspropImplLibraries is a + // map from sysprop_library to implementation library; it will be used in whole_static_libs, + // static_libs, and shared_libs. syspropImplLibraries := syspropImplLibraries(actx.Config()) vendorSnapshotStaticLibs := vendorSnapshotStaticLibs(actx.Config()) diff --git a/cc/library.go b/cc/library.go index 2127c08da..7ae75f277 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1202,15 +1202,21 @@ func (library *libraryDecorator) link(ctx ModuleContext, } } + // If the library is sysprop_library, expose either public or internal header selectively. if library.baseCompiler.hasSrcExt(".sysprop") { dir := android.PathForModuleGen(ctx, "sysprop", "include") if library.Properties.Sysprop.Platform != nil { - isProduct := ctx.ProductSpecific() && !ctx.useVndk() - isVendor := ctx.useVndk() + isClientProduct := ctx.ProductSpecific() && !ctx.useVndk() + isClientVendor := ctx.useVndk() isOwnerPlatform := Bool(library.Properties.Sysprop.Platform) + // If the owner is different from the user, expose public header. That is, + // 1) if the user is product (as owner can only be platform / vendor) + // 2) if one is platform and the other is vendor + // Exceptions are ramdisk and recovery. They are not enforced at all. So + // they always use internal header. if !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && - (isProduct || (isOwnerPlatform == isVendor)) { + (isClientProduct || (isOwnerPlatform == isClientVendor)) { dir = android.PathForModuleGen(ctx, "sysprop/public", "include") } } diff --git a/cc/sysprop.go b/cc/sysprop.go index 6cac7fb10..f578b507a 100644 --- a/cc/sysprop.go +++ b/cc/sysprop.go @@ -14,6 +14,25 @@ package cc +// This file contains a map to redirect dependencies towards sysprop_library. +// As sysprop_library has to support both Java and C++, sysprop_library internally +// generates cc_library and java_library. For example, the following sysprop_library +// +// sysprop_library { +// name: "foo", +// } +// +// will internally generate with prefix "lib" +// +// cc_library { +// name: "libfoo", +// } +// +// When a cc module links against "foo", build system will redirect the +// dependency to "libfoo". To do that, SyspropMutator gathers all sysprop_library, +// records their cc implementation library names to a map. The map will be used in +// cc.Module.DepsMutator. + import ( "sync" @@ -22,7 +41,7 @@ import ( type syspropLibraryInterface interface { BaseModuleName() string - CcModuleName() string + CcImplementationModuleName() string } var ( @@ -43,6 +62,8 @@ func SyspropMutator(mctx android.BottomUpMutatorContext) { syspropImplLibrariesLock.Lock() defer syspropImplLibrariesLock.Unlock() - syspropImplLibraries[m.BaseModuleName()] = m.CcModuleName() + // BaseModuleName is the name of sysprop_library + // CcImplementationModuleName is the name of cc_library generated by sysprop_library + syspropImplLibraries[m.BaseModuleName()] = m.CcImplementationModuleName() } } diff --git a/java/sysprop.go b/java/sysprop.go index 1a70499b8..e41aef68a 100644 --- a/java/sysprop.go +++ b/java/sysprop.go @@ -14,6 +14,10 @@ package java +// This file contains a map to redirect dependencies towards sysprop_library. If a sysprop_library +// is owned by Platform, and the client module links against system API, the public stub of the +// sysprop_library should be used. The map will contain public stub names of sysprop_libraries. + import ( "sync" diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go index 1740ba8cf..828d1cf5c 100644 --- a/sysprop/sysprop_library.go +++ b/sysprop/sysprop_library.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// sysprop package defines a module named sysprop_library that can implement sysprop as API +// See https://source.android.com/devices/architecture/sysprops-apis for details package sysprop import ( @@ -71,6 +73,8 @@ func init() { }) } +// syspropJavaGenRule module generates srcjar containing generated java APIs. +// It also depends on check api rule, so api check has to pass to use sysprop_library. func (g *syspropJavaGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) { var checkApiFileTimeStamp android.WritablePath @@ -170,6 +174,7 @@ var ( syspropLibrariesLock sync.Mutex ) +// List of sysprop_library used by property_contexts to perform type check. func syspropLibraries(config android.Config) *[]string { return config.Once(syspropLibrariesKey, func() interface{} { return &[]string{} @@ -192,7 +197,7 @@ func (m *syspropLibrary) Owner() string { return m.properties.Property_owner } -func (m *syspropLibrary) CcModuleName() string { +func (m *syspropLibrary) CcImplementationModuleName() string { return "lib" + m.BaseModuleName() } @@ -223,6 +228,8 @@ func (m *syspropLibrary) CurrentSyspropApiFile() android.Path { return m.currentApiFile } +// GenerateAndroidBuildActions of sysprop_library handles API dump and API check. +// generated java_library will depend on these API files. func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { baseModuleName := m.BaseModuleName() @@ -251,7 +258,8 @@ func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) // check API rule rule = android.NewRuleBuilder() - // 1. current.txt <-> api_dump.txt + // 1. compares current.txt to api-dump.txt + // current.txt should be identical to api-dump.txt. msg := fmt.Sprintf(`\n******************************\n`+ `API of sysprop_library %s doesn't match with current.txt\n`+ `Please update current.txt by:\n`+ @@ -267,7 +275,8 @@ func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) Flag(`"` + msg + `"`). Text("; exit 38) )") - // 2. current.txt <-> latest.txt + // 2. compares current.txt to latest.txt (frozen API) + // current.txt should be compatible with latest.txt msg = fmt.Sprintf(`\n******************************\n`+ `API of sysprop_library %s doesn't match with latest version\n`+ `Please fix the breakage and rebuild.\n`+ @@ -410,14 +419,16 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { installedInVendorOrOdm := ctx.SocSpecific() || ctx.DeviceSpecific() installedInProduct := ctx.ProductSpecific() isOwnerPlatform := false - var stub string + var javaSyspropStub string + // javaSyspropStub contains stub libraries used by generated APIs, instead of framework stub. + // This is to make sysprop_library link against core_current. if installedInVendorOrOdm { - stub = "sysprop-library-stub-vendor" + javaSyspropStub = "sysprop-library-stub-vendor" } else if installedInProduct { - stub = "sysprop-library-stub-product" + javaSyspropStub = "sysprop-library-stub-product" } else { - stub = "sysprop-library-stub-platform" + javaSyspropStub = "sysprop-library-stub-platform" } switch m.Owner() { @@ -441,8 +452,10 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { "Unknown value %s: must be one of Platform, Vendor or Odm", m.Owner()) } + // Generate a C++ implementation library. + // cc_library can receive *.sysprop files as their srcs, generating sources itself. ccProps := ccLibraryProperties{} - ccProps.Name = proptools.StringPtr(m.CcModuleName()) + ccProps.Name = proptools.StringPtr(m.CcImplementationModuleName()) ccProps.Srcs = m.properties.Srcs ccProps.Soc_specific = proptools.BoolPtr(ctx.SocSpecific()) ccProps.Device_specific = proptools.BoolPtr(ctx.DeviceSpecific()) @@ -463,15 +476,17 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { // We need to only use public version, if the partition where sysprop_library will be installed // is different from owner. - if ctx.ProductSpecific() { - // Currently product partition can't own any sysprop_library. + // Currently product partition can't own any sysprop_library. So product always uses public. scope = "public" } else if isOwnerPlatform && installedInVendorOrOdm { // Vendor or Odm should use public version of Platform's sysprop_library. scope = "public" } + // Generate a Java implementation library. + // Contrast to C++, syspropJavaGenRule module will generate srcjar and the srcjar will be fed + // to Java implementation library. ctx.CreateModule(syspropJavaGenFactory, &syspropGenProperties{ Srcs: m.properties.Srcs, Scope: scope, @@ -486,7 +501,7 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { Product_specific: proptools.BoolPtr(ctx.ProductSpecific()), Installable: m.properties.Installable, Sdk_version: proptools.StringPtr("core_current"), - Libs: []string{stub}, + Libs: []string{javaSyspropStub}, }) // if platform sysprop_library is installed in /system or /system-ext, we regard it as an API @@ -505,11 +520,13 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { Srcs: []string{":" + m.javaGenPublicStubName()}, Installable: proptools.BoolPtr(false), Sdk_version: proptools.StringPtr("core_current"), - Libs: []string{stub}, + Libs: []string{javaSyspropStub}, Stem: proptools.StringPtr(m.BaseModuleName()), }) } + // syspropLibraries will be used by property_contexts to check types. + // Record absolute paths of sysprop_library to prevent soong_namespace problem. if m.ExportedToMake() { syspropLibrariesLock.Lock() defer syspropLibrariesLock.Unlock() @@ -519,6 +536,8 @@ func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { } } +// syspropDepsMutator adds dependencies from java implementation library to sysprop library. +// java implementation library then depends on check API rule of sysprop library. func syspropDepsMutator(ctx android.BottomUpMutatorContext) { if m, ok := ctx.Module().(*syspropLibrary); ok { ctx.AddReverseDependency(m, nil, m.javaGenModuleName())