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
This commit is contained in:
Martin Stjernholm
2021-11-23 01:24:06 +00:00
parent b5f81d2a6a
commit e65c3aee02
5 changed files with 86 additions and 19 deletions

View File

@@ -97,7 +97,10 @@ type ConfigVarProperties struct {
type Prebuilt struct { type Prebuilt struct {
properties PrebuiltProperties 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 srcsPropertyName string
} }
@@ -177,6 +180,23 @@ func (p *Prebuilt) UsePrebuilt() bool {
// Return the src value or nil if it is not available. // Return the src value or nil if it is not available.
type PrebuiltSrcsSupplier func(ctx BaseModuleContext, prebuilt Module) []string 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 // Initialize the module as a prebuilt module that uses the provided supplier to access the
// prebuilt sources of the module. // 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 // 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. // a problem arises, e.g. calling SingleSourcePath() when more than one source is provided.
func InitPrebuiltModuleWithSrcSupplier(module PrebuiltInterface, srcsSupplier PrebuiltSrcsSupplier, srcsPropertyName string) { func InitPrebuiltModuleWithSrcSupplier(module PrebuiltInterface, srcsSupplier PrebuiltSrcsSupplier, srcsPropertyName string) {
p := module.Prebuilt()
module.AddProperties(&p.properties)
module.base().customizableProperties = module.GetProperties()
if srcsSupplier == nil { if srcsSupplier == nil {
panic(fmt.Errorf("srcsSupplier must not be 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")) panic(fmt.Errorf("srcsPropertyName must not be empty"))
} }
p := initPrebuiltModuleCommon(module)
p.srcsSupplier = srcsSupplier p.srcsSupplier = srcsSupplier
p.srcsPropertyName = srcsPropertyName p.srcsPropertyName = srcsPropertyName
} }
@@ -336,7 +353,7 @@ func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) {
func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) { func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
m := ctx.Module() m := ctx.Module()
if p := GetEmbeddedPrebuilt(m); p != nil { 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")) panic(fmt.Errorf("prebuilt module did not have InitPrebuiltModule called on it"))
} }
if !p.properties.SourceExists { if !p.properties.SourceExists {

View File

@@ -263,9 +263,10 @@ func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries
library.androidMkWriteExportedFlags(entries) library.androidMkWriteExportedFlags(entries)
library.androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries) library.androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries)
_, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base()) if entries.OutputFile.Valid() {
_, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base())
entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext) entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
}
if library.coverageOutputFile.Valid() { if library.coverageOutputFile.Valid() {
entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String()) entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String())

View File

@@ -102,7 +102,7 @@ func LibraryHeaderFactory() android.Module {
// cc_prebuilt_library_headers is a prebuilt version of cc_library_headers // cc_prebuilt_library_headers is a prebuilt version of cc_library_headers
func prebuiltLibraryHeaderFactory() android.Module { func prebuiltLibraryHeaderFactory() android.Module {
module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported) module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported, "")
library.HeaderOnly() library.HeaderOnly()
return module.Init() return module.Init()
} }

View File

@@ -15,8 +15,13 @@
package cc package cc
import ( import (
"fmt"
"strings" "strings"
"testing" "testing"
"android/soong/android"
"github.com/google/blueprint"
) )
func TestLibraryHeaders(t *testing.T) { 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) 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)
})
}
}

View File

@@ -235,7 +235,7 @@ func (p *prebuiltLibraryLinker) implementationModuleName(name string) string {
return android.RemoveOptionalPrebuiltPrefix(name) 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, library := NewLibrary(hod)
module.compiler = nil module.compiler = nil
@@ -247,11 +247,15 @@ func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDec
module.AddProperties(&prebuilt.properties) module.AddProperties(&prebuilt.properties)
srcsSupplier := func(ctx android.BaseModuleContext, _ android.Module) []string { if srcsProperty == "" {
return prebuilt.prebuiltSrcs(ctx) 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. // Prebuilt libraries can be used in SDKs.
android.InitSdkAwareModule(module) android.InitSdkAwareModule(module)
@@ -261,7 +265,7 @@ func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDec
// cc_prebuilt_library installs a precompiled shared library that are // cc_prebuilt_library installs a precompiled shared library that are
// listed in the srcs property in the device's directory. // listed in the srcs property in the device's directory.
func PrebuiltLibraryFactory() android.Module { func PrebuiltLibraryFactory() android.Module {
module, _ := NewPrebuiltLibrary(android.HostAndDeviceSupported) module, _ := NewPrebuiltLibrary(android.HostAndDeviceSupported, "srcs")
// Prebuilt shared libraries can be included in APEXes // Prebuilt shared libraries can be included in APEXes
android.InitApexModule(module) 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 // to be used as a data dependency of a test-related module (such as cc_test, or
// cc_test_library). // cc_test_library).
func PrebuiltSharedTestLibraryFactory() android.Module { func PrebuiltSharedTestLibraryFactory() android.Module {
module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported) module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported, "srcs")
library.BuildOnlyShared() library.BuildOnlyShared()
library.baseInstaller = NewTestInstaller() library.baseInstaller = NewTestInstaller()
return module.Init() return module.Init()
} }
func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
module, library := NewPrebuiltLibrary(hod) module, library := NewPrebuiltLibrary(hod, "srcs")
library.BuildOnlyShared() library.BuildOnlyShared()
// Prebuilt shared libraries can be included in APEXes // Prebuilt shared libraries can be included in APEXes
@@ -304,7 +308,7 @@ func PrebuiltStaticLibraryFactory() android.Module {
} }
func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
module, library := NewPrebuiltLibrary(hod) module, library := NewPrebuiltLibrary(hod, "srcs")
library.BuildOnlyStatic() library.BuildOnlyStatic()
module.bazelHandler = &prebuiltStaticLibraryBazelHandler{module: module, library: library} module.bazelHandler = &prebuiltStaticLibraryBazelHandler{module: module, library: library}
return module, library return module, library