Add a new property trim_extension for gensrcs

In order to provide a more flexible ability for gensrcs's output, due to
current output_extension property will only allow to replace the string
after the last "." of input, in order to handle input with multiple dot
in file name, provide a way to trim the suffix of input string.

Bug: 335536003
Test: cd build/soong/genrule ; go test -run TestGenSrcs
Test: cd build/soong/genrule ; go test -run TestGenSrcsWithTrimExtAndOutpuExtension
Test: cd build/soong/genrule ; go test -run TestGenSrcsWithTrimExtButNoOutpuExtension
Test: cd build/soong/genrule ; go test -run TestGenSrcsWithOutpuExtension
Test: cd build/soong/android ; go test -run TestPathsForModuleSrc

Change-Id: I033bbe1d225f207f0f6bdc140df308884f214b51
This commit is contained in:
yangbill 2024-04-18 03:05:49 +00:00
parent a559cab24a
commit 6d032dd911
3 changed files with 187 additions and 2 deletions

View file

@ -277,6 +277,7 @@ type WritablePath interface {
type genPathProvider interface {
genPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleGenPath
genPathWithExtAndTrimExt(ctx ModuleOutPathContext, subdir, ext string, trimExt string) ModuleGenPath
}
type objPathProvider interface {
objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath
@ -295,6 +296,16 @@ func GenPathWithExt(ctx ModuleOutPathContext, subdir string, p Path, ext string)
return PathForModuleGen(ctx)
}
// GenPathWithExtAndTrimExt derives a new file path in ctx's generated sources directory
// from the current path, but with the new extension and trim the suffix.
func GenPathWithExtAndTrimExt(ctx ModuleOutPathContext, subdir string, p Path, ext string, trimExt string) ModuleGenPath {
if path, ok := p.(genPathProvider); ok {
return path.genPathWithExtAndTrimExt(ctx, subdir, ext, trimExt)
}
ReportPathErrorf(ctx, "Tried to create generated file from unsupported path: %s(%s)", reflect.TypeOf(p).Name(), p)
return PathForModuleGen(ctx)
}
// ObjPathWithExt derives a new file path in ctx's object directory from the
// current path, but with the new extension.
func ObjPathWithExt(ctx ModuleOutPathContext, subdir string, p Path, ext string) ModuleObjPath {
@ -1507,6 +1518,17 @@ func (p SourcePath) genPathWithExt(ctx ModuleOutPathContext, subdir, ext string)
return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
func (p SourcePath) genPathWithExtAndTrimExt(ctx ModuleOutPathContext, subdir, ext string, trimExt string) ModuleGenPath {
// If Trim_extension being set, force append Output_extension without replace original extension.
if trimExt != "" {
if ext != "" {
return PathForModuleGen(ctx, subdir, strings.TrimSuffix(p.path, trimExt)+"."+ext)
}
return PathForModuleGen(ctx, subdir, strings.TrimSuffix(p.path, trimExt))
}
return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
func (p SourcePath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath {
return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
@ -1594,6 +1616,17 @@ func (p ModuleGenPath) genPathWithExt(ctx ModuleOutPathContext, subdir, ext stri
return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
func (p ModuleGenPath) genPathWithExtAndTrimExt(ctx ModuleOutPathContext, subdir, ext string, trimExt string) ModuleGenPath {
// If Trim_extension being set, force append Output_extension without replace original extension.
if trimExt != "" {
if ext != "" {
return PathForModuleGen(ctx, subdir, strings.TrimSuffix(p.path, trimExt)+"."+ext)
}
return PathForModuleGen(ctx, subdir, strings.TrimSuffix(p.path, trimExt))
}
return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
func (p ModuleGenPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath {
return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}

View file

@ -714,13 +714,13 @@ func NewGenSrcs() *Module {
rule := getSandboxedRuleBuilder(ctx, android.NewRuleBuilder(pctx, ctx).Sbox(genDir, nil))
for _, in := range shard {
outFile := android.GenPathWithExt(ctx, finalSubDir, in, String(properties.Output_extension))
outFile := android.GenPathWithExtAndTrimExt(ctx, finalSubDir, in, String(properties.Output_extension), String(properties.Trim_extension))
// If sharding is enabled, then outFile is the path to the output file in
// the shard directory, and copyTo is the path to the output file in the
// final directory.
if len(shards) > 1 {
shardFile := android.GenPathWithExt(ctx, genSubDir, in, String(properties.Output_extension))
shardFile := android.GenPathWithExtAndTrimExt(ctx, genSubDir, in, String(properties.Output_extension), String(properties.Trim_extension))
copyTo = append(copyTo, outFile)
outFile = shardFile
}
@ -786,6 +786,9 @@ type genSrcsProperties struct {
// Additional files needed for build that are not tooling related.
Data []string `android:"path"`
// Trim the matched extension for each input file, and it should start with ".".
Trim_extension *string
}
const defaultShardSize = 50

View file

@ -894,6 +894,155 @@ func TestGenSrcsWithSrcsFromExternalPackage(t *testing.T) {
)
}
func TestGenSrcsWithTrimExtAndOutpuExtension(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForGenRuleTest,
android.FixtureMergeMockFs(android.MockFS{
"external-protos/path/Android.bp": []byte(`
filegroup {
name: "external-protos",
srcs: [
"baz.a.b.c.proto/baz.a.b.c.proto",
"bar.a.b.c.proto",
"qux.ext.a.b.c.proto",
],
}
`),
"package-dir/Android.bp": []byte(`
gensrcs {
name: "module-name",
cmd: "mkdir -p $(genDir) && cat $(in) >> $(genDir)/$(out)",
srcs: [
"src/foo.a.b.c.proto",
":external-protos",
],
trim_extension: ".a.b.c.proto",
output_extension: "proto.h",
}
`),
}),
).RunTest(t)
exportedIncludeDir := "out/soong/.intermediates/package-dir/module-name/gen/gensrcs"
gen := result.Module("module-name", "").(*Module)
android.AssertPathsRelativeToTopEquals(
t,
"include path",
[]string{exportedIncludeDir},
gen.exportedIncludeDirs,
)
android.AssertPathsRelativeToTopEquals(
t,
"files",
[]string{
exportedIncludeDir + "/package-dir/src/foo.proto.h",
exportedIncludeDir + "/external-protos/path/baz.a.b.c.proto/baz.proto.h",
exportedIncludeDir + "/external-protos/path/bar.proto.h",
exportedIncludeDir + "/external-protos/path/qux.ext.proto.h",
},
gen.outputFiles,
)
}
func TestGenSrcsWithTrimExtButNoOutpuExtension(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForGenRuleTest,
android.FixtureMergeMockFs(android.MockFS{
"external-protos/path/Android.bp": []byte(`
filegroup {
name: "external-protos",
srcs: [
"baz.a.b.c.proto/baz.a.b.c.proto",
"bar.a.b.c.proto",
"qux.ext.a.b.c.proto",
],
}
`),
"package-dir/Android.bp": []byte(`
gensrcs {
name: "module-name",
cmd: "mkdir -p $(genDir) && cat $(in) >> $(genDir)/$(out)",
srcs: [
"src/foo.a.b.c.proto",
":external-protos",
],
trim_extension: ".a.b.c.proto",
}
`),
}),
).RunTest(t)
exportedIncludeDir := "out/soong/.intermediates/package-dir/module-name/gen/gensrcs"
gen := result.Module("module-name", "").(*Module)
android.AssertPathsRelativeToTopEquals(
t,
"include path",
[]string{exportedIncludeDir},
gen.exportedIncludeDirs,
)
android.AssertPathsRelativeToTopEquals(
t,
"files",
[]string{
exportedIncludeDir + "/package-dir/src/foo",
exportedIncludeDir + "/external-protos/path/baz.a.b.c.proto/baz",
exportedIncludeDir + "/external-protos/path/bar",
exportedIncludeDir + "/external-protos/path/qux.ext",
},
gen.outputFiles,
)
}
func TestGenSrcsWithOutpuExtension(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForGenRuleTest,
android.FixtureMergeMockFs(android.MockFS{
"external-protos/path/Android.bp": []byte(`
filegroup {
name: "external-protos",
srcs: ["baz/baz.a.b.c.proto", "bar.a.b.c.proto"],
}
`),
"package-dir/Android.bp": []byte(`
gensrcs {
name: "module-name",
cmd: "mkdir -p $(genDir) && cat $(in) >> $(genDir)/$(out)",
srcs: [
"src/foo.a.b.c.proto",
":external-protos",
],
output_extension: "proto.h",
}
`),
}),
).RunTest(t)
exportedIncludeDir := "out/soong/.intermediates/package-dir/module-name/gen/gensrcs"
gen := result.Module("module-name", "").(*Module)
android.AssertPathsRelativeToTopEquals(
t,
"include path",
[]string{exportedIncludeDir},
gen.exportedIncludeDirs,
)
android.AssertPathsRelativeToTopEquals(
t,
"files",
[]string{
exportedIncludeDir + "/package-dir/src/foo.a.b.c.proto.h",
exportedIncludeDir + "/external-protos/path/baz/baz.a.b.c.proto.h",
exportedIncludeDir + "/external-protos/path/bar.a.b.c.proto.h",
},
gen.outputFiles,
)
}
func TestPrebuiltTool(t *testing.T) {
testcases := []struct {
name string