Merge "Add CCACHE_DIR to allowed environment variables"
diff --git a/Android.bp b/Android.bp
index f425c3f..2a4653a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -204,6 +204,7 @@
"cc/linker.go",
"cc/binary.go",
+ "cc/binary_sdk_member.go",
"cc/fuzz.go",
"cc/library.go",
"cc/library_sdk_member.go",
diff --git a/android/apex.go b/android/apex.go
index 17ec9b1..43a42df 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -19,6 +19,14 @@
"sync"
)
+type ApexInfo struct {
+ // Name of the apex variant that this module is mutated into
+ ApexName string
+
+ // Whether this apex variant needs to target Android 10
+ LegacyAndroid10Support bool
+}
+
// ApexModule is the interface that a module type is expected to implement if
// the module has to be built differently depending on whether the module
// is destined for an apex or not (installed to one of the regular partitions).
@@ -38,12 +46,12 @@
Module
apexModuleBase() *ApexModuleBase
- // Marks that this module should be built for the APEXes of the specified names.
+ // Marks that this module should be built for the specified APEXes.
// Call this before apex.apexMutator is run.
- BuildForApexes(apexNames []string)
+ BuildForApexes(apexes []ApexInfo)
- // Returns the name of the APEXes that this modoule will be built for
- ApexVariations() []string
+ // Returns the APEXes that this module will be built for
+ ApexVariations() []ApexInfo
// Returns the name of APEX that this module will be built for. Empty string
// is returned when 'IsForPlatform() == true'. Note that a module can be
@@ -72,10 +80,6 @@
// for an APEX marked via BuildForApexes().
CreateApexVariations(mctx BottomUpMutatorContext) []Module
- // Sets the name of the apex variant of this module. Called inside
- // CreateApexVariations.
- setApexName(apexName string)
-
// Tests if this module is available for the specified APEX or ":platform"
AvailableFor(what string) bool
@@ -94,8 +98,7 @@
// Default is ["//apex_available:platform"].
Apex_available []string
- // Name of the apex variant that this module is mutated into
- ApexName string `blueprint:"mutated"`
+ Info ApexInfo `blueprint:"mutated"`
}
// Provides default implementation for the ApexModule interface. APEX-aware
@@ -106,37 +109,37 @@
canHaveApexVariants bool
apexVariationsLock sync.Mutex // protects apexVariations during parallel apexDepsMutator
- apexVariations []string
+ apexVariations []ApexInfo
}
func (m *ApexModuleBase) apexModuleBase() *ApexModuleBase {
return m
}
-func (m *ApexModuleBase) BuildForApexes(apexNames []string) {
+func (m *ApexModuleBase) BuildForApexes(apexes []ApexInfo) {
m.apexVariationsLock.Lock()
defer m.apexVariationsLock.Unlock()
- for _, apexName := range apexNames {
- if !InList(apexName, m.apexVariations) {
- m.apexVariations = append(m.apexVariations, apexName)
+nextApex:
+ for _, apex := range apexes {
+ for _, v := range m.apexVariations {
+ if v.ApexName == apex.ApexName {
+ continue nextApex
+ }
}
+ m.apexVariations = append(m.apexVariations, apex)
}
}
-func (m *ApexModuleBase) ApexVariations() []string {
+func (m *ApexModuleBase) ApexVariations() []ApexInfo {
return m.apexVariations
}
func (m *ApexModuleBase) ApexName() string {
- return m.ApexProperties.ApexName
+ return m.ApexProperties.Info.ApexName
}
func (m *ApexModuleBase) IsForPlatform() bool {
- return m.ApexProperties.ApexName == ""
-}
-
-func (m *ApexModuleBase) setApexName(apexName string) {
- m.ApexProperties.ApexName = apexName
+ return m.ApexProperties.Info.ApexName == ""
}
func (m *ApexModuleBase) CanHaveApexVariants() bool {
@@ -185,25 +188,35 @@
}
}
+type byApexName []ApexInfo
+
+func (a byApexName) Len() int { return len(a) }
+func (a byApexName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a byApexName) Less(i, j int) bool { return a[i].ApexName < a[j].ApexName }
+
func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Module {
if len(m.apexVariations) > 0 {
m.checkApexAvailableProperty(mctx)
- sort.Strings(m.apexVariations)
+ sort.Sort(byApexName(m.apexVariations))
variations := []string{}
variations = append(variations, "") // Original variation for platform
- variations = append(variations, m.apexVariations...)
+ for _, apex := range m.apexVariations {
+ variations = append(variations, apex.ApexName)
+ }
defaultVariation := ""
mctx.SetDefaultDependencyVariation(&defaultVariation)
modules := mctx.CreateVariations(variations...)
- for i, m := range modules {
+ for i, mod := range modules {
platformVariation := i == 0
- if platformVariation && !mctx.Host() && !m.(ApexModule).AvailableFor(AvailableToPlatform) {
- m.SkipInstall()
+ if platformVariation && !mctx.Host() && !mod.(ApexModule).AvailableFor(AvailableToPlatform) {
+ mod.SkipInstall()
}
- m.(ApexModule).setApexName(variations[i])
+ if !platformVariation {
+ mod.(ApexModule).apexModuleBase().ApexProperties.Info = m.apexVariations[i-1]
+ }
}
return modules
}
@@ -230,16 +243,16 @@
// depended on by the specified APEXes. Directly depending means that a module
// is explicitly listed in the build definition of the APEX via properties like
// native_shared_libs, java_libs, etc.
-func UpdateApexDependency(apexNames []string, moduleName string, directDep bool) {
+func UpdateApexDependency(apexes []ApexInfo, moduleName string, directDep bool) {
apexNamesMapMutex.Lock()
defer apexNamesMapMutex.Unlock()
- for _, apexName := range apexNames {
+ for _, apex := range apexes {
apexesForModule, ok := apexNamesMap()[moduleName]
if !ok {
apexesForModule = make(map[string]bool)
apexNamesMap()[moduleName] = apexesForModule
}
- apexesForModule[apexName] = apexesForModule[apexName] || directDep
+ apexesForModule[apex.ApexName] = apexesForModule[apex.ApexName] || directDep
}
}
diff --git a/android/arch.go b/android/arch.go
index fb1accc..73a490d 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1521,12 +1521,7 @@
// hasArmAbi returns true if arch has at least one arm ABI
func hasArmAbi(arch Arch) bool {
- for _, abi := range arch.Abi {
- if strings.HasPrefix(abi, "arm") {
- return true
- }
- }
- return false
+ return PrefixInList(arch.Abi, "arm")
}
// hasArmArch returns true if targets has at least non-native_bridge arm Android arch
diff --git a/android/config.go b/android/config.go
index 9cf9662..1fe6f05 100644
--- a/android/config.go
+++ b/android/config.go
@@ -890,11 +890,7 @@
func (c *config) EnforceRROExcludedOverlay(path string) bool {
excluded := c.productVariables.EnforceRROExcludedOverlays
if excluded != nil {
- for _, exclude := range excluded {
- if strings.HasPrefix(path, exclude) {
- return true
- }
- }
+ return HasAnyPrefix(path, excluded)
}
return false
}
@@ -1050,12 +1046,12 @@
func (c *deviceConfig) CoverageEnabledForPath(path string) bool {
coverage := false
if c.config.productVariables.CoveragePaths != nil {
- if InList("*", c.config.productVariables.CoveragePaths) || PrefixInList(path, c.config.productVariables.CoveragePaths) {
+ if InList("*", c.config.productVariables.CoveragePaths) || HasAnyPrefix(path, c.config.productVariables.CoveragePaths) {
coverage = true
}
}
if coverage && c.config.productVariables.CoverageExcludePaths != nil {
- if PrefixInList(path, c.config.productVariables.CoverageExcludePaths) {
+ if HasAnyPrefix(path, c.config.productVariables.CoverageExcludePaths) {
coverage = false
}
}
@@ -1128,21 +1124,21 @@
if c.productVariables.IntegerOverflowExcludePaths == nil {
return false
}
- return PrefixInList(path, c.productVariables.IntegerOverflowExcludePaths)
+ return HasAnyPrefix(path, c.productVariables.IntegerOverflowExcludePaths)
}
func (c *config) CFIDisabledForPath(path string) bool {
if c.productVariables.CFIExcludePaths == nil {
return false
}
- return PrefixInList(path, c.productVariables.CFIExcludePaths)
+ return HasAnyPrefix(path, c.productVariables.CFIExcludePaths)
}
func (c *config) CFIEnabledForPath(path string) bool {
if c.productVariables.CFIIncludePaths == nil {
return false
}
- return PrefixInList(path, c.productVariables.CFIIncludePaths)
+ return HasAnyPrefix(path, c.productVariables.CFIIncludePaths)
}
func (c *config) VendorConfig(name string) VendorConfig {
diff --git a/android/neverallow.go b/android/neverallow.go
index 48581df..0cb2029 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -407,8 +407,8 @@
}
func (r *rule) appliesToPath(dir string) bool {
- includePath := len(r.paths) == 0 || hasAnyPrefix(dir, r.paths)
- excludePath := hasAnyPrefix(dir, r.unlessPaths)
+ includePath := len(r.paths) == 0 || HasAnyPrefix(dir, r.paths)
+ excludePath := HasAnyPrefix(dir, r.unlessPaths)
return includePath && !excludePath
}
@@ -474,15 +474,6 @@
return names
}
-func hasAnyPrefix(s string, prefixes []string) bool {
- for _, prefix := range prefixes {
- if strings.HasPrefix(s, prefix) {
- return true
- }
- }
- return false
-}
-
func hasAnyProperty(properties []interface{}, props []ruleProperty) bool {
for _, v := range props {
if hasProperty(properties, v) {
diff --git a/android/util.go b/android/util.go
index e985fc1..ade851e 100644
--- a/android/util.go
+++ b/android/util.go
@@ -122,7 +122,7 @@
}
// Returns true if the given string s is prefixed with any string in the given prefix list.
-func PrefixInList(s string, prefixList []string) bool {
+func HasAnyPrefix(s string, prefixList []string) bool {
for _, prefix := range prefixList {
if strings.HasPrefix(s, prefix) {
return true
@@ -132,7 +132,7 @@
}
// Returns true if any string in the given list has the given prefix.
-func PrefixedStringInList(list []string, prefix string) bool {
+func PrefixInList(list []string, prefix string) bool {
for _, s := range list {
if strings.HasPrefix(s, prefix) {
return true
diff --git a/android/util_test.go b/android/util_test.go
index 90fefee..1f9ca36 100644
--- a/android/util_test.go
+++ b/android/util_test.go
@@ -252,7 +252,7 @@
for _, testCase := range testcases {
t.Run(testCase.str, func(t *testing.T) {
- out := PrefixInList(testCase.str, prefixes)
+ out := HasAnyPrefix(testCase.str, prefixes)
if out != testCase.expected {
t.Errorf("incorrect output:")
t.Errorf(" str: %#v", testCase.str)
diff --git a/android/vts_config.go b/android/vts_config.go
index 86f6e72..9a1df7c 100644
--- a/android/vts_config.go
+++ b/android/vts_config.go
@@ -17,6 +17,7 @@
import (
"fmt"
"io"
+ "strings"
)
func init() {
@@ -26,6 +27,8 @@
type vtsConfigProperties struct {
// Override the default (AndroidTest.xml) test manifest file name.
Test_config *string
+ // Additional test suites to add the test to.
+ Test_suites []string `android:"arch_variant"`
}
type VtsConfig struct {
@@ -50,7 +53,8 @@
fmt.Fprintf(w, "LOCAL_TEST_CONFIG := %s\n",
*me.properties.Test_config)
}
- fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE := vts")
+ fmt.Fprintf(w, "LOCAL_COMPATIBILITY_SUITE := vts %s\n",
+ strings.Join(me.properties.Test_suites, " "))
},
}
return androidMkData
diff --git a/apex/apex.go b/apex/apex.go
index 54a335a..002bf5b 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1024,17 +1024,17 @@
// Mark the direct and transitive dependencies of apex bundles so that they
// can be built for the apex bundles.
func apexDepsMutator(mctx android.TopDownMutatorContext) {
- var apexBundleNames []string
+ var apexBundles []android.ApexInfo
var directDep bool
if a, ok := mctx.Module().(*apexBundle); ok && !a.vndkApex {
- apexBundleNames = []string{mctx.ModuleName()}
+ apexBundles = []android.ApexInfo{{mctx.ModuleName(), proptools.Bool(a.properties.Legacy_android10_support)}}
directDep = true
} else if am, ok := mctx.Module().(android.ApexModule); ok {
- apexBundleNames = am.ApexVariations()
+ apexBundles = am.ApexVariations()
directDep = false
}
- if len(apexBundleNames) == 0 {
+ if len(apexBundles) == 0 {
return
}
@@ -1042,8 +1042,8 @@
depName := mctx.OtherModuleName(child)
if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() &&
(directDep || am.DepIsInSameApex(mctx, child)) {
- android.UpdateApexDependency(apexBundleNames, depName, directDep)
- am.BuildForApexes(apexBundleNames)
+ android.UpdateApexDependency(apexBundles, depName, directDep)
+ am.BuildForApexes(apexBundles)
}
})
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 0420586..5000c88 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -3437,6 +3437,7 @@
apex {
name: "myapex",
key: "myapex.key",
+ native_shared_libs: ["mylib"],
legacy_android10_support: true,
}
@@ -3445,12 +3446,54 @@
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
- `)
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ stl: "libc++",
+ system_shared_libs: [],
+ apex_available: [ "myapex" ],
+ }
+
+ cc_library {
+ name: "libc++",
+ srcs: ["mylib.cpp"],
+ stl: "none",
+ system_shared_libs: [],
+ apex_available: [ "myapex" ],
+ }
+
+ cc_library_static {
+ name: "libc++demangle",
+ srcs: ["mylib.cpp"],
+ stl: "none",
+ system_shared_libs: [],
+ }
+
+ cc_library_static {
+ name: "libunwind_llvm",
+ srcs: ["mylib.cpp"],
+ stl: "none",
+ system_shared_libs: [],
+ }
+ `, withUnbundledBuild)
module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
args := module.Rule("apexRule").Args
ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
ensureNotContains(t, args["opt_flags"], "--no_hashtree")
+
+ // The copies of the libraries in the apex should have one more dependency than
+ // the ones outside the apex, namely the unwinder. Ideally we should check
+ // the dependency names directly here but for some reason the names are blank in
+ // this test.
+ for _, lib := range []string{"libc++", "mylib"} {
+ apexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared_myapex").Rule("ld").Implicits
+ nonApexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld").Implicits
+ if len(apexImplicits) != len(nonApexImplicits)+1 {
+ t.Errorf("%q missing unwinder dep", lib)
+ }
+ }
}
func TestJavaSDKLibrary(t *testing.T) {
diff --git a/cc/binary.go b/cc/binary.go
index 280d17b..661264e 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -200,6 +200,11 @@
module.compiler = NewBaseCompiler()
module.linker = binary
module.installer = binary
+
+ // Allow module to be added as member of an sdk/module_exports.
+ module.sdkMemberTypes = []android.SdkMemberType{
+ ccBinarySdkMemberType,
+ }
return module, binary
}
diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go
new file mode 100644
index 0000000..53bc065
--- /dev/null
+++ b/cc/binary_sdk_member.go
@@ -0,0 +1,143 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cc
+
+import (
+ "path/filepath"
+
+ "android/soong/android"
+ "github.com/google/blueprint"
+)
+
+func init() {
+ android.RegisterSdkMemberType(ccBinarySdkMemberType)
+}
+
+var ccBinarySdkMemberType = &binarySdkMemberType{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
+ PropertyName: "native_binaries",
+ },
+}
+
+type binarySdkMemberType struct {
+ android.SdkMemberTypeBase
+}
+
+func (mt *binarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
+ targets := mctx.MultiTargets()
+ for _, lib := range names {
+ for _, target := range targets {
+ name, version := StubsLibNameAndVersion(lib)
+ if version == "" {
+ version = LatestStubsVersionFor(mctx.Config(), name)
+ }
+ mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
+ {Mutator: "version", Variation: version},
+ }...), dependencyTag, name)
+ }
+ }
+}
+
+func (mt *binarySdkMemberType) IsInstance(module android.Module) bool {
+ // Check the module to see if it can be used with this module type.
+ if m, ok := module.(*Module); ok {
+ for _, allowableMemberType := range m.sdkMemberTypes {
+ if allowableMemberType == mt {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+func (mt *binarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
+ info := mt.organizeVariants(member)
+ buildSharedNativeBinarySnapshot(info, builder, member)
+}
+
+// Organize the variants by architecture.
+func (mt *binarySdkMemberType) organizeVariants(member android.SdkMember) *nativeBinaryInfo {
+ memberName := member.Name()
+ info := &nativeBinaryInfo{
+ name: memberName,
+ memberType: mt,
+ }
+
+ for _, variant := range member.Variants() {
+ ccModule := variant.(*Module)
+
+ info.archVariantProperties = append(info.archVariantProperties, nativeBinaryInfoProperties{
+ name: memberName,
+ archType: ccModule.Target().Arch.ArchType.String(),
+ outputFile: ccModule.OutputFile().Path(),
+ })
+ }
+
+ // Initialize the unexported properties that will not be set during the
+ // extraction process.
+ info.commonProperties.name = memberName
+
+ // Extract common properties from the arch specific properties.
+ extractCommonProperties(&info.commonProperties, info.archVariantProperties)
+
+ return info
+}
+
+func buildSharedNativeBinarySnapshot(info *nativeBinaryInfo, builder android.SnapshotBuilder, member android.SdkMember) {
+ pbm := builder.AddPrebuiltModule(member, "cc_prebuilt_binary")
+ pbm.AddProperty("compile_multilib", "both")
+ archProperties := pbm.AddPropertySet("arch")
+ for _, av := range info.archVariantProperties {
+ archTypeProperties := archProperties.AddPropertySet(av.archType)
+ archTypeProperties.AddProperty("srcs", []string{nativeBinaryPathFor(av)})
+
+ builder.CopyToSnapshot(av.outputFile, nativeBinaryPathFor(av))
+ }
+}
+
+const (
+ nativeBinaryDir = "bin"
+)
+
+// path to the native binary. Relative to <sdk_root>/<api_dir>
+func nativeBinaryPathFor(lib nativeBinaryInfoProperties) string {
+ return filepath.Join(lib.archType,
+ nativeBinaryDir, lib.outputFile.Base())
+}
+
+// nativeBinaryInfoProperties represents properties of a native binary
+//
+// The exported (capitalized) fields will be examined and may be changed during common value extraction.
+// The unexported fields will be left untouched.
+type nativeBinaryInfoProperties struct {
+ // The name of the library, is not exported as this must not be changed during optimization.
+ name string
+
+ // archType is not exported as if set (to a non default value) it is always arch specific.
+ // This is "" for common properties.
+ archType string
+
+ // outputFile is not exported as it is always arch specific.
+ outputFile android.Path
+}
+
+// nativeBinaryInfo represents a collection of arch-specific modules having the same name
+type nativeBinaryInfo struct {
+ name string
+ memberType *binarySdkMemberType
+ archVariantProperties []nativeBinaryInfoProperties
+ commonProperties nativeBinaryInfoProperties
+}
diff --git a/cc/builder.go b/cc/builder.go
index 3ecfe54..136263b 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -55,9 +55,9 @@
},
"ccCmd", "cFlags")
- ccNoDeps = pctx.AndroidRemoteStaticRule("ccNoDeps", android.RemoteRuleSupports{Goma: true},
+ ccNoDeps = pctx.AndroidStaticRule("ccNoDeps",
blueprint.RuleParams{
- Command: "$relPwd ${config.CcWrapper}$ccCmd -c $cFlags -o $out $in",
+ Command: "$relPwd $ccCmd -c $cFlags -o $out $in",
CommandDeps: []string{"$ccCmd"},
},
"ccCmd", "cFlags")
diff --git a/cc/cc.go b/cc/cc.go
index b70e55c..5af8459 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -95,6 +95,8 @@
HeaderLibs []string
RuntimeLibs []string
+ StaticUnwinderIfLegacy bool
+
ReexportSharedLibHeaders, ReexportStaticLibHeaders, ReexportHeaderLibHeaders []string
ObjFiles []string
@@ -385,6 +387,7 @@
lateSharedDepTag = DependencyTag{Name: "late shared", Library: true, Shared: true}
staticExportDepTag = DependencyTag{Name: "static", Library: true, ReexportFlags: true}
lateStaticDepTag = DependencyTag{Name: "late static", Library: true}
+ staticUnwinderDepTag = DependencyTag{Name: "static unwinder", Library: true}
wholeStaticDepTag = DependencyTag{Name: "whole static", Library: true, ReexportFlags: true}
headerDepTag = DependencyTag{Name: "header", Library: true}
headerExportDepTag = DependencyTag{Name: "header", Library: true, ReexportFlags: true}
@@ -1788,6 +1791,12 @@
}, depTag, lib)
}
+ if deps.StaticUnwinderIfLegacy && ctx.Config().UnbundledBuild() {
+ actx.AddVariationDependencies([]blueprint.Variation{
+ {Mutator: "link", Variation: "static"},
+ }, staticUnwinderDepTag, staticUnwinder(actx))
+ }
+
for _, lib := range deps.LateStaticLibs {
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
@@ -2161,6 +2170,14 @@
}
}
+ if depTag == staticUnwinderDepTag {
+ if c.ApexProperties.Info.LegacyAndroid10Support {
+ depTag = StaticDepTag
+ } else {
+ return
+ }
+ }
+
// Extract ExplicitlyVersioned field from the depTag and reset it inside the struct.
// Otherwise, SharedDepTag and lateSharedDepTag with ExplicitlyVersioned set to true
// won't be matched to SharedDepTag and lateSharedDepTag.
diff --git a/cc/cflag_artifacts.go b/cc/cflag_artifacts.go
index b61f2a8..855ff25 100644
--- a/cc/cflag_artifacts.go
+++ b/cc/cflag_artifacts.go
@@ -41,12 +41,7 @@
// filter.
func allowedDir(subdir string) bool {
subdir += "/"
- for _, prefix := range TrackedCFlagsDir {
- if strings.HasPrefix(subdir, prefix) {
- return true
- }
- }
- return false
+ return android.HasAnyPrefix(subdir, TrackedCFlagsDir)
}
func (s *cflagArtifactsText) genFlagFilename(flag string) string {
diff --git a/cc/compiler.go b/cc/compiler.go
index 1ced451..c1a8d96 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -241,12 +241,7 @@
// Return true if the module is in the WarningAllowedProjects.
func warningsAreAllowed(subdir string) bool {
subdir += "/"
- for _, prefix := range config.WarningAllowedProjects {
- if strings.HasPrefix(subdir, prefix) {
- return true
- }
- }
- return false
+ return android.HasAnyPrefix(subdir, config.WarningAllowedProjects)
}
func addToModuleList(ctx ModuleContext, key android.OnceKey, module string) {
@@ -515,7 +510,7 @@
// Exclude directories from manual binder interface whitelisting.
//TODO(b/145621474): Move this check into IInterface.h when clang-tidy no longer uses absolute paths.
- if android.PrefixInList(ctx.ModuleDir(), allowedManualInterfacePaths) {
+ if android.HasAnyPrefix(ctx.ModuleDir(), allowedManualInterfacePaths) {
flags.Local.CFlags = append(flags.Local.CFlags, "-DDO_NOT_CHECK_MANUAL_BINDER_INTERFACES")
}
@@ -604,16 +599,12 @@
func isThirdParty(path string) bool {
thirdPartyDirPrefixes := []string{"external/", "vendor/", "hardware/"}
- for _, prefix := range thirdPartyDirPrefixes {
- if strings.HasPrefix(path, prefix) {
- for _, prefix := range thirdPartyDirPrefixExceptions {
- if prefix.MatchString(path) {
- return false
- }
+ if android.HasAnyPrefix(path, thirdPartyDirPrefixes) {
+ for _, prefix := range thirdPartyDirPrefixExceptions {
+ if prefix.MatchString(path) {
+ return false
}
- break
}
}
-
return true
}
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 26a104b..0d03699 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -171,10 +171,8 @@
"-Wno-implicit-int-float-conversion",
// New warnings to be fixed after clang-r377782.
"-Wno-bitwise-conditional-parentheses", // http://b/148286937
- "-Wno-bool-operation", // http://b/148287141
"-Wno-int-in-bool-context", // http://b/148287349
"-Wno-sizeof-array-div", // http://b/148815709
- "-Wno-tautological-bitwise-compare", // http://b/148831363
"-Wno-tautological-overlap-compare", // http://b/148815696
}, " "))
diff --git a/cc/config/global.go b/cc/config/global.go
index 57a5852..d01dd84 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -127,8 +127,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r377782"
- ClangDefaultShortVersion = "10.0.3"
+ ClangDefaultVersion = "clang-r377782b"
+ ClangDefaultShortVersion = "10.0.4"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index 5cecbd6..54f693e 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -19,6 +19,7 @@
// has VndkUseCoreVariant set.
var VndkMustUseVendorVariantList = []string{
"android.hardware.light-ndk_platform",
+ "android.hardware.identity-ndk_platform",
"android.hardware.nfc@1.2",
"android.hardware.power-ndk_platform",
"android.hardware.vibrator-ndk_platform",
diff --git a/cc/library.go b/cc/library.go
index 0bddab5..bca9a96 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -281,11 +281,9 @@
}
func (f *flagExporter) reexportFlags(flags ...string) {
- for _, flag := range flags {
- if strings.HasPrefix(flag, "-I") || strings.HasPrefix(flag, "-isystem") {
- panic(fmt.Errorf("Exporting invalid flag %q: "+
- "use reexportDirs or reexportSystemDirs to export directories", flag))
- }
+ if android.PrefixInList(flags, "-I") || android.PrefixInList(flags, "-isystem") {
+ panic(fmt.Errorf("Exporting invalid flag %q: "+
+ "use reexportDirs or reexportSystemDirs to export directories", flag))
}
f.flags = append(f.flags, flags...)
}
diff --git a/cc/stl.go b/cc/stl.go
index af015f9..eda8a4f 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -151,6 +151,14 @@
return version < 21
}
+func staticUnwinder(ctx android.BaseModuleContext) string {
+ if ctx.Arch().ArchType == android.Arm {
+ return "libunwind_llvm"
+ } else {
+ return "libgcc_stripped"
+ }
+}
+
func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
switch stl.Properties.SelectedStl {
case "libstdc++":
@@ -172,16 +180,16 @@
}
if ctx.toolchain().Bionic() {
if ctx.staticBinary() {
- deps.StaticLibs = append(deps.StaticLibs, "libm", "libc")
- if ctx.Arch().ArchType == android.Arm {
- deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm")
- } else {
- deps.StaticLibs = append(deps.StaticLibs, "libgcc_stripped")
- }
+ deps.StaticLibs = append(deps.StaticLibs, "libm", "libc", staticUnwinder(ctx))
+ } else {
+ deps.StaticUnwinderIfLegacy = true
}
}
case "":
// None or error.
+ if ctx.toolchain().Bionic() && ctx.Module().Name() == "libc++" {
+ deps.StaticUnwinderIfLegacy = true
+ }
case "ndk_system":
// TODO: Make a system STL prebuilt for the NDK.
// The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 9b0e7a5..6cb9873 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -426,7 +426,7 @@
cmd.FlagWithArg("--copy-dex-files=", "false")
}
- if !anyHavePrefix(preoptFlags, "--compiler-filter=") {
+ if !android.PrefixInList(preoptFlags, "--compiler-filter=") {
var compilerFilter string
if contains(global.SystemServerJars, module.Name) {
// Jars of system server, use the product option if it is set, speed otherwise.
@@ -618,32 +618,4 @@
return false
}
-// remove all elements in a from b, returning a new slice
-func filterOut(a []string, b []string) []string {
- var ret []string
- for _, x := range b {
- if !contains(a, x) {
- ret = append(ret, x)
- }
- }
- return ret
-}
-
-func replace(l []string, from, to string) {
- for i := range l {
- if l[i] == from {
- l[i] = to
- }
- }
-}
-
var copyOf = android.CopyOf
-
-func anyHavePrefix(l []string, prefix string) bool {
- for _, x := range l {
- if strings.HasPrefix(x, prefix) {
- return true
- }
- }
- return false
-}
diff --git a/java/aar.go b/java/aar.go
index 24c5e7d..6e3b9e6 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -101,6 +101,7 @@
usesNonSdkApis bool
sdkLibraries []string
hasNoCode bool
+ LoggingParent string
splitNames []string
splits []split
@@ -134,15 +135,8 @@
manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
- hasVersionCode := false
- hasVersionName := false
- for _, f := range a.aaptProperties.Aaptflags {
- if strings.HasPrefix(f, "--version-code") {
- hasVersionCode = true
- } else if strings.HasPrefix(f, "--version-name") {
- hasVersionName = true
- }
- }
+ hasVersionCode := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-code")
+ hasVersionName := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-name")
// Flags specified in Android.bp
linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
@@ -241,7 +235,8 @@
manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
manifestPath := manifestFixer(ctx, manifestSrcPath, sdkContext, sdkLibraries,
- a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode)
+ a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode,
+ a.LoggingParent)
// Add additional manifest files to transitive manifests.
additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
@@ -337,7 +332,7 @@
// Extract assets from the resource package output so that they can be used later in aapt2link
// for modules that depend on this one.
- if android.PrefixedStringInList(linkFlags, "-A ") || len(assetPackages) > 0 {
+ if android.PrefixInList(linkFlags, "-A ") || len(assetPackages) > 0 {
assets := android.PathForModuleOut(ctx, "assets.zip")
ctx.Build(pctx, android.BuildParams{
Rule: extractAssetsRule,
diff --git a/java/android_manifest.go b/java/android_manifest.go
index e3646f5..9a71be2 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -53,7 +53,7 @@
// Uses manifest_fixer.py to inject minSdkVersion, etc. into an AndroidManifest.xml
func manifestFixer(ctx android.ModuleContext, manifest android.Path, sdkContext sdkContext, sdkLibraries []string,
- isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, useEmbeddedDex, hasNoCode bool) android.Path {
+ isLibrary, useEmbeddedNativeLibs, usesNonSdkApis, useEmbeddedDex, hasNoCode bool, loggingParent string) android.Path {
var args []string
if isLibrary {
@@ -91,6 +91,9 @@
args = append(args, "--has-no-code")
}
+ if loggingParent != "" {
+ args = append(args, "--logging-parent", loggingParent)
+ }
var deps android.Paths
targetSdkVersion, err := sdkContext.targetSdkVersion().effectiveVersionString(ctx)
if err != nil {
diff --git a/java/app.go b/java/app.go
index 02f3e7f..71bad68 100755
--- a/java/app.go
+++ b/java/app.go
@@ -111,6 +111,9 @@
// the package name of this app. The package name in the manifest file is used if one was not given.
Package_name *string
+
+ // the logging parent of this app.
+ Logging_parent *string
}
type AndroidApp struct {
@@ -273,13 +276,7 @@
aaptLinkFlags := []string{}
// Add TARGET_AAPT_CHARACTERISTICS values to AAPT link flags if they exist and --product flags were not provided.
- hasProduct := false
- for _, f := range a.aaptProperties.Aaptflags {
- if strings.HasPrefix(f, "--product") {
- hasProduct = true
- break
- }
- }
+ hasProduct := android.PrefixInList(a.aaptProperties.Aaptflags, "--product")
if !hasProduct && len(ctx.Config().ProductAAPTCharacteristics()) > 0 {
aaptLinkFlags = append(aaptLinkFlags, "--product", ctx.Config().ProductAAPTCharacteristics())
}
@@ -309,7 +306,7 @@
a.aapt.splitNames = a.appProperties.Package_splits
a.aapt.sdkLibraries = a.exportedSdkLibs
-
+ a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...)
// apps manifests are handled by aapt, don't let Module see them
diff --git a/java/app_test.go b/java/app_test.go
index c86b038..6d94160 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1181,6 +1181,7 @@
name: "bar",
base: "foo",
certificate: ":new_certificate",
+ logging_parent: "bah",
}
android_app_certificate {
@@ -1196,37 +1197,41 @@
`)
expectedVariants := []struct {
- moduleName string
- variantName string
- apkName string
- apkPath string
- signFlag string
- overrides []string
- aaptFlag string
+ moduleName string
+ variantName string
+ apkName string
+ apkPath string
+ signFlag string
+ overrides []string
+ aaptFlag string
+ logging_parent string
}{
{
- moduleName: "foo",
- variantName: "android_common",
- apkPath: "/target/product/test_device/system/app/foo/foo.apk",
- signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- overrides: []string{"qux"},
- aaptFlag: "",
+ moduleName: "foo",
+ variantName: "android_common",
+ apkPath: "/target/product/test_device/system/app/foo/foo.apk",
+ signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ overrides: []string{"qux"},
+ aaptFlag: "",
+ logging_parent: "",
},
{
- moduleName: "bar",
- variantName: "android_common_bar",
- apkPath: "/target/product/test_device/system/app/bar/bar.apk",
- signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
- overrides: []string{"qux", "foo"},
- aaptFlag: "",
+ moduleName: "bar",
+ variantName: "android_common_bar",
+ apkPath: "/target/product/test_device/system/app/bar/bar.apk",
+ signFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
+ overrides: []string{"qux", "foo"},
+ aaptFlag: "",
+ logging_parent: "bah",
},
{
- moduleName: "baz",
- variantName: "android_common_baz",
- apkPath: "/target/product/test_device/system/app/baz/baz.apk",
- signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- overrides: []string{"qux", "foo"},
- aaptFlag: "--rename-manifest-package org.dandroid.bp",
+ moduleName: "baz",
+ variantName: "android_common_baz",
+ apkPath: "/target/product/test_device/system/app/baz/baz.apk",
+ signFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
+ overrides: []string{"qux", "foo"},
+ aaptFlag: "--rename-manifest-package org.dandroid.bp",
+ logging_parent: "",
},
}
for _, expected := range expectedVariants {
@@ -1260,6 +1265,13 @@
expected.overrides, mod.appProperties.Overrides)
}
+ // Test Overridable property: Logging_parent
+ logging_parent := mod.aapt.LoggingParent
+ if expected.logging_parent != logging_parent {
+ t.Errorf("Incorrect overrides property value for logging parent, expected: %q, got: %q",
+ expected.logging_parent, logging_parent)
+ }
+
// Check the package renaming flag, if exists.
res := variant.Output("package-res.apk")
aapt2Flags := res.Args["flags"]
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 96f8042..28f56d2 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -15,6 +15,7 @@
package java
import (
+ "fmt"
"path/filepath"
"strings"
@@ -29,14 +30,29 @@
return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string {
global := dexpreopt.GetGlobalConfig(ctx)
var systemServerClasspathLocations []string
- for _, m := range *DexpreoptedSystemServerJars(ctx.Config()) {
+ var dexpreoptJars = *DexpreoptedSystemServerJars(ctx.Config())
+ // 1) The jars that are dexpreopted.
+ for _, m := range dexpreoptJars {
systemServerClasspathLocations = append(systemServerClasspathLocations,
filepath.Join("/system/framework", m+".jar"))
}
+ // 2) The jars that are from an updatable apex.
for _, m := range global.UpdatableSystemServerJars {
systemServerClasspathLocations = append(systemServerClasspathLocations,
dexpreopt.GetJarLocationFromApexJarPair(m))
}
+ // 3) The jars from make (which are not updatable, not preopted).
+ for _, m := range dexpreopt.NonUpdatableSystemServerJars(ctx, global) {
+ if !android.InList(m, dexpreoptJars) {
+ systemServerClasspathLocations = append(systemServerClasspathLocations,
+ filepath.Join("/system/framework", m+".jar"))
+ }
+ }
+ if len(systemServerClasspathLocations) != len(global.SystemServerJars)+len(global.UpdatableSystemServerJars) {
+ panic(fmt.Errorf("Wrong number of system server jars, got %d, expected %d",
+ len(systemServerClasspathLocations),
+ len(global.SystemServerJars)+len(global.UpdatableSystemServerJars)))
+ }
return systemServerClasspathLocations
})
}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 959f1c7..fd4b90d 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -547,10 +547,10 @@
case bootClasspathTag:
if dep, ok := module.(Dependency); ok {
deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
- } else if sm, ok := module.(*SystemModules); ok {
+ } else if sm, ok := module.(SystemModulesProvider); ok {
// A system modules dependency has been added to the bootclasspath
// so add its libs to the bootclasspath.
- deps.bootClasspath = append(deps.bootClasspath, sm.headerJars...)
+ deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...)
} else {
panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
}
@@ -578,11 +578,9 @@
if deps.systemModules != nil {
panic("Found two system module dependencies")
}
- sm := module.(*SystemModules)
- if sm.outputDir == nil && len(sm.outputDeps) == 0 {
- panic("Missing directory for system module dependency")
- }
- deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
+ sm := module.(SystemModulesProvider)
+ outputDir, outputDeps := sm.OutputDirAndDeps()
+ deps.systemModules = &systemModules{outputDir, outputDeps}
}
})
// do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
@@ -605,11 +603,8 @@
continue
}
packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
- for _, pkg := range filterPackages {
- if strings.HasPrefix(packageName, pkg) {
- filtered = append(filtered, src)
- break
- }
+ if android.HasAnyPrefix(packageName, filterPackages) {
+ filtered = append(filtered, src)
}
}
return filtered
diff --git a/java/java.go b/java/java.go
index c3e2c96..462dba8 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1031,18 +1031,16 @@
case bootClasspathTag:
// If a system modules dependency has been added to the bootclasspath
// then add its libs to the bootclasspath.
- sm := module.(*SystemModules)
- deps.bootClasspath = append(deps.bootClasspath, sm.headerJars...)
+ sm := module.(SystemModulesProvider)
+ deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...)
case systemModulesTag:
if deps.systemModules != nil {
panic("Found two system module dependencies")
}
- sm := module.(*SystemModules)
- if sm.outputDir == nil || len(sm.outputDeps) == 0 {
- panic("Missing directory for system module dependency")
- }
- deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
+ sm := module.(SystemModulesProvider)
+ outputDir, outputDeps := sm.OutputDirAndDeps()
+ deps.systemModules = &systemModules{outputDir, outputDeps}
}
}
})
diff --git a/java/java_test.go b/java/java_test.go
index a2226b5..52b3bc0 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -982,6 +982,65 @@
}
}
+func TestDroidstubsWithSystemModules(t *testing.T) {
+ ctx, _ := testJava(t, `
+ droidstubs {
+ name: "stubs-source-system-modules",
+ srcs: [
+ "bar-doc/*.java",
+ ],
+ sdk_version: "none",
+ system_modules: "source-system-modules",
+ }
+
+ java_library {
+ name: "source-jar",
+ srcs: [
+ "a.java",
+ ],
+ }
+
+ java_system_modules {
+ name: "source-system-modules",
+ libs: ["source-jar"],
+ }
+
+ droidstubs {
+ name: "stubs-prebuilt-system-modules",
+ srcs: [
+ "bar-doc/*.java",
+ ],
+ sdk_version: "none",
+ system_modules: "prebuilt-system-modules",
+ }
+
+ java_import {
+ name: "prebuilt-jar",
+ jars: ["a.jar"],
+ }
+
+ java_system_modules_import {
+ name: "prebuilt-system-modules",
+ libs: ["prebuilt-jar"],
+ }
+ `)
+
+ checkSystemModulesUseByDroidstubs(t, ctx, "stubs-source-system-modules", "source-jar.jar")
+
+ checkSystemModulesUseByDroidstubs(t, ctx, "stubs-prebuilt-system-modules", "prebuilt-jar.jar")
+}
+
+func checkSystemModulesUseByDroidstubs(t *testing.T, ctx *android.TestContext, moduleName string, systemJar string) {
+ metalavaRule := ctx.ModuleForTests(moduleName, "android_common").Rule("metalava")
+ var systemJars []string
+ for _, i := range metalavaRule.Implicits {
+ systemJars = append(systemJars, i.Base())
+ }
+ if len(systemJars) != 1 || systemJars[0] != systemJar {
+ t.Errorf("inputs of %q must be []string{%q}, but was %#v.", moduleName, systemJar, systemJars)
+ }
+}
+
func TestJarGenrules(t *testing.T) {
ctx, _ := testJava(t, `
java_library {
@@ -1377,3 +1436,59 @@
}
}
}
+
+func TestJavaLibraryWithSystemModules(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "lib-with-source-system-modules",
+ srcs: [
+ "a.java",
+ ],
+ sdk_version: "none",
+ system_modules: "source-system-modules",
+ }
+
+ java_library {
+ name: "source-jar",
+ srcs: [
+ "a.java",
+ ],
+ }
+
+ java_system_modules {
+ name: "source-system-modules",
+ libs: ["source-jar"],
+ }
+
+ java_library {
+ name: "lib-with-prebuilt-system-modules",
+ srcs: [
+ "a.java",
+ ],
+ sdk_version: "none",
+ system_modules: "prebuilt-system-modules",
+ }
+
+ java_import {
+ name: "prebuilt-jar",
+ jars: ["a.jar"],
+ }
+
+ java_system_modules_import {
+ name: "prebuilt-system-modules",
+ libs: ["prebuilt-jar"],
+ }
+ `)
+
+ checkBootClasspathForSystemModule(t, ctx, "lib-with-source-system-modules", "/source-jar.jar")
+
+ checkBootClasspathForSystemModule(t, ctx, "lib-with-prebuilt-system-modules", "/prebuilt-jar.jar")
+}
+
+func checkBootClasspathForSystemModule(t *testing.T, ctx *android.TestContext, moduleName string, expectedSuffix string) {
+ javacRule := ctx.ModuleForTests(moduleName, "android_common").Rule("javac")
+ bootClasspath := javacRule.Args["bootClasspath"]
+ if strings.HasPrefix(bootClasspath, "--system ") && strings.HasSuffix(bootClasspath, expectedSuffix) {
+ t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath)
+ }
+}
diff --git a/java/system_modules.go b/java/system_modules.go
index 731503f..47de6e3 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -117,6 +117,15 @@
return module
}
+type SystemModulesProvider interface {
+ HeaderJars() android.Paths
+ OutputDirAndDeps() (android.Path, android.Paths)
+}
+
+var _ SystemModulesProvider = (*SystemModules)(nil)
+
+var _ SystemModulesProvider = (*systemModulesImport)(nil)
+
type SystemModules struct {
android.ModuleBase
android.DefaultableModuleBase
@@ -136,6 +145,17 @@
Libs []string
}
+func (system *SystemModules) HeaderJars() android.Paths {
+ return system.headerJars
+}
+
+func (system *SystemModules) OutputDirAndDeps() (android.Path, android.Paths) {
+ if system.outputDir == nil || len(system.outputDeps) == 0 {
+ panic("Missing directory for system module dependency")
+ }
+ return system.outputDir, system.outputDeps
+}
+
func (system *SystemModules) GenerateAndroidBuildActions(ctx android.ModuleContext) {
var jars android.Paths
diff --git a/scripts/manifest_fixer.py b/scripts/manifest_fixer.py
index 945bc18..c59732b 100755
--- a/scripts/manifest_fixer.py
+++ b/scripts/manifest_fixer.py
@@ -51,6 +51,9 @@
help='specify additional <uses-library> tag to add. android:requred is set to false')
parser.add_argument('--uses-non-sdk-api', dest='uses_non_sdk_api', action='store_true',
help='manifest is for a package built against the platform')
+ parser.add_argument('--logging-parent', dest='logging_parent', default='',
+ help=('specify logging parent as an additional <meta-data> tag. '
+ 'This value is ignored if the logging_parent meta-data tag is present.'))
parser.add_argument('--use-embedded-dex', dest='use_embedded_dex', action='store_true',
help=('specify if the app wants to use embedded dex and avoid extracted,'
'locally compiled code. Must not conflict if already declared '
@@ -124,6 +127,52 @@
element.setAttributeNode(target_attr)
+def add_logging_parent(doc, logging_parent_value):
+ """Add logging parent as an additional <meta-data> tag.
+
+ Args:
+ doc: The XML document. May be modified by this function.
+ logging_parent_value: A string representing the logging
+ parent value.
+ Raises:
+ RuntimeError: Invalid manifest
+ """
+ manifest = parse_manifest(doc)
+
+ logging_parent_key = 'android.content.pm.LOGGING_PARENT'
+ elems = get_children_with_tag(manifest, 'application')
+ application = elems[0] if len(elems) == 1 else None
+ if len(elems) > 1:
+ raise RuntimeError('found multiple <application> tags')
+ elif not elems:
+ application = doc.createElement('application')
+ indent = get_indent(manifest.firstChild, 1)
+ first = manifest.firstChild
+ manifest.insertBefore(doc.createTextNode(indent), first)
+ manifest.insertBefore(application, first)
+
+ indent = get_indent(application.firstChild, 2)
+
+ last = application.lastChild
+ if last is not None and last.nodeType != minidom.Node.TEXT_NODE:
+ last = None
+
+ if not find_child_with_attribute(application, 'meta-data', android_ns,
+ 'name', logging_parent_key):
+ ul = doc.createElement('meta-data')
+ ul.setAttributeNS(android_ns, 'android:name', logging_parent_key)
+ ul.setAttributeNS(android_ns, 'android:value', logging_parent_value)
+ application.insertBefore(doc.createTextNode(indent), last)
+ application.insertBefore(ul, last)
+ last = application.lastChild
+
+ # align the closing tag with the opening tag if it's not
+ # indented
+ if last and last.nodeType != minidom.Node.TEXT_NODE:
+ indent = get_indent(application.previousSibling, 1)
+ application.appendChild(doc.createTextNode(indent))
+
+
def add_uses_libraries(doc, new_uses_libraries, required):
"""Add additional <uses-library> tags
@@ -291,6 +340,9 @@
if args.uses_non_sdk_api:
add_uses_non_sdk_api(doc)
+ if args.logging_parent:
+ add_logging_parent(doc, args.logging_parent)
+
if args.use_embedded_dex:
add_use_embedded_dex(doc)
diff --git a/scripts/manifest_fixer_test.py b/scripts/manifest_fixer_test.py
index ea8095e..d6e7f26 100755
--- a/scripts/manifest_fixer_test.py
+++ b/scripts/manifest_fixer_test.py
@@ -226,6 +226,47 @@
self.assertEqual(output, expected)
+class AddLoggingParentTest(unittest.TestCase):
+ """Unit tests for add_logging_parent function."""
+
+ def add_logging_parent_test(self, input_manifest, logging_parent=None):
+ doc = minidom.parseString(input_manifest)
+ if logging_parent:
+ manifest_fixer.add_logging_parent(doc, logging_parent)
+ output = StringIO.StringIO()
+ manifest_fixer.write_xml(output, doc)
+ return output.getvalue()
+
+ manifest_tmpl = (
+ '<?xml version="1.0" encoding="utf-8"?>\n'
+ '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
+ '%s'
+ '</manifest>\n')
+
+ def uses_logging_parent(self, logging_parent=None):
+ attrs = ''
+ if logging_parent:
+ meta_text = ('<meta-data android:name="android.content.pm.LOGGING_PARENT" '
+ 'android:value="%s"/>\n') % (logging_parent)
+ attrs += ' <application>\n %s </application>\n' % (meta_text)
+
+ return attrs
+
+ def test_no_logging_parent(self):
+ """Tests manifest_fixer with no logging_parent."""
+ manifest_input = self.manifest_tmpl % ''
+ expected = self.manifest_tmpl % self.uses_logging_parent()
+ output = self.add_logging_parent_test(manifest_input)
+ self.assertEqual(output, expected)
+
+ def test_logging_parent(self):
+ """Tests manifest_fixer with no logging_parent."""
+ manifest_input = self.manifest_tmpl % ''
+ expected = self.manifest_tmpl % self.uses_logging_parent('FOO')
+ output = self.add_logging_parent_test(manifest_input, 'FOO')
+ self.assertEqual(output, expected)
+
+
class AddUsesLibrariesTest(unittest.TestCase):
"""Unit tests for add_uses_libraries function."""
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 9a75610..8c32d8c 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -337,6 +337,68 @@
)
}
+func TestSnapshotWithCcBinary(t *testing.T) {
+ result := testSdkWithCc(t, `
+ module_exports {
+ name: "mymodule_exports",
+ native_binaries: ["mynativebinary"],
+ }
+
+ cc_binary {
+ name: "mynativebinary",
+ srcs: [
+ "Test.cpp",
+ ],
+ compile_multilib: "both",
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `)
+
+ result.CheckSnapshot("mymodule_exports", "android_common", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_binary {
+ name: "mymodule_exports_mynativebinary@current",
+ sdk_member_name: "mynativebinary",
+ compile_multilib: "both",
+ arch: {
+ arm64: {
+ srcs: ["arm64/bin/mynativebinary"],
+ },
+ arm: {
+ srcs: ["arm/bin/mynativebinary"],
+ },
+ },
+}
+
+cc_prebuilt_binary {
+ name: "mynativebinary",
+ prefer: false,
+ compile_multilib: "both",
+ arch: {
+ arm64: {
+ srcs: ["arm64/bin/mynativebinary"],
+ },
+ arm: {
+ srcs: ["arm/bin/mynativebinary"],
+ },
+ },
+}
+
+module_exports_snapshot {
+ name: "mymodule_exports@current",
+ native_binaries: ["mymodule_exports_mynativebinary@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/mynativebinary/android_arm64_armv8-a/mynativebinary -> arm64/bin/mynativebinary
+.intermediates/mynativebinary/android_arm_armv7-a-neon/mynativebinary -> arm/bin/mynativebinary
+`),
+ )
+}
+
func TestSnapshotWithCcSharedLibrary(t *testing.T) {
result := testSdkWithCc(t, `
sdk {