From e65c3aee021fda3e7d37cae5064080effff73ecf Mon Sep 17 00:00:00 2001 From: Martin Stjernholm Date: Tue, 23 Nov 2021 01:24:06 +0000 Subject: [PATCH] Fix prebuilt selection logic for cc_prebuilt_library_headers. Unlike other prebuilt modules it doesn't have a srcs property of any kind, so android.Prebuilt cannot defer to the source module just because its srcsSupplier would return nil. Test: m nothing Bug: 202192894 Change-Id: Iafcf165569bad6eae37820cf71aa0fcacb720e02 --- android/prebuilt.go | 29 +++++++++++++++++++----- cc/androidmk.go | 7 +++--- cc/library_headers.go | 2 +- cc/library_headers_test.go | 45 ++++++++++++++++++++++++++++++++++++++ cc/prebuilt.go | 22 +++++++++++-------- 5 files changed, 86 insertions(+), 19 deletions(-) diff --git a/android/prebuilt.go b/android/prebuilt.go index e18989271..b0a4f434f 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -97,7 +97,10 @@ type ConfigVarProperties struct { type Prebuilt struct { properties PrebuiltProperties - srcsSupplier PrebuiltSrcsSupplier + // nil if the prebuilt has no srcs property at all. See InitPrebuiltModuleWithoutSrcs. + srcsSupplier PrebuiltSrcsSupplier + + // "-" if the prebuilt has no srcs property at all. See InitPrebuiltModuleWithoutSrcs. srcsPropertyName string } @@ -177,6 +180,23 @@ func (p *Prebuilt) UsePrebuilt() bool { // Return the src value or nil if it is not available. type PrebuiltSrcsSupplier func(ctx BaseModuleContext, prebuilt Module) []string +func initPrebuiltModuleCommon(module PrebuiltInterface) *Prebuilt { + p := module.Prebuilt() + module.AddProperties(&p.properties) + module.base().customizableProperties = module.GetProperties() + return p +} + +// Initialize the module as a prebuilt module that has no dedicated property that lists its +// sources. SingleSourcePathFromSupplier should not be called for this module. +// +// This is the case e.g. for header modules, which provides the headers in source form +// regardless whether they are prebuilt or not. +func InitPrebuiltModuleWithoutSrcs(module PrebuiltInterface) { + p := initPrebuiltModuleCommon(module) + p.srcsPropertyName = "-" +} + // Initialize the module as a prebuilt module that uses the provided supplier to access the // prebuilt sources of the module. // @@ -190,10 +210,6 @@ type PrebuiltSrcsSupplier func(ctx BaseModuleContext, prebuilt Module) []string // The provided property name is used to provide helpful error messages in the event that // a problem arises, e.g. calling SingleSourcePath() when more than one source is provided. func InitPrebuiltModuleWithSrcSupplier(module PrebuiltInterface, srcsSupplier PrebuiltSrcsSupplier, srcsPropertyName string) { - p := module.Prebuilt() - module.AddProperties(&p.properties) - module.base().customizableProperties = module.GetProperties() - if srcsSupplier == nil { panic(fmt.Errorf("srcsSupplier must not be nil")) } @@ -201,6 +217,7 @@ func InitPrebuiltModuleWithSrcSupplier(module PrebuiltInterface, srcsSupplier Pr panic(fmt.Errorf("srcsPropertyName must not be empty")) } + p := initPrebuiltModuleCommon(module) p.srcsSupplier = srcsSupplier p.srcsPropertyName = srcsPropertyName } @@ -336,7 +353,7 @@ func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) { func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) { m := ctx.Module() if p := GetEmbeddedPrebuilt(m); p != nil { - if p.srcsSupplier == nil { + if p.srcsSupplier == nil && p.srcsPropertyName == "" { panic(fmt.Errorf("prebuilt module did not have InitPrebuiltModule called on it")) } if !p.properties.SourceExists { diff --git a/cc/androidmk.go b/cc/androidmk.go index 45bb1ca2a..636bab81e 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -263,9 +263,10 @@ func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries library.androidMkWriteExportedFlags(entries) library.androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries) - _, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base()) - - entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext) + if entries.OutputFile.Valid() { + _, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base()) + entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext) + } if library.coverageOutputFile.Valid() { entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String()) diff --git a/cc/library_headers.go b/cc/library_headers.go index ede6ab3c0..141a2a56b 100644 --- a/cc/library_headers.go +++ b/cc/library_headers.go @@ -102,7 +102,7 @@ func LibraryHeaderFactory() android.Module { // cc_prebuilt_library_headers is a prebuilt version of cc_library_headers func prebuiltLibraryHeaderFactory() android.Module { - module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported) + module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported, "") library.HeaderOnly() return module.Init() } diff --git a/cc/library_headers_test.go b/cc/library_headers_test.go index 564ef61fb..9789ab04b 100644 --- a/cc/library_headers_test.go +++ b/cc/library_headers_test.go @@ -15,8 +15,13 @@ package cc import ( + "fmt" "strings" "testing" + + "android/soong/android" + + "github.com/google/blueprint" ) func TestLibraryHeaders(t *testing.T) { @@ -60,3 +65,43 @@ func TestPrebuiltLibraryHeaders(t *testing.T) { t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags) } } + +func TestPrebuiltLibraryHeadersPreferred(t *testing.T) { + bp := ` + cc_library_headers { + name: "headers", + export_include_dirs: ["my_include"], + } + cc_prebuilt_library_headers { + name: "headers", + prefer: %t, + export_include_dirs: ["my_include"], + } + cc_library_static { + name: "lib", + srcs: ["foo.c"], + header_libs: ["headers"], + } + ` + + for _, prebuiltPreferred := range []bool{false, true} { + t.Run(fmt.Sprintf("prebuilt prefer %t", prebuiltPreferred), func(t *testing.T) { + ctx := testCc(t, fmt.Sprintf(bp, prebuiltPreferred)) + lib := ctx.ModuleForTests("lib", "android_arm64_armv8-a_static") + sourceDep := ctx.ModuleForTests("headers", "android_arm64_armv8-a") + prebuiltDep := ctx.ModuleForTests("prebuilt_headers", "android_arm64_armv8-a") + hasSourceDep := false + hasPrebuiltDep := false + ctx.VisitDirectDeps(lib.Module(), func(dep blueprint.Module) { + if dep == sourceDep.Module() { + hasSourceDep = true + } + if dep == prebuiltDep.Module() { + hasPrebuiltDep = true + } + }) + android.AssertBoolEquals(t, "depends on source headers", !prebuiltPreferred, hasSourceDep) + android.AssertBoolEquals(t, "depends on prebuilt headers", prebuiltPreferred, hasPrebuiltDep) + }) + } +} diff --git a/cc/prebuilt.go b/cc/prebuilt.go index 16945ac69..a279054c3 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -235,7 +235,7 @@ func (p *prebuiltLibraryLinker) implementationModuleName(name string) string { return android.RemoveOptionalPrebuiltPrefix(name) } -func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { +func NewPrebuiltLibrary(hod android.HostOrDeviceSupported, srcsProperty string) (*Module, *libraryDecorator) { module, library := NewLibrary(hod) module.compiler = nil @@ -247,11 +247,15 @@ func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDec module.AddProperties(&prebuilt.properties) - srcsSupplier := func(ctx android.BaseModuleContext, _ android.Module) []string { - return prebuilt.prebuiltSrcs(ctx) - } + if srcsProperty == "" { + android.InitPrebuiltModuleWithoutSrcs(module) + } else { + srcsSupplier := func(ctx android.BaseModuleContext, _ android.Module) []string { + return prebuilt.prebuiltSrcs(ctx) + } - android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs") + android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, srcsProperty) + } // Prebuilt libraries can be used in SDKs. android.InitSdkAwareModule(module) @@ -261,7 +265,7 @@ func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDec // cc_prebuilt_library installs a precompiled shared library that are // listed in the srcs property in the device's directory. func PrebuiltLibraryFactory() android.Module { - module, _ := NewPrebuiltLibrary(android.HostAndDeviceSupported) + module, _ := NewPrebuiltLibrary(android.HostAndDeviceSupported, "srcs") // Prebuilt shared libraries can be included in APEXes android.InitApexModule(module) @@ -280,14 +284,14 @@ func PrebuiltSharedLibraryFactory() android.Module { // to be used as a data dependency of a test-related module (such as cc_test, or // cc_test_library). func PrebuiltSharedTestLibraryFactory() android.Module { - module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported) + module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported, "srcs") library.BuildOnlyShared() library.baseInstaller = NewTestInstaller() return module.Init() } func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { - module, library := NewPrebuiltLibrary(hod) + module, library := NewPrebuiltLibrary(hod, "srcs") library.BuildOnlyShared() // Prebuilt shared libraries can be included in APEXes @@ -304,7 +308,7 @@ func PrebuiltStaticLibraryFactory() android.Module { } func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { - module, library := NewPrebuiltLibrary(hod) + module, library := NewPrebuiltLibrary(hod, "srcs") library.BuildOnlyStatic() module.bazelHandler = &prebuiltStaticLibraryBazelHandler{module: module, library: library} return module, library