Merge "Turn on string-plus-int warning"
diff --git a/android/config.go b/android/config.go
index 92879de..1520739 100644
--- a/android/config.go
+++ b/android/config.go
@@ -581,7 +581,7 @@
if defaultCert == "" || filepath.Dir(defaultCert) == "build/target/product/security" {
// When defaultCert is unset or is set to the testkeys path, use the APEX keys
// that is under the module dir
- return PathForModuleSrc(ctx).SourcePath
+ return pathForModuleSrc(ctx)
} else {
// If not, APEX keys are under the specified directory
return PathForSource(ctx, filepath.Dir(defaultCert))
diff --git a/android/filegroup.go b/android/filegroup.go
index c2be22a..ec522fc 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -60,7 +60,11 @@
}
func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
- fg.srcs = ctx.ExpandSourcesSubDir(fg.properties.Srcs, fg.properties.Exclude_srcs, String(fg.properties.Path))
+ fg.srcs = PathsForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs)
+
+ if fg.properties.Path != nil {
+ fg.srcs = PathsWithModuleSrcSubDir(ctx, fg.srcs, String(fg.properties.Path))
+ }
}
func (fg *fileGroup) Srcs() Paths {
diff --git a/android/module.go b/android/module.go
index 9a69a26..afd2b71 100644
--- a/android/module.go
+++ b/android/module.go
@@ -117,7 +117,6 @@
ExpandSources(srcFiles, excludes []string) Paths
ExpandSource(srcFile, prop string) Path
ExpandOptionalSource(srcFile *string, prop string) OptionalPath
- ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
Glob(globPattern string, excludes []string) Paths
GlobFiles(globPattern string, excludes []string) Paths
@@ -855,7 +854,7 @@
if a.commonProperties.Notice != nil {
// For filegroup-based notice file references.
- a.noticeFile = ctx.ExpandSource(*a.commonProperties.Notice, "notice")
+ a.noticeFile = PathForModuleSrc(ctx, *a.commonProperties.Notice)
}
}
@@ -1420,27 +1419,18 @@
// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
// be tagged with `android:"path" to support automatic source module dependency resolution.
+//
+// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
- return ctx.ExpandSourcesSubDir(srcFiles, excludes, "")
+ return PathsForModuleSrcExcludes(ctx, srcFiles, excludes)
}
// Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
// be tagged with `android:"path" to support automatic source module dependency resolution.
+//
+// Deprecated: use PathForModuleSrc instead.
func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
- srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
- if len(srcFiles) == 1 {
- return srcFiles[0]
- } else if len(srcFiles) == 0 {
- if ctx.Config().AllowMissingDependencies() {
- ctx.AddMissingDependencies([]string{srcFile})
- } else {
- ctx.PropertyErrorf(prop, "%s path %s does not exist", prop, srcFile)
- }
- return nil
- } else {
- ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
- return nil
- }
+ return PathForModuleSrc(ctx, srcFile)
}
// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
@@ -1448,82 +1438,11 @@
// dependency resolution.
func (ctx *androidModuleContext) ExpandOptionalSource(srcFile *string, prop string) OptionalPath {
if srcFile != nil {
- return OptionalPathForPath(ctx.ExpandSource(*srcFile, prop))
+ return OptionalPathForPath(PathForModuleSrc(ctx, *srcFile))
}
return OptionalPath{}
}
-func (ctx *androidModuleContext) ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths {
- prefix := PathForModuleSrc(ctx).String()
-
- var expandedExcludes []string
- if excludes != nil {
- expandedExcludes = make([]string, 0, len(excludes))
- }
-
- for _, e := range excludes {
- if m := SrcIsModule(e); m != "" {
- module := ctx.GetDirectDepWithTag(m, SourceDepTag)
- if module == nil {
- if ctx.Config().AllowMissingDependencies() {
- ctx.AddMissingDependencies([]string{m})
- } else {
- ctx.ModuleErrorf(`missing dependency on %q, is the property annotated with android:"path"?`, m)
- }
- continue
- }
- 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)
- }
- } else {
- expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
- }
- }
- expandedSrcFiles := make(Paths, 0, len(srcFiles))
- for _, s := range srcFiles {
- if m := SrcIsModule(s); m != "" {
- module := ctx.GetDirectDepWithTag(m, SourceDepTag)
- if module == nil {
- if ctx.Config().AllowMissingDependencies() {
- ctx.AddMissingDependencies([]string{m})
- } else {
- ctx.ModuleErrorf(`missing dependency on %q, is the property annotated with android:"path"?`, m)
- }
- continue
- }
- if srcProducer, ok := module.(SourceFileProducer); ok {
- moduleSrcs := srcProducer.Srcs()
- for _, e := range expandedExcludes {
- for j, ms := range moduleSrcs {
- if ms.String() == e {
- moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
- }
- }
- }
- expandedSrcFiles = append(expandedSrcFiles, moduleSrcs...)
- } else {
- ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
- }
- } else if pathtools.IsGlob(s) {
- globbedSrcFiles := ctx.GlobFiles(filepath.Join(prefix, s), expandedExcludes)
- for i, s := range globbedSrcFiles {
- globbedSrcFiles[i] = s.(ModuleSrcPath).WithSubDir(ctx, subDir)
- }
- expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
- } else {
- p := PathForModuleSrc(ctx, s).WithSubDir(ctx, subDir)
- j := findStringInSlice(p.String(), expandedExcludes)
- if j == -1 {
- expandedSrcFiles = append(expandedSrcFiles, p)
- }
-
- }
- }
- return expandedSrcFiles
-}
-
func (ctx *androidModuleContext) RequiredModuleNames() []string {
return ctx.module.base().commonProperties.Required
}
diff --git a/android/paths.go b/android/paths.go
index afde55e..cdcb719 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -220,11 +220,104 @@
// PathsForModuleSrc returns Paths rooted from the module's local source
// directory
func PathsForModuleSrc(ctx ModuleContext, paths []string) Paths {
- ret := make(Paths, len(paths))
- for i, path := range paths {
- ret[i] = PathForModuleSrc(ctx, path)
+ return PathsForModuleSrcExcludes(ctx, paths, nil)
+}
+
+func PathsForModuleSrcExcludes(ctx ModuleContext, paths, excludes []string) Paths {
+ prefix := pathForModuleSrc(ctx).String()
+
+ var expandedExcludes []string
+ if excludes != nil {
+ expandedExcludes = make([]string, 0, len(excludes))
}
- return ret
+
+ for _, e := range excludes {
+ if m := SrcIsModule(e); m != "" {
+ module := ctx.GetDirectDepWithTag(m, SourceDepTag)
+ if module == nil {
+ if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies([]string{m})
+ } else {
+ ctx.ModuleErrorf(`missing dependency on %q, is the property annotated with android:"path"?`, m)
+ }
+ continue
+ }
+ 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)
+ }
+ } else {
+ expandedExcludes = append(expandedExcludes, filepath.Join(prefix, e))
+ }
+ }
+
+ if paths == nil {
+ return nil
+ }
+
+ expandedSrcFiles := make(Paths, 0, len(paths))
+ for _, s := range paths {
+ srcFiles, err := expandOneSrcPath(ctx, s, expandedExcludes)
+ if depErr, ok := err.(missingDependencyError); ok {
+ if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies(depErr.missingDeps)
+ } else {
+ ctx.ModuleErrorf(`%s, is the property annotated with android:"path"?`, depErr.Error())
+ }
+ } else if err != nil {
+ reportPathError(ctx, err)
+ }
+ expandedSrcFiles = append(expandedSrcFiles, srcFiles...)
+ }
+ return expandedSrcFiles
+}
+
+type missingDependencyError struct {
+ missingDeps []string
+}
+
+func (e missingDependencyError) Error() string {
+ return "missing dependencies: " + strings.Join(e.missingDeps, ", ")
+}
+
+func expandOneSrcPath(ctx ModuleContext, s string, expandedExcludes []string) (Paths, error) {
+ if m := SrcIsModule(s); m != "" {
+ module := ctx.GetDirectDepWithTag(m, SourceDepTag)
+ if module == nil {
+ return nil, missingDependencyError{[]string{m}}
+ }
+ if srcProducer, ok := module.(SourceFileProducer); ok {
+ moduleSrcs := srcProducer.Srcs()
+ for _, e := range expandedExcludes {
+ for j := 0; j < len(moduleSrcs); j++ {
+ if moduleSrcs[j].String() == e {
+ moduleSrcs = append(moduleSrcs[:j], moduleSrcs[j+1:]...)
+ j--
+ }
+ }
+ }
+ return moduleSrcs, nil
+ } else {
+ return nil, fmt.Errorf("path dependency %q is not a source file producing module", m)
+ }
+ } else if pathtools.IsGlob(s) {
+ paths := ctx.GlobFiles(pathForModuleSrc(ctx, s).String(), expandedExcludes)
+ return PathsWithModuleSrcSubDir(ctx, paths, ""), nil
+ } else {
+ p := pathForModuleSrc(ctx, s)
+ if exists, _, err := ctx.Fs().Exists(p.String()); err != nil {
+ reportPathErrorf(ctx, "%s: %s", p, err.Error())
+ } else if !exists {
+ reportPathErrorf(ctx, "module source path %q does not exist", p)
+ }
+
+ j := findStringInSlice(p.String(), expandedExcludes)
+ if j >= 0 {
+ return nil, nil
+ }
+ return Paths{p}, nil
+ }
}
// pathsForModuleSrcFromFullPath returns Paths rooted from the module's local
@@ -254,10 +347,9 @@
continue
}
- moduleSrcPath := ModuleSrcPath{srcPath}
- moduleSrcPath.basePath.rel = srcPath.path
+ srcPath.basePath.rel = srcPath.path
- ret = append(ret, moduleSrcPath)
+ ret = append(ret, srcPath)
}
return ret
}
@@ -620,13 +712,20 @@
return p.withRel(path)
}
+// join is like Join but does less path validation.
+func (p SourcePath) join(ctx PathContext, paths ...string) SourcePath {
+ path, err := validateSafePath(paths...)
+ if err != nil {
+ reportPathError(ctx, err)
+ }
+ return p.withRel(path)
+}
+
// OverlayPath returns the overlay for `path' if it exists. This assumes that the
// SourcePath is the path to a resource overlay directory.
func (p SourcePath) OverlayPath(ctx ModuleContext, path Path) OptionalPath {
var relDir string
- if moduleSrcPath, ok := path.(ModuleSrcPath); ok {
- relDir = moduleSrcPath.path
- } else if srcPath, ok := path.(SourcePath); ok {
+ if srcPath, ok := path.(SourcePath); ok {
relDir = srcPath.path
} else {
reportPathErrorf(ctx, "Cannot find relative path for %s(%s)", reflect.TypeOf(path).Name(), path)
@@ -738,45 +837,75 @@
return PathForOutput(ctx, ".intermediates", path)
}
-// ModuleSrcPath is a Path representing a file rooted from a module's local source dir
-type ModuleSrcPath struct {
- SourcePath
+var _ genPathProvider = SourcePath{}
+var _ objPathProvider = SourcePath{}
+var _ resPathProvider = SourcePath{}
+
+// PathForModuleSrc returns a Path representing the paths... under the
+// module's local source directory.
+func PathForModuleSrc(ctx ModuleContext, pathComponents ...string) Path {
+ p, err := validatePath(pathComponents...)
+ if err != nil {
+ reportPathError(ctx, err)
+ }
+ paths, err := expandOneSrcPath(ctx, p, nil)
+ if err != nil {
+ if depErr, ok := err.(missingDependencyError); ok {
+ if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies(depErr.missingDeps)
+ } else {
+ ctx.ModuleErrorf(`%s, is the property annotated with android:"path"?`, depErr.Error())
+ }
+ } else {
+ reportPathError(ctx, err)
+ }
+ return nil
+ } else if len(paths) == 0 {
+ reportPathErrorf(ctx, "%q produced no files, expected exactly one", p)
+ return nil
+ } else if len(paths) > 1 {
+ reportPathErrorf(ctx, "%q produced %d files, expected exactly one", p, len(paths))
+ }
+ return paths[0]
}
-var _ Path = ModuleSrcPath{}
-var _ genPathProvider = ModuleSrcPath{}
-var _ objPathProvider = ModuleSrcPath{}
-var _ resPathProvider = ModuleSrcPath{}
-
-// PathForModuleSrc returns a ModuleSrcPath representing the paths... under the
-// module's local source directory.
-func PathForModuleSrc(ctx ModuleContext, paths ...string) ModuleSrcPath {
+func pathForModuleSrc(ctx ModuleContext, paths ...string) SourcePath {
p, err := validatePath(paths...)
if err != nil {
reportPathError(ctx, err)
}
- srcPath, err := pathForSource(ctx, ctx.ModuleDir(), p)
+ path, err := pathForSource(ctx, ctx.ModuleDir(), p)
if err != nil {
reportPathError(ctx, err)
}
- if pathtools.IsGlob(srcPath.String()) {
- reportPathErrorf(ctx, "path may not contain a glob: %s", srcPath.String())
- }
-
- path := ModuleSrcPath{srcPath}
path.basePath.rel = p
- if exists, _, err := ctx.Fs().Exists(path.String()); err != nil {
- reportPathErrorf(ctx, "%s: %s", path, err.Error())
- } else if !exists {
- reportPathErrorf(ctx, "module source path %q does not exist", path)
- }
-
return path
}
+// PathsWithModuleSrcSubDir takes a list of Paths and returns a new list of Paths where Rel() on each path
+// will return the path relative to subDir in the module's source directory. If any input paths are not located
+// inside subDir then a path error will be reported.
+func PathsWithModuleSrcSubDir(ctx ModuleContext, paths Paths, subDir string) Paths {
+ paths = append(Paths(nil), paths...)
+ subDirFullPath := pathForModuleSrc(ctx, subDir)
+ for i, path := range paths {
+ rel := Rel(ctx, subDirFullPath.String(), path.String())
+ paths[i] = subDirFullPath.join(ctx, rel)
+ }
+ return paths
+}
+
+// PathWithModuleSrcSubDir takes a Path and returns a Path where Rel() will return the path relative to subDir in the
+// module's source directory. If the input path is not located inside subDir then a path error will be reported.
+func PathWithModuleSrcSubDir(ctx ModuleContext, path Path, subDir string) Path {
+ subDirFullPath := pathForModuleSrc(ctx, subDir)
+ rel := Rel(ctx, subDirFullPath.String(), path.String())
+ return subDirFullPath.Join(ctx, rel)
+}
+
// OptionalPathForModuleSrc returns an OptionalPath. The OptionalPath contains a
// valid path if p is non-nil.
func OptionalPathForModuleSrc(ctx ModuleContext, p *string) OptionalPath {
@@ -786,25 +915,19 @@
return OptionalPathForPath(PathForModuleSrc(ctx, *p))
}
-func (p ModuleSrcPath) genPathWithExt(ctx ModuleContext, subdir, ext string) ModuleGenPath {
+func (p SourcePath) genPathWithExt(ctx ModuleContext, subdir, ext string) ModuleGenPath {
return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
-func (p ModuleSrcPath) objPathWithExt(ctx ModuleContext, subdir, ext string) ModuleObjPath {
+func (p SourcePath) objPathWithExt(ctx ModuleContext, subdir, ext string) ModuleObjPath {
return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
-func (p ModuleSrcPath) resPathWithName(ctx ModuleContext, name string) ModuleResPath {
+func (p SourcePath) resPathWithName(ctx ModuleContext, name string) ModuleResPath {
// TODO: Use full directory if the new ctx is not the current ctx?
return PathForModuleRes(ctx, p.path, name)
}
-func (p ModuleSrcPath) WithSubDir(ctx ModuleContext, subdir string) ModuleSrcPath {
- subdir = PathForModuleSrc(ctx, subdir).String()
- p.rel = Rel(ctx, subdir, p.path)
- return p
-}
-
// ModuleOutPath is a Path representing a module's output directory.
type ModuleOutPath struct {
OutputPath
diff --git a/android/paths_test.go b/android/paths_test.go
index cadf371..2e0e0e8 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -24,6 +24,7 @@
"testing"
"github.com/google/blueprint/pathtools"
+ "github.com/google/blueprint/proptools"
)
type strsTestCase struct {
@@ -508,15 +509,27 @@
}
func TestDirectorySortedPaths(t *testing.T) {
+ config := TestConfig("out", nil)
+
+ ctx := PathContextForTesting(config, map[string][]byte{
+ "a.txt": nil,
+ "a/txt": nil,
+ "a/b/c": nil,
+ "a/b/d": nil,
+ "b": nil,
+ "b/b.txt": nil,
+ "a/a.txt": nil,
+ })
+
makePaths := func() Paths {
return Paths{
- PathForTesting("a.txt"),
- PathForTesting("a/txt"),
- PathForTesting("a/b/c"),
- PathForTesting("a/b/d"),
- PathForTesting("b"),
- PathForTesting("b/b.txt"),
- PathForTesting("a/a.txt"),
+ PathForSource(ctx, "a.txt"),
+ PathForSource(ctx, "a/txt"),
+ PathForSource(ctx, "a/b/c"),
+ PathForSource(ctx, "a/b/d"),
+ PathForSource(ctx, "b"),
+ PathForSource(ctx, "b/b.txt"),
+ PathForSource(ctx, "a/a.txt"),
}
}
@@ -694,39 +707,117 @@
}
}
-type expandSourcesTestModule struct {
+type pathForModuleSrcTestModule struct {
ModuleBase
props struct {
Srcs []string `android:"path"`
Exclude_srcs []string `android:"path"`
+
+ Src *string `android:"path"`
}
- srcs Paths
+ src string
+ rel string
+
+ srcs []string
rels []string
+
+ missingDeps []string
}
-func expandSourcesTestModuleFactory() Module {
- module := &expandSourcesTestModule{}
+func pathForModuleSrcTestModuleFactory() Module {
+ module := &pathForModuleSrcTestModule{}
module.AddProperties(&module.props)
InitAndroidModule(module)
return module
}
-func (p *expandSourcesTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
- p.srcs = ctx.ExpandSources(p.props.Srcs, p.props.Exclude_srcs)
+func (p *pathForModuleSrcTestModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ srcs := PathsForModuleSrcExcludes(ctx, p.props.Srcs, p.props.Exclude_srcs)
+ p.srcs = srcs.Strings()
- for _, src := range p.srcs {
+ for _, src := range srcs {
p.rels = append(p.rels, src.Rel())
}
+
+ if p.props.Src != nil {
+ src := PathForModuleSrc(ctx, *p.props.Src)
+ if src != nil {
+ p.src = src.String()
+ p.rel = src.Rel()
+ }
+ }
+
+ p.missingDeps = ctx.GetMissingDependencies()
+}
+
+type pathForModuleSrcTestCase struct {
+ name string
+ bp string
+ srcs []string
+ rels []string
+ src string
+ rel string
+}
+
+func testPathForModuleSrc(t *testing.T, buildDir string, tests []pathForModuleSrcTestCase) {
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ config := TestConfig(buildDir, nil)
+ ctx := NewTestContext()
+
+ ctx.RegisterModuleType("test", ModuleFactoryAdaptor(pathForModuleSrcTestModuleFactory))
+ ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory))
+
+ fgBp := `
+ filegroup {
+ name: "a",
+ srcs: ["src/a"],
+ }
+ `
+
+ mockFS := map[string][]byte{
+ "fg/Android.bp": []byte(fgBp),
+ "foo/Android.bp": []byte(test.bp),
+ "fg/src/a": nil,
+ "foo/src/b": nil,
+ "foo/src/c": nil,
+ "foo/src/d": nil,
+ "foo/src/e/e": nil,
+ "foo/src_special/$": nil,
+ }
+
+ ctx.MockFileSystem(mockFS)
+
+ ctx.Register()
+ _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp"})
+ FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ FailIfErrored(t, errs)
+
+ m := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
+
+ if g, w := m.srcs, test.srcs; !reflect.DeepEqual(g, w) {
+ t.Errorf("want srcs %q, got %q", w, g)
+ }
+
+ if g, w := m.rels, test.rels; !reflect.DeepEqual(g, w) {
+ t.Errorf("want rels %q, got %q", w, g)
+ }
+
+ if g, w := m.src, test.src; g != w {
+ t.Errorf("want src %q, got %q", w, g)
+ }
+
+ if g, w := m.rel, test.rel; g != w {
+ t.Errorf("want rel %q, got %q", w, g)
+ }
+ })
+ }
}
-func TestExpandSources(t *testing.T) {
- tests := []struct {
- name string
- bp string
- srcs []string
- rels []string
- }{
+func TestPathsForModuleSrc(t *testing.T) {
+ tests := []pathForModuleSrcTestCase{
{
name: "path",
bp: `
@@ -782,57 +873,118 @@
},
}
+ buildDir, err := ioutil.TempDir("", "soong_paths_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",
+ bp: `
+ test {
+ name: "foo",
+ src: "src/b",
+ }`,
+ src: "foo/src/b",
+ rel: "src/b",
+ },
+ {
+ name: "glob",
+ bp: `
+ test {
+ name: "foo",
+ src: "src/e/*",
+ }`,
+ src: "foo/src/e/e",
+ rel: "src/e/e",
+ },
+ {
+ name: "filegroup",
+ bp: `
+ test {
+ name: "foo",
+ src: ":a",
+ }`,
+ src: "fg/src/a",
+ rel: "src/a",
+ },
+ {
+ name: "special characters glob",
+ bp: `
+ test {
+ name: "foo",
+ src: "src_special/*",
+ }`,
+ src: "foo/src_special/$",
+ rel: "src_special/$",
+ },
+ }
+
buildDir, err := ioutil.TempDir("", "soong_path_for_module_src_test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(buildDir)
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- config := TestConfig(buildDir, nil)
- ctx := NewTestContext()
+ testPathForModuleSrc(t, buildDir, tests)
+}
- ctx.RegisterModuleType("test", ModuleFactoryAdaptor(expandSourcesTestModuleFactory))
- ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory))
-
- fgBp := `
- filegroup {
- name: "a",
- srcs: ["src/a"],
- }
- `
-
- mockFS := map[string][]byte{
- "fg/Android.bp": []byte(fgBp),
- "foo/Android.bp": []byte(test.bp),
- "fg/src/a": nil,
- "foo/src/b": nil,
- "foo/src/c": nil,
- "foo/src/d": nil,
- "foo/src/e/e": nil,
- "foo/src_special/$": nil,
- }
-
- ctx.MockFileSystem(mockFS)
-
- ctx.Register()
- _, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp"})
- FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- FailIfErrored(t, errs)
-
- m := ctx.ModuleForTests("foo", "").Module().(*expandSourcesTestModule)
-
- if g, w := m.srcs.Strings(), test.srcs; !reflect.DeepEqual(g, w) {
- t.Errorf("want srcs %q, got %q", w, g)
- }
-
- if g, w := m.rels, test.rels; !reflect.DeepEqual(g, w) {
- t.Errorf("want rels %q, got %q", w, g)
- }
- })
+func TestPathsForModuleSrc_AllowMissingDependencies(t *testing.T) {
+ buildDir, err := ioutil.TempDir("", "soong_paths_for_module_src_allow_missing_dependencies_test")
+ if err != nil {
+ t.Fatal(err)
}
+ defer os.RemoveAll(buildDir)
+
+ config := TestConfig(buildDir, nil)
+ config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
+
+ ctx := NewTestContext()
+ ctx.SetAllowMissingDependencies(true)
+
+ ctx.RegisterModuleType("test", ModuleFactoryAdaptor(pathForModuleSrcTestModuleFactory))
+
+ bp := `
+ test {
+ name: "foo",
+ srcs: [":a"],
+ exclude_srcs: [":b"],
+ src: ":c",
+ }
+ `
+
+ mockFS := map[string][]byte{
+ "Android.bp": []byte(bp),
+ }
+
+ ctx.MockFileSystem(mockFS)
+
+ ctx.Register()
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ FailIfErrored(t, errs)
+
+ foo := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)
+
+ if g, w := foo.missingDeps, []string{"a", "b", "c"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("want missing deps %q, got %q", w, g)
+ }
+
+ if g, w := foo.srcs, []string{}; !reflect.DeepEqual(g, w) {
+ t.Errorf("want srcs %q, got %q", w, g)
+ }
+
+ if g, w := foo.src, ""; g != w {
+ t.Errorf("want src %q, got %q", w, g)
+ }
+
}
func ExampleOutputPath_ReplaceExtension() {
diff --git a/android/prebuilt.go b/android/prebuilt.go
index ea4870d..5bd0e2d 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -61,7 +61,7 @@
// Return the singleton source after expanding any filegroup in the
// sources.
- return ctx.ExpandSource((*p.srcs)[0], "")
+ return PathForModuleSrc(ctx, (*p.srcs)[0])
}
func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index 0c68b0c..2a3e07e 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -88,7 +88,7 @@
}
func (p *PrebuiltEtc) SourceFilePath(ctx ModuleContext) Path {
- return ctx.ExpandSource(String(p.properties.Src), "src")
+ return PathForModuleSrc(ctx, String(p.properties.Src))
}
// This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
@@ -110,7 +110,7 @@
}
func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) {
- p.sourceFilePath = ctx.ExpandSource(String(p.properties.Src), "src")
+ p.sourceFilePath = PathForModuleSrc(ctx, String(p.properties.Src))
filename := String(p.properties.Filename)
filename_from_src := Bool(p.properties.Filename_from_src)
if filename == "" {
diff --git a/android/sh_binary.go b/android/sh_binary.go
index 8bb3517..bee61ef 100644
--- a/android/sh_binary.go
+++ b/android/sh_binary.go
@@ -82,7 +82,7 @@
}
func (s *ShBinary) SourceFilePath(ctx ModuleContext) Path {
- return ctx.ExpandSource(String(s.properties.Src), "src")
+ return PathForModuleSrc(ctx, String(s.properties.Src))
}
func (s *ShBinary) OutputFile() OutputPath {
@@ -98,7 +98,7 @@
}
func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
- s.sourceFilePath = ctx.ExpandSource(String(s.properties.Src), "src")
+ s.sourceFilePath = PathForModuleSrc(ctx, String(s.properties.Src))
filename := String(s.properties.Filename)
filename_from_src := Bool(s.properties.Filename_from_src)
if filename == "" {
diff --git a/apex/apex.go b/apex/apex.go
index 04b70d4..ad1ef74 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -839,7 +839,7 @@
a.container_private_key_file = key
}
- manifest := ctx.ExpandSource(proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"), "manifest")
+ manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
var abis []string
for _, target := range ctx.MultiTargets() {
@@ -936,7 +936,7 @@
}
if a.properties.AndroidManifest != nil {
- androidManifestFile := ctx.ExpandSource(proptools.String(a.properties.AndroidManifest), "androidManifest")
+ androidManifestFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.AndroidManifest))
implicitInputs = append(implicitInputs, androidManifestFile)
optFlags = append(optFlags, "--android_manifest "+androidManifestFile.String())
}
@@ -1015,7 +1015,7 @@
if a.installable() {
// For flattened APEX, do nothing but make sure that apex_manifest.json file is also copied along
// with other ordinary files.
- manifest := ctx.ExpandSource(proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"), "manifest")
+ manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
// rename to apex_manifest.json
copiedManifest := android.PathForModuleOut(ctx, "apex_manifest.json")
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 01e98f1..073f62d 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -76,7 +76,7 @@
cflags = append(cflags, bpf.properties.Cflags...)
- srcs := ctx.ExpandSources(bpf.properties.Srcs, nil)
+ srcs := android.PathsForModuleSrc(ctx, bpf.properties.Srcs)
for _, src := range srcs {
obj := android.ObjPathWithExt(ctx, "", src, "o")
diff --git a/cc/binary.go b/cc/binary.go
index cae1739..7f7c600 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -384,7 +384,7 @@
TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs,
deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
- builderFlags, outputFile)
+ builderFlags, outputFile, nil)
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
diff --git a/cc/builder.go b/cc/builder.go
index 97ae806..dab887c 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -26,6 +26,7 @@
"strings"
"github.com/google/blueprint"
+ "github.com/google/blueprint/pathtools"
"android/soong/android"
"android/soong/cc/config"
@@ -597,7 +598,7 @@
// and shared libraries, to a shared library (.so) or dynamic executable
func TransformObjToDynamicBinary(ctx android.ModuleContext,
objFiles, sharedLibs, staticLibs, lateStaticLibs, wholeStaticLibs, deps android.Paths,
- crtBegin, crtEnd android.OptionalPath, groupLate bool, flags builderFlags, outputFile android.WritablePath) {
+ crtBegin, crtEnd android.OptionalPath, groupLate bool, flags builderFlags, outputFile android.WritablePath, implicitOutputs android.WritablePaths) {
ldCmd := "${config.ClangBin}/clang++"
@@ -634,7 +635,11 @@
}
for _, lib := range sharedLibs {
- libFlagsList = append(libFlagsList, lib.String())
+ libFile := lib.String()
+ if ctx.Windows() {
+ libFile = pathtools.ReplaceExtension(libFile, "a")
+ }
+ libFlagsList = append(libFlagsList, libFile)
}
deps = append(deps, staticLibs...)
@@ -645,11 +650,12 @@
}
ctx.Build(pctx, android.BuildParams{
- Rule: ld,
- Description: "link " + outputFile.Base(),
- Output: outputFile,
- Inputs: objFiles,
- Implicits: deps,
+ Rule: ld,
+ Description: "link " + outputFile.Base(),
+ Output: outputFile,
+ ImplicitOutputs: implicitOutputs,
+ Inputs: objFiles,
+ Implicits: deps,
Args: map[string]string{
"ldCmd": ldCmd,
"crtBegin": crtBegin.String(),
diff --git a/cc/compiler.go b/cc/compiler.go
index df396e8..0ab1f01 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -256,7 +256,7 @@
func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
tc := ctx.toolchain()
- compiler.srcsBeforeGen = ctx.ExpandSources(compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
+ compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
CheckBadCompilerFlags(ctx, "cflags", compiler.Properties.Cflags)
diff --git a/cc/library.go b/cc/library.go
index 5df5112..7216832 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -347,9 +347,10 @@
)
}
} else {
- f = append(f,
- "-shared",
- "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
+ f = append(f, "-shared")
+ if !ctx.Windows() {
+ f = append(f, "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
+ }
}
flags.LdFlags = append(f, flags.LdFlags...)
@@ -450,11 +451,11 @@
buildFlags := flagsToBuilderFlags(flags)
if library.static() {
- srcs := ctx.ExpandSources(library.Properties.Static.Srcs, nil)
+ srcs := android.PathsForModuleSrc(ctx, library.Properties.Static.Srcs)
objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary,
srcs, library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
} else if library.shared() {
- srcs := ctx.ExpandSources(library.Properties.Shared.Srcs, nil)
+ srcs := android.PathsForModuleSrc(ctx, library.Properties.Shared.Srcs)
objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary,
srcs, library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
}
@@ -673,6 +674,14 @@
outputFile := android.PathForModuleOut(ctx, fileName)
ret := outputFile
+ var implicitOutputs android.WritablePaths
+ if ctx.Windows() {
+ importLibraryPath := android.PathForModuleOut(ctx, pathtools.ReplaceExtension(fileName, "a"))
+
+ flags.LdFlags = append(flags.LdFlags, "-Wl,--out-implib="+importLibraryPath.String())
+ implicitOutputs = append(implicitOutputs, importLibraryPath)
+ }
+
builderFlags := flagsToBuilderFlags(flags)
// Optimize out relinking against shared libraries whose interface hasn't changed by
@@ -724,7 +733,7 @@
TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
- linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile)
+ linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs)
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
diff --git a/cc/linker.go b/cc/linker.go
index fd958ba..179a998 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -290,10 +290,6 @@
if ctx.Darwin() {
return false
}
- // http://b/110800681 - lld cannot link Android's Windows modules yet.
- if ctx.Windows() {
- return false
- }
if linker.Properties.Use_clang_lld != nil {
return Bool(linker.Properties.Use_clang_lld)
}
@@ -347,7 +343,7 @@
// darwin defaults to treating undefined symbols as errors
flags.LdFlags = append(flags.LdFlags, "-Wl,-undefined,dynamic_lookup")
}
- } else if !ctx.Darwin() {
+ } else if !ctx.Darwin() && !ctx.Windows() {
flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
}
@@ -384,7 +380,7 @@
flags.LdFlags = append(flags.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...)
- if ctx.Host() {
+ if ctx.Host() && !ctx.Windows() {
rpath_prefix := `\$$ORIGIN/`
if ctx.Darwin() {
rpath_prefix = "@loader_path/"
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index 2024180..5e45c1a 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -90,7 +90,7 @@
properties headerProperties
installPaths android.Paths
- licensePath android.ModuleSrcPath
+ licensePath android.Path
}
func getHeaderInstallDir(ctx android.ModuleContext, header android.Path, from string,
@@ -140,7 +140,7 @@
return
}
- srcFiles := ctx.ExpandSources(m.properties.Srcs, m.properties.Exclude_srcs)
+ srcFiles := android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
for _, header := range srcFiles {
installDir := getHeaderInstallDir(ctx, header, String(m.properties.From),
String(m.properties.To))
@@ -204,7 +204,7 @@
properties versionedHeaderProperties
installPaths android.Paths
- licensePath android.ModuleSrcPath
+ licensePath android.Path
}
func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -232,7 +232,8 @@
processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, srcFiles, installPaths)
}
-func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path, srcFiles android.Paths, installPaths []android.WritablePath) android.Path {
+func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path,
+ srcFiles android.Paths, installPaths []android.WritablePath) android.Path {
// The versioner depends on a dependencies directory to simplify determining include paths
// when parsing headers. This directory contains architecture specific directories as well
// as a common directory, each of which contains symlinks to the actually directories to
@@ -326,7 +327,7 @@
properties preprocessedHeadersProperties
installPaths android.Paths
- licensePath android.ModuleSrcPath
+ licensePath android.Path
}
func (m *preprocessedHeadersModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -337,7 +338,7 @@
preprocessor := android.PathForModuleSrc(ctx, String(m.properties.Preprocessor))
m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License))
- srcFiles := ctx.ExpandSources(m.properties.Srcs, m.properties.Exclude_srcs)
+ srcFiles := android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
installDir := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To))
for _, src := range srcFiles {
installPath := installDir.Join(ctx, src.Base())
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 7297718..26418ad 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -35,7 +35,11 @@
asanLdflags = []string{"-Wl,-u,__asan_preinit"}
asanLibs = []string{"libasan"}
- hwasanCflags = []string{"-fno-omit-frame-pointer", "-Wno-frame-larger-than=", "-mllvm", "-hwasan-create-frame-descriptions=0"}
+ // TODO(pcc): Stop passing -hwasan-allow-ifunc here once it has been made
+ // the default.
+ hwasanCflags = []string{"-fno-omit-frame-pointer", "-Wno-frame-larger-than=",
+ "-mllvm", "-hwasan-create-frame-descriptions=0",
+ "-mllvm", "-hwasan-allow-ifunc"}
cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso",
"-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blacklist.txt"}
@@ -50,12 +54,7 @@
intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
- // Pass -Xclang before -fsanitize-minimal-runtime to work around a driver
- // check which rejects -fsanitize-minimal-runtime together with
- // -fsanitize=shadow-call-stack even though this combination of flags
- // is valid.
- // TODO(pcc): Remove the -Xclang once LLVM r346526 is rolled into the compiler.
- minimalRuntimeFlags = []string{"-Xclang", "-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
+ minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
"-fno-sanitize-recover=integer,undefined"}
hwasanGlobalOptions = []string{"heap_history_size=1023,stack_history_size=512"}
)
@@ -312,10 +311,7 @@
}
// SCS is only implemented on AArch64.
- // We also disable SCS if ASAN, TSAN or HWASAN are enabled because Clang considers
- // them to be incompatible, although they are in fact compatible.
- // TODO(pcc): Remove these checks once r347282 is rolled into the compiler.
- if ctx.Arch().ArchType != android.Arm64 || Bool(s.Address) || Bool(s.Thread) || Bool(s.Hwaddress) {
+ if ctx.Arch().ArchType != android.Arm64 {
s.Scs = nil
}
diff --git a/cc/test.go b/cc/test.go
index f0274e9..c3fadbd 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -253,7 +253,7 @@
}
func (test *testBinary) install(ctx ModuleContext, file android.Path) {
- test.data = ctx.ExpandSources(test.Properties.Data, nil)
+ test.data = android.PathsForModuleSrc(ctx, test.Properties.Data)
optionsMap := map[string]string{}
if Bool(test.testDecorator.Properties.Isolated) {
optionsMap["not-shardable"] = "true"
@@ -378,7 +378,7 @@
}
func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Path) {
- benchmark.data = ctx.ExpandSources(benchmark.Properties.Data, nil)
+ benchmark.data = android.PathsForModuleSrc(ctx, benchmark.Properties.Data)
benchmark.testConfig = tradefed.AutoGenNativeBenchmarkTestConfig(ctx, benchmark.Properties.Test_config,
benchmark.Properties.Test_config_template, benchmark.Properties.Test_suites)
diff --git a/cc/test_data_test.go b/cc/test_data_test.go
index 7ba244e..21ea765 100644
--- a/cc/test_data_test.go
+++ b/cc/test_data_test.go
@@ -178,5 +178,5 @@
}
func (test *testDataTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- test.data = ctx.ExpandSources(test.Properties.Data, nil)
+ test.data = android.PathsForModuleSrc(ctx, test.Properties.Data)
}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index f265eb6..c8be61a 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -225,14 +225,14 @@
}
for _, toolFile := range g.properties.Tool_files {
- paths := ctx.ExpandSources([]string{toolFile}, nil)
+ paths := android.PathsForModuleSrc(ctx, []string{toolFile})
g.deps = append(g.deps, paths...)
addLocationLabel(toolFile, paths.Strings())
}
var srcFiles android.Paths
for _, in := range g.properties.Srcs {
- paths := ctx.ExpandSources([]string{in}, g.properties.Exclude_srcs)
+ paths := android.PathsForModuleSrcExcludes(ctx, []string{in}, g.properties.Exclude_srcs)
srcFiles = append(srcFiles, paths...)
addLocationLabel(in, paths.Strings())
}
diff --git a/java/aapt2.go b/java/aapt2.go
index d217b9f..bcc8e97 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -161,7 +161,7 @@
func aapt2Link(ctx android.ModuleContext,
packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath,
flags []string, deps android.Paths,
- compiledRes, compiledOverlay android.Paths) {
+ compiledRes, compiledOverlay android.Paths, splitPackages android.WritablePaths) {
genDir := android.PathForModuleGen(ctx, "aapt2", "R")
@@ -196,12 +196,14 @@
inFlags = append(inFlags, "-R", "@"+overlayFileList.String())
}
+ implicitOutputs := append(splitPackages, proguardOptions, genJar, rTxt, extraPackages)
+
ctx.Build(pctx, android.BuildParams{
Rule: aapt2LinkRule,
Description: "aapt2 link",
Implicits: deps,
Output: packageRes,
- ImplicitOutputs: android.WritablePaths{proguardOptions, genJar, rTxt, extraPackages},
+ ImplicitOutputs: implicitOutputs,
Args: map[string]string{
"flags": strings.Join(flags, " "),
"inFlags": strings.Join(inFlags, " "),
diff --git a/java/aar.go b/java/aar.go
index 3f13e59..1a5ea4d 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -83,9 +83,18 @@
useEmbeddedDex bool
usesNonSdkApis bool
+ splitNames []string
+ splits []split
+
aaptProperties aaptProperties
}
+type split struct {
+ name string
+ suffix string
+ path android.Path
+}
+
func (a *aapt) ExportPackage() android.Path {
return a.exportPackage
}
@@ -121,7 +130,7 @@
// Find implicit or explicit asset and resource dirs
assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
- resourceZips := ctx.ExpandSources(a.aaptProperties.Resource_zips, nil)
+ resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
var linkDeps android.Paths
@@ -248,8 +257,23 @@
compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files).Paths()...)
}
+ var splitPackages android.WritablePaths
+ var splits []split
+
+ for _, s := range a.splitNames {
+ suffix := strings.Replace(s, ",", "_", -1)
+ path := android.PathForModuleOut(ctx, "package_"+suffix+".apk")
+ linkFlags = append(linkFlags, "--split", path.String()+":"+s)
+ splitPackages = append(splitPackages, path)
+ splits = append(splits, split{
+ name: s,
+ suffix: suffix,
+ path: path,
+ })
+ }
+
aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
- linkFlags, linkDeps, compiledRes, compiledOverlay)
+ linkFlags, linkDeps, compiledRes, compiledOverlay, splitPackages)
a.aaptSrcJar = srcJar
a.exportPackage = packageRes
@@ -258,6 +282,7 @@
a.rroDirs = rroDirs
a.extraAaptPackagesFile = extraPackages
a.rTxt = rTxt
+ a.splits = splits
}
// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
@@ -564,7 +589,7 @@
overlayRes := append(android.Paths{flata}, transitiveStaticLibs...)
aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile,
- linkFlags, linkDeps, nil, overlayRes)
+ linkFlags, linkDeps, nil, overlayRes, nil)
}
var _ Dependency = (*AARImport)(nil)
diff --git a/java/androidmk.go b/java/androidmk.go
index 04b328d..0c3b1c7 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -131,6 +131,28 @@
}
}
+func (prebuilt *DexImport) AndroidMk() android.AndroidMkData {
+ return android.AndroidMkData{
+ Class: "JAVA_LIBRARIES",
+ OutputFile: android.OptionalPathForPath(prebuilt.maybeStrippedDexJarFile),
+ Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
+ Extra: []android.AndroidMkExtraFunc{
+ func(w io.Writer, outputFile android.Path) {
+ if prebuilt.dexJarFile != nil {
+ fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", prebuilt.dexJarFile.String())
+ // TODO(b/125517186): export the dex jar as a classes jar to match some mis-uses in Make until
+ // boot_jars_package_check.mk can check dex jars.
+ fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", prebuilt.dexJarFile.String())
+ fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", prebuilt.dexJarFile.String())
+ }
+ if len(prebuilt.dexpreopter.builtInstalled) > 0 {
+ fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", prebuilt.dexpreopter.builtInstalled)
+ }
+ },
+ },
+ }
+}
+
func (prebuilt *AARImport) AndroidMk() android.AndroidMkData {
return android.AndroidMkData{
Class: "JAVA_LIBRARIES",
@@ -262,6 +284,10 @@
if len(app.dexpreopter.builtInstalled) > 0 {
fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", app.dexpreopter.builtInstalled)
}
+ for _, split := range app.aapt.splits {
+ install := "$(LOCAL_MODULE_PATH)/" + strings.TrimSuffix(app.installApkName, ".apk") + split.suffix + ".apk"
+ fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED +=", split.path.String()+":"+install)
+ }
},
},
}
diff --git a/java/app.go b/java/app.go
index 8a422fc..8f5d010 100644
--- a/java/app.go
+++ b/java/app.go
@@ -226,6 +226,8 @@
aaptLinkFlags = append(aaptLinkFlags, a.additionalAaptFlags...)
+ a.aapt.splitNames = a.appProperties.Package_splits
+
a.aapt.buildActions(ctx, sdkContext(a), aaptLinkFlags...)
// apps manifests are handled by aapt, don't let Module see them
@@ -341,19 +343,32 @@
CreateAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates)
a.outputFile = packageFile
+ for _, split := range a.aapt.splits {
+ // Sign the split APKs
+ packageFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"_"+split.suffix+".apk")
+ CreateAppPackage(ctx, packageFile, split.path, nil, nil, certificates)
+ a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
+ }
+
// Build an app bundle.
bundleFile := android.PathForModuleOut(ctx, "base.zip")
BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile)
a.bundleFile = bundleFile
// Install the app package.
+ var installDir android.OutputPath
if ctx.ModuleName() == "framework-res" {
// framework-res.apk is installed as system/framework/framework-res.apk
- ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".apk", a.outputFile)
+ installDir = android.PathForModuleInstall(ctx, "framework")
} else if Bool(a.appProperties.Privileged) {
- ctx.InstallFile(android.PathForModuleInstall(ctx, "priv-app", a.installApkName), a.installApkName+".apk", a.outputFile)
+ installDir = android.PathForModuleInstall(ctx, "priv-app", a.installApkName)
} else {
- ctx.InstallFile(android.PathForModuleInstall(ctx, "app", a.installApkName), a.installApkName+".apk", a.outputFile)
+ installDir = android.PathForModuleInstall(ctx, "app", a.installApkName)
+ }
+
+ ctx.InstallFile(installDir, a.installApkName+".apk", a.outputFile)
+ for _, split := range a.aapt.splits {
+ ctx.InstallFile(installDir, a.installApkName+"_"+split.suffix+".apk", split.path)
}
}
@@ -455,7 +470,7 @@
a.generateAndroidBuildActions(ctx)
a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites)
- a.data = ctx.ExpandSources(a.testProperties.Data, nil)
+ a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
}
func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/java/app_builder.go b/java/app_builder.go
index bc91d55..e5ccbbc 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -65,7 +65,8 @@
func CreateAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate) {
- unsignedApk := android.PathForModuleOut(ctx, "unsigned.apk")
+ unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
+ unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
var inputs android.Paths
if dexJarFile != nil {
diff --git a/java/app_test.go b/java/app_test.go
index 1784fc3..3942ecd 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -106,6 +106,30 @@
}
}
+func TestAppSplits(t *testing.T) {
+ ctx := testApp(t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ package_splits: ["v4", "v7,hdpi"],
+ }`)
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ expectedOutputs := []string{
+ filepath.Join(buildDir, ".intermediates/foo/android_common/foo.apk"),
+ filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v4.apk"),
+ filepath.Join(buildDir, ".intermediates/foo/android_common/foo_v7_hdpi.apk"),
+ }
+ for _, expectedOutput := range expectedOutputs {
+ 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)
+ }
+}
+
func TestResourceDirs(t *testing.T) {
testCases := []struct {
name string
diff --git a/java/config/config.go b/java/config/config.go
index 2762a4d..3452a1d 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -41,6 +41,7 @@
"services",
"android.car",
"android.car7",
+ "conscrypt",
"core-oj",
"core-libart",
}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 64de21a..a23b477 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -152,7 +152,7 @@
ctx.VisitAllModules(func(module android.Module) {
// Collect dex jar paths for the modules listed above.
- if j, ok := module.(Dependency); ok {
+ if j, ok := module.(interface{ DexJar() android.Path }); ok {
name := ctx.ModuleName(module)
if i := android.IndexList(name, image.modules); i != -1 {
bootDexJars[i] = j.DexJar()
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index c99540d..141f7ba 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -37,13 +37,18 @@
srcs: ["b.java"],
installable: true,
}
+
+ dex_import {
+ name: "baz",
+ jars: ["a.jar"],
+ }
`
config := testConfig(nil)
pathCtx := android.PathContextForTesting(config, nil)
dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
- dexpreoptConfig.RuntimeApexJars = []string{"foo", "bar"}
+ dexpreoptConfig.RuntimeApexJars = []string{"foo", "bar", "baz"}
setDexpreoptTestGlobalConfig(config, dexpreoptConfig)
ctx := testContext(config, bp, nil)
@@ -59,6 +64,7 @@
expectedInputs := []string{
"dex_bootjars_input/foo.jar",
"dex_bootjars_input/bar.jar",
+ "dex_bootjars_input/baz.jar",
}
for i := range expectedInputs {
@@ -78,15 +84,19 @@
"dex_bootjars/system/framework/arm64/boot.art",
"dex_bootjars/system/framework/arm64/boot-bar.art",
+ "dex_bootjars/system/framework/arm64/boot-baz.art",
"dex_bootjars/system/framework/arm64/boot.oat",
"dex_bootjars/system/framework/arm64/boot-bar.oat",
+ "dex_bootjars/system/framework/arm64/boot-baz.oat",
"dex_bootjars/system/framework/arm64/boot.vdex",
"dex_bootjars/system/framework/arm64/boot-bar.vdex",
+ "dex_bootjars/system/framework/arm64/boot-baz.vdex",
"dex_bootjars_unstripped/system/framework/arm64/boot.oat",
"dex_bootjars_unstripped/system/framework/arm64/boot-bar.oat",
+ "dex_bootjars_unstripped/system/framework/arm64/boot-baz.oat",
}
for i := range expectedOutputs {
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index 6838bd2..4af2f5c 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -119,6 +119,15 @@
}`,
enabled: false,
},
+ {
+ name: "dex_import",
+ bp: `
+ dex_import {
+ name: "foo",
+ jars: ["a.jar"],
+ }`,
+ enabled: true,
+ },
}
for _, test := range tests {
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 777cd9c..e163617 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -696,7 +696,7 @@
})
// do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
// may contain filegroup or genrule.
- srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
+ srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
flags := j.collectAidlFlags(ctx, deps)
srcFiles = j.genSources(ctx, srcFiles, flags)
@@ -715,12 +715,12 @@
}
j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
- j.argFiles = ctx.ExpandSources(j.properties.Arg_files, nil)
+ j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
argFilesMap := map[string]string{}
argFileLabels := []string{}
for _, label := range j.properties.Arg_files {
- var paths = ctx.ExpandSources([]string{label}, nil)
+ var paths = android.PathsForModuleSrc(ctx, []string{label})
if _, exists := argFilesMap[label]; !exists {
argFilesMap[label] = strings.Join(paths.Strings(), " ")
argFileLabels = append(argFileLabels, label)
@@ -935,22 +935,22 @@
})
if len(d.properties.Html_dirs) > 0 {
- htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
- *implicits = append(*implicits, ctx.Glob(htmlDir.Join(ctx, "**/*").String(), nil)...)
- args = args + " -htmldir " + htmlDir.String()
+ htmlDir := d.properties.Html_dirs[0]
+ *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")})...)
+ args = args + " -htmldir " + htmlDir
}
if len(d.properties.Html_dirs) > 1 {
- htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
- *implicits = append(*implicits, ctx.Glob(htmlDir2.Join(ctx, "**/*").String(), nil)...)
- args = args + " -htmldir2 " + htmlDir2.String()
+ htmlDir2 := d.properties.Html_dirs[1]
+ *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(htmlDir2, "**/*")})...)
+ args = args + " -htmldir2 " + htmlDir2
}
if len(d.properties.Html_dirs) > 2 {
ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
}
- knownTags := ctx.ExpandSources(d.properties.Knowntags, nil)
+ knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
*implicits = append(*implicits, knownTags...)
for _, kt := range knownTags {
@@ -1415,12 +1415,12 @@
"has to be non-empty if annotations was enabled (unless validating nullability)")
}
if migratingNullability {
- previousApi := ctx.ExpandSource(String(d.properties.Previous_api), "previous_api")
+ previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
*implicits = append(*implicits, previousApi)
flags += " --migrate-nullness " + previousApi.String()
}
if s := String(d.properties.Validate_nullability_from_list); s != "" {
- flags += " --validate-nullability-from-list " + ctx.ExpandSource(s, "validate_nullability_from_list").String()
+ flags += " --validate-nullability-from-list " + android.PathForModuleSrc(ctx, s).String()
}
if validatingNullability {
d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
@@ -1791,9 +1791,9 @@
func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- path := android.PathForModuleSrc(ctx, String(d.properties.Path))
- d.dir = path
- d.deps = ctx.Glob(path.Join(ctx, "**/*").String(), nil)
+ path := String(d.properties.Path)
+ d.dir = android.PathForModuleSrc(ctx, path)
+ d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
}
//
diff --git a/java/java.go b/java/java.go
index dcd6dbe..e0da006 100644
--- a/java/java.go
+++ b/java/java.go
@@ -46,6 +46,7 @@
android.RegisterModuleType("java_import_host", ImportFactoryHost)
android.RegisterModuleType("java_device_for_host", DeviceForHostFactory)
android.RegisterModuleType("java_host_for_device", HostForDeviceFactory)
+ android.RegisterModuleType("dex_import", DexImportFactory)
android.RegisterSingletonType("logtags", LogtagsSingleton)
}
@@ -288,7 +289,8 @@
proguardDictionary android.Path
// output file of the module, which may be a classes jar or a dex jar
- outputFile android.Path
+ outputFile android.Path
+ extraOutputFiles android.Paths
exportAidlIncludeDirs android.Paths
@@ -322,7 +324,7 @@
}
func (j *Module) Srcs() android.Paths {
- return android.Paths{j.outputFile}
+ return append(android.Paths{j.outputFile}, j.extraOutputFiles...)
}
func (j *Module) DexJarFile() android.Path {
@@ -940,7 +942,7 @@
if flags.javaVersion == "1.9" {
j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
}
- srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
+ srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
if hasSrcExt(srcFiles.Strings(), ".proto") {
flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
}
@@ -956,7 +958,7 @@
j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.Strings()...)
if j.properties.Jarjar_rules != nil {
- j.expandJarjarRules = ctx.ExpandSource(*j.properties.Jarjar_rules, "jarjar_rules")
+ j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules)
}
jarName := ctx.ModuleName() + ".jar"
@@ -1131,10 +1133,10 @@
manifest := j.overrideManifest
if !manifest.Valid() && j.properties.Manifest != nil {
- manifest = android.OptionalPathForPath(ctx.ExpandSource(*j.properties.Manifest, "manifest"))
+ manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest))
}
- services := ctx.ExpandSources(j.properties.Services, nil)
+ services := android.PathsForModuleSrc(ctx, j.properties.Services)
if len(services) > 0 {
servicesJar := android.PathForModuleOut(ctx, "services", jarName)
var zipargs []string
@@ -1430,14 +1432,14 @@
Module
}
-func (j *Library) shouldUncompressDex(ctx android.ModuleContext) bool {
+func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
// Store uncompressed (and do not strip) dex files from boot class path jars.
if inList(ctx.ModuleName(), ctx.Config().BootJars()) {
return true
}
// Store uncompressed dex files that are preopted on /system.
- if !j.dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, j.dexpreopter.installPath)) {
+ if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) {
return true
}
if ctx.Config().UncompressPrivAppDex() &&
@@ -1452,7 +1454,7 @@
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
j.dexpreopter.isInstallable = Bool(j.properties.Installable)
- j.dexpreopter.uncompressedDex = j.shouldUncompressDex(ctx)
+ j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex
j.compile(ctx)
@@ -1545,7 +1547,7 @@
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template, j.testProperties.Test_suites)
- j.data = ctx.ExpandSources(j.testProperties.Data, nil)
+ j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
j.Library.GenerateAndroidBuildActions(ctx)
}
@@ -1639,7 +1641,7 @@
j.isWrapperVariant = true
if j.binaryProperties.Wrapper != nil {
- j.wrapperFile = ctx.ExpandSource(*j.binaryProperties.Wrapper, "wrapper")
+ j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper)
} else {
j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh")
}
@@ -1763,7 +1765,7 @@
}
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- jars := ctx.ExpandSources(j.properties.Jars, nil)
+ jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
jarName := ctx.ModuleName() + ".jar"
outputFile := android.PathForModuleOut(ctx, "combined", jarName)
@@ -1900,6 +1902,113 @@
return module
}
+// dex_import module
+
+type DexImportProperties struct {
+ Jars []string
+}
+
+type DexImport struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+ prebuilt android.Prebuilt
+
+ properties DexImportProperties
+
+ dexJarFile android.Path
+ maybeStrippedDexJarFile android.Path
+
+ dexpreopter
+}
+
+func (j *DexImport) Prebuilt() *android.Prebuilt {
+ return &j.prebuilt
+}
+
+func (j *DexImport) PrebuiltSrcs() []string {
+ return j.properties.Jars
+}
+
+func (j *DexImport) Name() string {
+ return j.prebuilt.Name(j.ModuleBase.Name())
+}
+
+func (j *DexImport) DepsMutator(ctx android.BottomUpMutatorContext) {
+ android.ExtractSourcesDeps(ctx, j.properties.Jars)
+}
+
+func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if len(j.properties.Jars) != 1 {
+ ctx.PropertyErrorf("jars", "exactly one jar must be provided")
+ }
+
+ j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", ctx.ModuleName()+".jar")
+ j.dexpreopter.isInstallable = true
+ j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
+
+ inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
+ dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar")
+
+ if j.dexpreopter.uncompressedDex {
+ rule := android.NewRuleBuilder()
+
+ temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned")
+ rule.Temporary(temporary)
+
+ // use zip2zip to uncompress classes*.dex files
+ rule.Command().
+ Tool(ctx.Config().HostToolPath(ctx, "zip2zip")).
+ FlagWithInput("-i ", inputJar).
+ FlagWithOutput("-o ", temporary).
+ FlagWithArg("-0 ", "'classes*.dex'")
+
+ // use zipalign to align uncompressed classes*.dex files
+ rule.Command().
+ Tool(ctx.Config().HostToolPath(ctx, "zipalign")).
+ Flag("-f").
+ Text("4").
+ Input(temporary).
+ Output(dexOutputFile)
+
+ rule.DeleteTemporaryFiles()
+
+ rule.Build(pctx, ctx, "uncompress_dex", "uncompress dex")
+ } else {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: inputJar,
+ Output: dexOutputFile,
+ })
+ }
+
+ j.dexJarFile = dexOutputFile
+
+ dexOutputFile = j.dexpreopt(ctx, dexOutputFile)
+
+ j.maybeStrippedDexJarFile = dexOutputFile
+
+ ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
+ ctx.ModuleName()+".jar", dexOutputFile)
+}
+
+func (j *DexImport) DexJar() android.Path {
+ return j.dexJarFile
+}
+
+// dex_import imports a `.jar` file containing classes.dex files.
+//
+// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed
+// to the device.
+func DexImportFactory() android.Module {
+ module := &DexImport{}
+
+ module.AddProperties(&module.properties)
+
+ android.InitPrebuiltModule(module, &module.properties.Jars)
+ InitJavaModule(module, android.DeviceSupported)
+ return module
+}
+
//
// Defaults
//
@@ -1962,6 +2071,7 @@
&ImportProperties{},
&AARImportProperties{},
&sdkLibraryProperties{},
+ &DexImportProperties{},
)
android.InitDefaultsModule(module)
diff --git a/java/java_resources.go b/java/java_resources.go
index 6c1fd39..7161168 100644
--- a/java/java_resources.go
+++ b/java/java_resources.go
@@ -39,20 +39,20 @@
var excludeFiles []string
for _, exclude := range excludeResourceDirs {
- dirs := ctx.Glob(android.PathForModuleSrc(ctx).Join(ctx, exclude).String(), nil)
+ dirs := ctx.Glob(android.PathForSource(ctx, ctx.ModuleDir()).Join(ctx, exclude).String(), nil)
for _, dir := range dirs {
excludeDirs = append(excludeDirs, dir.String())
- excludeFiles = append(excludeFiles, dir.(android.ModuleSrcPath).Join(ctx, "**/*").String())
+ excludeFiles = append(excludeFiles, dir.(android.SourcePath).Join(ctx, "**/*").String())
}
}
- excludeFiles = append(excludeFiles, ctx.ExpandSources(excludeResourceFiles, nil).Strings()...)
+ excludeFiles = append(excludeFiles, android.PathsForModuleSrc(ctx, excludeResourceFiles).Strings()...)
excludeFiles = append(excludeFiles, resourceExcludes...)
for _, resourceDir := range resourceDirs {
// resourceDir may be a glob, resolve it first
- dirs := ctx.Glob(android.PathForModuleSrc(ctx).Join(ctx, resourceDir).String(), excludeDirs)
+ dirs := ctx.Glob(android.PathForSource(ctx, ctx.ModuleDir()).Join(ctx, resourceDir).String(), excludeDirs)
for _, dir := range dirs {
files := ctx.GlobFiles(filepath.Join(dir.String(), "**/*"), excludeFiles)
@@ -96,7 +96,7 @@
func resourceFilesToJarArgs(ctx android.ModuleContext,
res, exclude []string) (args []string, deps android.Paths) {
- files := ctx.ExpandSources(res, exclude)
+ files := android.PathsForModuleSrcExcludes(ctx, res, exclude)
lastDir := ""
for i, f := range files {
diff --git a/java/java_test.go b/java/java_test.go
index 952da11..35dd696 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -79,6 +79,7 @@
ctx.RegisterModuleType("java_system_modules", android.ModuleFactoryAdaptor(SystemModulesFactory))
ctx.RegisterModuleType("java_genrule", android.ModuleFactoryAdaptor(genRuleFactory))
ctx.RegisterModuleType("java_plugin", android.ModuleFactoryAdaptor(PluginFactory))
+ ctx.RegisterModuleType("dex_import", android.ModuleFactoryAdaptor(DexImportFactory))
ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
ctx.RegisterModuleType("genrule", android.ModuleFactoryAdaptor(genrule.GenRuleFactory))
ctx.RegisterModuleType("droiddoc", android.ModuleFactoryAdaptor(DroiddocFactory))
@@ -330,6 +331,11 @@
name: "baz",
jars: ["b.jar"],
}
+
+ dex_import {
+ name: "qux",
+ jars: ["b.jar"],
+ }
`)
javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
@@ -344,6 +350,8 @@
if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != bazJar.String() {
t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, bazJar.String())
}
+
+ ctx.ModuleForTests("qux", "android_common").Rule("Cp")
}
func TestDefaults(t *testing.T) {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 6441c63..18866d5 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -675,6 +675,34 @@
if module.sdkLibraryProperties.Api_packages == nil {
mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
}
+
+ missing_current_api := false
+
+ for _, scope := range []string{"", "system-", "test-"} {
+ for _, api := range []string{"current.txt", "removed.txt"} {
+ path := path.Join(mctx.ModuleDir(), "api", scope+api)
+ p := android.ExistentPathForSource(mctx, path)
+ if !p.Valid() {
+ mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
+ missing_current_api = true
+ }
+ }
+ }
+
+ if missing_current_api {
+ script := "build/soong/scripts/gen-java-current-api-files.sh"
+ p := android.ExistentPathForSource(mctx, script)
+
+ if !p.Valid() {
+ panic(fmt.Sprintf("script file %s doesn't exist", script))
+ }
+
+ mctx.ModuleErrorf("One or more current api files are missing. "+
+ "You can update them by:\n"+
+ "%s %q && m update-api", script, mctx.ModuleDir())
+ return
+ }
+
// for public API stubs
module.createStubsLibrary(mctx, apiScopePublic)
module.createDocs(mctx, apiScopePublic)
diff --git a/python/python.go b/python/python.go
index 6d16020..6eb9b6e 100644
--- a/python/python.go
+++ b/python/python.go
@@ -414,7 +414,7 @@
panic(fmt.Errorf("unknown Python Actual_version: %q for module: %q.",
p.properties.Actual_version, ctx.ModuleName()))
}
- expandedSrcs := ctx.ExpandSources(srcs, exclude_srcs)
+ expandedSrcs := android.PathsForModuleSrcExcludes(ctx, srcs, exclude_srcs)
requiresSrcs := true
if p.bootstrapper != nil && !p.bootstrapper.autorun() {
requiresSrcs = false
@@ -424,7 +424,7 @@
}
// expand data files from "data" property.
- expandedData := ctx.ExpandSources(p.properties.Data, nil)
+ expandedData := android.PathsForModuleSrc(ctx, p.properties.Data)
// sanitize pkg_path.
pkgPath := String(p.properties.Pkg_path)
diff --git a/scripts/gen-java-current-api-files.sh b/scripts/gen-java-current-api-files.sh
new file mode 100755
index 0000000..517d391
--- /dev/null
+++ b/scripts/gen-java-current-api-files.sh
@@ -0,0 +1,33 @@
+#!/bin/bash -e
+
+# Copyright (C) 2019 The Android Open Source Project
+#
+# 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.
+
+if [[ -z "$1" ]]; then
+ echo "usage: $0 <modulePath>" >&2
+ exit 1
+fi
+
+api_dir=$1/api
+
+mkdir -p "$api_dir"
+
+scopes=("" system- test-)
+apis=(current removed)
+
+for scope in "${scopes[@]}"; do
+ for api in "${apis[@]}"; do
+ touch "${api_dir}/${scope}${api}.txt"
+ done
+done
diff --git a/xml/xml.go b/xml/xml.go
index d89327f..7c670fb 100644
--- a/xml/xml.go
+++ b/xml/xml.go
@@ -79,7 +79,7 @@
p.PrebuiltEtc.GenerateAndroidBuildActions(ctx)
if p.properties.Schema != nil {
- schema := ctx.ExpandSource(proptools.String(p.properties.Schema), "schema")
+ schema := android.PathForModuleSrc(ctx, proptools.String(p.properties.Schema))
switch schema.Ext() {
case ".dtd":