Merge "Run extractor for Go files in build/soong directory"
diff --git a/android/config.go b/android/config.go
index 291d36f..101f457 100644
--- a/android/config.go
+++ b/android/config.go
@@ -948,6 +948,10 @@
return String(c.config.productVariables.Platform_vndk_version)
}
+func (c *deviceConfig) ProductVndkVersion() string {
+ return String(c.config.productVariables.ProductVndkVersion)
+}
+
func (c *deviceConfig) ExtraVndkVersions() []string {
return c.config.productVariables.ExtraVndkVersions
}
diff --git a/android/neverallow.go b/android/neverallow.go
index 48efb4f..cef73fb 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -136,9 +136,6 @@
"external/icu",
"external/okhttp",
"external/wycheproof",
-
- // Not really a core library but still needs access to same capabilities.
- "development",
}
// Core library constraints. The sdk_version: "none" can only be used in core library projects.
diff --git a/android/paths.go b/android/paths.go
index 024432e..c841372 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -118,6 +118,9 @@
type WritablePath interface {
Path
+ // return the path to the build directory.
+ buildDir() string
+
// the writablePath method doesn't directly do anything,
// but it allows a struct to distinguish between whether or not it implements the WritablePath interface
writablePath()
@@ -848,7 +851,12 @@
return p
}
+func (p OutputPath) buildDir() string {
+ return p.config.buildDir
+}
+
var _ Path = OutputPath{}
+var _ WritablePath = OutputPath{}
// PathForOutput joins the provided paths and returns an OutputPath that is
// validated to not escape the build dir.
@@ -1151,6 +1159,13 @@
baseDir string // "../" for Make paths to convert "out/soong" to "out", "" for Soong paths
}
+func (p InstallPath) buildDir() string {
+ return p.config.buildDir
+}
+
+var _ Path = InstallPath{}
+var _ WritablePath = InstallPath{}
+
func (p InstallPath) writablePath() {}
func (p InstallPath) String() string {
@@ -1302,6 +1317,10 @@
func (p PhonyPath) writablePath() {}
+func (p PhonyPath) buildDir() string {
+ return p.config.buildDir
+}
+
var _ Path = PhonyPath{}
var _ WritablePath = PhonyPath{}
diff --git a/android/testing.go b/android/testing.go
index aaf98f5..4f0591b 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "path/filepath"
"regexp"
"strings"
"testing"
@@ -411,3 +412,33 @@
data.fillInData(config, bpPath, mod)
return data
}
+
+// Normalize the path for testing.
+//
+// If the path is relative to the build directory then return the relative path
+// to avoid tests having to deal with the dynamically generated build directory.
+//
+// Otherwise, return the supplied path as it is almost certainly a source path
+// that is relative to the root of the source tree.
+//
+// The build and source paths should be distinguishable based on their contents.
+func NormalizePathForTesting(path Path) string {
+ p := path.String()
+ if w, ok := path.(WritablePath); ok {
+ rel, err := filepath.Rel(w.buildDir(), p)
+ if err != nil {
+ panic(err)
+ }
+ return rel
+ }
+ return p
+}
+
+func NormalizePathsForTesting(paths Paths) []string {
+ var result []string
+ for _, path := range paths {
+ relative := NormalizePathForTesting(path)
+ result = append(result, relative)
+ }
+ return result
+}
diff --git a/android/variable.go b/android/variable.go
index 548e09b..2bf84dd 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -307,6 +307,8 @@
ProductPrivateSepolicyDirs []string `json:",omitempty"`
ProductCompatibleProperty *bool `json:",omitempty"`
+ ProductVndkVersion *string `json:",omitempty"`
+
TargetFSConfigGen []string `json:",omitempty"`
MissingUsesLibraries []string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index ce463fc..e0ee1ea 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -884,18 +884,6 @@
return newApexFile(ctx, fileToCopy, lib.Name(), dirInApex, javaSharedLib, lib)
}
-func apexFileForPrebuiltJavaLibrary(ctx android.BaseModuleContext, java *java.Import) apexFile {
- dirInApex := "javalib"
- // The output is only one, but for some reason, ImplementationJars returns Paths, not Path
- implJars := java.ImplementationJars()
- if len(implJars) != 1 {
- panic(fmt.Errorf("java.ImplementationJars() must return single Path, but got: %s",
- strings.Join(implJars.Strings(), ", ")))
- }
- fileToCopy := implJars[0]
- return newApexFile(ctx, fileToCopy, java.Name(), dirInApex, javaSharedLib, java)
-}
-
func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt android.PrebuiltEtcModule, depName string) apexFile {
dirInApex := filepath.Join("etc", prebuilt.SubDir())
fileToCopy := prebuilt.OutputFile()
@@ -1043,13 +1031,6 @@
}
filesInfo = append(filesInfo, newApexFile(ctx, pf, pf.Base(), "etc/permissions", etc, nil))
return true // track transitive dependencies
- } else if javaLib, ok := child.(*java.Import); ok {
- af := apexFileForPrebuiltJavaLibrary(ctx, javaLib)
- if !af.Ok() {
- ctx.PropertyErrorf("java_libs", "%q does not have a jar output", depName)
- } else {
- filesInfo = append(filesInfo, af)
- }
} else {
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
}
@@ -1060,6 +1041,8 @@
return true // track transitive dependencies
} else if ap, ok := child.(*java.AndroidAppImport); ok {
filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap, pkgName))
+ } else if ap, ok := child.(*java.AndroidTestHelperApp); ok {
+ filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap, pkgName))
} else {
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 60ed801..97600b6 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -372,7 +372,7 @@
binaries: ["foo",],
}
},
- java_libs: ["myjar", "myprebuiltjar"],
+ java_libs: ["myjar"],
}
apex {
@@ -447,12 +447,6 @@
system_modules: "none",
compile_dex: true,
}
-
- java_import {
- name: "myprebuiltjar",
- jars: ["prebuilt.jar"],
- installable: true,
- }
`)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
@@ -470,7 +464,6 @@
// Ensure that apex variant is created for the direct dep
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_myapex")
- ensureListContains(t, ctx.ModuleVariantsForTests("myprebuiltjar"), "android_common_myapex")
// Ensure that apex variant is created for the indirect dep
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
@@ -480,7 +473,6 @@
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
ensureContains(t, copyCmds, "image.apex/javalib/myjar.jar")
- ensureContains(t, copyCmds, "image.apex/javalib/myprebuiltjar.jar")
// .. but not for java libs
ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar")
@@ -489,7 +481,6 @@
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared")
ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common")
ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common")
- ensureListContains(t, ctx.ModuleVariantsForTests("myprebuiltjar"), "android_common")
// Ensure that all symlinks are present.
found_foo_link_64 := false
@@ -2924,6 +2915,36 @@
ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt/AppFooPrivPrebuilt.apk")
}
+func TestApexWithTestHelperApp(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ apps: [
+ "TesterHelpAppFoo",
+ ],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ android_test_helper_app {
+ name: "TesterHelpAppFoo",
+ srcs: ["foo/bar/MyClass.java"],
+ }
+
+ `)
+
+ module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
+ apexRule := module.Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+
+ ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo/TesterHelpAppFoo.apk")
+}
+
func TestApexPropertiesShouldBeDefaultable(t *testing.T) {
// libfoo's apex_available comes from cc_defaults
testApexError(t, `"myapex" .*: requires "libfoo" that is not available for the APEX`, `
diff --git a/cc/androidmk.go b/cc/androidmk.go
index c1225bc..988ebd4 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -25,6 +25,7 @@
var (
nativeBridgeSuffix = ".native_bridge"
+ productSuffix = ".product"
vendorSuffix = ".vendor"
recoverySuffix = ".recovery"
)
@@ -37,7 +38,7 @@
Os() android.OsType
Host() bool
UseVndk() bool
- vndkVersion() string
+ VndkVersion() string
static() bool
InRecovery() bool
}
@@ -92,7 +93,7 @@
if c.UseVndk() {
fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
if c.IsVndk() && !c.static() {
- fmt.Fprintln(w, "LOCAL_SOONG_VNDK_VERSION := "+c.vndkVersion())
+ fmt.Fprintln(w, "LOCAL_SOONG_VNDK_VERSION := "+c.VndkVersion())
// VNDK libraries available to vendor are not installed because
// they are packaged in VNDK APEX and installed by APEX packages (apex/apex.go)
if !c.isVndkExt() {
diff --git a/cc/cc.go b/cc/cc.go
index 470ea44..f16bb12 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -215,8 +215,9 @@
PreventInstall bool `blueprint:"mutated"`
ApexesProvidingSharedLibs []string `blueprint:"mutated"`
- VndkVersion string `blueprint:"mutated"`
- SubName string `blueprint:"mutated"`
+ ImageVariationPrefix string `blueprint:"mutated"`
+ VndkVersion string `blueprint:"mutated"`
+ SubName string `blueprint:"mutated"`
// *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
// file
@@ -228,7 +229,7 @@
// Set by imageMutator
CoreVariantNeeded bool `blueprint:"mutated"`
RecoveryVariantNeeded bool `blueprint:"mutated"`
- VendorVariants []string `blueprint:"mutated"`
+ ExtraVariants []string `blueprint:"mutated"`
// Allows this module to use non-APEX version of libraries. Useful
// for building binaries that are started before APEXes are activated.
@@ -242,20 +243,24 @@
type VendorProperties struct {
// whether this module should be allowed to be directly depended by other
// modules with `vendor: true`, `proprietary: true`, or `vendor_available:true`.
- // If set to true, two variants will be built separately, one like
- // normal, and the other limited to the set of libraries and headers
- // that are exposed to /vendor modules.
+ // In addition, this module should be allowed to be directly depended by
+ // product modules with `product_specific: true`.
+ // If set to true, three variants will be built separately, one like
+ // normal, another limited to the set of libraries and headers
+ // that are exposed to /vendor modules, and the other to /product modules.
//
- // The vendor variant may be used with a different (newer) /system,
+ // The vendor and product variants may be used with a different (newer) /system,
// so it shouldn't have any unversioned runtime dependencies, or
// make assumptions about the system that may not be true in the
// future.
//
- // If set to false, this module becomes inaccessible from /vendor modules.
+ // If set to false, this module becomes inaccessible from /vendor or /product
+ // modules.
//
// Default value is true when vndk: {enabled: true} or vendor: true.
//
// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
+ // If PRODUCT_PRODUCT_VNDK_VERSION isn't set, product variant will not be used.
Vendor_available *bool
// whether this module is capable of being loaded with other instance
@@ -283,6 +288,8 @@
isVndk() bool
isVndkSp() bool
isVndkExt() bool
+ inProduct() bool
+ inVendor() bool
inRecovery() bool
shouldCreateSourceAbiDump() bool
selectedStl() string
@@ -683,7 +690,7 @@
}
func (c *Module) VndkVersion() string {
- return c.vndkVersion()
+ return c.Properties.VndkVersion
}
func (c *Module) Init() android.Module {
@@ -755,6 +762,12 @@
return false
}
+// Returns true if the module is using VNDK libraries instead of the libraries in /system/lib or /system/lib64.
+// "product" and "vendor" variant modules return true for this function.
+// When BOARD_VNDK_VERSION is set, vendor variants of "vendor_available: true", "vendor: true",
+// "soc_specific: true" and more vendor installed modules are included here.
+// When PRODUCT_PRODUCT_VNDK_VERSION is set, product variants of "vendor_available: true" or
+// "product_specific: true" modules are included here.
func (c *Module) UseVndk() bool {
return c.Properties.VndkVersion != ""
}
@@ -790,10 +803,6 @@
return false
}
-func (c *Module) vndkVersion() string {
- return c.Properties.VndkVersion
-}
-
func (c *Module) isPgoCompile() bool {
if pgo := c.pgo; pgo != nil {
return pgo.Properties.PgoCompile
@@ -833,12 +842,32 @@
return ""
}
-// Returns true only when this module is configured to have core and vendor
+// Returns true only when this module is configured to have core, product and vendor
// variants.
func (c *Module) HasVendorVariant() bool {
return c.IsVndk() || Bool(c.VendorProperties.Vendor_available)
}
+const (
+ // VendorVariationPrefix is the variant prefix used for /vendor code that compiles
+ // against the VNDK.
+ VendorVariationPrefix = "vendor."
+
+ // ProductVariationPrefix is the variant prefix used for /product code that compiles
+ // against the VNDK.
+ ProductVariationPrefix = "product."
+)
+
+// Returns true if the module is "product" variant. Usually these modules are installed in /product
+func (c *Module) inProduct() bool {
+ return c.Properties.ImageVariationPrefix == ProductVariationPrefix
+}
+
+// Returns true if the module is "vendor" variant. Usually these modules are installed in /vendor
+func (c *Module) inVendor() bool {
+ return c.Properties.ImageVariationPrefix == VendorVariationPrefix
+}
+
func (c *Module) InRecovery() bool {
return c.ModuleBase.InRecovery() || c.ModuleBase.InstallInRecovery()
}
@@ -947,9 +976,14 @@
moduleContextImpl
}
+func (ctx *moduleContext) ProductSpecific() bool {
+ return ctx.ModuleContext.ProductSpecific() ||
+ (ctx.mod.HasVendorVariant() && ctx.mod.inProduct() && !ctx.mod.IsVndk())
+}
+
func (ctx *moduleContext) SocSpecific() bool {
return ctx.ModuleContext.SocSpecific() ||
- (ctx.mod.HasVendorVariant() && ctx.mod.UseVndk() && !ctx.mod.IsVndk())
+ (ctx.mod.HasVendorVariant() && ctx.mod.inVendor() && !ctx.mod.IsVndk())
}
type moduleContextImpl struct {
@@ -983,15 +1017,11 @@
func (ctx *moduleContextImpl) sdkVersion() string {
if ctx.ctx.Device() {
if ctx.useVndk() {
- vndk_ver := ctx.ctx.DeviceConfig().VndkVersion()
- if vndk_ver == "current" {
- platform_vndk_ver := ctx.ctx.DeviceConfig().PlatformVndkVersion()
- if inList(platform_vndk_ver, ctx.ctx.Config().PlatformVersionCombinedCodenames()) {
- return "current"
- }
- return platform_vndk_ver
+ vndkVer := ctx.mod.VndkVersion()
+ if inList(vndkVer, ctx.ctx.Config().PlatformVersionCombinedCodenames()) {
+ return "current"
}
- return vndk_ver
+ return vndkVer
}
return String(ctx.mod.Properties.Sdk_version)
}
@@ -1042,6 +1072,14 @@
return ctx.mod.MustUseVendorVariant()
}
+func (ctx *moduleContextImpl) inProduct() bool {
+ return ctx.mod.inProduct()
+}
+
+func (ctx *moduleContextImpl) inVendor() bool {
+ return ctx.mod.inVendor()
+}
+
func (ctx *moduleContextImpl) inRecovery() bool {
return ctx.mod.InRecovery()
}
@@ -1225,6 +1263,29 @@
return ok && test.isAllTestsVariation()
}
+func (c *Module) getNameSuffixWithVndkVersion(ctx android.ModuleContext) string {
+ // Returns the name suffix for product and vendor variants. If the VNDK version is not
+ // "current", it will append the VNDK version to the name suffix.
+ var vndkVersion string
+ var nameSuffix string
+ if c.inProduct() {
+ vndkVersion = ctx.DeviceConfig().ProductVndkVersion()
+ nameSuffix = productSuffix
+ } else {
+ vndkVersion = ctx.DeviceConfig().VndkVersion()
+ nameSuffix = vendorSuffix
+ }
+ if vndkVersion == "current" {
+ vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
+ }
+ if c.Properties.VndkVersion != vndkVersion {
+ // add version suffix only if the module is using different vndk version than the
+ // version in product or vendor partition.
+ nameSuffix += "." + c.Properties.VndkVersion
+ }
+ return nameSuffix
+}
+
func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
// Handle the case of a test module split by `test_per_src` mutator.
//
@@ -1244,21 +1305,17 @@
c.Properties.SubName += nativeBridgeSuffix
}
- if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok {
+ _, llndk := c.linker.(*llndkStubDecorator)
+ _, llndkHeader := c.linker.(*llndkHeadersDecorator)
+ if llndk || llndkHeader || (c.UseVndk() && c.HasVendorVariant()) {
+ // .vendor.{version} suffix is added for vendor variant or .product.{version} suffix is
+ // added for product variant only when we have vendor and product variants with core
+ // variant. The suffix is not added for vendor-only or product-only module.
+ c.Properties.SubName += c.getNameSuffixWithVndkVersion(actx)
+ } else if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok {
// .vendor suffix is added for backward compatibility with VNDK snapshot whose names with
// such suffixes are already hard-coded in prebuilts/vndk/.../Android.bp.
c.Properties.SubName += vendorSuffix
- } else if _, ok := c.linker.(*llndkStubDecorator); ok || (c.UseVndk() && c.HasVendorVariant()) {
- // .vendor.{version} suffix is added only when we will have two variants: core and vendor.
- // The suffix is not added for vendor-only module.
- c.Properties.SubName += vendorSuffix
- vendorVersion := actx.DeviceConfig().VndkVersion()
- if vendorVersion == "current" {
- vendorVersion = actx.DeviceConfig().PlatformVndkVersion()
- }
- if c.Properties.VndkVersion != vendorVersion {
- c.Properties.SubName += "." + c.Properties.VndkVersion
- }
} else if c.InRecovery() && !c.OnlyInRecovery() {
c.Properties.SubName += recoverySuffix
}
@@ -2206,15 +2263,7 @@
} else if c.UseVndk() && bothVendorAndCoreVariantsExist {
// The vendor module in Make will have been renamed to not conflict with the core
// module, so update the dependency name here accordingly.
- ret := libName + vendorSuffix
- vendorVersion := ctx.DeviceConfig().VndkVersion()
- if vendorVersion == "current" {
- vendorVersion = ctx.DeviceConfig().PlatformVndkVersion()
- }
- if c.Properties.VndkVersion != vendorVersion {
- ret += "." + c.Properties.VndkVersion
- }
- return ret
+ return libName + c.getNameSuffixWithVndkVersion(ctx)
} else if (ctx.Platform() || ctx.ProductSpecific()) && isVendorPublicLib {
return libName + vendorPublicLibrarySuffix
} else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() {
@@ -2367,6 +2416,9 @@
}
return "native:vndk_private"
}
+ if c.inProduct() {
+ return "native:product"
+ }
return "native:vendor"
} else if c.InRecovery() {
return "native:recovery"
@@ -2492,12 +2544,6 @@
return module
}
-const (
- // VendorVariationPrefix is the variant prefix used for /vendor code that compiles
- // against the VNDK.
- VendorVariationPrefix = "vendor."
-)
-
func squashVendorSrcs(m *Module) {
if lib, ok := m.compiler.(*libraryDecorator); ok {
lib.baseCompiler.Properties.Srcs = append(lib.baseCompiler.Properties.Srcs,
@@ -2569,49 +2615,65 @@
var recoveryVariantNeeded bool = false
var vendorVariants []string
+ var productVariants []string
platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
- deviceVndkVersion := mctx.DeviceConfig().VndkVersion()
- if deviceVndkVersion == "current" {
- deviceVndkVersion = platformVndkVersion
+ boardVndkVersion := mctx.DeviceConfig().VndkVersion()
+ productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
+ if boardVndkVersion == "current" {
+ boardVndkVersion = platformVndkVersion
+ }
+ if productVndkVersion == "current" {
+ productVndkVersion = platformVndkVersion
}
- if mctx.DeviceConfig().VndkVersion() == "" {
+ if boardVndkVersion == "" {
// If the device isn't compiling against the VNDK, we always
// use the core mode.
coreVariantNeeded = true
} else if _, ok := m.linker.(*llndkStubDecorator); ok {
- // LL-NDK stubs only exist in the vendor variant, since the
- // real libraries will be used in the core variant.
+ // LL-NDK stubs only exist in the vendor and product variants,
+ // since the real libraries will be used in the core variant.
vendorVariants = append(vendorVariants,
platformVndkVersion,
- deviceVndkVersion,
+ boardVndkVersion,
+ )
+ productVariants = append(productVariants,
+ platformVndkVersion,
+ productVndkVersion,
)
} else if _, ok := m.linker.(*llndkHeadersDecorator); ok {
// ... and LL-NDK headers as well
vendorVariants = append(vendorVariants,
platformVndkVersion,
- deviceVndkVersion,
+ boardVndkVersion,
+ )
+ productVariants = append(productVariants,
+ platformVndkVersion,
+ productVndkVersion,
)
} else if lib, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok {
// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
// PRODUCT_EXTRA_VNDK_VERSIONS.
vendorVariants = append(vendorVariants, lib.version())
} else if m.HasVendorVariant() && !vendorSpecific {
- // This will be available in both /system and /vendor
- // or a /system directory that is available to vendor.
+ // This will be available in /system, /vendor and /product
+ // or a /system directory that is available to vendor and product.
coreVariantNeeded = true
vendorVariants = append(vendorVariants, platformVndkVersion)
+ productVariants = append(productVariants, platformVndkVersion)
// VNDK modules must not create BOARD_VNDK_VERSION variant because its
// code is PLATFORM_VNDK_VERSION.
// On the other hand, vendor_available modules which are not VNDK should
// also build BOARD_VNDK_VERSION because it's installed in /vendor.
+ // vendor_available modules are also available to /product.
if !m.IsVndk() {
- vendorVariants = append(vendorVariants, deviceVndkVersion)
+ vendorVariants = append(vendorVariants, boardVndkVersion)
+ productVariants = append(productVariants, productVndkVersion)
}
} else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
// This will be available in /vendor (or /odm) only
- vendorVariants = append(vendorVariants, deviceVndkVersion)
+ vendorVariants = append(vendorVariants, boardVndkVersion)
} else {
// This is either in /system (or similar: /data), or is a
// modules built with the NDK. Modules built with the NDK
@@ -2619,6 +2681,19 @@
coreVariantNeeded = true
}
+ if boardVndkVersion != "" && productVndkVersion != "" {
+ if coreVariantNeeded && productSpecific && String(m.Properties.Sdk_version) == "" {
+ // The module has "product_specific: true" that does not create core variant.
+ coreVariantNeeded = false
+ productVariants = append(productVariants, productVndkVersion)
+ }
+ } else {
+ // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
+ // restriction to use system libs.
+ // No product variants defined in this case.
+ productVariants = []string{}
+ }
+
if Bool(m.Properties.Recovery_available) {
recoveryVariantNeeded = true
}
@@ -2629,7 +2704,11 @@
}
for _, variant := range android.FirstUniqueStrings(vendorVariants) {
- m.Properties.VendorVariants = append(m.Properties.VendorVariants, VendorVariationPrefix+variant)
+ m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, VendorVariationPrefix+variant)
+ }
+
+ for _, variant := range android.FirstUniqueStrings(productVariants) {
+ m.Properties.ExtraVariants = append(m.Properties.ExtraVariants, ProductVariationPrefix+variant)
}
m.Properties.RecoveryVariantNeeded = recoveryVariantNeeded
@@ -2645,7 +2724,7 @@
}
func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
- return c.Properties.VendorVariants
+ return c.Properties.ExtraVariants
}
func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
@@ -2654,8 +2733,13 @@
m.MakeAsPlatform()
squashRecoverySrcs(m)
} else if strings.HasPrefix(variant, VendorVariationPrefix) {
+ m.Properties.ImageVariationPrefix = VendorVariationPrefix
m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
squashVendorSrcs(m)
+ } else if strings.HasPrefix(variant, ProductVariationPrefix) {
+ m.Properties.ImageVariationPrefix = ProductVariationPrefix
+ m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
+ squashVendorSrcs(m)
}
}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 27ff38f..1e70529 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -82,11 +82,8 @@
return testCcWithConfig(t, config)
}
-func testCcError(t *testing.T, pattern string, bp string) {
+func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
t.Helper()
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := CreateTestContext()
ctx.Register(config)
@@ -106,9 +103,27 @@
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
}
+func testCcError(t *testing.T, pattern string, bp string) {
+ config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+ config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+ testCcErrorWithConfig(t, pattern, config)
+ return
+}
+
+func testCcErrorProductVndk(t *testing.T, pattern string, bp string) {
+ config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+ config.TestProductVariables.ProductVndkVersion = StringPtr("current")
+ config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+ testCcErrorWithConfig(t, pattern, config)
+ return
+}
+
const (
coreVariant = "android_arm64_armv8-a_shared"
vendorVariant = "android_vendor.VER_arm64_armv8-a_shared"
+ productVariant = "android_product.VER_arm64_armv8-a_shared"
recoveryVariant = "android_recovery_arm64_armv8-a_shared"
)
@@ -1445,6 +1460,160 @@
`)
}
+func TestEnforceProductVndkVersion(t *testing.T) {
+ bp := `
+ cc_library {
+ name: "libllndk",
+ }
+ llndk_library {
+ name: "libllndk",
+ symbol_file: "",
+ }
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+ cc_library {
+ name: "libva",
+ vendor_available: true,
+ nocrt: true,
+ }
+ cc_library {
+ name: "libproduct_va",
+ product_specific: true,
+ vendor_available: true,
+ nocrt: true,
+ }
+ cc_library {
+ name: "libprod",
+ product_specific: true,
+ shared_libs: [
+ "libllndk",
+ "libvndk",
+ "libvndk_sp",
+ "libva",
+ "libproduct_va",
+ ],
+ nocrt: true,
+ }
+ cc_library {
+ name: "libvendor",
+ vendor: true,
+ shared_libs: [
+ "libllndk",
+ "libvndk",
+ "libvndk_sp",
+ "libva",
+ "libproduct_va",
+ ],
+ nocrt: true,
+ }
+ `
+
+ config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+ config.TestProductVariables.ProductVndkVersion = StringPtr("current")
+ config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+
+ ctx := testCcWithConfig(t, config)
+
+ checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
+ checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
+}
+
+func TestEnforceProductVndkVersionErrors(t *testing.T) {
+ testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
+ cc_library {
+ name: "libprod",
+ product_specific: true,
+ shared_libs: [
+ "libvendor",
+ ],
+ nocrt: true,
+ }
+ cc_library {
+ name: "libvendor",
+ vendor: true,
+ nocrt: true,
+ }
+ `)
+ testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
+ cc_library {
+ name: "libprod",
+ product_specific: true,
+ shared_libs: [
+ "libsystem",
+ ],
+ nocrt: true,
+ }
+ cc_library {
+ name: "libsystem",
+ nocrt: true,
+ }
+ `)
+ testCcErrorProductVndk(t, "Vendor module that is not VNDK should not link to \".*\" which is marked as `vendor_available: false`", `
+ cc_library {
+ name: "libprod",
+ product_specific: true,
+ shared_libs: [
+ "libvndk_private",
+ ],
+ nocrt: true,
+ }
+ cc_library {
+ name: "libvndk_private",
+ vendor_available: false,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+ `)
+ testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
+ cc_library {
+ name: "libprod",
+ product_specific: true,
+ shared_libs: [
+ "libsystem_ext",
+ ],
+ nocrt: true,
+ }
+ cc_library {
+ name: "libsystem_ext",
+ system_ext_specific: true,
+ nocrt: true,
+ }
+ `)
+ testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:", `
+ cc_library {
+ name: "libsystem",
+ shared_libs: [
+ "libproduct_va",
+ ],
+ nocrt: true,
+ }
+ cc_library {
+ name: "libproduct_va",
+ product_specific: true,
+ vendor_available: true,
+ nocrt: true,
+ }
+ `)
+}
+
func TestMakeLinkType(t *testing.T) {
bp := `
cc_library {
diff --git a/cc/genrule.go b/cc/genrule.go
index b9765a4..548d5f2 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -55,6 +55,10 @@
return true
}
+ if ctx.DeviceConfig().ProductVndkVersion() != "" && ctx.ProductSpecific() {
+ return false
+ }
+
return Bool(g.Vendor_available) || !(ctx.SocSpecific() || ctx.DeviceSpecific())
}
@@ -67,16 +71,26 @@
return nil
}
+ var variants []string
if Bool(g.Vendor_available) || ctx.SocSpecific() || ctx.DeviceSpecific() {
- var variants []string
variants = append(variants, VendorVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
if vndkVersion := ctx.DeviceConfig().VndkVersion(); vndkVersion != "current" {
variants = append(variants, VendorVariationPrefix+vndkVersion)
}
+ }
+
+ if ctx.DeviceConfig().ProductVndkVersion() == "" {
return variants
}
- return nil
+ if Bool(g.Vendor_available) || ctx.ProductSpecific() {
+ variants = append(variants, ProductVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
+ if vndkVersion := ctx.DeviceConfig().ProductVndkVersion(); vndkVersion != "current" {
+ variants = append(variants, ProductVariationPrefix+vndkVersion)
+ }
+ }
+
+ return variants
}
func (g *GenruleExtraProperties) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
diff --git a/cc/installer.go b/cc/installer.go
index 9fdc88a..2f55ac5 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -72,7 +72,11 @@
dir = filepath.Join(dir, ctx.Arch().ArchType.String())
}
if installer.location == InstallInData && ctx.useVndk() {
- dir = filepath.Join(dir, "vendor")
+ if ctx.inProduct() {
+ dir = filepath.Join(dir, "product")
+ } else {
+ dir = filepath.Join(dir, "vendor")
+ }
}
return android.PathForModuleInstall(ctx, dir, installer.subDir,
installer.relativeInstallPath(), installer.relative)
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index f3ee5c1..3dee692 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -76,17 +76,12 @@
}
func (stub *llndkStubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
- vndk_ver := ctx.Module().(*Module).Properties.VndkVersion
- if vndk_ver == "current" {
- platform_vndk_ver := ctx.DeviceConfig().PlatformVndkVersion()
- if !inList(platform_vndk_ver, ctx.Config().PlatformVersionCombinedCodenames()) {
- vndk_ver = platform_vndk_ver
- }
- } else if vndk_ver == "" {
- // For non-enforcing devices, use "current"
- vndk_ver = "current"
+ vndkVer := ctx.Module().(*Module).VndkVersion()
+ if !inList(vndkVer, ctx.Config().PlatformVersionCombinedCodenames()) || vndkVer == "" {
+ // For non-enforcing devices, vndkVer is empty. Use "current" in that case, too.
+ vndkVer = "current"
}
- objs, versionScript := compileStubLibrary(ctx, flags, String(stub.Properties.Symbol_file), vndk_ver, "--llndk")
+ objs, versionScript := compileStubLibrary(ctx, flags, String(stub.Properties.Symbol_file), vndkVer, "--llndk")
stub.versionScriptPath = versionScript
return objs
}
diff --git a/cc/vndk.go b/cc/vndk.go
index f531af3..e4453eb 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -132,16 +132,16 @@
return
}
if !vndk.isVndk() {
- // Non-VNDK modules (those installed to /vendor) can't depend on modules marked with
- // vendor_available: false.
+ // Non-VNDK modules (those installed to /vendor, /product, or /system/product) can't depend
+ // on modules marked with vendor_available: false.
violation := false
if lib, ok := to.linker.(*llndkStubDecorator); ok && !Bool(lib.Properties.Vendor_available) {
violation = true
} else {
if _, ok := to.linker.(libraryInterface); ok && to.VendorProperties.Vendor_available != nil && !Bool(to.VendorProperties.Vendor_available) {
// Vendor_available == nil && !Bool(Vendor_available) should be okay since
- // it means a vendor-only library which is a valid dependency for non-VNDK
- // modules.
+ // it means a vendor-only, or product-only library which is a valid dependency
+ // for non-VNDK modules.
violation = true
}
}
@@ -350,7 +350,7 @@
}
if lib, ok := m.linker.(libraryInterface); ok {
- useCoreVariant := m.vndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
+ useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() &&
mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant()
return lib.shared() && m.UseVndk() && m.IsVndk() && !m.isVndkExt() && !useCoreVariant
}
@@ -665,14 +665,14 @@
if m.Target().NativeBridge == android.NativeBridgeEnabled {
return nil, "", false
}
- if !m.UseVndk() || !m.IsForPlatform() || !m.installable() {
+ if !m.UseVndk() || !m.IsForPlatform() || !m.installable() || !m.inVendor() {
return nil, "", false
}
l, ok := m.linker.(vndkSnapshotLibraryInterface)
if !ok || !l.shared() {
return nil, "", false
}
- if m.vndkVersion() == ctx.DeviceConfig().PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() {
+ if m.VndkVersion() == ctx.DeviceConfig().PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() {
if m.isVndkSp() {
return l, "vndk-sp", true
} else {
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 3b7f772..ff3f10a 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1948,12 +1948,42 @@
properties PrebuiltStubsSourcesProperties
- srcs android.Paths
+ // The source directories containing stubs source files.
+ srcDirs android.Paths
stubsSrcJar android.ModuleOutPath
}
+func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return android.Paths{p.stubsSrcJar}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
+}
+
func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- p.srcs = android.PathsForModuleSrc(ctx, p.properties.Srcs)
+ p.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
+
+ p.srcDirs = android.PathsForModuleSrc(ctx, p.properties.Srcs)
+
+ rule := android.NewRuleBuilder()
+ command := rule.Command().
+ BuiltTool(ctx, "soong_zip").
+ Flag("-write_if_changed").
+ Flag("-jar").
+ FlagWithOutput("-o ", p.stubsSrcJar)
+
+ for _, d := range p.srcDirs {
+ dir := d.String()
+ command.
+ FlagWithArg("-C ", dir).
+ FlagWithInput("-D ", d)
+ }
+
+ rule.Restat()
+
+ rule.Build(pctx, ctx, "zip src", "Create srcjar from prebuilt source")
}
func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
@@ -1964,10 +1994,6 @@
return p.prebuilt.Name(p.ModuleBase.Name())
}
-func (p *PrebuiltStubsSources) Srcs() android.Paths {
- return append(android.Paths{}, p.srcs...)
-}
-
// prebuilt_stubs_sources imports a set of java source files as if they were
// generated by droidstubs.
//
diff --git a/java/java_test.go b/java/java_test.go
index 096cdb9..2f67cda 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -484,28 +484,24 @@
prebuilt_stubs_sources {
name: "stubs-source",
- srcs: ["stubs/sources/**/*.java"],
+ srcs: ["stubs/sources"],
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
+ fooModule := ctx.ModuleForTests("foo", "android_common")
+ javac := fooModule.Rule("javac")
combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
barJar := ctx.ModuleForTests("bar", "android_common").Rule("combineJar").Output
bazJar := ctx.ModuleForTests("baz", "android_common").Rule("combineJar").Output
sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output
- inputs := []string{}
- for _, p := range javac.BuildParams.Inputs {
- inputs = append(inputs, p.String())
- }
+ fooLibrary := fooModule.Module().(*Library)
+ assertDeepEquals(t, "foo java sources incorrect",
+ []string{"a.java"}, fooLibrary.compiledJavaSrcs.Strings())
- expected := []string{
- "a.java",
- "stubs/sources/foo/Foo.java",
- }
- if !reflect.DeepEqual(expected, inputs) {
- t.Errorf("foo inputs incorrect: expected %q, found %q", expected, inputs)
- }
+ assertDeepEquals(t, "foo java source jars incorrect",
+ []string{".intermediates/stubs-source/android_common/stubs-source-stubs.srcjar"},
+ android.NormalizePathsForTesting(fooLibrary.compiledSrcJars))
if !strings.Contains(javac.Args["classpath"], barJar.String()) {
t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String())
@@ -522,6 +518,12 @@
ctx.ModuleForTests("qux", "android_common").Rule("Cp")
}
+func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) {
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("%s: expected %q, found %q", message, expected, actual)
+ }
+}
+
func TestDefaults(t *testing.T) {
ctx, _ := testJava(t, `
java_defaults {
diff --git a/sdk/testing.go b/sdk/testing.go
index 950cf0a..c0d6f51 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -183,7 +183,7 @@
switch bp.Rule.String() {
case android.Cp.String():
// Get source relative to build directory.
- src := r.pathRelativeToBuildDir(bp.Input)
+ src := android.NormalizePathForTesting(bp.Input)
// Get destination relative to the snapshot root
dest := bp.Output.Rel()
_, _ = fmt.Fprintf(copyRules, "%s -> %s\n", src, dest)
@@ -199,12 +199,12 @@
// This could be an intermediate zip file and not the actual output zip.
// In that case this will be overridden when the rule to merge the zips
// is processed.
- info.outputZip = r.pathRelativeToBuildDir(bp.Output)
+ info.outputZip = android.NormalizePathForTesting(bp.Output)
case mergeZips.String():
// Copy the current outputZip to the intermediateZip.
info.intermediateZip = info.outputZip
- mergeInput := r.pathRelativeToBuildDir(bp.Input)
+ mergeInput := android.NormalizePathForTesting(bp.Input)
if info.intermediateZip != mergeInput {
r.t.Errorf("Expected intermediate zip %s to be an input to merge zips but found %s instead",
info.intermediateZip, mergeInput)
@@ -212,10 +212,10 @@
// Override output zip (which was actually the intermediate zip file) with the actual
// output zip.
- info.outputZip = r.pathRelativeToBuildDir(bp.Output)
+ info.outputZip = android.NormalizePathForTesting(bp.Output)
// Save the zips to be merged into the intermediate zip.
- info.mergeZips = r.pathsRelativeToBuildDir(bp.Inputs)
+ info.mergeZips = android.NormalizePathsForTesting(bp.Inputs)
}
}
@@ -232,19 +232,6 @@
return r.ctx.ModuleForTests(name, variant)
}
-func (r *testSdkResult) pathRelativeToBuildDir(path android.Path) string {
- buildDir := filepath.Clean(r.config.BuildDir()) + "/"
- return strings.TrimPrefix(filepath.Clean(path.String()), buildDir)
-}
-
-func (r *testSdkResult) pathsRelativeToBuildDir(paths android.Paths) []string {
- var result []string
- for _, path := range paths {
- result = append(result, r.pathRelativeToBuildDir(path))
- }
- return result
-}
-
// Check the snapshot build rules.
//
// Takes a list of functions which check different facets of the snapshot build rules.