Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bcee1f4 authored by Colin Cross's avatar Colin Cross Committed by android-build-merger
Browse files

Replace ctx.ExpandSources with android.PathsForModuleSrc

am: 8a49795d

Change-Id: I42fc5461cff28f58039787b434527500d4e88eb6
parents 734ad216 8a49795d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ func FileGroupFactory() Module {
}

func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
	fg.srcs = ctx.ExpandSources(fg.properties.Srcs, fg.properties.Exclude_srcs)
	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))
+8 −81
Original line number Diff line number Diff line
@@ -854,7 +854,7 @@ func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)

		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)
		}
	}

@@ -1419,91 +1419,18 @@ type SourceFileProducer interface {

// 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 {
	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)
			globbedSrcFiles = PathsWithModuleSrcSubDir(ctx, globbedSrcFiles, "")
			expandedSrcFiles = append(expandedSrcFiles, globbedSrcFiles...)
		} else {
			p := PathForModuleSrc(ctx, s)
			j := findStringInSlice(p.String(), expandedExcludes)
			if j == -1 {
				expandedSrcFiles = append(expandedSrcFiles, p)
			}
		}
	}
	return expandedSrcFiles
	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.ExpandSources([]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
@@ -1511,7 +1438,7 @@ func (ctx *androidModuleContext) ExpandSource(srcFile, prop string) Path {
// 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{}
}
+120 −12
Original line number Diff line number Diff line
@@ -220,11 +220,104 @@ func ExistentPathsForSources(ctx PathContext, paths []string) Paths {
// 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))
	}

	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
	}
	return ret
}

// pathsForModuleSrcFromFullPath returns Paths rooted from the module's local
@@ -750,15 +843,30 @@ var _ resPathProvider = SourcePath{}

// PathForModuleSrc returns a Path representing the paths... under the
// module's local source directory.
func PathForModuleSrc(ctx ModuleContext, paths ...string) Path {
	path := pathForModuleSrc(ctx, paths...)

	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)
func PathForModuleSrc(ctx ModuleContext, pathComponents ...string) Path {
	p, err := validatePath(pathComponents...)
	if err != nil {
		reportPathError(ctx, err)
	}
	return path
	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]
}

func pathForModuleSrc(ctx ModuleContext, paths ...string) SourcePath {
+190 −50
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import (
	"testing"

	"github.com/google/blueprint/pathtools"
	"github.com/google/blueprint/proptools"
)

type strsTestCase struct {
@@ -706,39 +707,117 @@ func TestPathForSource(t *testing.T) {
	}
}

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()
}

func TestExpandSources(t *testing.T) {
	tests := []struct {
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 TestPathsForModuleSrc(t *testing.T) {
	tests := []pathForModuleSrcTestCase{
		{
			name: "path",
			bp: `
@@ -794,57 +873,118 @@ func TestExpandSources(t *testing.T) {
		},
	}

	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) {
	testPathForModuleSrc(t, buildDir, tests)
}

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(expandSourcesTestModuleFactory))
			ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory))
	ctx.RegisterModuleType("test", ModuleFactoryAdaptor(pathForModuleSrcTestModuleFactory))

			fgBp := `
				filegroup {
					name: "a",
					srcs: ["src/a"],
	bp := `
		test {
			name: "foo",
			srcs: [":a"],
			exclude_srcs: [":b"],
			src: ":c",
		}
	`

	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,
		"Android.bp": []byte(bp),
	}

	ctx.MockFileSystem(mockFS)

	ctx.Register()
			_, errs := ctx.ParseFileList(".", []string{"fg/Android.bp", "foo/Android.bp"})
	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
	FailIfErrored(t, errs)
	_, errs = ctx.PrepareBuildActions(config)
	FailIfErrored(t, errs)

			m := ctx.ModuleForTests("foo", "").Module().(*expandSourcesTestModule)
	foo := ctx.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule)

			if g, w := m.srcs.Strings(), test.srcs; !reflect.DeepEqual(g, w) {
				t.Errorf("want srcs %q, got %q", w, g)
	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 := m.rels, test.rels; !reflect.DeepEqual(g, w) {
				t.Errorf("want rels %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() {
+1 −1
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path {

	// 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) {
Loading