Merge "Add --top_level_phony to catch more real-to-phony problems"
diff --git a/Android.bp b/Android.bp
index 62e276a..3215fa2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -71,6 +71,7 @@
"android/env.go",
],
testSrcs: [
+ "android/arch_test.go",
"android/config_test.go",
"android/expand_test.go",
"android/namespace_test.go",
diff --git a/android/arch.go b/android/arch.go
index bb8cc02..6aeccb0 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -105,7 +105,6 @@
var archVariants = map[ArchType][]string{
Arm: {
- "armv7-a",
"armv7-a-neon",
"armv8-a",
"armv8-2a",
@@ -617,10 +616,10 @@
}
}
-func filterArchStructFields(fields []reflect.StructField) []reflect.StructField {
- var ret []reflect.StructField
+func filterArchStructFields(fields []reflect.StructField) (filteredFields []reflect.StructField, filtered bool) {
for _, field := range fields {
if !proptools.HasTag(field, "android", "arch_variant") {
+ filtered = true
continue
}
@@ -638,15 +637,17 @@
// Recurse into structs
switch field.Type.Kind() {
case reflect.Struct:
- var ok bool
- field.Type, ok = filterArchStruct(field.Type)
- if !ok {
+ var subFiltered bool
+ field.Type, subFiltered = filterArchStruct(field.Type)
+ filtered = filtered || subFiltered
+ if field.Type == nil {
continue
}
case reflect.Ptr:
if field.Type.Elem().Kind() == reflect.Struct {
- nestedType, ok := filterArchStruct(field.Type.Elem())
- if !ok {
+ nestedType, subFiltered := filterArchStruct(field.Type.Elem())
+ filtered = filtered || subFiltered
+ if nestedType == nil {
continue
}
field.Type = reflect.PtrTo(nestedType)
@@ -655,13 +656,17 @@
panic("Interfaces are not supported in arch_variant properties")
}
- ret = append(ret, field)
+ filteredFields = append(filteredFields, field)
}
- return ret
+ return filteredFields, filtered
}
-func filterArchStruct(prop reflect.Type) (reflect.Type, bool) {
+// filterArchStruct takes a reflect.Type that is either a sturct or a pointer to a struct, and returns a reflect.Type
+// that only contains the fields in the original type that have an `android:"arch_variant"` struct tag, and a bool
+// that is true if the new struct type has fewer fields than the original type. If there are no fields in the
+// original type with the struct tag it returns nil and true.
+func filterArchStruct(prop reflect.Type) (filteredProp reflect.Type, filtered bool) {
var fields []reflect.StructField
ptr := prop.Kind() == reflect.Ptr
@@ -673,13 +678,20 @@
fields = append(fields, prop.Field(i))
}
- fields = filterArchStructFields(fields)
+ filteredFields, filtered := filterArchStructFields(fields)
- if len(fields) == 0 {
- return nil, false
+ if len(filteredFields) == 0 {
+ return nil, true
}
- ret := reflect.StructOf(fields)
+ if !filtered {
+ if ptr {
+ return reflect.PtrTo(prop), false
+ }
+ return prop, false
+ }
+
+ ret := reflect.StructOf(filteredFields)
if ptr {
ret = reflect.PtrTo(ret)
}
@@ -687,7 +699,13 @@
return ret, true
}
-func filterArchStructSharded(prop reflect.Type) ([]reflect.Type, bool) {
+// filterArchStruct takes a reflect.Type that is either a sturct or a pointer to a struct, and returns a list of
+// reflect.Type that only contains the fields in the original type that have an `android:"arch_variant"` struct tag,
+// and a bool that is true if the new struct type has fewer fields than the original type. If there are no fields in
+// the original type with the struct tag it returns nil and true. Each returned struct type will have a maximum of
+// 10 top level fields in it to attempt to avoid hitting the reflect.StructOf name length limit, although the limit
+// can still be reached with a single struct field with many fields in it.
+func filterArchStructSharded(prop reflect.Type) (filteredProp []reflect.Type, filtered bool) {
var fields []reflect.StructField
ptr := prop.Kind() == reflect.Ptr
@@ -699,24 +717,29 @@
fields = append(fields, prop.Field(i))
}
- fields = filterArchStructFields(fields)
+ fields, filtered = filterArchStructFields(fields)
+ if !filtered {
+ if ptr {
+ return []reflect.Type{reflect.PtrTo(prop)}, false
+ }
+ return []reflect.Type{prop}, false
+ }
if len(fields) == 0 {
- return nil, false
+ return nil, true
}
shards := shardFields(fields, 10)
- var ret []reflect.Type
for _, shard := range shards {
s := reflect.StructOf(shard)
if ptr {
s = reflect.PtrTo(s)
}
- ret = append(ret, s)
+ filteredProp = append(filteredProp, s)
}
- return ret, true
+ return filteredProp, true
}
func shardFields(fields []reflect.StructField, shardSize int) [][]reflect.StructField {
@@ -731,9 +754,12 @@
return ret
}
+// createArchType takes a reflect.Type that is either a struct or a pointer to a struct, and returns a list of
+// reflect.Type that contains the arch-variant properties inside structs for each architecture, os, target, multilib,
+// etc.
func createArchType(props reflect.Type) []reflect.Type {
- propShards, ok := filterArchStructSharded(props)
- if !ok {
+ propShards, _ := filterArchStructSharded(props)
+ if len(propShards) == 0 {
return nil
}
@@ -1269,7 +1295,6 @@
func getMegaDeviceConfig() []archConfig {
return []archConfig{
- {"arm", "armv7-a", "generic", []string{"armeabi-v7a"}},
{"arm", "armv7-a-neon", "generic", []string{"armeabi-v7a"}},
{"arm", "armv7-a-neon", "cortex-a7", []string{"armeabi-v7a"}},
{"arm", "armv7-a-neon", "cortex-a8", []string{"armeabi-v7a"}},
@@ -1321,7 +1346,7 @@
func getNdkAbisConfig() []archConfig {
return []archConfig{
- {"arm", "armv7-a", "", []string{"armeabi"}},
+ {"arm", "armv7-a-neon", "", []string{"armeabi"}},
{"arm64", "armv8-a", "", []string{"arm64-v8a"}},
{"x86", "", "", []string{"x86"}},
{"x86_64", "", "", []string{"x86_64"}},
diff --git a/android/arch_test.go b/android/arch_test.go
new file mode 100644
index 0000000..0589e6c
--- /dev/null
+++ b/android/arch_test.go
@@ -0,0 +1,232 @@
+// Copyright 2019 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 android
+
+import (
+ "reflect"
+ "testing"
+)
+
+type Named struct {
+ A *string `android:"arch_variant"`
+ B *string
+}
+
+type NamedAllFiltered struct {
+ A *string
+}
+
+type NamedNoneFiltered struct {
+ A *string `android:"arch_variant"`
+}
+
+func TestFilterArchStruct(t *testing.T) {
+ tests := []struct {
+ name string
+ in interface{}
+ out interface{}
+ filtered bool
+ }{
+ // Property tests
+ {
+ name: "basic",
+ in: &struct {
+ A *string `android:"arch_variant"`
+ B *string
+ }{},
+ out: &struct {
+ A *string
+ }{},
+ filtered: true,
+ },
+ {
+ name: "all filtered",
+ in: &struct {
+ A *string
+ }{},
+ out: nil,
+ filtered: true,
+ },
+ {
+ name: "none filtered",
+ in: &struct {
+ A *string `android:"arch_variant"`
+ }{},
+ out: &struct {
+ A *string `android:"arch_variant"`
+ }{},
+ filtered: false,
+ },
+
+ // Sub-struct tests
+ {
+ name: "substruct",
+ in: &struct {
+ A struct {
+ A *string `android:"arch_variant"`
+ B *string
+ } `android:"arch_variant"`
+ }{},
+ out: &struct {
+ A struct {
+ A *string
+ }
+ }{},
+ filtered: true,
+ },
+ {
+ name: "substruct all filtered",
+ in: &struct {
+ A struct {
+ A *string
+ } `android:"arch_variant"`
+ }{},
+ out: nil,
+ filtered: true,
+ },
+ {
+ name: "substruct none filtered",
+ in: &struct {
+ A struct {
+ A *string `android:"arch_variant"`
+ } `android:"arch_variant"`
+ }{},
+ out: &struct {
+ A struct {
+ A *string `android:"arch_variant"`
+ } `android:"arch_variant"`
+ }{},
+ filtered: false,
+ },
+
+ // Named sub-struct tests
+ {
+ name: "named substruct",
+ in: &struct {
+ A Named `android:"arch_variant"`
+ }{},
+ out: &struct {
+ A struct {
+ A *string
+ }
+ }{},
+ filtered: true,
+ },
+ {
+ name: "substruct all filtered",
+ in: &struct {
+ A NamedAllFiltered `android:"arch_variant"`
+ }{},
+ out: nil,
+ filtered: true,
+ },
+ {
+ name: "substruct none filtered",
+ in: &struct {
+ A NamedNoneFiltered `android:"arch_variant"`
+ }{},
+ out: &struct {
+ A NamedNoneFiltered `android:"arch_variant"`
+ }{},
+ filtered: false,
+ },
+
+ // Pointer to sub-struct tests
+ {
+ name: "pointer substruct",
+ in: &struct {
+ A *struct {
+ A *string `android:"arch_variant"`
+ B *string
+ } `android:"arch_variant"`
+ }{},
+ out: &struct {
+ A *struct {
+ A *string
+ }
+ }{},
+ filtered: true,
+ },
+ {
+ name: "pointer substruct all filtered",
+ in: &struct {
+ A *struct {
+ A *string
+ } `android:"arch_variant"`
+ }{},
+ out: nil,
+ filtered: true,
+ },
+ {
+ name: "pointer substruct none filtered",
+ in: &struct {
+ A *struct {
+ A *string `android:"arch_variant"`
+ } `android:"arch_variant"`
+ }{},
+ out: &struct {
+ A *struct {
+ A *string `android:"arch_variant"`
+ } `android:"arch_variant"`
+ }{},
+ filtered: false,
+ },
+
+ // Pointer to named sub-struct tests
+ {
+ name: "pointer named substruct",
+ in: &struct {
+ A *Named `android:"arch_variant"`
+ }{},
+ out: &struct {
+ A *struct {
+ A *string
+ }
+ }{},
+ filtered: true,
+ },
+ {
+ name: "pointer substruct all filtered",
+ in: &struct {
+ A *NamedAllFiltered `android:"arch_variant"`
+ }{},
+ out: nil,
+ filtered: true,
+ },
+ {
+ name: "pointer substruct none filtered",
+ in: &struct {
+ A *NamedNoneFiltered `android:"arch_variant"`
+ }{},
+ out: &struct {
+ A *NamedNoneFiltered `android:"arch_variant"`
+ }{},
+ filtered: false,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ out, filtered := filterArchStruct(reflect.TypeOf(test.in))
+ if filtered != test.filtered {
+ t.Errorf("expected filtered %v, got %v", test.filtered, filtered)
+ }
+ expected := reflect.TypeOf(test.out)
+ if out != expected {
+ t.Errorf("expected type %v, got %v", expected, out)
+ }
+ })
+ }
+}
diff --git a/android/config.go b/android/config.go
index 6d81a38..122b99b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -918,6 +918,17 @@
"invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>")
}
+func (c *deviceConfig) OverridePackageNameFor(name string) string {
+ newName, overridden := findOverrideValue(
+ c.config.productVariables.PackageNameOverrides,
+ name,
+ "invalid override rule %q in PRODUCT_PACKAGE_NAME_OVERRIDES should be <module_name>:<package_name>")
+ if overridden {
+ return newName
+ }
+ return name
+}
+
func findOverrideValue(overrides []string, name string, errorMsg string) (newValue string, overridden bool) {
if overrides == nil || len(overrides) == 0 {
return "", false
diff --git a/android/paths.go b/android/paths.go
index 13b31c7..4b84c97 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -503,16 +503,9 @@
return ret, err
}
- abs, err := filepath.Abs(ret.String())
- if err != nil {
- return ret, err
- }
- buildroot, err := filepath.Abs(ctx.Config().buildDir)
- if err != nil {
- return ret, err
- }
- if strings.HasPrefix(abs, buildroot) {
- return ret, fmt.Errorf("source path %s is in output", abs)
+ // absolute path already checked by validateSafePath
+ if strings.HasPrefix(ret.String(), ctx.Config().buildDir) {
+ return ret, fmt.Errorf("source path %s is in output", ret.String())
}
return ret, err
@@ -526,16 +519,9 @@
return ret, err
}
- abs, err := filepath.Abs(ret.String())
- if err != nil {
- return ret, err
- }
- buildroot, err := filepath.Abs(ctx.Config().buildDir)
- if err != nil {
- return ret, err
- }
- if strings.HasPrefix(abs, buildroot) {
- return ret, fmt.Errorf("source path %s is in output", abs)
+ // absolute path already checked by validatePath
+ if strings.HasPrefix(ret.String(), ctx.Config().buildDir) {
+ return ret, fmt.Errorf("source path %s is in output", ret.String())
}
return ret, nil
diff --git a/android/paths_test.go b/android/paths_test.go
index c4332d2..1ed0734 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -630,3 +630,64 @@
})
}
}
+
+func TestPathForSource(t *testing.T) {
+ testCases := []struct {
+ name string
+ buildDir string
+ src string
+ err string
+ }{
+ {
+ name: "normal",
+ buildDir: "out",
+ src: "a/b/c",
+ },
+ {
+ name: "abs",
+ buildDir: "out",
+ src: "/a/b/c",
+ err: "is outside directory",
+ },
+ {
+ name: "in out dir",
+ buildDir: "out",
+ src: "out/a/b/c",
+ err: "is in output",
+ },
+ }
+
+ funcs := []struct {
+ name string
+ f func(ctx PathContext, pathComponents ...string) (SourcePath, error)
+ }{
+ {"pathForSource", pathForSource},
+ {"safePathForSource", safePathForSource},
+ }
+
+ for _, f := range funcs {
+ t.Run(f.name, func(t *testing.T) {
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ testConfig := TestConfig(test.buildDir, nil)
+ ctx := &configErrorWrapper{config: testConfig}
+ _, err := f.f(ctx, test.src)
+ if len(ctx.errors) > 0 {
+ t.Fatalf("unexpected errors %v", ctx.errors)
+ }
+ if err != nil {
+ if test.err == "" {
+ t.Fatalf("unexpected error %q", err.Error())
+ } else if !strings.Contains(err.Error(), test.err) {
+ t.Fatalf("incorrect error, want substring %q got %q", test.err, err.Error())
+ }
+ } else {
+ if test.err != "" {
+ t.Fatalf("missing error %q", test.err)
+ }
+ }
+ })
+ }
+ })
+ }
+}
diff --git a/android/testing.go b/android/testing.go
index d318839..b7a043e 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -190,14 +190,14 @@
return BuildParams{}, searchedOutputs
}
-// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputspath whose String() or Rel()
+// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
// value matches the provided string. Returns an empty BuildParams if no rule is found.
func (m TestingModule) MaybeOutput(file string) BuildParams {
p, _ := m.maybeOutput(file)
return p
}
-// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputspath whose String() or Rel()
+// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
// value matches the provided string. Panics if no rule is found.
func (m TestingModule) Output(file string) BuildParams {
p, searchedOutputs := m.maybeOutput(file)
@@ -208,6 +208,19 @@
return p
}
+// AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms.
+func (m TestingModule) AllOutputs() []string {
+ var outputFullPaths []string
+ for _, p := range m.module.BuildParamsForTests() {
+ outputs := append(WritablePaths(nil), p.Outputs...)
+ if p.Output != nil {
+ outputs = append(outputs, p.Output)
+ }
+ outputFullPaths = append(outputFullPaths, outputs.Strings()...)
+ }
+ return outputFullPaths
+}
+
func FailIfErrored(t *testing.T, errs []error) {
t.Helper()
if len(errs) > 0 {
diff --git a/android/variable.go b/android/variable.go
index 67e876a..2cccd50 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -271,6 +271,7 @@
ManifestPackageNameOverrides []string `json:",omitempty"`
CertificateOverrides []string `json:",omitempty"`
+ PackageNameOverrides []string `json:",omitempty"`
EnforceSystemCertificate *bool `json:",omitempty"`
EnforceSystemCertificateWhitelist []string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 0aedb1a..46c9dcf 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -570,6 +570,11 @@
}
case executableTag:
if cc, ok := child.(*cc.Module); ok {
+ if !cc.Arch().Native {
+ // There is only one 'bin' directory so we shouldn't bother copying in
+ // native-bridge'd binaries and only use main ones.
+ return true
+ }
fileToCopy, dirInApex := getCopyManifestForExecutable(cc)
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeExecutable, cc})
return true
diff --git a/cc/binary.go b/cc/binary.go
index 9d0cf60..65e8eb5 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -363,8 +363,10 @@
var sharedLibs android.Paths
// Ignore shared libs for static executables.
if !binary.static() {
- sharedLibs = deps.SharedLibs
+ sharedLibs = deps.EarlySharedLibs
+ sharedLibs = append(sharedLibs, deps.SharedLibs...)
sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
+ linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
}
diff --git a/cc/cc.go b/cc/cc.go
index ee6cd4e..baee70a 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -96,9 +96,9 @@
type PathDeps struct {
// Paths to .so files
- SharedLibs, LateSharedLibs android.Paths
+ SharedLibs, EarlySharedLibs, LateSharedLibs android.Paths
// Paths to the dependencies to use for .so files (.so.toc files)
- SharedLibsDeps, LateSharedLibsDeps android.Paths
+ SharedLibsDeps, EarlySharedLibsDeps, LateSharedLibsDeps android.Paths
// Paths to .a files
StaticLibs, LateStaticLibs, WholeStaticLibs android.Paths
@@ -328,6 +328,7 @@
var (
sharedDepTag = dependencyTag{name: "shared", library: true}
sharedExportDepTag = dependencyTag{name: "shared", library: true, reexportFlags: true}
+ earlySharedDepTag = dependencyTag{name: "early_shared", library: true}
lateSharedDepTag = dependencyTag{name: "late shared", library: true}
staticDepTag = dependencyTag{name: "static", library: true}
staticExportDepTag = dependencyTag{name: "static", library: true, reexportFlags: true}
@@ -1570,6 +1571,11 @@
depPtr = &depPaths.SharedLibsDeps
depFile = ccDep.linker.(libraryInterface).toc()
directSharedDeps = append(directSharedDeps, ccDep)
+ case earlySharedDepTag:
+ ptr = &depPaths.EarlySharedLibs
+ depPtr = &depPaths.EarlySharedLibsDeps
+ depFile = ccDep.linker.(libraryInterface).toc()
+ directSharedDeps = append(directSharedDeps, ccDep)
case lateSharedDepTag, ndkLateStubDepTag:
ptr = &depPaths.LateSharedLibs
depPtr = &depPaths.LateSharedLibsDeps
@@ -1663,7 +1669,7 @@
// Export the shared libs to Make.
switch depTag {
- case sharedDepTag, sharedExportDepTag, lateSharedDepTag:
+ case sharedDepTag, sharedExportDepTag, lateSharedDepTag, earlySharedDepTag:
if dependentLibrary, ok := ccDep.linker.(*libraryDecorator); ok {
if dependentLibrary.buildStubs() && android.InAnyApex(depName) {
// Add the dependency to the APEX(es) providing the library so that
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index cd7c410..aee16eb 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -51,11 +51,6 @@
}
armClangArchVariantCflags = map[string][]string{
- "armv7-a": []string{
- "-march=armv7-a",
- "-mfloat-abi=softfp",
- "-mfpu=vfpv3-d16",
- },
"armv7-a-neon": []string{
"-march=armv7-a",
"-mfloat-abi=softfp",
@@ -189,8 +184,6 @@
pctx.StaticVariable("ArmClangThumbCflags", strings.Join(ClangFilterUnknownCflags(armThumbCflags), " "))
// Clang arch variant cflags
- pctx.StaticVariable("ArmClangArmv7ACflags",
- strings.Join(armClangArchVariantCflags["armv7-a"], " "))
pctx.StaticVariable("ArmClangArmv7ANeonCflags",
strings.Join(armClangArchVariantCflags["armv7-a-neon"], " "))
pctx.StaticVariable("ArmClangArmv8ACflags",
@@ -219,7 +212,6 @@
var (
armClangArchVariantCflagsVar = map[string]string{
- "armv7-a": "${config.ArmClangArmv7ACflags}",
"armv7-a-neon": "${config.ArmClangArmv7ANeonCflags}",
"armv8-a": "${config.ArmClangArmv8ACflags}",
"armv8-2a": "${config.ArmClangArmv82ACflags}",
@@ -335,8 +327,6 @@
default:
fixCortexA8 = "-Wl,--no-fix-cortex-a8"
}
- case "armv7-a":
- fixCortexA8 = "-Wl,--fix-cortex-a8"
case "armv8-a", "armv8-2a":
// Nothing extra for armv8-a/armv8-2a
default:
diff --git a/cc/library.go b/cc/library.go
index 4adb081..ad07db4 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -29,27 +29,23 @@
"android/soong/genrule"
)
+type StaticSharedLibraryProperties struct {
+ Srcs []string `android:"arch_variant"`
+ Cflags []string `android:"arch_variant"`
+
+ Enabled *bool `android:"arch_variant"`
+ Whole_static_libs []string `android:"arch_variant"`
+ Static_libs []string `android:"arch_variant"`
+ Shared_libs []string `android:"arch_variant"`
+ System_shared_libs []string `android:"arch_variant"`
+
+ Export_shared_lib_headers []string `android:"arch_variant"`
+ Export_static_lib_headers []string `android:"arch_variant"`
+}
+
type LibraryProperties struct {
- Static struct {
- Srcs []string `android:"arch_variant"`
- Cflags []string `android:"arch_variant"`
-
- Enabled *bool `android:"arch_variant"`
- Whole_static_libs []string `android:"arch_variant"`
- Static_libs []string `android:"arch_variant"`
- Shared_libs []string `android:"arch_variant"`
- System_shared_libs []string `android:"arch_variant"`
- } `android:"arch_variant"`
- Shared struct {
- Srcs []string `android:"arch_variant"`
- Cflags []string `android:"arch_variant"`
-
- Enabled *bool `android:"arch_variant"`
- Whole_static_libs []string `android:"arch_variant"`
- Static_libs []string `android:"arch_variant"`
- Shared_libs []string `android:"arch_variant"`
- System_shared_libs []string `android:"arch_variant"`
- } `android:"arch_variant"`
+ Static StaticSharedLibraryProperties `android:"arch_variant"`
+ Shared StaticSharedLibraryProperties `android:"arch_variant"`
// local file name to pass to the linker as -unexported_symbols_list
Unexported_symbols_list *string `android:"arch_variant"`
@@ -539,6 +535,9 @@
library.Properties.Static.Whole_static_libs...)
deps.StaticLibs = append(deps.StaticLibs, library.Properties.Static.Static_libs...)
deps.SharedLibs = append(deps.SharedLibs, library.Properties.Static.Shared_libs...)
+
+ deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.Properties.Static.Export_shared_lib_headers...)
+ deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.Properties.Static.Export_static_lib_headers...)
} else if library.shared() {
if ctx.toolchain().Bionic() && !Bool(library.baseLinker.Properties.Nocrt) {
if !ctx.useSdk() {
@@ -560,6 +559,9 @@
deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.Properties.Shared.Whole_static_libs...)
deps.StaticLibs = append(deps.StaticLibs, library.Properties.Shared.Static_libs...)
deps.SharedLibs = append(deps.SharedLibs, library.Properties.Shared.Shared_libs...)
+
+ deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.Properties.Shared.Export_shared_lib_headers...)
+ deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.Properties.Shared.Export_static_lib_headers...)
}
if ctx.useVndk() {
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
@@ -696,9 +698,11 @@
}
}
- sharedLibs := deps.SharedLibs
+ sharedLibs := deps.EarlySharedLibs
+ sharedLibs = append(sharedLibs, deps.SharedLibs...)
sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
+ linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
linkerDeps = append(linkerDeps, objs.tidyFiles...)
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 79fbd47..90656da 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -672,10 +672,10 @@
// Add the dependency to the runtime library for each of the sanitizer variants
func sanitizerRuntimeMutator(mctx android.BottomUpMutatorContext) {
- if mctx.Os() != android.Android {
- return
- }
if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
+ if !c.Enabled() {
+ return
+ }
var sanitizers []string
var diagSanitizers []string
@@ -809,7 +809,7 @@
mctx.AddFarVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "shared"},
{Mutator: "arch", Variation: mctx.Target().String()},
- }, sharedDepTag, runtimeLibrary)
+ }, earlySharedDepTag, runtimeLibrary)
}
// static lib does not have dependency to the runtime library. The
// dependency will be added to the executables or shared libs using
diff --git a/java/aar.go b/java/aar.go
index a108ba0..d08e487 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -332,7 +332,7 @@
a.Module.compile(ctx, a.aaptSrcJar)
- a.aarFile = android.PathForOutput(ctx, ctx.ModuleName()+".aar")
+ a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
var res android.Paths
if a.androidLibraryProperties.BuildAAR {
BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
diff --git a/java/app.go b/java/app.go
index 45ef489..cc863e6 100644
--- a/java/app.go
+++ b/java/app.go
@@ -82,6 +82,9 @@
installJniLibs []jniLib
bundleFile android.Path
+
+ // the install APK name is normally the same as the module name, but can be overridden with PRODUCT_PACKAGE_NAME_OVERRIDES.
+ installApkName string
}
func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths {
@@ -215,11 +218,11 @@
// framework-res.apk is installed as system/framework/framework-res.apk
installDir = "framework"
} else if Bool(a.appProperties.Privileged) {
- installDir = filepath.Join("priv-app", ctx.ModuleName())
+ installDir = filepath.Join("priv-app", a.installApkName)
} else {
- installDir = filepath.Join("app", ctx.ModuleName())
+ installDir = filepath.Join("app", a.installApkName)
}
- a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, ctx.ModuleName()+".apk")
+ a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
if ctx.ModuleName() != "framework-res" {
a.Module.compile(ctx, a.aaptSrcJar)
@@ -276,6 +279,9 @@
}
func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
+ // Check if the install APK name needs to be overridden.
+ a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(ctx.ModuleName())
+
// Process all building blocks, from AAPT to certificates.
a.aaptBuildActions(ctx)
@@ -307,9 +313,9 @@
// framework-res.apk is installed as system/framework/framework-res.apk
ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
} else if Bool(a.appProperties.Privileged) {
- ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app", ctx.ModuleName()), ctx.ModuleName()+".apk", a.outputFile)
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app", a.installApkName), a.installApkName+".apk", a.outputFile)
} else {
- ctx.InstallFile(android.PathForModuleInstall(ctx, "app", ctx.ModuleName()), ctx.ModuleName()+".apk", a.outputFile)
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "app", a.installApkName), a.installApkName+".apk", a.outputFile)
}
}
diff --git a/java/app_builder.go b/java/app_builder.go
index 28fc4c4..5b999d8 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -122,9 +122,10 @@
}
ctx.Build(pctx, android.BuildParams{
- Rule: buildAAR,
- Implicits: deps,
- Output: outputFile,
+ Rule: buildAAR,
+ Description: "aar",
+ Implicits: deps,
+ Output: outputFile,
Args: map[string]string{
"manifest": manifest.String(),
"classesJar": classesJarPath,
diff --git a/java/app_test.go b/java/app_test.go
index 9e2bc23..7e06dba 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -110,57 +110,55 @@
name string
enforceRROTargets []string
enforceRROExcludedOverlays []string
- fooOverlayFiles []string
- fooRRODirs []string
- barOverlayFiles []string
- barRRODirs []string
+ overlayFiles map[string][]string
+ rroDirs map[string][]string
}{
{
name: "no RRO",
enforceRROTargets: nil,
enforceRROExcludedOverlays: nil,
- fooOverlayFiles: []string{
- "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
- "device/vendor/blah/overlay/foo/res/values/strings.xml",
+ overlayFiles: map[string][]string{
+ "foo": []string{
+ "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+ "device/vendor/blah/overlay/foo/res/values/strings.xml",
+ },
+ "bar": []string{
+ "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
+ "device/vendor/blah/overlay/bar/res/values/strings.xml",
+ },
},
- fooRRODirs: nil,
- barOverlayFiles: []string{
- "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
- "device/vendor/blah/overlay/bar/res/values/strings.xml",
+ rroDirs: map[string][]string{
+ "foo": nil,
+ "bar": nil,
},
- barRRODirs: nil,
},
{
name: "enforce RRO on foo",
enforceRROTargets: []string{"foo"},
enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
- fooOverlayFiles: []string{
- "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+ overlayFiles: map[string][]string{
+ "foo": []string{"device/vendor/blah/static_overlay/foo/res/values/strings.xml"},
+ "bar": []string{
+ "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
+ "device/vendor/blah/overlay/bar/res/values/strings.xml",
+ },
},
- fooRRODirs: []string{
- "device/vendor/blah/overlay/foo/res",
+ rroDirs: map[string][]string{
+ "foo": []string{"device/vendor/blah/overlay/foo/res"},
+ "bar": nil,
},
- barOverlayFiles: []string{
- "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
- "device/vendor/blah/overlay/bar/res/values/strings.xml",
- },
- barRRODirs: nil,
},
{
name: "enforce RRO on all",
enforceRROTargets: []string{"*"},
enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
- fooOverlayFiles: []string{
- "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
+ overlayFiles: map[string][]string{
+ "foo": []string{"device/vendor/blah/static_overlay/foo/res/values/strings.xml"},
+ "bar": []string{"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
},
- fooRRODirs: []string{
- "device/vendor/blah/overlay/foo/res",
- },
- barOverlayFiles: []string{
- "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
- },
- barRRODirs: []string{
- "device/vendor/blah/overlay/bar/res",
+ rroDirs: map[string][]string{
+ "foo": []string{"device/vendor/blah/overlay/foo/res"},
+ "bar": []string{"device/vendor/blah/overlay/bar/res"},
},
},
}
@@ -222,27 +220,19 @@
return overlayFiles, rroDirs
}
- fooOverlayFiles, fooRRODirs := getOverlays("foo")
- barOverlayFiles, barRRODirs := getOverlays("bar")
+ apps := []string{"foo", "bar"}
+ for _, app := range apps {
+ overlayFiles, rroDirs := getOverlays(app)
- if !reflect.DeepEqual(fooOverlayFiles, testCase.fooOverlayFiles) {
- t.Errorf("expected foo overlay files:\n %#v\n got:\n %#v",
- testCase.fooOverlayFiles, fooOverlayFiles)
+ if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[app]) {
+ t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
+ app, testCase.overlayFiles[app], overlayFiles)
+ }
+ if !reflect.DeepEqual(rroDirs, testCase.rroDirs[app]) {
+ t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
+ app, testCase.rroDirs[app], rroDirs)
+ }
}
- if !reflect.DeepEqual(fooRRODirs, testCase.fooRRODirs) {
- t.Errorf("expected foo rroDirs: %#v\n got:\n %#v",
- testCase.fooRRODirs, fooRRODirs)
- }
-
- if !reflect.DeepEqual(barOverlayFiles, testCase.barOverlayFiles) {
- t.Errorf("expected bar overlay files:\n %#v\n got:\n %#v",
- testCase.barOverlayFiles, barOverlayFiles)
- }
- if !reflect.DeepEqual(barRRODirs, testCase.barRRODirs) {
- t.Errorf("expected bar rroDirs: %#v\n got:\n %#v",
- testCase.barRRODirs, barRRODirs)
- }
-
})
}
}
@@ -540,3 +530,66 @@
})
}
}
+
+func TestPackageNameOverride(t *testing.T) {
+ testCases := []struct {
+ name string
+ bp string
+ packageNameOverride string
+ expected []string
+ }{
+ {
+ name: "default",
+ bp: `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ }
+ `,
+ packageNameOverride: "",
+ expected: []string{
+ buildDir + "/.intermediates/foo/android_common/foo.apk",
+ buildDir + "/target/product/test_device/system/app/foo/foo.apk",
+ },
+ },
+ {
+ name: "overridden",
+ bp: `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ }
+ `,
+ packageNameOverride: "foo:bar",
+ expected: []string{
+ // The package apk should be still be the original name for test dependencies.
+ buildDir + "/.intermediates/foo/android_common/foo.apk",
+ buildDir + "/target/product/test_device/system/app/bar/bar.apk",
+ },
+ },
+ }
+
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ config := testConfig(nil)
+ if test.packageNameOverride != "" {
+ config.TestProductVariables.PackageNameOverrides = []string{test.packageNameOverride}
+ }
+ ctx := testAppContext(config, test.bp, nil)
+
+ run(t, ctx, config)
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ outputs := foo.AllOutputs()
+ outputMap := make(map[string]bool)
+ for _, o := range outputs {
+ outputMap[o] = true
+ }
+ for _, e := range test.expected {
+ if _, exist := outputMap[e]; !exist {
+ t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
+ }
+ }
+ })
+ }
+}
diff --git a/java/builder.go b/java/builder.go
index df17f7b..7aac881 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -47,7 +47,8 @@
`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
`-source $javaVersion -target $javaVersion ` +
`-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list ; fi ) && ` +
- `${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir`,
+ `${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir && ` +
+ `rm -rf "$srcJarDir"`,
CommandDeps: []string{
"${config.JavacCmd}",
"${config.SoongZipCmd}",
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 0d2842a..01e2989 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -34,7 +34,9 @@
`$opts $bootclasspathArgs $classpathArgs $sourcepathArgs ` +
`-d $outDir -quiet && ` +
`${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
- `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds`,
+ `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds && ` +
+ `rm -rf "$srcJarDir"`,
+
CommandDeps: []string{
"${config.ZipSyncCmd}",
"${config.JavadocCmd}",
@@ -74,7 +76,8 @@
`${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
`$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
`$opts && ` +
- `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir`,
+ `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
+ `rm -rf "$srcJarDir"`,
CommandDeps: []string{
"${config.ZipSyncCmd}",
"${config.JavaCmd}",
@@ -94,7 +97,7 @@
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
`${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
`$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
- `$opts && touch $out ) || ` +
+ `$opts && touch $out && rm -rf "$srcJarDir") || ` +
`( echo -e "$msg" ; exit 38 )`,
CommandDeps: []string{
"${config.ZipSyncCmd}",
@@ -120,7 +123,8 @@
`${config.JavaCmd} -jar ${config.DokkaJar} $srcJarDir ` +
`$classpathArgs -format dac -dacRoot /reference/kotlin -output $outDir $opts && ` +
`${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
- `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir`,
+ `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
+ `rm -rf "$srcJarDir"`,
CommandDeps: []string{
"${config.ZipSyncCmd}",
"${config.DokkaJar}",
@@ -1500,7 +1504,7 @@
}
}
*implicits = append(*implicits, androidJars...)
- flags += " --android-jar-pattern " + t.dir.String() + "/%/android.jar "
+ flags += " --android-jar-pattern " + t.dir.String() + "/%/public/android.jar "
} else {
ctx.PropertyErrorf("api_levels_annotations_dirs",
"module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
@@ -1570,7 +1574,7 @@
func (d *Droidstubs) transformCheckApi(ctx android.ModuleContext,
apiFile, removedApiFile android.Path, implicits android.Paths,
- javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, msg string,
+ javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, subdir, msg string,
output android.WritablePath) {
ctx.Build(pctx, android.BuildParams{
Rule: metalavaApiCheck,
@@ -1580,7 +1584,7 @@
Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
implicits...),
Args: map[string]string{
- "srcJarDir": android.PathForModuleOut(ctx, "apicheck-srcjars").String(),
+ "srcJarDir": android.PathForModuleOut(ctx, subdir, "srcjars").String(),
"srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
"javaVersion": javaVersion,
"bootclasspathArgs": bootclasspathArgs,
@@ -1669,7 +1673,7 @@
flags.metalavaInclusionAnnotationsFlags + flags.metalavaMergeAnnoDirFlags + " "
d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
- javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts,
+ javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "current-apicheck",
fmt.Sprintf(`\n******************************\n`+
`You have tried to change the API from what has been previously approved.\n\n`+
`To make these errors go away, you have two choices:\n`+
@@ -1700,7 +1704,7 @@
removedApiFile.String() + flags.metalavaMergeAnnoDirFlags + " "
d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
- javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts,
+ javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "last-apicheck",
`\n******************************\n`+
`You have tried to change the API from what has been previously released in\n`+
`an SDK. Please fix the errors listed above.\n`+
diff --git a/java/java.go b/java/java.go
index b070639..230e8f2 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1421,10 +1421,10 @@
}
func (j *Library) shouldUncompressDex(ctx android.ModuleContext) bool {
- // Store uncompressed (and do not strip) dex files from boot class path jars that are not
- // part of the boot image.
+ // Store uncompressed (and do not strip) dex files from boot class path jars that are
+ // in an apex.
if inList(ctx.ModuleName(), ctx.Config().BootJars()) &&
- !inList(ctx.ModuleName(), ctx.Config().PreoptBootJars()) {
+ android.DirectlyInAnyApex(ctx, ctx.ModuleName()) {
return true
}
return false
diff --git a/java/kotlin.go b/java/kotlin.go
index 9c47f98..81b89f9 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -32,7 +32,8 @@
`${config.GenKotlinBuildFileCmd} $classpath $classesDir $out.rsp $srcJarDir/list > $kotlinBuildFile &&` +
`${config.KotlincCmd} ${config.JavacHeapFlags} $kotlincFlags ` +
`-jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile && ` +
- `${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir`,
+ `${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir && ` +
+ `rm -rf "$srcJarDir"`,
CommandDeps: []string{
"${config.KotlincCmd}",
"${config.KotlinCompilerJar}",
@@ -89,7 +90,8 @@
`$kaptProcessorPath ` +
`$kaptProcessor ` +
`-Xbuild-file=$kotlinBuildFile && ` +
- `${config.SoongZipCmd} -jar -o $out -C $kaptDir/sources -D $kaptDir/sources`,
+ `${config.SoongZipCmd} -jar -o $out -C $kaptDir/sources -D $kaptDir/sources && ` +
+ `rm -rf "$srcJarDir"`,
CommandDeps: []string{
"${config.KotlincCmd}",
"${config.KotlinCompilerJar}",
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 531c5d5..17decd0 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -78,7 +78,6 @@
"bash": Allowed,
"bc": Allowed,
"bzip2": Allowed,
- "cp": Allowed,
"date": Allowed,
"dd": Allowed,
"diff": Allowed,
@@ -90,7 +89,6 @@
"grep": Allowed,
"gzip": Allowed,
"hexdump": Allowed,
- "hostname": Allowed,
"jar": Allowed,
"java": Allowed,
"javap": Allowed,
@@ -133,6 +131,7 @@
"cat": Toybox,
"chmod": Toybox,
"cmp": Toybox,
+ "cp": Toybox,
"comm": Toybox,
"cut": Toybox,
"dirname": Toybox,
@@ -142,6 +141,7 @@
"expr": Toybox,
"head": Toybox,
"getconf": Toybox,
+ "hostname": Toybox,
"id": Toybox,
"ln": Toybox,
"ls": Toybox,