Merge changes Ifd2858dd,I2585dd99,I65e7a456

* changes:
  apex: use SubName for requiredDeps
  apex: support "vendor: true"
  apex: AndroidMk writes common properties
This commit is contained in:
Treehugger Robot 2020-06-29 02:20:56 +00:00 committed by Gerrit Code Review
commit 0c6f111d7b
4 changed files with 218 additions and 38 deletions

View File

@ -58,7 +58,7 @@ type AndroidMkData struct {
Extra []AndroidMkExtraFunc
preamble bytes.Buffer
Entries AndroidMkEntries
}
type AndroidMkExtraFunc func(w io.Writer, outputFile Path)
@ -483,7 +483,7 @@ func translateGoBinaryModule(ctx SingletonContext, w io.Writer, mod blueprint.Mo
func (data *AndroidMkData) fillInData(config Config, bpPath string, mod blueprint.Module) {
// Get the preamble content through AndroidMkEntries logic.
entries := AndroidMkEntries{
data.Entries = AndroidMkEntries{
Class: data.Class,
SubName: data.SubName,
DistFiles: data.DistFiles,
@ -494,16 +494,12 @@ func (data *AndroidMkData) fillInData(config Config, bpPath string, mod blueprin
Host_required: data.Host_required,
Target_required: data.Target_required,
}
entries.fillInEntries(config, bpPath, mod)
// preamble doesn't need the footer content.
entries.footer = bytes.Buffer{}
entries.write(&data.preamble)
data.Entries.fillInEntries(config, bpPath, mod)
// copy entries back to data since it is used in Custom
data.Required = entries.Required
data.Host_required = entries.Host_required
data.Target_required = entries.Target_required
data.Required = data.Entries.Required
data.Host_required = data.Entries.Host_required
data.Target_required = data.Entries.Target_required
}
func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
@ -559,7 +555,9 @@ func WriteAndroidMkData(w io.Writer, data AndroidMkData) {
return
}
w.Write(data.preamble.Bytes())
// write preamble via Entries
data.Entries.footer = bytes.Buffer{}
data.Entries.write(w)
for _, extra := range data.Extra {
extra(w, data.OutputFile.Path())

View File

@ -33,14 +33,7 @@ func (a *apexBundle) AndroidMk() android.AndroidMkData {
Disabled: true,
}
}
writers := []android.AndroidMkData{}
writers = append(writers, a.androidMkForType())
return android.AndroidMkData{
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
for _, data := range writers {
data.Custom(w, name, prefix, moduleDir, data)
}
}}
return a.androidMkForType()
}
func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, moduleDir string) []string {
@ -308,6 +301,20 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.ToMakePath().String())
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", name+apexType.suffix())
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !a.installable())
// Because apex writes .mk with Custom(), we need to write manually some common properties
// which are available via data.Entries
commonProperties := []string{
"LOCAL_INIT_RC", "LOCAL_VINTF_FRAGMENTS",
"LOCAL_PROPRIETARY_MODULE", "LOCAL_VENDOR_MODULE", "LOCAL_ODM_MODULE", "LOCAL_PRODUCT_MODULE", "LOCAL_SYSTEM_EXT_MODULE",
"LOCAL_MODULE_OWNER",
}
for _, name := range commonProperties {
if value, ok := data.Entries.EntryMap[name]; ok {
fmt.Fprintln(w, name+" := "+strings.Join(value, " "))
}
}
if len(a.overridableProperties.Overrides) > 0 {
fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(a.overridableProperties.Overrides, " "))
}

View File

