Merge "system-clang-format: Add IncludeBlocks: Preserve"
diff --git a/Android.bp b/Android.bp
index c9a48b4..4db98f8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -81,6 +81,7 @@
"android/arch_test.go",
"android/config_test.go",
"android/expand_test.go",
+ "android/module_test.go",
"android/namespace_test.go",
"android/neverallow_test.go",
"android/onceper_test.go",
diff --git a/android/apex.go b/android/apex.go
index bf11ba2..17df762 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -15,6 +15,7 @@
package android
import (
+ "sort"
"sync"
"github.com/google/blueprint"
@@ -86,7 +87,9 @@
ApexProperties ApexProperties
canHaveApexVariants bool
- apexVariations []string
+
+ apexVariationsLock sync.Mutex // protects apexVariations during parallel apexDepsMutator
+ apexVariations []string
}
func (m *ApexModuleBase) apexModuleBase() *ApexModuleBase {
@@ -94,6 +97,8 @@
}
func (m *ApexModuleBase) BuildForApex(apexName string) {
+ m.apexVariationsLock.Lock()
+ defer m.apexVariationsLock.Unlock()
if !InList(apexName, m.apexVariations) {
m.apexVariations = append(m.apexVariations, apexName)
}
@@ -122,6 +127,7 @@
func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []blueprint.Module {
if len(m.apexVariations) > 0 {
+ sort.Strings(m.apexVariations)
variations := []string{""} // Original variation for platform
variations = append(variations, m.apexVariations...)
diff --git a/android/arch.go b/android/arch.go
index 68fc149..04eb1e2 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -710,7 +710,7 @@
// - The HostOrDeviceSupported value passed in to InitAndroidArchModule by the module type factory, which selects
// whether the module type can compile for host, device or both.
// - The host_supported and device_supported properties on the module.
-// If host is supported for the module, the Host and HostCross OsClasses are are selected. If device is supported
+// If host is supported for the module, the Host and HostCross OsClasses are selected. If device is supported
// for the module, the Device OsClass is selected.
// Within each selected OsClass, the multilib selection is determined by:
// - The compile_multilib property if it set (which may be overriden by target.android.compile_multlib or
diff --git a/android/config.go b/android/config.go
index 1507c25..b0d8b7f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1103,6 +1103,10 @@
return Bool(c.productVariables.ProductCompatibleProperty)
}
+func (c *config) MissingUsesLibraries() []string {
+ return c.productVariables.MissingUsesLibraries
+}
+
func (c *deviceConfig) BoardVndkRuntimeDisable() bool {
return Bool(c.config.productVariables.BoardVndkRuntimeDisable)
}
diff --git a/android/module.go b/android/module.go
index 3906fd7..eb9b0fc 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1462,39 +1462,60 @@
return -1
}
-func SrcIsModule(s string) string {
+// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input
+// was not a module reference.
+func SrcIsModule(s string) (module string) {
if len(s) > 1 && s[0] == ':' {
return s[1:]
}
return ""
}
-type sourceDependencyTag struct {
- blueprint.BaseDependencyTag
+// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the
+// module name and an empty string for the tag, or empty strings if the input was not a module reference.
+func SrcIsModuleWithTag(s string) (module, tag string) {
+ if len(s) > 1 && s[0] == ':' {
+ module = s[1:]
+ if tagStart := strings.IndexByte(module, '{'); tagStart > 0 {
+ if module[len(module)-1] == '}' {
+ tag = module[tagStart+1 : len(module)-1]
+ module = module[:tagStart]
+ return module, tag
+ }
+ }
+ return module, ""
+ }
+ return "", ""
}
-var SourceDepTag sourceDependencyTag
+type sourceOrOutputDependencyTag struct {
+ blueprint.BaseDependencyTag
+ tag string
+}
+
+func sourceOrOutputDepTag(tag string) blueprint.DependencyTag {
+ return sourceOrOutputDependencyTag{tag: tag}
+}
+
+var SourceDepTag = sourceOrOutputDepTag("")
// Adds necessary dependencies to satisfy filegroup or generated sources modules listed in srcFiles
// using ":module" syntax, if any.
//
// Deprecated: tag the property with `android:"path"` instead.
func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
- var deps []string
set := make(map[string]bool)
for _, s := range srcFiles {
- if m := SrcIsModule(s); m != "" {
- if _, found := set[m]; found {
- ctx.ModuleErrorf("found source dependency duplicate: %q!", m)
+ if m, t := SrcIsModuleWithTag(s); m != "" {
+ if _, found := set[s]; found {
+ ctx.ModuleErrorf("found source dependency duplicate: %q!", s)
} else {
- set[m] = true
- deps = append(deps, m)
+ set[s] = true
+ ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
}
}
}
-
- ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
}
// Adds necessary dependencies to satisfy filegroup or generated sources modules specified in s
@@ -1503,16 +1524,25 @@
// Deprecated: tag the property with `android:"path"` instead.
func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) {
if s != nil {
- if m := SrcIsModule(*s); m != "" {
- ctx.AddDependency(ctx.Module(), SourceDepTag, m)
+ if m, t := SrcIsModuleWithTag(*s); m != "" {
+ ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
}
}
}
+// A module that implements SourceFileProducer can be referenced from any property that is tagged with `android:"path"`
+// using the ":module" syntax and provides a list of paths to be used as if they were listed in the property.
type SourceFileProducer interface {
Srcs() Paths
}
+// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"`
+// using the ":module" syntax or ":module{.tag}" syntax and provides a list of otuput files to be used as if they were
+// listed in the property.
+type OutputFileProducer interface {
+ OutputFiles(tag string) (Paths, error)
+}
+
type HostToolProvider interface {
HostToolPath() OptionalPath
}
@@ -1740,4 +1770,5 @@
Jars []string `json:"jars,omitempty"`
Classes []string `json:"class,omitempty"`
Installed_paths []string `json:"installed,omitempty"`
+ SrcJars []string `json:"srcjars,omitempty"`
}
diff --git a/android/module_test.go b/android/module_test.go
new file mode 100644
index 0000000..c790a68
--- /dev/null
+++ b/android/module_test.go
@@ -0,0 +1,141 @@
+// Copyright 2015 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 "testing"
+
+func TestSrcIsModule(t *testing.T) {
+ type args struct {
+ s string
+ }
+ tests := []struct {
+ name string
+ args args
+ wantModule string
+ }{
+ {
+ name: "file",
+ args: args{
+ s: "foo",
+ },
+ wantModule: "",
+ },
+ {
+ name: "module",
+ args: args{
+ s: ":foo",
+ },
+ wantModule: "foo",
+ },
+ {
+ name: "tag",
+ args: args{
+ s: ":foo{.bar}",
+ },
+ wantModule: "foo{.bar}",
+ },
+ {
+ name: "extra colon",
+ args: args{
+ s: ":foo:bar",
+ },
+ wantModule: "foo:bar",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if gotModule := SrcIsModule(tt.args.s); gotModule != tt.wantModule {
+ t.Errorf("SrcIsModule() = %v, want %v", gotModule, tt.wantModule)
+ }
+ })
+ }
+}
+
+func TestSrcIsModuleWithTag(t *testing.T) {
+ type args struct {
+ s string
+ }
+ tests := []struct {
+ name string
+ args args
+ wantModule string
+ wantTag string
+ }{
+ {
+ name: "file",
+ args: args{
+ s: "foo",
+ },
+ wantModule: "",
+ wantTag: "",
+ },
+ {
+ name: "module",
+ args: args{
+ s: ":foo",
+ },
+ wantModule: "foo",
+ wantTag: "",
+ },
+ {
+ name: "tag",
+ args: args{
+ s: ":foo{.bar}",
+ },
+ wantModule: "foo",
+ wantTag: ".bar",
+ },
+ {
+ name: "empty tag",
+ args: args{
+ s: ":foo{}",
+ },
+ wantModule: "foo",
+ wantTag: "",
+ },
+ {
+ name: "extra colon",
+ args: args{
+ s: ":foo:bar",
+ },
+ wantModule: "foo:bar",
+ },
+ {
+ name: "invalid tag",
+ args: args{
+ s: ":foo{.bar",
+ },
+ wantModule: "foo{.bar",
+ },
+ {
+ name: "invalid tag 2",
+ args: args{
+ s: ":foo.bar}",
+ },
+ wantModule: "foo.bar}",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ gotModule, gotTag := SrcIsModuleWithTag(tt.args.s)
+ if gotModule != tt.wantModule {
+ t.Errorf("SrcIsModuleWithTag() gotModule = %v, want %v", gotModule, tt.wantModule)
+ }
+ if gotTag != tt.wantTag {
+ t.Errorf("SrcIsModuleWithTag() gotTag = %v, want %v", gotTag, tt.wantTag)
+ }
+ })
+ }
+}
diff --git a/android/path_properties.go b/android/path_properties.go
index 1a12290..af7af59 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -39,14 +39,12 @@
pathProperties := pathPropertiesForPropertyStruct(ctx, ps)
pathProperties = FirstUniqueStrings(pathProperties)
- var deps []string
for _, s := range pathProperties {
- if m := SrcIsModule(s); m != "" {
- deps = append(deps, m)
+ if m, t := SrcIsModuleWithTag(s); m != "" {
+ ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m)
}
}
- ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
}
}
diff --git a/android/path_properties_test.go b/android/path_properties_test.go
index ecc2d21..fa187fa 100644
--- a/android/path_properties_test.go
+++ b/android/path_properties_test.go
@@ -41,8 +41,10 @@
}
func (p *pathDepsMutatorTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
- ctx.VisitDirectDepsWithTag(SourceDepTag, func(dep Module) {
- p.sourceDeps = append(p.sourceDeps, ctx.OtherModuleName(dep))
+ ctx.VisitDirectDeps(func(dep Module) {
+ if _, ok := ctx.OtherModuleDependencyTag(dep).(sourceOrOutputDependencyTag); ok {
+ p.sourceDeps = append(p.sourceDeps, ctx.OtherModuleName(dep))
+ }
})
}
@@ -59,7 +61,7 @@
name: "foo",
foo: ":a",
bar: [":b"],
- baz: ":c",
+ baz: ":c{.bar}",
qux: ":d",
}`,
deps: []string{"a", "b", "c"},
diff --git a/android/paths.go b/android/paths.go
index da387a8..3915ff4 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -217,21 +217,23 @@
return ret
}
-// PathsForModuleSrc returns Paths rooted from the module's local source directory. It expands globs and references
-// to SourceFileProducer modules using the ":name" syntax. Properties passed as the paths argument must have been
-// annotated with struct tag `android:"path"` so that dependencies on SourceFileProducer modules will have already
-// been handled by the path_properties mutator. If ctx.Config().AllowMissingDependencies() is true, then any missing
-// SourceFileProducer dependencies will cause the module to be marked as having missing dependencies.
+// PathsForModuleSrc returns Paths rooted from the module's local source directory. It expands globs, references to
+// SourceFileProducer modules using the ":name" syntax, and references to OutputFileProducer modules using the
+// ":name{.tag}" syntax. Properties passed as the paths argument must have been annotated with struct tag
+// `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the
+// path_properties mutator. If ctx.Config().AllowMissingDependencies() is true then any missing SourceFileProducer or
+// OutputFileProducer dependencies will cause the module to be marked as having missing dependencies.
func PathsForModuleSrc(ctx ModuleContext, paths []string) Paths {
return PathsForModuleSrcExcludes(ctx, paths, nil)
}
// PathsForModuleSrcExcludes returns Paths rooted from the module's local source directory, excluding paths listed in
-// the excludes arguments. It expands globs and references to SourceFileProducer modules in both paths and excludes
-// using the ":name" syntax. Properties passed as the paths or excludes argument must have been annotated with struct
-// tag `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the
-// path_properties mutator. If ctx.Config().AllowMissingDependencies() is true, then any missing SourceFileProducer
-// dependencies will cause the module to be marked as having missing dependencies.
+// the excludes arguments. It expands globs, references to SourceFileProducer modules using the ":name" syntax, and
+// references to OutputFileProducer modules using the ":name{.tag}" syntax. Properties passed as the paths or excludes
+// argument must have been annotated with struct tag `android:"path"` so that dependencies on SourceFileProducer modules
+// will have already been handled by the path_properties mutator. If ctx.Config().AllowMissingDependencies() is
+// truethen any missing SourceFileProducer or OutputFileProducer dependencies will cause the module to be marked as
+// having missing dependencies.
func PathsForModuleSrcExcludes(ctx ModuleContext, paths, excludes []string) Paths {
ret, missingDeps := PathsAndMissingDepsForModuleSrcExcludes(ctx, paths, excludes)
if ctx.Config().AllowMissingDependencies() {
@@ -245,12 +247,13 @@
}
// PathsAndMissingDepsForModuleSrcExcludes returns Paths rooted from the module's local source directory, excluding
-// paths listed in the excludes arguments, and a list of missing dependencies. It expands globs and references to
-// SourceFileProducer modules in both paths and excludes using the ":name" syntax. Properties passed as the paths or
-// excludes argument must have been annotated with struct tag `android:"path"` so that dependencies on
-// SourceFileProducer modules will have already been handled by the path_properties mutator. If
-// ctx.Config().AllowMissingDependencies() is true, then any missing SourceFileProducer dependencies will be returned,
-// and they will NOT cause the module to be marked as having missing dependencies.
+// paths listed in the excludes arguments, and a list of missing dependencies. It expands globs, references to
+// SourceFileProducer modules using the ":name" syntax, and references to OutputFileProducer modules using the
+// ":name{.tag}" syntax. Properties passed as the paths or excludes argument must have been annotated with struct tag
+// `android:"path"` so that dependencies on SourceFileProducer modules will have already been handled by the
+// path_properties mutator. If ctx.Config().AllowMissingDependencies() is true then any missing SourceFileProducer or
+// OutputFileProducer dependencies will be returned, and they will NOT cause the module to be marked as having missing
+// dependencies.
func PathsAndMissingDepsForModuleSrcExcludes(ctx ModuleContext, paths, excludes []string) (Paths, []string) {
prefix := pathForModuleSrc(ctx).String()
@@ -262,16 +265,24 @@
var missingExcludeDeps []string
for _, e := range excludes {
- if m := SrcIsModule(e); m != "" {
- module := ctx.GetDirectDepWithTag(m, SourceDepTag)
+ if m, t := SrcIsModuleWithTag(e); m != "" {
+ module := ctx.GetDirectDepWithTag(m, sourceOrOutputDepTag(t))
if module == nil {
missingExcludeDeps = append(missingExcludeDeps, m)
continue
}
- if srcProducer, ok := module.(SourceFileProducer); ok {
+ if outProducer, ok := module.(OutputFileProducer); ok {
+ outputFiles, err := outProducer.OutputFiles(t)
+ if err != nil {
+ ctx.ModuleErrorf("path dependency %q: %s", e, err)
+ }
+ expandedExcludes = append(expandedExcludes, outputFiles.Strings()...)
+ } else if t != "" {
+ ctx.ModuleErrorf("path dependency %q is not an output file producing module", e)
+ } else if srcProducer, ok := module.(SourceFileProducer); ok {
expandedExcludes = append(expandedExcludes, srcProducer.Srcs().Strings()...)
} else {
- ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
+ ctx.ModuleErrorf("path dependency %q is not a source file producing module", e)
}
} else {
expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
@@ -307,12 +318,20 @@
}
func expandOneSrcPath(ctx ModuleContext, s string, expandedExcludes []string) (Paths, error) {
- if m := SrcIsModule(s); m != "" {
- module := ctx.GetDirectDepWithTag(m, SourceDepTag)
+ if m, t := SrcIsModuleWithTag(s); m != "" {
+ module := ctx.GetDirectDepWithTag(m, sourceOrOutputDepTag(t))
if module == nil {
return nil, missingDependencyError{[]string{m}}
}
- if srcProducer, ok := module.(SourceFileProducer); ok {
+ if outProducer, ok := module.(OutputFileProducer); ok {
+ outputFiles, err := outProducer.OutputFiles(t)
+ if err != nil {
+ return nil, fmt.Errorf("path dependency %q: %s", s, err)
+ }
+ return outputFiles, nil
+ } else if t != "" {
+ return nil, fmt.Errorf("path dependency %q is not an output file producing module", s)
+ } else if srcProducer, ok := module.(SourceFileProducer); ok {
moduleSrcs := srcProducer.Srcs()
for _, e := range expandedExcludes {
for j := 0; j < len(moduleSrcs); j++ {
@@ -324,7 +343,7 @@
}
return moduleSrcs, nil
} else {
- return nil, fmt.Errorf("path dependency %q is not a source file producing module", m)
+ return nil, fmt.Errorf("path dependency %q is not a source file producing module", s)
}
} else if pathtools.IsGlob(s) {
paths := ctx.GlobFiles(pathForModuleSrc(ctx, s).String(), expandedExcludes)
diff --git a/android/paths_test.go b/android/paths_test.go
index b52d713..85c8d84 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -760,6 +760,45 @@
}
}
+type pathForModuleSrcOutputFileProviderModule struct {
+ ModuleBase
+ props struct {
+ Outs []string
+ Tagged []string
+ }
+
+ outs Paths
+ tagged Paths
+}
+
+func pathForModuleSrcOutputFileProviderModuleFactory() Module {
+ module := &pathForModuleSrcOutputFileProviderModule{}
+ module.AddProperties(&module.props)
+ InitAndroidModule(module)
+ return module
+}
+
+func (p *pathForModuleSrcOutputFileProviderModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ for _, out := range p.props.Outs {
+ p.outs = append(p.outs, PathForModuleOut(ctx, out))
+ }
+
+ for _, tagged := range p.props.Tagged {
+ p.tagged = append(p.tagged, PathForModuleOut(ctx, tagged))
+ }
+}
+
+func (p *pathForModuleSrcOutputFileProviderModule) OutputFiles(tag string) (Paths, error) {
+ switch tag {
+ case "":
+ return p.outs, nil
+ case ".tagged":
+ return p.tagged, nil
+ default:
+ return nil, fmt.Errorf("unsupported tag %q", tag)
+ }
+}
+
type pathForModuleSrcTestCase struct {
name string
bp string
@@ -776,6 +815,7 @@
ctx := NewTestContext()
ctx.RegisterModuleType("test", ModuleFactoryAdaptor(pathForModuleSrcTestModuleFactory))
+ ctx.RegisterModuleType("output_file_provider", ModuleFactoryAdaptor(pathForModuleSrcOutputFileProviderModuleFactory))
ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory))
fgBp := `
@@ -785,9 +825,18 @@
}
`
+ ofpBp := `
+ output_file_provider {
+ name: "b",
+ outs: ["gen/b"],
+ tagged: ["gen/c"],
+ }
+ `
+
mockFS := map[string][]byte{
"fg/Android.bp": []byte(fgBp),
"foo/Android.bp": []byte(test.bp),
+ "ofp/Android.bp": []byte(ofpBp),
"fg/src/a": nil,
"foo/src/b": nil,
"foo/src/c": nil,
@@ -799,7 +848,7 @@
ctx.MockFileSystem(mockFS)
ctx.Register()
- _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp"})
+ _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp", "ofp/Android.bp"})
FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
FailIfErrored(t, errs)
@@ -826,6 +875,12 @@
}
func TestPathsForModuleSrc(t *testing.T) {
+ buildDir, err := ioutil.TempDir("", "soong_paths_for_module_src_test")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(buildDir)
+
tests := []pathForModuleSrcTestCase{
{
name: "path",
@@ -871,6 +926,26 @@
rels: []string{"src/a"},
},
{
+ name: "output file provider",
+ bp: `
+ test {
+ name: "foo",
+ srcs: [":b"],
+ }`,
+ srcs: []string{buildDir + "/.intermediates/ofp/b/gen/b"},
+ rels: []string{"gen/b"},
+ },
+ {
+ name: "output file provider tagged",
+ bp: `
+ test {
+ name: "foo",
+ srcs: [":b{.tagged}"],
+ }`,
+ srcs: []string{buildDir + "/.intermediates/ofp/b/gen/c"},
+ rels: []string{"gen/c"},
+ },
+ {
name: "special characters glob",
bp: `
test {
@@ -882,16 +957,16 @@
},
}
- buildDir, err := ioutil.TempDir("", "soong_paths_for_module_src_test")
+ testPathForModuleSrc(t, buildDir, tests)
+}
+
+func TestPathForModuleSrc(t *testing.T) {
+ buildDir, err := ioutil.TempDir("", "soong_path_for_module_src_test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(buildDir)
- testPathForModuleSrc(t, buildDir, tests)
-}
-
-func TestPathForModuleSrc(t *testing.T) {
tests := []pathForModuleSrcTestCase{
{
name: "path",
@@ -924,6 +999,26 @@
rel: "src/a",
},
{
+ name: "output file provider",
+ bp: `
+ test {
+ name: "foo",
+ src: ":b",
+ }`,
+ src: buildDir + "/.intermediates/ofp/b/gen/b",
+ rel: "gen/b",
+ },
+ {
+ name: "output file provider tagged",
+ bp: `
+ test {
+ name: "foo",
+ src: ":b{.tagged}",
+ }`,
+ src: buildDir + "/.intermediates/ofp/b/gen/c",
+ rel: "gen/c",
+ },
+ {
name: "special characters glob",
bp: `
test {
@@ -935,12 +1030,6 @@
},
}
- buildDir, err := ioutil.TempDir("", "soong_path_for_module_src_test")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(buildDir)
-
testPathForModuleSrc(t, buildDir, tests)
}
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index b13ce2a..069e1f5 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -24,6 +24,7 @@
RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory)
RegisterModuleType("prebuilt_font", PrebuiltFontFactory)
+ RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory)
PreDepsMutators(func(ctx RegisterMutatorsContext) {
ctx.BottomUp("prebuilt_etc", prebuiltEtcMutator).Parallel()
@@ -61,7 +62,9 @@
sourceFilePath Path
outputFilePath OutputPath
// The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share.
- installDirBase string
+ installDirBase string
+ // The base install location when soc_specific property is set to true, e.g. "firmware" for prebuilt_firmware.
+ socInstallDirBase string
installDirPath OutputPath
additionalDependencies *Paths
}
@@ -121,7 +124,14 @@
return
}
p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
- p.installDirPath = PathForModuleInstall(ctx, p.installDirBase, String(p.properties.Sub_dir))
+
+ // If soc install dir was specified and SOC specific is set, set the installDirPath to the specified
+ // socInstallDirBase.
+ installBaseDir := p.installDirBase
+ if ctx.SocSpecific() && p.socInstallDirBase != "" {
+ installBaseDir = p.socInstallDirBase
+ }
+ p.installDirPath = PathForModuleInstall(ctx, installBaseDir, String(p.properties.Sub_dir))
// This ensures that outputFilePath has the correct name for others to
// use, as the source file may have a different name.
@@ -250,3 +260,14 @@
InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
return module
}
+
+// prebuilt_firmware installs a firmware file to <partition>/etc/firmware directory for system image.
+// If soc_specific property is set to true, the firmware file is installed to the vendor <partition>/firmware
+// directory for vendor image.
+func PrebuiltFirmwareFactory() Module {
+ module := &PrebuiltEtc{installDirBase: "etc/firmware", socInstallDirBase: "firmware"}
+ InitPrebuiltEtcModule(module)
+ // This module is device-only
+ InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
+ return module
+}
diff --git a/android/prebuilt_etc_test.go b/android/prebuilt_etc_test.go
index a5c4480..d977c30 100644
--- a/android/prebuilt_etc_test.go
+++ b/android/prebuilt_etc_test.go
@@ -31,6 +31,7 @@
ctx.RegisterModuleType("prebuilt_usr_share", ModuleFactoryAdaptor(PrebuiltUserShareFactory))
ctx.RegisterModuleType("prebuilt_usr_share_host", ModuleFactoryAdaptor(PrebuiltUserShareHostFactory))
ctx.RegisterModuleType("prebuilt_font", ModuleFactoryAdaptor(PrebuiltFontFactory))
+ ctx.RegisterModuleType("prebuilt_firmware", ModuleFactoryAdaptor(PrebuiltFirmwareFactory))
ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
ctx.BottomUp("prebuilt_etc", prebuiltEtcMutator).Parallel()
})
@@ -235,3 +236,39 @@
t.Errorf("expected %q, got %q", expected, p.installDirPath.RelPathString())
}
}
+
+func TestPrebuiltFirmwareDirPath(t *testing.T) {
+ targetPath := "target/product/test_device"
+ tests := []struct {
+ description string
+ config string
+ expectedPath string
+ }{{
+ description: "prebuilt: system firmware",
+ config: `
+ prebuilt_firmware {
+ name: "foo.conf",
+ src: "foo.conf",
+ }`,
+ expectedPath: filepath.Join(targetPath, "system/etc/firmware"),
+ }, {
+ description: "prebuilt: vendor firmware",
+ config: `
+ prebuilt_firmware {
+ name: "foo.conf",
+ src: "foo.conf",
+ soc_specific: true,
+ sub_dir: "sub_dir",
+ }`,
+ expectedPath: filepath.Join(targetPath, "vendor/firmware/sub_dir"),
+ }}
+ for _, tt := range tests {
+ t.Run(tt.description, func(t *testing.T) {
+ ctx, _ := testPrebuiltEtc(t, tt.config)
+ p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a_core").Module().(*PrebuiltEtc)
+ if p.installDirPath.RelPathString() != tt.expectedPath {
+ t.Errorf("expected %q, got %q", tt.expectedPath, p.installDirPath)
+ }
+ })
+ }
+}
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index e182641..a5b85c8 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -15,6 +15,7 @@
package android
import (
+ "fmt"
"io/ioutil"
"os"
"testing"
@@ -250,8 +251,13 @@
return &p.prebuilt
}
-func (p *prebuiltModule) Srcs() Paths {
- return Paths{p.src}
+func (p *prebuiltModule) OutputFiles(tag string) (Paths, error) {
+ switch tag {
+ case "":
+ return Paths{p.src}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
}
type sourceModule struct {
diff --git a/android/sh_binary.go b/android/sh_binary.go
index cf415c5..fb7446d 100644
--- a/android/sh_binary.go
+++ b/android/sh_binary.go
@@ -16,7 +16,6 @@
import (
"fmt"
- "io"
"strings"
)
@@ -58,6 +57,10 @@
// the name of the test configuration (for example "AndroidTest.xml") that should be
// installed with the module.
Test_config *string `android:"arch_variant"`
+
+ // list of files or filegroup modules that provide data that should be installed alongside
+ // the test.
+ Data []string `android:"path,arch_variant"`
}
type ShBinary struct {
@@ -73,6 +76,8 @@
ShBinary
testProperties TestProperties
+
+ data Paths
}
func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) {
@@ -122,30 +127,50 @@
})
}
-func (s *ShBinary) AndroidMk() AndroidMkData {
- return AndroidMkData{
+func (s *ShBinary) AndroidMkEntries() AndroidMkEntries {
+ return AndroidMkEntries{
Class: "EXECUTABLES",
OutputFile: OptionalPathForPath(s.outputFilePath),
Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
- Extra: []AndroidMkExtraFunc{
- func(w io.Writer, outputFile Path) {
- fmt.Fprintln(w, "LOCAL_MODULE_RELATIVE_PATH :=", String(s.properties.Sub_dir))
- fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX :=")
- fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", s.outputFilePath.Rel())
- },
+ AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) {
+ s.customAndroidMkEntries(entries)
},
}
}
-func (s *ShTest) AndroidMk() AndroidMkData {
- data := s.ShBinary.AndroidMk()
- data.Class = "NATIVE_TESTS"
- data.Extra = append(data.Extra, func(w io.Writer, outputFile Path) {
- fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
- strings.Join(s.testProperties.Test_suites, " "))
- fmt.Fprintln(w, "LOCAL_TEST_CONFIG :=", String(s.testProperties.Test_config))
- })
- return data
+func (s *ShBinary) customAndroidMkEntries(entries *AndroidMkEntries) {
+ entries.SetString("LOCAL_MODULE_RELATIVE_PATH", String(s.properties.Sub_dir))
+ entries.SetString("LOCAL_MODULE_SUFFIX", "")
+ entries.SetString("LOCAL_MODULE_STEM", s.outputFilePath.Rel())
+}
+
+func (s *ShTest) GenerateAndroidBuildActions(ctx ModuleContext) {
+ s.ShBinary.GenerateAndroidBuildActions(ctx)
+
+ s.data = PathsForModuleSrc(ctx, s.testProperties.Data)
+}
+
+func (s *ShTest) AndroidMkEntries() AndroidMkEntries {
+ return AndroidMkEntries{
+ Class: "NATIVE_TESTS",
+ OutputFile: OptionalPathForPath(s.outputFilePath),
+ Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
+ AddCustomEntries: func(name, prefix, moduleDir string, entries *AndroidMkEntries) {
+ s.customAndroidMkEntries(entries)
+
+ entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
+ entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config))
+ for _, d := range s.data {
+ rel := d.Rel()
+ path := d.String()
+ if !strings.HasSuffix(path, rel) {
+ panic(fmt.Errorf("path %q does not end with %q", path, rel))
+ }
+ path = strings.TrimSuffix(path, rel)
+ entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel)
+ }
+ },
+ }
}
func InitShBinaryModule(s *ShBinary) {
diff --git a/android/sh_binary_test.go b/android/sh_binary_test.go
new file mode 100644
index 0000000..becb35a
--- /dev/null
+++ b/android/sh_binary_test.go
@@ -0,0 +1,58 @@
+package android
+
+import (
+ "io/ioutil"
+ "os"
+ "reflect"
+ "testing"
+)
+
+func testShBinary(t *testing.T, bp string) (*TestContext, Config) {
+ buildDir, err := ioutil.TempDir("", "soong_sh_binary_test")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(buildDir)
+
+ config := TestArchConfig(buildDir, nil)
+
+ ctx := NewTestArchContext()
+ ctx.RegisterModuleType("sh_test", ModuleFactoryAdaptor(ShTestFactory))
+ ctx.Register()
+ mockFiles := map[string][]byte{
+ "Android.bp": []byte(bp),
+ "test.sh": nil,
+ "testdata/data1": nil,
+ "testdata/sub/data2": nil,
+ }
+ ctx.MockFileSystem(mockFiles)
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ FailIfErrored(t, errs)
+
+ return ctx, config
+}
+
+func TestShTestTestData(t *testing.T) {
+ ctx, config := testShBinary(t, `
+ sh_test {
+ name: "foo",
+ src: "test.sh",
+ filename: "test.sh",
+ data: [
+ "testdata/data1",
+ "testdata/sub/data2",
+ ],
+ }
+ `)
+
+ mod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest)
+
+ entries := AndroidMkEntriesForTest(t, config, "", mod)
+ expected := []string{":testdata/data1", ":testdata/sub/data2"}
+ actual := entries.EntryMap["LOCAL_TEST_DATA"]
+ if !reflect.DeepEqual(expected, actual) {
+ t.Errorf("Unexpected test data expected: %q, actual: %q", expected, actual)
+ }
+}
diff --git a/android/variable.go b/android/variable.go
index ff3ebaf..d039a16 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -306,6 +306,8 @@
ProductCompatibleProperty *bool `json:",omitempty"`
TargetFSConfigGen []string `json:",omitempty"`
+
+ MissingUsesLibraries []string `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index cb71725..24057af 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -529,7 +529,7 @@
ctx.file.errorf(ctx.mkvalue, "unsupported sanitize expression")
case *bpparser.String:
switch v.Value {
- case "never", "address", "coverage", "thread", "undefined", "cfi":
+ case "never", "address", "fuzzer", "thread", "undefined", "cfi":
bpTrue := &bpparser.Bool{
Value: true,
}
diff --git a/androidmk/cmd/androidmk/androidmk_test.go b/androidmk/cmd/androidmk/androidmk_test.go
index 2eab0cc..4d5180e 100644
--- a/androidmk/cmd/androidmk/androidmk_test.go
+++ b/androidmk/cmd/androidmk/androidmk_test.go
@@ -1179,6 +1179,84 @@
`,
},
{
+ desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT_ETC)",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/firmware/bar
+LOCAL_SRC_FILES := foo.fw
+include $(BUILD_PREBUILT)
+`,
+ expected: `
+prebuilt_firmware {
+ name: "foo",
+
+ src: "foo.fw",
+ sub_dir: "bar",
+}
+`,
+ },
+ {
+ desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT)",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/firmware/bar
+LOCAL_SRC_FILES := foo.fw
+include $(BUILD_PREBUILT)
+`,
+ expected: `
+prebuilt_firmware {
+ name: "foo",
+
+ src: "foo.fw",
+ sub_dir: "bar",
+}
+`,
+ },
+ {
+ desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT_VENDOR)",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/bar
+LOCAL_SRC_FILES := foo.fw
+include $(BUILD_PREBUILT)
+`,
+ expected: `
+prebuilt_firmware {
+ name: "foo",
+
+ src: "foo.fw",
+ sub_dir: "bar",
+ proprietary: true,
+}
+`,
+ },
+ {
+ desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT)/vendor",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/firmware/bar
+LOCAL_SRC_FILES := foo.fw
+include $(BUILD_PREBUILT)
+`,
+ expected: `
+prebuilt_firmware {
+ name: "foo",
+
+ src: "foo.fw",
+ sub_dir: "bar",
+ proprietary: true,
+}
+`,
+ },
+ {
desc: "vts_config",
in: `
include $(CLEAR_VARS)
diff --git a/apex/apex.go b/apex/apex.go
index 51d0718..aed7d6f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -560,11 +560,16 @@
return String(a.properties.Certificate)
}
-func (a *apexBundle) Srcs() android.Paths {
- if file, ok := a.outputFiles[imageApex]; ok {
- return android.Paths{file}
- } else {
- return nil
+func (a *apexBundle) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ if file, ok := a.outputFiles[imageApex]; ok {
+ return android.Paths{file}, nil
+ } else {
+ return nil, nil
+ }
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
}
@@ -1383,8 +1388,13 @@
p.properties.Source = src
}
-func (p *Prebuilt) Srcs() android.Paths {
- return android.Paths{p.outputApex}
+func (p *Prebuilt) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return android.Paths{p.outputApex}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
}
func (p *Prebuilt) InstallFilename() string {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 5276ce4..f71abd7 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -585,7 +585,7 @@
cc_library {
name: "libc",
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
@@ -596,7 +596,7 @@
cc_library {
name: "libm",
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
@@ -607,7 +607,7 @@
cc_library {
name: "libdl",
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
diff --git a/bpf/bpf.go b/bpf/bpf.go
index dcbf9ad..90ec963 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -122,13 +122,18 @@
}
}
-// Implements SourceFileProducer interface so that the obj output can be used in the data property
+// Implements OutputFileFileProducer interface so that the obj output can be used in the data property
// of other modules.
-func (bpf *bpf) Srcs() android.Paths {
- return bpf.objs
+func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return bpf.objs, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
}
-var _ android.SourceFileProducer = (*bpf)(nil)
+var _ android.OutputFileProducer = (*bpf)(nil)
func bpfFactory() android.Module {
module := &bpf{}
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index 17cff18..cac4d9a 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -503,16 +503,18 @@
}
var localModuleUpdate = map[string][]etcPrebuiltModuleUpdate{
- "HOST_OUT": {{prefix: "/etc", modType: "prebuilt_etc_host"}, {prefix: "/usr/share", modType: "prebuilt_usr_share_host"}},
- "PRODUCT_OUT": {{prefix: "/system/etc"}, {prefix: "/vendor/etc", flags: []string{"proprietary"}}},
- "TARGET_OUT": {{prefix: "/etc"}, {prefix: "/usr/share", modType: "prebuilt_usr_share"}, {prefix: "/fonts", modType: "prebuilt_font"}},
- "TARGET_OUT_ETC": {{prefix: ""}},
+ "HOST_OUT": {{prefix: "/etc", modType: "prebuilt_etc_host"}, {prefix: "/usr/share", modType: "prebuilt_usr_share_host"}},
+ "PRODUCT_OUT": {{prefix: "/system/etc"}, {prefix: "/vendor/etc", flags: []string{"proprietary"}}},
+ "TARGET_OUT": {{prefix: "/usr/share", modType: "prebuilt_usr_share"}, {prefix: "/fonts", modType: "prebuilt_font"},
+ {prefix: "/etc/firmware", modType: "prebuilt_firmware"}, {prefix: "/vendor/firmware", modType: "prebuilt_firmware", flags: []string{"proprietary"}},
+ {prefix: "/etc"}},
+ "TARGET_OUT_ETC": {{prefix: "/firmware", modType: "prebuilt_firmware"}, {prefix: ""}},
"TARGET_OUT_PRODUCT": {{prefix: "/etc", flags: []string{"product_specific"}}, {prefix: "/fonts", modType: "prebuilt_font", flags: []string{"product_specific"}}},
"TARGET_OUT_PRODUCT_ETC": {{prefix: "", flags: []string{"product_specific"}}},
"TARGET_OUT_ODM": {{prefix: "/etc", flags: []string{"device_specific"}}},
"TARGET_OUT_PRODUCT_SERVICES": {{prefix: "/etc", flags: []string{"product_services_specific"}}},
"TARGET_OUT_PRODUCT_SERVICES_ETC": {{prefix: "", flags: []string{"product_services_specific"}}},
- "TARGET_OUT_VENDOR": {{prefix: "/etc", flags: []string{"proprietary"}}},
+ "TARGET_OUT_VENDOR": {{prefix: "/etc", flags: []string{"proprietary"}}, {prefix: "/firmware", modType: "prebuilt_firmware", flags: []string{"proprietary"}}},
"TARGET_OUT_VENDOR_ETC": {{prefix: "", flags: []string{"proprietary"}}},
"TARGET_RECOVERY_ROOT_OUT": {{prefix: "/system/etc", flags: []string{"recovery"}}},
}
diff --git a/cc/binary.go b/cc/binary.go
index 93d1de2..8428d7e 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -326,7 +326,7 @@
}
strippedOutputFile := outputFile
outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
- binary.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
+ binary.stripper.stripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, builderFlags)
}
binary.unstrippedOutputFile = outputFile
@@ -350,7 +350,7 @@
if binary.stripper.needsStrip(ctx) {
out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
binary.distFile = android.OptionalPathForPath(out)
- binary.stripper.strip(ctx, versionedOutputFile, out, builderFlags)
+ binary.stripper.stripExecutableOrSharedLib(ctx, versionedOutputFile, out, builderFlags)
}
binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
diff --git a/cc/cc.go b/cc/cc.go
index 4600a15..e61857d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -19,6 +19,7 @@
// is handled in builder.go
import (
+ "fmt"
"io"
"strconv"
"strings"
@@ -52,6 +53,9 @@
ctx.TopDown("hwasan_deps", sanitizerDepsMutator(hwasan))
ctx.BottomUp("hwasan", sanitizerMutator(hwasan)).Parallel()
+ ctx.TopDown("fuzzer_deps", sanitizerDepsMutator(fuzzer))
+ ctx.BottomUp("fuzzer", sanitizerMutator(fuzzer)).Parallel()
+
ctx.TopDown("cfi_deps", sanitizerDepsMutator(cfi))
ctx.BottomUp("cfi", sanitizerMutator(cfi)).Parallel()
@@ -1922,11 +1926,16 @@
return c.outputFile
}
-func (c *Module) Srcs() android.Paths {
- if c.outputFile.Valid() {
- return android.Paths{c.outputFile.Path()}
+func (c *Module) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ if c.outputFile.Valid() {
+ return android.Paths{c.outputFile.Path()}, nil
+ }
+ return android.Paths{}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
- return android.Paths{}
}
func (c *Module) static() bool {
@@ -2003,7 +2012,11 @@
}
func (c *Module) IDEInfo(dpInfo *android.IdeInfo) {
- dpInfo.Srcs = append(dpInfo.Srcs, c.Srcs().Strings()...)
+ outputFiles, err := c.OutputFiles("")
+ if err != nil {
+ panic(err)
+ }
+ dpInfo.Srcs = append(dpInfo.Srcs, outputFiles.Strings()...)
}
func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 997e11e..ca34185 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -184,7 +184,7 @@
cc_library {
name: "libTest",
srcs: ["foo.c"],
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
vendor_available: true,
@@ -647,7 +647,7 @@
testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
cc_library {
name: "libllndk",
- no_libgcc: true,
+ no_libcrt: true,
shared_libs: ["libnondoubleloadable"],
}
@@ -1786,7 +1786,7 @@
shared_libs: ["libllndk"],
vendor: true,
srcs: ["foo.c"],
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
}
`)
@@ -1815,7 +1815,7 @@
cc_library {
name: "libvendor_available1",
vendor_available: true,
- no_libgcc : true,
+ no_libcrt : true,
nocrt : true,
system_shared_libs : [],
}
@@ -1823,7 +1823,7 @@
name: "libvendor_available2",
vendor_available: true,
runtime_libs: ["libvendor_available1"],
- no_libgcc : true,
+ no_libcrt : true,
nocrt : true,
system_shared_libs : [],
}
@@ -1836,21 +1836,21 @@
exclude_runtime_libs: ["libvendor_available1"],
}
},
- no_libgcc : true,
+ no_libcrt : true,
nocrt : true,
system_shared_libs : [],
}
cc_library {
name: "libcore",
runtime_libs: ["libvendor_available1"],
- no_libgcc : true,
+ no_libcrt : true,
nocrt : true,
system_shared_libs : [],
}
cc_library {
name: "libvendor1",
vendor: true,
- no_libgcc : true,
+ no_libcrt : true,
nocrt : true,
system_shared_libs : [],
}
@@ -1858,7 +1858,7 @@
name: "libvendor2",
vendor: true,
runtime_libs: ["libvendor_available1", "libvendor1"],
- no_libgcc : true,
+ no_libcrt : true,
nocrt : true,
system_shared_libs : [],
}
@@ -2050,7 +2050,7 @@
name: "libvendorpublic",
srcs: ["foo.c"],
vendor: true,
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
}
@@ -2059,7 +2059,7 @@
shared_libs: ["libvendorpublic"],
vendor: false,
srcs: ["foo.c"],
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
}
cc_library {
@@ -2067,7 +2067,7 @@
shared_libs: ["libvendorpublic"],
vendor: true,
srcs: ["foo.c"],
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
}
`)
diff --git a/cc/library.go b/cc/library.go
index 3053831..0bc5b5b 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -721,7 +721,7 @@
}
strippedOutputFile := outputFile
outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
- library.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
+ library.stripper.stripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, builderFlags)
}
library.unstrippedOutputFile = outputFile
@@ -738,7 +738,7 @@
if library.stripper.needsStrip(ctx) {
out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
library.distFile = android.OptionalPathForPath(out)
- library.stripper.strip(ctx, versionedOutputFile, out, builderFlags)
+ library.stripper.stripExecutableOrSharedLib(ctx, versionedOutputFile, out, builderFlags)
}
library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
diff --git a/cc/linker.go b/cc/linker.go
index 986a562..dda2fcb 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -57,9 +57,6 @@
// This flag should only be necessary for compiling low-level libraries like libc.
Allow_undefined_symbols *bool `android:"arch_variant"`
- // don't link in libgcc.a
- No_libgcc *bool
-
// don't link in libclang_rt.builtins-*.a
No_libcrt *bool `android:"arch_variant"`
@@ -230,9 +227,6 @@
deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc_stripped")
- } else if !Bool(linker.Properties.No_libgcc) {
- deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
- deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
}
systemSharedLibs := linker.Properties.System_shared_libs
diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go
index 026ff22..fb16887 100644
--- a/cc/ndk_prebuilt.go
+++ b/cc/ndk_prebuilt.go
@@ -25,7 +25,7 @@
func init() {
android.RegisterModuleType("ndk_prebuilt_object", ndkPrebuiltObjectFactory)
android.RegisterModuleType("ndk_prebuilt_static_stl", ndkPrebuiltStaticStlFactory)
- android.RegisterModuleType("ndk_prebuilt_shared_stl", ndkPrebuiltSharedStlFactory)
+ android.RegisterModuleType("ndk_prebuilt_shared_stl", NdkPrebuiltSharedStlFactory)
}
// NDK prebuilt libraries.
@@ -107,7 +107,7 @@
// library (stl) library for linking operation. The soong's module name format
// is ndk_<NAME>.so where the library is located under
// ./prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs/$(HOST_ARCH)/<NAME>.so.
-func ndkPrebuiltSharedStlFactory() android.Module {
+func NdkPrebuiltSharedStlFactory() android.Module {
module, library := NewLibrary(android.DeviceSupported)
library.BuildOnlyShared()
module.compiler = nil
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 48e4667..f92c50d 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -98,7 +98,7 @@
libName := ctx.baseModuleName() + flags.Toolchain.ShlibSuffix()
if p.needsStrip(ctx) {
stripped := android.PathForModuleOut(ctx, "stripped", libName)
- p.strip(ctx, in, stripped, builderFlags)
+ p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
in = stripped
}
@@ -197,7 +197,7 @@
if p.needsStrip(ctx) {
stripped := android.PathForModuleOut(ctx, "stripped", fileName)
- p.strip(ctx, in, stripped, builderFlags)
+ p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
in = stripped
}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 4486d2e..fdda7be 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -77,6 +77,7 @@
intOverflow
cfi
scs
+ fuzzer
)
// Name of the sanitizer variation for this sanitizer type
@@ -94,6 +95,8 @@
return "cfi"
case scs:
return "scs"
+ case fuzzer:
+ return "fuzzer"
default:
panic(fmt.Errorf("unknown sanitizerType %d", t))
}
@@ -114,6 +117,8 @@
return "cfi"
case scs:
return "shadow-call-stack"
+ case fuzzer:
+ return "fuzzer"
default:
panic(fmt.Errorf("unknown sanitizerType %d", t))
}
@@ -133,7 +138,7 @@
Undefined *bool `android:"arch_variant"`
All_undefined *bool `android:"arch_variant"`
Misc_undefined []string `android:"arch_variant"`
- Coverage *bool `android:"arch_variant"`
+ Fuzzer *bool `android:"arch_variant"`
Safestack *bool `android:"arch_variant"`
Cfi *bool `android:"arch_variant"`
Integer_overflow *bool `android:"arch_variant"`
@@ -223,22 +228,16 @@
s.Undefined = boolPtr(true)
}
- if found, globalSanitizers = removeFromList("address", globalSanitizers); found {
- if s.Address == nil {
- s.Address = boolPtr(true)
- } else if *s.Address == false {
- // Coverage w/o address is an error. If globalSanitizers includes both, and the module
- // disables address, then disable coverage as well.
- _, globalSanitizers = removeFromList("coverage", globalSanitizers)
- }
+ if found, globalSanitizers = removeFromList("address", globalSanitizers); found && s.Address == nil {
+ s.Address = boolPtr(true)
}
if found, globalSanitizers = removeFromList("thread", globalSanitizers); found && s.Thread == nil {
s.Thread = boolPtr(true)
}
- if found, globalSanitizers = removeFromList("coverage", globalSanitizers); found && s.Coverage == nil {
- s.Coverage = boolPtr(true)
+ if found, globalSanitizers = removeFromList("fuzzer", globalSanitizers); found && s.Fuzzer == nil {
+ s.Fuzzer = boolPtr(true)
}
if found, globalSanitizers = removeFromList("safe-stack", globalSanitizers); found && s.Safestack == nil {
@@ -346,7 +345,7 @@
if ctx.staticBinary() {
s.Address = nil
- s.Coverage = nil
+ s.Fuzzer = nil
s.Thread = nil
}
@@ -362,7 +361,7 @@
}
if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) ||
- Bool(s.Coverage) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
+ Bool(s.Fuzzer) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs)) {
sanitize.Properties.SanitizerEnabled = true
}
@@ -377,10 +376,10 @@
s.Thread = nil
}
- if Bool(s.Coverage) {
- if !Bool(s.Address) {
- ctx.ModuleErrorf(`Use of "coverage" also requires "address"`)
- }
+ // TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
+ // mutually incompatible.
+ if Bool(s.Fuzzer) {
+ s.Cfi = nil
}
}
@@ -461,8 +460,13 @@
flags.CFlags = append(flags.CFlags, hwasanCflags...)
}
- if Bool(sanitize.Properties.Sanitize.Coverage) {
- flags.CFlags = append(flags.CFlags, "-fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp")
+ if Bool(sanitize.Properties.Sanitize.Fuzzer) {
+ flags.CFlags = append(flags.CFlags, "-fsanitize=fuzzer-no-link")
+ flags.LdFlags = append(flags.LdFlags, "-fsanitize=fuzzer-no-link")
+
+ // TODO(b/131771163): LTO and Fuzzer support is mutually incompatible.
+ _, flags.LdFlags = removeFromList("-flto", flags.LdFlags)
+ flags.LdFlags = append(flags.LdFlags, "-fno-lto")
}
if Bool(sanitize.Properties.Sanitize.Cfi) {
@@ -497,20 +501,26 @@
flags.CFlags = append(flags.CFlags, sanitizeArg)
flags.AsFlags = append(flags.AsFlags, sanitizeArg)
if ctx.Host() {
- flags.CFlags = append(flags.CFlags, "-fno-sanitize-recover=all")
- flags.LdFlags = append(flags.LdFlags, sanitizeArg)
// Host sanitizers only link symbols in the final executable, so
// there will always be undefined symbols in intermediate libraries.
_, flags.LdFlags = removeFromList("-Wl,--no-undefined", flags.LdFlags)
+ flags.LdFlags = append(flags.LdFlags, sanitizeArg)
} else {
- flags.CFlags = append(flags.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort")
-
if enableMinimalRuntime(sanitize) {
flags.CFlags = append(flags.CFlags, strings.Join(minimalRuntimeFlags, " "))
flags.libFlags = append([]string{minimalRuntimePath}, flags.libFlags...)
flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs,"+minimalRuntimeLib)
}
}
+
+ if Bool(sanitize.Properties.Sanitize.Fuzzer) {
+ // When fuzzing, we wish to crash with diagnostics on any bug.
+ flags.CFlags = append(flags.CFlags, "-fno-sanitize-trap=all", "-fno-sanitize-recover=all")
+ } else if ctx.Host() {
+ flags.CFlags = append(flags.CFlags, "-fno-sanitize-recover=all")
+ } else {
+ flags.CFlags = append(flags.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort")
+ }
// http://b/119329758, Android core does not boot up with this sanitizer yet.
if toDisableImplicitIntegerChange(flags.CFlags) {
flags.CFlags = append(flags.CFlags, "-fno-sanitize=implicit-integer-sign-change")
@@ -573,6 +583,8 @@
return sanitize.Properties.Sanitize.Cfi
case scs:
return sanitize.Properties.Sanitize.Scs
+ case fuzzer:
+ return sanitize.Properties.Sanitize.Fuzzer
default:
panic(fmt.Errorf("unknown sanitizerType %d", t))
}
@@ -583,22 +595,21 @@
!sanitize.isSanitizerEnabled(hwasan) &&
!sanitize.isSanitizerEnabled(tsan) &&
!sanitize.isSanitizerEnabled(cfi) &&
- !sanitize.isSanitizerEnabled(scs)
+ !sanitize.isSanitizerEnabled(scs) &&
+ !sanitize.isSanitizerEnabled(fuzzer)
}
func (sanitize *sanitize) isVariantOnProductionDevice() bool {
return !sanitize.isSanitizerEnabled(asan) &&
!sanitize.isSanitizerEnabled(hwasan) &&
- !sanitize.isSanitizerEnabled(tsan)
+ !sanitize.isSanitizerEnabled(tsan) &&
+ !sanitize.isSanitizerEnabled(fuzzer)
}
func (sanitize *sanitize) SetSanitizer(t sanitizerType, b bool) {
switch t {
case asan:
sanitize.Properties.Sanitize.Address = boolPtr(b)
- if !b {
- sanitize.Properties.Sanitize.Coverage = nil
- }
case hwasan:
sanitize.Properties.Sanitize.Hwaddress = boolPtr(b)
case tsan:
@@ -609,6 +620,8 @@
sanitize.Properties.Sanitize.Cfi = boolPtr(b)
case scs:
sanitize.Properties.Sanitize.Scs = boolPtr(b)
+ case fuzzer:
+ sanitize.Properties.Sanitize.Fuzzer = boolPtr(b)
default:
panic(fmt.Errorf("unknown sanitizerType %d", t))
}
@@ -793,6 +806,10 @@
sanitizers = append(sanitizers, "shadow-call-stack")
}
+ if Bool(c.sanitize.Properties.Sanitize.Fuzzer) {
+ sanitizers = append(sanitizers, "fuzzer-no-link")
+ }
+
// Save the list of sanitizers. These will be used again when generating
// the build rules (for Cflags, etc.)
c.sanitize.Properties.Sanitizers = sanitizers
@@ -931,6 +948,19 @@
modules[1].(*Module).Properties.HideFromMake = true
}
}
+ } else if t == fuzzer {
+ // TODO(b/131771163): CFI and fuzzer support are mutually incompatible
+ // as CFI pulls in LTO.
+ if mctx.Device() {
+ modules[1].(*Module).sanitize.SetSanitizer(cfi, false)
+ }
+ if isSanitizerEnabled {
+ modules[0].(*Module).Properties.PreventInstall = true
+ modules[0].(*Module).Properties.HideFromMake = true
+ } else {
+ modules[1].(*Module).Properties.PreventInstall = true
+ modules[1].(*Module).Properties.HideFromMake = true
+ }
} else if t == hwasan {
if mctx.Device() {
// CFI and HWASAN are currently mutually exclusive so disable
@@ -996,6 +1026,7 @@
func enableMinimalRuntime(sanitize *sanitize) bool {
if !Bool(sanitize.Properties.Sanitize.Address) &&
!Bool(sanitize.Properties.Sanitize.Hwaddress) &&
+ !Bool(sanitize.Properties.Sanitize.Fuzzer) &&
(Bool(sanitize.Properties.Sanitize.Integer_overflow) ||
len(sanitize.Properties.Sanitize.Misc_undefined) > 0) &&
!(Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
diff --git a/cc/strip.go b/cc/strip.go
index 4daa759..f3e3374 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -41,7 +41,7 @@
}
func (stripper *stripper) strip(ctx ModuleContext, in android.Path, out android.ModuleOutPath,
- flags builderFlags) {
+ flags builderFlags, isStaticLib bool) {
if ctx.Darwin() {
TransformDarwinStrip(ctx, in, out)
} else {
@@ -57,9 +57,19 @@
if Bool(stripper.StripProperties.Strip.Use_gnu_strip) {
flags.stripUseGnuStrip = true
}
- if ctx.Config().Debuggable() && !flags.stripKeepMiniDebugInfo {
+ if ctx.Config().Debuggable() && !flags.stripKeepMiniDebugInfo && !isStaticLib {
flags.stripAddGnuDebuglink = true
}
TransformStrip(ctx, in, out, flags)
}
}
+
+func (stripper *stripper) stripExecutableOrSharedLib(ctx ModuleContext, in android.Path,
+ out android.ModuleOutPath, flags builderFlags) {
+ stripper.strip(ctx, in, out, flags, false)
+}
+
+func (stripper *stripper) stripStaticLib(ctx ModuleContext, in android.Path, out android.ModuleOutPath,
+ flags builderFlags) {
+ stripper.strip(ctx, in, out, flags, true)
+}
diff --git a/cc/testing.go b/cc/testing.go
index d9be900..df7cb78 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -78,7 +78,7 @@
cc_library {
name: "libc",
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
recovery_available: true,
@@ -89,7 +89,7 @@
}
cc_library {
name: "libm",
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
recovery_available: true,
@@ -100,7 +100,7 @@
}
cc_library {
name: "libdl",
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
recovery_available: true,
@@ -111,7 +111,7 @@
}
cc_library {
name: "libc++_static",
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
@@ -120,7 +120,7 @@
}
cc_library {
name: "libc++",
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
@@ -133,7 +133,7 @@
}
cc_library {
name: "libunwind_llvm",
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
stl: "none",
diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go
index b4c51ab..fef4508 100644
--- a/cc/toolchain_library.go
+++ b/cc/toolchain_library.go
@@ -86,7 +86,7 @@
fileName := ctx.ModuleName() + staticLibraryExtension
outputFile := android.PathForModuleOut(ctx, fileName)
buildFlags := flagsToBuilderFlags(flags)
- library.stripper.strip(ctx, srcPath, outputFile, buildFlags)
+ library.stripper.stripStaticLib(ctx, srcPath, outputFile, buildFlags)
return outputFile
}
diff --git a/cc/vndk.go b/cc/vndk.go
index 60a3d78..f9f3764 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -467,6 +467,10 @@
return
}
+ if m.Target().NativeBridge == android.NativeBridgeEnabled {
+ return
+ }
+
lib, is_lib := m.linker.(*libraryDecorator)
prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
@@ -526,8 +530,15 @@
var modulePathTxtBuilder strings.Builder
+ modulePaths := modulePaths(ctx.Config())
+ var libs []string
+ for lib := range modulePaths {
+ libs = append(libs, lib)
+ }
+ sort.Strings(libs)
+
first := true
- for lib, dir := range modulePaths(ctx.Config()) {
+ for _, lib := range libs {
if first {
first = false
} else {
@@ -535,7 +546,7 @@
}
modulePathTxtBuilder.WriteString(lib)
modulePathTxtBuilder.WriteString(".so ")
- modulePathTxtBuilder.WriteString(dir)
+ modulePathTxtBuilder.WriteString(modulePaths[lib])
}
ctx.Build(pctx, android.BuildParams{
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index e11e33a..5a1bd74 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -65,8 +65,6 @@
AlwaysOtherDebugInfo bool // always generate mini debug info for non-system server modules (overrides NoDebugInfo=true)
NeverOtherDebugInfo bool // never generate mini debug info for non-system server modules (overrides NoDebugInfo=true)
- MissingUsesLibraries []string // libraries that may be listed in OptionalUsesLibraries but will not be installed by the product
-
IsEng bool // build is a eng variant
SanitizeLite bool // build is the second phase of a SANITIZE_LITE build
@@ -118,10 +116,10 @@
ProfileClassListing android.OptionalPath
ProfileIsTextListing bool
- EnforceUsesLibraries bool
- OptionalUsesLibraries []string
- UsesLibraries []string
- LibraryPaths map[string]android.Path
+ EnforceUsesLibraries bool
+ PresentOptionalUsesLibraries []string
+ UsesLibraries []string
+ LibraryPaths map[string]android.Path
Archs []android.ArchType
DexPreoptImages []android.Path
@@ -310,7 +308,6 @@
NeverSystemServerDebugInfo: false,
AlwaysOtherDebugInfo: false,
NeverOtherDebugInfo: false,
- MissingUsesLibraries: nil,
IsEng: false,
SanitizeLite: false,
DefaultAppImages: false,
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 2d521da..0be37d0 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -226,11 +226,6 @@
bootImageLocation = PathToLocation(bootImage, arch)
}
- // Lists of used and optional libraries from the build config, with optional libraries that are known to not
- // be present in the current product removed.
- var filteredUsesLibs []string
- var filteredOptionalUsesLibs []string
-
// The class loader context using paths in the build
var classLoaderContextHost android.Paths
@@ -248,11 +243,10 @@
var classLoaderContextHostString string
if module.EnforceUsesLibraries {
- filteredOptionalUsesLibs = filterOut(global.MissingUsesLibraries, module.OptionalUsesLibraries)
- filteredUsesLibs = append(copyOf(module.UsesLibraries), filteredOptionalUsesLibs...)
+ usesLibs := append(copyOf(module.UsesLibraries), module.PresentOptionalUsesLibraries...)
// Create class loader context for dex2oat from uses libraries and filtered optional libraries
- for _, l := range filteredUsesLibs {
+ for _, l := range usesLibs {
classLoaderContextHost = append(classLoaderContextHost,
pathForLibrary(module, l))
@@ -267,7 +261,9 @@
// targetSdkVersion in the manifest or APK is < 28, and the module does not explicitly depend on
// org.apache.http.legacy, then implicitly add the classes to the classpath for dexpreopt. One the
// device the classes will be in a file called org.apache.http.legacy.impl.jar.
- if !contains(module.UsesLibraries, httpLegacy) && !contains(module.OptionalUsesLibraries, httpLegacy) {
+ module.LibraryPaths[httpLegacyImpl] = module.LibraryPaths[httpLegacy]
+
+ if !contains(module.UsesLibraries, httpLegacy) && !contains(module.PresentOptionalUsesLibraries, httpLegacy) {
conditionalClassLoaderContextHost28 = append(conditionalClassLoaderContextHost28,
pathForLibrary(module, httpLegacyImpl))
conditionalClassLoaderContextTarget28 = append(conditionalClassLoaderContextTarget28,
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 6dfa9d2..0402f87 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -33,7 +33,7 @@
ProfileClassListing: android.OptionalPath{},
ProfileIsTextListing: false,
EnforceUsesLibraries: false,
- OptionalUsesLibraries: nil,
+ PresentOptionalUsesLibraries: nil,
UsesLibraries: nil,
LibraryPaths: nil,
Archs: []android.ArchType{android.Arm},
diff --git a/java/app.go b/java/app.go
index f7f08a8..8624a74 100644
--- a/java/app.go
+++ b/java/app.go
@@ -17,12 +17,13 @@
// This file contains the module types for compiling Android apps.
import (
- "github.com/google/blueprint"
- "github.com/google/blueprint/proptools"
"path/filepath"
"reflect"
"strings"
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
"android/soong/cc"
"android/soong/tradefed"
@@ -119,6 +120,8 @@
aapt
android.OverridableModuleBase
+ usesLibrary usesLibrary
+
certificate Certificate
appProperties appProperties
@@ -172,10 +175,12 @@
ctx.AddFarVariationDependencies(variation, tag, a.appProperties.Jni_libs...)
if String(a.appProperties.Stl) == "c++_shared" {
if embedJni {
- ctx.AddFarVariationDependencies(variation, tag, "libc++")
+ ctx.AddFarVariationDependencies(variation, tag, "ndk_libc++_shared")
}
}
}
+
+ a.usesLibrary.deps(ctx, Bool(a.properties.No_framework_libs))
}
func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
@@ -276,6 +281,7 @@
aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
a.aapt.splitNames = a.appProperties.Package_splits
+ a.aapt.sdkLibraries = a.exportedSdkLibs
a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...)
@@ -308,9 +314,17 @@
} else {
installDir = filepath.Join("app", a.installApkName)
}
+
a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
a.dexpreopter.isInstallable = Bool(a.properties.Installable)
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
+
+ a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
+ a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs
+ a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx)
+ a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx)
+ a.dexpreopter.manifestFile = a.mergedManifestFile
+
a.deviceProperties.UncompressDex = a.dexpreopter.uncompressedDex
if ctx.ModuleName() != "framework-res" {
@@ -368,12 +382,19 @@
}
func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
+ var apkDeps android.Paths
+
// Check if the install APK name needs to be overridden.
a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Name())
// Process all building blocks, from AAPT to certificates.
a.aaptBuildActions(ctx)
+ if a.usesLibrary.enforceUsesLibraries() {
+ manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(ctx, a.mergedManifestFile)
+ apkDeps = append(apkDeps, manifestCheckFile)
+ }
+
a.proguardBuildActions(ctx)
dexJarFile := a.dexBuildActions(ctx)
@@ -391,13 +412,13 @@
// Build a final signed app package.
// TODO(jungjw): Consider changing this to installApkName.
packageFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".apk")
- CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates)
+ CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps)
a.outputFile = packageFile
for _, split := range a.aapt.splits {
// Sign the split APKs
packageFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"_"+split.suffix+".apk")
- CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates)
+ CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps)
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
}
@@ -483,7 +504,8 @@
&module.Module.protoProperties,
&module.aaptProperties,
&module.appProperties,
- &module.overridableAppProperties)
+ &module.overridableAppProperties,
+ &module.usesLibrary.usesLibraryProperties)
module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
return class == android.Device && ctx.Config().DevicePrefer32BitApps()
@@ -559,6 +581,7 @@
&module.appProperties,
&module.appTestProperties,
&module.overridableAppProperties,
+ &module.usesLibrary.usesLibraryProperties,
&module.testProperties)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
@@ -599,7 +622,8 @@
&module.aaptProperties,
&module.appProperties,
&module.appTestHelperAppProperties,
- &module.overridableAppProperties)
+ &module.overridableAppProperties,
+ &module.usesLibrary.usesLibraryProperties)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
@@ -666,6 +690,8 @@
certificate *Certificate
dexpreopter
+
+ usesLibrary usesLibrary
}
type AndroidAppImportProperties struct {
@@ -753,6 +779,8 @@
if cert != "" {
ctx.AddDependency(ctx.Module(), certificateTag, cert)
}
+
+ a.usesLibrary.deps(ctx, false)
}
func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
@@ -808,7 +836,12 @@
// TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
// TODO: LOCAL_PACKAGE_SPLITS
- srcApk := android.PathForModuleSrc(ctx, a.getSrcApkPath(ctx))
+ var srcApk android.Path
+ srcApk = android.PathForModuleSrc(ctx, a.getSrcApkPath(ctx))
+
+ if a.usesLibrary.enforceUsesLibraries() {
+ srcApk = a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk)
+ }
// TODO: Install or embed JNI libraries
@@ -821,6 +854,12 @@
a.dexpreopter.isInstallable = true
a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned)
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
+
+ a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
+ a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs
+ a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx)
+ a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx)
+
dexOutput := a.dexpreopter.dexpreopt(ctx, jnisUncompressed)
if a.dexpreopter.uncompressedDex {
dexUncompressed := android.PathForModuleOut(ctx, "dex-uncompressed", ctx.ModuleName()+".apk")
@@ -866,9 +905,129 @@
module.properties.Dpi_variants = reflect.New(dpiVariantsStruct).Interface()
module.AddProperties(&module.properties)
module.AddProperties(&module.dexpreoptProperties)
+ module.AddProperties(&module.usesLibrary.usesLibraryProperties)
InitJavaModule(module, android.DeviceSupported)
android.InitSingleSourcePrebuiltModule(module, &module.properties.Apk)
return module
}
+
+type UsesLibraryProperties struct {
+ // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
+ Uses_libs []string
+
+ // A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
+ // required=false.
+ Optional_uses_libs []string
+
+ // If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
+ // to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
+ Enforce_uses_libs *bool
+}
+
+// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
+// <uses-library> tags that end up in the manifest of an APK match the ones known to the build system through the
+// uses_libs and optional_uses_libs properties. The build system's values are used by dexpreopt to preopt apps
+// with knowledge of their shared libraries.
+type usesLibrary struct {
+ usesLibraryProperties UsesLibraryProperties
+}
+
+func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, noFrameworkLibs bool) {
+ ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...)
+ ctx.AddVariationDependencies(nil, usesLibTag, u.presentOptionalUsesLibs(ctx)...)
+ if !noFrameworkLibs {
+ // dexpreopt/dexpreopt.go needs the paths to the dex jars of these libraries in case construct_context.sh needs
+ // to pass them to dex2oat. Add them as a dependency so we can determine the path to the dex jar of each
+ // library to dexpreopt.
+ ctx.AddVariationDependencies(nil, usesLibTag,
+ "org.apache.http.legacy",
+ "android.hidl.base-V1.0-java",
+ "android.hidl.manager-V1.0-java")
+ }
+}
+
+// presentOptionalUsesLibs returns optional_uses_libs after filtering out MissingUsesLibraries, which don't exist in the
+// build.
+func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
+ optionalUsesLibs, _ := android.FilterList(u.usesLibraryProperties.Optional_uses_libs, ctx.Config().MissingUsesLibraries())
+ return optionalUsesLibs
+}
+
+// usesLibraryPaths returns a map of module names of shared library dependencies to the paths to their dex jars.
+func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) map[string]android.Path {
+ usesLibPaths := make(map[string]android.Path)
+
+ if !ctx.Config().UnbundledBuild() {
+ ctx.VisitDirectDepsWithTag(usesLibTag, func(m android.Module) {
+ if lib, ok := m.(Dependency); ok {
+ if dexJar := lib.DexJar(); dexJar != nil {
+ usesLibPaths[ctx.OtherModuleName(m)] = dexJar
+ } else {
+ ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must produce a dex jar, does it have installable: true?",
+ ctx.OtherModuleName(m))
+ }
+ } else if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies([]string{ctx.OtherModuleName(m)})
+ } else {
+ ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library",
+ ctx.OtherModuleName(m))
+ }
+ })
+ }
+
+ return usesLibPaths
+}
+
+// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
+// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
+// unconditionally in the future.
+func (u *usesLibrary) enforceUsesLibraries() bool {
+ defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 ||
+ len(u.usesLibraryProperties.Optional_uses_libs) > 0
+ return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, defaultEnforceUsesLibs)
+}
+
+// verifyUsesLibrariesManifest checks the <uses-library> tags in an AndroidManifest.xml against the ones specified
+// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the manifest.
+func (u *usesLibrary) verifyUsesLibrariesManifest(ctx android.ModuleContext, manifest android.Path) android.Path {
+ outputFile := android.PathForModuleOut(ctx, "manifest_check", "AndroidManifest.xml")
+
+ rule := android.NewRuleBuilder()
+ cmd := rule.Command().Tool(ctx.Config().HostToolPath(ctx, "manifest_check")).
+ Flag("--enforce-uses-libraries").
+ Input(manifest).
+ FlagWithOutput("-o ", outputFile)
+
+ for _, lib := range u.usesLibraryProperties.Uses_libs {
+ cmd.FlagWithArg("--uses-library ", lib)
+ }
+
+ for _, lib := range u.usesLibraryProperties.Optional_uses_libs {
+ cmd.FlagWithArg("--optional-uses-library ", lib)
+ }
+
+ rule.Build(pctx, ctx, "verify_uses_libraries", "verify <uses-library>")
+
+ return outputFile
+}
+
+// verifyUsesLibrariesAPK checks the <uses-library> tags in the manifest of an APK against the ones specified
+// in the uses_libs and optional_uses_libs properties. It returns the path to a copy of the APK.
+func (u *usesLibrary) verifyUsesLibrariesAPK(ctx android.ModuleContext, apk android.Path) android.Path {
+ outputFile := android.PathForModuleOut(ctx, "verify_uses_libraries", apk.Base())
+
+ rule := android.NewRuleBuilder()
+ aapt := ctx.Config().HostToolPath(ctx, "aapt")
+ rule.Command().
+ Textf("aapt_binary=%s", aapt.String()).Implicit(aapt).
+ Textf(`uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Uses_libs, " ")).
+ Textf(`optional_uses_library_names="%s"`, strings.Join(u.usesLibraryProperties.Optional_uses_libs, " ")).
+ Tool(android.PathForSource(ctx, "build/make/core/verify_uses_libraries.sh")).Input(apk)
+ rule.Command().Text("cp -f").Input(apk).Output(outputFile)
+
+ rule.Build(pctx, ctx, "verify_uses_libraries", "verify <uses-library>")
+
+ return outputFile
+}
diff --git a/java/app_builder.go b/java/app_builder.go
index 82a390f..fa77bbf 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -63,7 +63,7 @@
})
func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
- packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate) {
+ packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths) {
unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
@@ -78,9 +78,10 @@
}
ctx.Build(pctx, android.BuildParams{
- Rule: combineApk,
- Inputs: inputs,
- Output: unsignedApk,
+ Rule: combineApk,
+ Inputs: inputs,
+ Output: unsignedApk,
+ Implicits: deps,
})
SignAppPackage(ctx, outputFile, unsignedApk, certificates)
diff --git a/java/app_test.go b/java/app_test.go
index 40a64af..0f2c1cf 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -130,8 +130,12 @@
foo.Output(expectedOutput)
}
- if g, w := foo.Module().(*AndroidApp).Srcs().Strings(), expectedOutputs; !reflect.DeepEqual(g, w) {
- t.Errorf("want Srcs() = %q, got %q", w, g)
+ outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if g, w := outputFiles.Strings(), expectedOutputs; !reflect.DeepEqual(g, w) {
+ t.Errorf(`want OutputFiles("") = %q, got %q`, w, g)
}
}
@@ -1199,6 +1203,10 @@
compile_multilib: "both",
sdk_version: "current",
}
+
+ ndk_prebuilt_shared_stl {
+ name: "ndk_libc++_shared",
+ }
`)
testCases := []struct {
@@ -1208,7 +1216,7 @@
{"stl",
[]string{
"libjni.so",
- "libc++.so",
+ "libc++_shared.so",
},
},
{"system",
@@ -1239,3 +1247,83 @@
})
}
}
+
+func TestUsesLibraries(t *testing.T) {
+ bp := `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ }
+
+ java_sdk_library {
+ name: "bar",
+ srcs: ["a.java"],
+ api_packages: ["bar"],
+ }
+
+ android_app {
+ name: "app",
+ srcs: ["a.java"],
+ uses_libs: ["foo"],
+ optional_uses_libs: [
+ "bar",
+ "baz",
+ ],
+ }
+
+ android_app_import {
+ name: "prebuilt",
+ apk: "prebuilts/apk/app.apk",
+ certificate: "platform",
+ uses_libs: ["foo"],
+ optional_uses_libs: [
+ "bar",
+ "baz",
+ ],
+ }
+ `
+
+ config := testConfig(nil)
+ config.TestProductVariables.MissingUsesLibraries = []string{"baz"}
+
+ ctx := testAppContext(config, bp, nil)
+
+ run(t, ctx, config)
+
+ app := ctx.ModuleForTests("app", "android_common")
+ prebuilt := ctx.ModuleForTests("prebuilt", "android_common")
+
+ // Test that all libraries are verified
+ cmd := app.Rule("verify_uses_libraries").RuleParams.Command
+ if w := "--uses-library foo"; !strings.Contains(cmd, w) {
+ t.Errorf("wanted %q in %q", w, cmd)
+ }
+
+ if w := "--optional-uses-library bar --optional-uses-library baz"; !strings.Contains(cmd, w) {
+ t.Errorf("wanted %q in %q", w, cmd)
+ }
+
+ cmd = prebuilt.Rule("verify_uses_libraries").RuleParams.Command
+
+ if w := `uses_library_names="foo"`; !strings.Contains(cmd, w) {
+ t.Errorf("wanted %q in %q", w, cmd)
+ }
+
+ if w := `optional_uses_library_names="bar baz"`; !strings.Contains(cmd, w) {
+ t.Errorf("wanted %q in %q", w, cmd)
+ }
+
+ // Test that only present libraries are preopted
+ cmd = app.Rule("dexpreopt").RuleParams.Command
+
+ if w := `dex_preopt_target_libraries="/system/framework/foo.jar /system/framework/bar.jar"`; !strings.Contains(cmd, w) {
+ t.Errorf("wanted %q in %q", w, cmd)
+ }
+
+ cmd = prebuilt.Rule("dexpreopt").RuleParams.Command
+
+ if w := `dex_preopt_target_libraries="/system/framework/foo.jar /system/framework/bar.jar"`; !strings.Contains(cmd, w) {
+ t.Errorf("wanted %q in %q", w, cmd)
+ }
+}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 08fd06e..23d2aa6 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -29,6 +29,12 @@
isInstallable bool
isPresignedPrebuilt bool
+ manifestFile android.Path
+ usesLibs []string
+ optionalUsesLibs []string
+ enforceUsesLibs bool
+ libraryPaths map[string]android.Path
+
builtInstalled string
}
@@ -154,6 +160,7 @@
DexLocation: dexLocation,
BuildPath: android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath,
DexPath: dexJarFile,
+ ManifestPath: d.manifestFile,
UncompressedDex: d.uncompressedDex,
HasApkLibraries: false,
PreoptFlags: nil,
@@ -161,10 +168,10 @@
ProfileClassListing: profileClassListing,
ProfileIsTextListing: profileIsTextListing,
- EnforceUsesLibraries: false,
- OptionalUsesLibraries: nil,
- UsesLibraries: nil,
- LibraryPaths: nil,
+ EnforceUsesLibraries: d.enforceUsesLibs,
+ PresentOptionalUsesLibraries: d.optionalUsesLibs,
+ UsesLibraries: d.usesLibs,
+ LibraryPaths: d.libraryPaths,
Archs: archs,
DexPreoptImages: images,
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 57da6b6..0ec7799 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -497,8 +497,13 @@
stubsSrcJar android.WritablePath
}
-func (j *Javadoc) Srcs() android.Paths {
- return android.Paths{j.stubsSrcJar}
+func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return android.Paths{j.stubsSrcJar}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
}
func JavadocFactory() android.Module {
@@ -519,7 +524,7 @@
return module
}
-var _ android.SourceFileProducer = (*Javadoc)(nil)
+var _ android.OutputFileProducer = (*Javadoc)(nil)
func (j *Javadoc) sdkVersion() string {
return String(j.properties.Sdk_version)
diff --git a/java/java.go b/java/java.go
index 8dbdfb6..0bccb67 100644
--- a/java/java.go
+++ b/java/java.go
@@ -351,15 +351,22 @@
dexpreopter
}
-func (j *Module) Srcs() android.Paths {
- return append(android.Paths{j.outputFile}, j.extraOutputFiles...)
+func (j *Module) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil
+ case ".jar":
+ return android.Paths{j.implementationAndResourcesJar}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
}
func (j *Module) DexJarFile() android.Path {
return j.dexJarFile
}
-var _ android.SourceFileProducer = (*Module)(nil)
+var _ android.OutputFileProducer = (*Module)(nil)
type Dependency interface {
HeaderJars() android.Paths
@@ -420,6 +427,7 @@
proguardRaiseTag = dependencyTag{name: "proguard-raise"}
certificateTag = dependencyTag{name: "certificate"}
instrumentationForTag = dependencyTag{name: "instrumentation_for"}
+ usesLibTag = dependencyTag{name: "uses-library"}
)
type sdkDep struct {
@@ -812,8 +820,6 @@
}
default:
switch tag {
- case android.DefaultsDepTag, android.SourceDepTag:
- // Nothing to do
case systemModulesTag:
if deps.systemModules != nil {
panic("Found two system module dependencies")
@@ -823,8 +829,6 @@
panic("Missing directory for system module dependency")
}
deps.systemModules = sm.outputFile
- default:
- ctx.ModuleErrorf("depends on non-java module %q", otherName)
}
}
})
@@ -1483,6 +1487,7 @@
func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
+ dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...)
dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
if j.expandJarjarRules != nil {
dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
diff --git a/java/java_test.go b/java/java_test.go
index 50b1c34..4d161c5 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -105,6 +105,7 @@
ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory))
ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory))
+ ctx.RegisterModuleType("ndk_prebuilt_shared_stl", android.ModuleFactoryAdaptor(cc.NdkPrebuiltSharedStlFactory))
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("link", cc.LinkageMutator).Parallel()
ctx.BottomUp("begin", cc.BeginMutator).Parallel()
@@ -134,6 +135,8 @@
"api/test-removed.txt": nil,
"framework/aidl/a.aidl": nil,
+ "prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so": nil,
+
"prebuilts/sdk/14/public/android.jar": nil,
"prebuilts/sdk/14/public/framework.aidl": nil,
"prebuilts/sdk/14/system/android.jar": nil,
@@ -174,6 +177,8 @@
"build/soong/scripts/jar-wrapper.sh": nil,
+ "build/make/core/verify_uses_libraries.sh": nil,
+
"build/make/core/proguard.flags": nil,
"build/make/core/proguard_basic_keeps.flags": nil,
diff --git a/java/jdeps.go b/java/jdeps.go
index 18498be..fccc40f 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -72,6 +72,7 @@
dpInfo.Aidl_include_dirs = android.FirstUniqueStrings(dpInfo.Aidl_include_dirs)
dpInfo.Jarjar_rules = android.FirstUniqueStrings(dpInfo.Jarjar_rules)
dpInfo.Jars = android.FirstUniqueStrings(dpInfo.Jars)
+ dpInfo.SrcJars = android.FirstUniqueStrings(dpInfo.SrcJars)
moduleInfos[name] = dpInfo
mkProvider, ok := module.(android.AndroidMkDataProvider)
diff --git a/java/robolectric.go b/java/robolectric.go
index 26f1e9d..b87ee0d 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -39,7 +39,7 @@
Test_options struct {
// Timeout in seconds when running the tests.
- Timeout *string
+ Timeout *int64
}
}
diff --git a/java/testing.go b/java/testing.go
index 22831c9..fc7842d 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -77,6 +77,33 @@
name: "framework-res",
no_framework_libs: true,
}
+
+ java_library {
+ name: "android.hidl.base-V1.0-java",
+ srcs: ["a.java"],
+ no_standard_libs: true,
+ sdk_version: "core_current",
+ system_modules: "core-platform-api-stubs-system-modules",
+ installable: true,
+ }
+
+ java_library {
+ name: "android.hidl.manager-V1.0-java",
+ srcs: ["a.java"],
+ no_standard_libs: true,
+ sdk_version: "core_current",
+ system_modules: "core-platform-api-stubs-system-modules",
+ installable: true,
+ }
+
+ java_library {
+ name: "org.apache.http.legacy",
+ srcs: ["a.java"],
+ no_standard_libs: true,
+ sdk_version: "core_current",
+ system_modules: "core-platform-api-stubs-system-modules",
+ installable: true,
+ }
`
systemModules := []string{
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index d78238a..b470ba5 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -278,7 +278,7 @@
cc_library {
name: "liblog",
- no_libgcc: true,
+ no_libcrt: true,
nocrt: true,
system_shared_libs: [],
recovery_available: true,