@ -1329,6 +1329,7 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
targets := ctx.MultiTargets()
config := ctx.DeviceConfig()
imageVariation := a.getImageVariation(ctx)
a.combineProperties(ctx)
@ -1348,13 +1349,13 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jni_libs: a.properties.Jni_libs,
Binaries: nil,
},
target, a.getImageVariation(config))
target, imageVariation)
// Add native modules targetting both ABIs
addDependenciesForNativeModules(ctx,
a.properties.Multilib.Both,
target,
a.getImageVariation(config))
imageVariation)
isPrimaryAbi := i == 0
if isPrimaryAbi {
@ -1367,13 +1368,13 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
Jni_libs: nil,
Binaries: a.properties.Binaries,
},
target, a.getImageVariation(config))
target, imageVariation)
// Add native modules targetting the first ABI
addDependenciesForNativeModules(ctx,
a.properties.Multilib.First,
target,
a.getImageVariation(config))
imageVariation)
}
switch target.Arch.ArchType.Multilib {
@ -1382,24 +1383,24 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
addDependenciesForNativeModules(ctx,
a.properties.Multilib.Lib32,
target,
a.getImageVariation(config))
imageVariation)
addDependenciesForNativeModules(ctx,
a.properties.Multilib.Prefer32,
target,
a.getImageVariation(config))
imageVariation)
case "lib64":
// Add native modules targetting 64-bit ABI
addDependenciesForNativeModules(ctx,
a.properties.Multilib.Lib64,
target,
a.getImageVariation(config))
imageVariation)
if !has32BitTarget {
addDependenciesForNativeModules(ctx,
a.properties.Multilib.Prefer32,
target,
a.getImageVariation(config))
imageVariation)
}
}
}
@ -1501,15 +1502,33 @@ func (a *apexBundle) testOnlyShouldSkipPayloadSign() bool {
return proptools.Bool(a.properties.Test_only_unsigned_payload)
}
func (a *apexBundle) getImageVariation(config android.DeviceConfig) string {
func (a *apexBundle) getImageVariation(ctx android.BottomUpMutatorContext) string {
deviceConfig := ctx.DeviceConfig()
if a.vndkApex {
return cc.VendorVariationPrefix + a.vndkVersion(config)
return cc.VendorVariationPrefix + a.vndkVersion(deviceConfig)
}
if config.VndkVersion() != "" && proptools.Bool(a.properties.Use_vendor) {
return cc.VendorVariationPrefix + config.PlatformVndkVersion()
} else {
return android.CoreVariation
var prefix string
var vndkVersion string
if deviceConfig.VndkVersion() != "" {
if proptools.Bool(a.properties.Use_vendor) {
prefix = cc.VendorVariationPrefix
vndkVersion = deviceConfig.PlatformVndkVersion()
} else if a.SocSpecific() || a.DeviceSpecific() {
prefix = cc.VendorVariationPrefix
vndkVersion = deviceConfig.VndkVersion()
} else if a.ProductSpecific() {
prefix = cc.ProductVariationPrefix
vndkVersion = deviceConfig.ProductVndkVersion()
}
}
if vndkVersion == "current" {
vndkVersion = deviceConfig.PlatformVndkVersion()
}
if vndkVersion != "" {
return prefix + vndkVersion
}
return android.CoreVariation
}
func (a *apexBundle) EnableSanitizer(sanitizerName string) {
@ -1541,7 +1560,7 @@ func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext
for _, target := range ctx.MultiTargets() {
if target.Arch.ArchType.Multilib == "lib64" {
ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
{Mutator: "image", Variation: a.getImageVariation(ctx.DeviceConfig())},
{Mutator: "image", Variation: a.getImageVariation(ctx)},
{Mutator: "link", Variation: "shared"},
{Mutator: "version", Variation: ""}, // "" is the non-stub variant
}...), sharedLibTag, "libclang_rt.hwasan-aarch64-android")
@ -1785,6 +1804,12 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
return
}
// Because APEXes targeting other than system/system_ext partitions
// can't set apex_available, we skip checks for these APEXes
if ctx.SocSpecific() || ctx.DeviceSpecific() || ctx.ProductSpecific() {
return
}
// Coverage build adds additional dependencies for the coverage-only runtime libraries.
// Requiring them and their transitive depencies with apex_available is not right
// because they just add noise.
@ -2099,7 +2124,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
af.transitiveDep = true
if !a.Host() && !android.DirectlyInApex(ctx.ModuleName(), ctx.OtherModuleName(cc)) && (cc.IsStubs() || cc.HasStubsVariants()) {
if !a.Host() && !android.DirectlyInApex(ctx.ModuleName(), depName) && (cc.IsStubs() || cc.HasStubsVariants()) {
// If the dependency is a stubs lib, don't include it in this APEX,
// but make sure that the lib is installed on the device.
// In case no APEX is having the lib, the lib is installed to the system
@ -2107,8 +2132,17 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
//
// Always include if we are a host-apex however since those won't have any
// system libraries.
if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.BaseModuleName(), a.requiredDeps) {
a.requiredDeps = append(a.requiredDeps, cc.BaseModuleName())
if !android.DirectlyInAnyApex(ctx, depName) {
// we need a module name for Make
name := cc.BaseModuleName() + cc.Properties.SubName
if proptools.Bool(a.properties.Use_vendor) {
// we don't use subName(.vendor) for a "use_vendor: true" apex
// which is supposed to be installed in /system
name = cc.BaseModuleName()
}
if !android.InList(name, a.requiredDeps) {
a.requiredDeps = append(a.requiredDeps, name)
}
}
requireNativeLibs = append(requireNativeLibs, af.Stem())
// Don't track further
@ -2203,6 +2237,12 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.installable() &&
!proptools.Bool(a.properties.Use_vendor)
// APEXes targeting other than system/system_ext partitions use vendor/product variants.
// So we can't link them to /system/lib libs which are core variants.
if a.SocSpecific() || a.DeviceSpecific() || a.ProductSpecific() {
a.linkToSystemLib = false
}
// We don't need the optimization for updatable APEXes, as it might give false signal
// to the system health when the APEXes are still bundled (b/149805758)
if a.Updatable() && a.properties.ApexType == imageApex {

View File

@ -2105,7 +2105,7 @@ func TestUseVendor(t *testing.T) {
ensureNotContains(t, inputsString, "android_arm64_armv8-a_shared_myapex/mylib2.so")
}
func TestUseVendorRestriction(t *testing.T) {
func TestUseVendorNotAllowedForSystemApexes(t *testing.T) {
testApexError(t, `module "myapex" .*: use_vendor: not allowed`, `
apex {
name: "myapex",
@ -2161,6 +2161,141 @@ func TestUseVendorFailsIfNotVendorAvailable(t *testing.T) {
`)
}
func TestVendorApex(t *testing.T) {
ctx, config := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
binaries: ["mybin"],
vendor: true,
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
cc_binary {
name: "mybin",
vendor: true,
shared_libs: ["libfoo"],
}
cc_library {
name: "libfoo",
proprietary: true,
}
`)
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"bin/mybin",
"lib64/libfoo.so",
// TODO(b/159195575): Add an option to use VNDK libs from VNDK APEX
"lib64/libc++.so",
})
apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, config, "", apexBundle)
name := apexBundle.BaseModuleName()
prefix := "TARGET_"
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
androidMk := builder.String()
ensureContains(t, androidMk, `LOCAL_MODULE_PATH := /tmp/target/product/test_device/vendor/apex`)
}
func TestAndroidMk_UseVendorRequired(t *testing.T) {
ctx, config := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
use_vendor: true,
native_shared_libs: ["mylib"],
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
cc_library {
name: "mylib",
vendor_available: true,
apex_available: ["myapex"],
}
`, func(fs map[string][]byte, config android.Config) {
setUseVendorAllowListForTest(config, []string{"myapex"})
})
apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, config, "", apexBundle)
name := apexBundle.BaseModuleName()
prefix := "TARGET_"
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
androidMk := builder.String()
ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += libc libm libdl\n")
}
func TestAndroidMk_VendorApexRequired(t *testing.T) {
ctx, config := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
vendor: true,
native_shared_libs: ["mylib"],
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
cc_library {
name: "mylib",
vendor_available: true,
}
`)
apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, config, "", apexBundle)
name := apexBundle.BaseModuleName()
prefix := "TARGET_"
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
androidMk := builder.String()
ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += libc.vendor libm.vendor libdl.vendor\n")
}
func TestAndroidMkWritesCommonProperties(t *testing.T) {
ctx, config := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
vintf_fragments: ["fragment.xml"],
init_rc: ["init.rc"],
}
apex_key {
name: "myapex.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
cc_binary {
name: "mybin",
}
`)
apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, config, "", apexBundle)
name := apexBundle.BaseModuleName()
prefix := "TARGET_"
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
androidMk := builder.String()
ensureContains(t, androidMk, "LOCAL_VINTF_FRAGMENTS := fragment.xml\n")
ensureContains(t, androidMk, "LOCAL_INIT_RC := init.rc\n")
}
func TestStaticLinking(t *testing.T) {
ctx, _ := testApex(t, `
apex {