diff options
author | Jooyung Han <jooyung@google.com> | 2021-05-26 22:20:42 +0900 |
---|---|---|
committer | Jooyung Han <jooyung@google.com> | 2021-05-27 11:42:34 +0900 |
commit | 5b9fd4b41819997c4d89e58d93766846db881a09 (patch) | |
tree | 89fe1b0eb5239ef9cd24358f5a81315ac96ea550 | |
parent | 15a79f217a2abb493d470ea33ed6ad0e5d436147 (diff) | |
download | aidl-5b9fd4b41819997c4d89e58d93766846db881a09.tar.gz |
fix import paths when compiling snapshots
When compiling snapshots we should import
- snapshot dir (e.g <foo-iface>/aidl_api/foo-iface/1)
- "current" of imported interfaces
(e.g <bar-iface>/aidl_api/bar-iface/current)
Previously, the snapshot of generated sources(e.g. hidl2aidl_test_gen)
caused the build error due to the wrong import path.
Bug: 189288369
Test: aidl_unitttests
Test: m hidl2aidl_test_gen-freeze-api
m
Merged-In: I92f8e290b89c737f4b16fc064e763bd47cd1a9da
Change-Id: I92f8e290b89c737f4b16fc064e763bd47cd1a9da
(cherry picked from commit 60699b5f0010228906c13f288ae37077c326deb3)
-rw-r--r-- | build/aidl_api.go | 45 | ||||
-rw-r--r-- | build/aidl_gen_rule.go | 41 | ||||
-rw-r--r-- | build/aidl_interface.go | 13 | ||||
-rw-r--r-- | build/aidl_interface_backends.go | 9 | ||||
-rw-r--r-- | build/aidl_mapping.go | 2 | ||||
-rw-r--r-- | build/aidl_test.go | 182 |
6 files changed, 259 insertions, 33 deletions
diff --git a/build/aidl_api.go b/build/aidl_api.go index 02290412..27983746 100644 --- a/build/aidl_api.go +++ b/build/aidl_api.go @@ -93,7 +93,7 @@ type apiDump struct { } func (m *aidlApi) createApiDumpFromSource(ctx android.ModuleContext) apiDump { - srcs, imports := getPaths(ctx, m.properties.Srcs) + srcs, imports := getPaths(ctx, m.properties.Srcs, m.properties.AidlRoot) if ctx.Failed() { return apiDump{} @@ -213,6 +213,49 @@ func (m *aidlApi) makeApiDumpAsVersion(ctx android.ModuleContext, dump apiDump, return timestampFile } +type depTag struct { + blueprint.BaseDependencyTag + name string +} + +var ( + apiDep = depTag{name: "api"} + interfaceDep = depTag{name: "interface"} + + importApiDep = depTag{name: "imported-api"} + importInterfaceDep = depTag{name: "imported-interface"} +) + +// calculates import flags(-I) from deps. +// When the target is ToT, use ToT of imported interfaces. If not, we use "current" snapshot of +// imported interfaces. +func getImportsFromDeps(ctx android.ModuleContext, targetIsToT bool) (importPaths []string, implicits android.Paths) { + ctx.VisitDirectDeps(func(dep android.Module) { + switch ctx.OtherModuleDependencyTag(dep) { + case importInterfaceDep: + iface := dep.(*aidlInterface) + if proptools.Bool(iface.properties.Unstable) || targetIsToT { + importPaths = append(importPaths, iface.properties.Full_import_paths...) + } else { + // use "current" snapshot from stable "imported" modules + currentDir := filepath.Join(ctx.OtherModuleDir(dep), aidlApiDir, iface.BaseModuleName(), currentVersion) + importPaths = append(importPaths, currentDir) + // TODO(b/189288369) this should be transitive + importPaths = append(importPaths, iface.properties.Include_dirs...) + } + case interfaceDep: + iface := dep.(*aidlInterface) + importPaths = append(importPaths, iface.properties.Include_dirs...) + case importApiDep, apiDep: + api := dep.(*aidlApi) + // add imported module's checkapiTimestamps as implicits to make sure that imported apiDump is up-to-date + implicits = append(implicits, api.checkApiTimestamps.Paths()...) + implicits = append(implicits, api.checkHashTimestamps.Paths()...) + } + }) + return +} + func (m *aidlApi) checkApi(ctx android.ModuleContext, oldDump, newDump apiDump, checkApiLevel string, messageFile android.Path) android.WritablePath { newVersion := newDump.dir.Base() timestampFile := android.PathForModuleOut(ctx, "checkapi_"+newVersion+".timestamp") diff --git a/build/aidl_gen_rule.go b/build/aidl_gen_rule.go index 79608245..f944617e 100644 --- a/build/aidl_gen_rule.go +++ b/build/aidl_gen_rule.go @@ -65,6 +65,7 @@ var ( type aidlGenProperties struct { Srcs []string `android:"path"` AidlRoot string // base directory for the input aidl file + IsToT bool ImportsWithoutVersion []string Stability *string Lang string // target language [java|cpp|ndk|rust] @@ -98,7 +99,7 @@ var _ android.SourceFileProducer = (*aidlGenRule)(nil) var _ genrule.SourceFileGenerator = (*aidlGenRule)(nil) func (g *aidlGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) { - srcs, imports := getPaths(ctx, g.properties.Srcs) + srcs, imports := getPaths(ctx, g.properties.Srcs, g.properties.AidlRoot) if ctx.Failed() { return @@ -107,23 +108,10 @@ func (g *aidlGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) { genDirTimestamp := android.PathForModuleGen(ctx, "timestamp") // $out/gen/timestamp g.implicitInputs = append(g.implicitInputs, genDirTimestamp) - var importPaths []string - importPaths = append(importPaths, imports...) - ctx.VisitDirectDeps(func(dep android.Module) { - if importedAidl, ok := dep.(*aidlInterface); ok { - importPaths = append(importPaths, importedAidl.properties.Full_import_paths...) - } else if api, ok := dep.(*aidlApi); ok { - // When compiling an AIDL interface, also make sure that each - // version of the interface is compatible with its previous version - for _, path := range api.checkApiTimestamps { - g.implicitInputs = append(g.implicitInputs, path) - } - for _, path := range api.checkHashTimestamps { - g.implicitInputs = append(g.implicitInputs, path) - } - } - }) - g.importFlags = strings.Join(wrap("-I", importPaths, ""), " ") + importPaths, implicits := getImportsFromDeps(ctx, g.properties.IsToT) + imports = append(imports, importPaths...) + + g.importFlags = strings.Join(wrap("-I", imports, ""), " ") g.genOutDir = android.PathForModuleGen(ctx) g.genHeaderDir = android.PathForModuleGen(ctx, "include") @@ -135,9 +123,10 @@ func (g *aidlGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) { // This is to clean genOutDir before generating any file ctx.Build(pctx, android.BuildParams{ - Rule: aidlDirPrepareRule, - Inputs: srcs, - Output: genDirTimestamp, + Rule: aidlDirPrepareRule, + Implicits: implicits, + Inputs: srcs, + Output: genDirTimestamp, Args: map[string]string{ "outDir": g.genOutDir.String(), }, @@ -283,11 +272,17 @@ func (g *aidlGenRule) GeneratedHeaderDirs() android.Paths { } func (g *aidlGenRule) DepsMutator(ctx android.BottomUpMutatorContext) { - ctx.AddDependency(ctx.Module(), nil, wrap("", g.properties.ImportsWithoutVersion, aidlInterfaceSuffix)...) + // original interface + ctx.AddDependency(ctx.Module(), interfaceDep, g.properties.BaseName+aidlInterfaceSuffix) + if !proptools.Bool(g.properties.Unstable) { - ctx.AddDependency(ctx.Module(), nil, g.properties.BaseName+aidlApiSuffix) + // for checkapi timestamps + ctx.AddDependency(ctx.Module(), apiDep, g.properties.BaseName+aidlApiSuffix) } + // imported interfaces + ctx.AddDependency(ctx.Module(), importInterfaceDep, wrap("", g.properties.ImportsWithoutVersion, aidlInterfaceSuffix)...) + ctx.AddReverseDependency(ctx.Module(), nil, aidlMetadataSingletonName) } diff --git a/build/aidl_interface.go b/build/aidl_interface.go index f25ea57f..2c1d922a 100644 --- a/build/aidl_interface.go +++ b/build/aidl_interface.go @@ -220,19 +220,28 @@ func checkDuplicatedVersions(mctx android.BottomUpMutatorContext) { } } -func getPaths(ctx android.ModuleContext, rawSrcs []string) (paths android.Paths, imports []string) { - srcs := android.PathsForModuleSrc(ctx, rawSrcs) +func getPaths(ctx android.ModuleContext, rawSrcs []string, root string) (srcs android.Paths, imports []string) { + // TODO(b/189288369): move this to android.PathsForModuleSrcSubDir(ctx, srcs, subdir) + for _, src := range rawSrcs { + if m, _ := android.SrcIsModuleWithTag(src); m != "" { + srcs = append(srcs, android.PathsForModuleSrc(ctx, []string{src})...) + } else { + srcs = append(srcs, android.PathsWithModuleSrcSubDir(ctx, android.PathsForModuleSrc(ctx, []string{src}), root)...) + } + } if len(srcs) == 0 { ctx.PropertyErrorf("srcs", "No sources provided.") } + // gather base directories from input .aidl files for _, src := range srcs { if src.Ext() != ".aidl" { // Silently ignore non-aidl files as some filegroups have both java and aidl files together continue } baseDir := strings.TrimSuffix(src.String(), src.Rel()) + baseDir = strings.TrimSuffix(baseDir, "/") if baseDir != "" && !android.InList(baseDir, imports) { imports = append(imports, baseDir) } diff --git a/build/aidl_interface_backends.go b/build/aidl_interface_backends.go index 49ce1514..79b66254 100644 --- a/build/aidl_interface_backends.go +++ b/build/aidl_interface_backends.go @@ -75,7 +75,8 @@ func addCppLibrary(mctx android.LoadHookContext, i *aidlInterface, version strin }, &aidlGenProperties{ Srcs: srcs, AidlRoot: aidlRoot, - ImportsWithoutVersion: concat(i.properties.ImportsWithoutVersion, []string{i.ModuleBase.Name()}), + IsToT: version == i.nextVersion(), + ImportsWithoutVersion: i.properties.ImportsWithoutVersion, Stability: i.properties.Stability, Lang: lang, BaseName: i.ModuleBase.Name(), @@ -232,7 +233,8 @@ func addJavaLibrary(mctx android.LoadHookContext, i *aidlInterface, version stri }, &aidlGenProperties{ Srcs: srcs, AidlRoot: aidlRoot, - ImportsWithoutVersion: concat(i.properties.ImportsWithoutVersion, []string{i.ModuleBase.Name()}), + IsToT: version == i.nextVersion(), + ImportsWithoutVersion: i.properties.ImportsWithoutVersion, Stability: i.properties.Stability, Lang: langJava, BaseName: i.ModuleBase.Name(), @@ -280,7 +282,8 @@ func addRustLibrary(mctx android.LoadHookContext, i *aidlInterface, version stri }, &aidlGenProperties{ Srcs: srcs, AidlRoot: aidlRoot, - ImportsWithoutVersion: concat(i.properties.ImportsWithoutVersion, []string{i.ModuleBase.Name()}), + ImportsWithoutVersion: i.properties.ImportsWithoutVersion, + IsToT: version == i.nextVersion(), Stability: i.properties.Stability, Lang: langRust, BaseName: i.ModuleBase.Name(), diff --git a/build/aidl_mapping.go b/build/aidl_mapping.go index b9194955..596285ef 100644 --- a/build/aidl_mapping.go +++ b/build/aidl_mapping.go @@ -52,7 +52,7 @@ func (s *aidlMapping) DepsMutator(ctx android.BottomUpMutatorContext) { } func (s *aidlMapping) GenerateAndroidBuildActions(ctx android.ModuleContext) { - srcs, imports := getPaths(ctx, s.properties.Srcs) + srcs, imports := getPaths(ctx, s.properties.Srcs, "") s.outputFilePath = android.PathForModuleOut(ctx, s.properties.Output) outDir := android.PathForModuleGen(ctx) diff --git a/build/aidl_test.go b/build/aidl_test.go index 9eb42cc8..3b12469a 100644 --- a/build/aidl_test.go +++ b/build/aidl_test.go @@ -27,6 +27,7 @@ import ( "android/soong/android" "android/soong/apex" "android/soong/cc" + "android/soong/genrule" "android/soong/java" "android/soong/rust" ) @@ -61,6 +62,7 @@ func _testAidl(t *testing.T, bp string, customizers ...android.FixturePreparer) preparers = append(preparers, cc.PrepareForTestWithCcDefaultModules, java.PrepareForTestWithJavaDefaultModules, + genrule.PrepareForTestWithGenRuleBuildComponents, ) bp = bp + ` @@ -126,12 +128,15 @@ func _testAidl(t *testing.T, bp string, customizers ...android.FixturePreparer) crate_name: "binder", srcs: [""], } - aidl_interfaces_metadata { - name: "aidl_metadata_json", - } ` preparers = append(preparers, android.FixtureWithRootAndroidBp(bp)) + preparers = append(preparers, android.FixtureAddTextFile("system/tools/aidl/build/Android.bp", ` + aidl_interfaces_metadata { + name: "aidl_metadata_json", + visibility: ["//system/tools/aidl:__subpackages__"], + } + `)) preparers = append(preparers, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { // To keep tests stable, fix Platform_sdk_codename and Platform_sdk_final @@ -970,6 +975,177 @@ func TestRustDuplicateNames(t *testing.T) { `) } +func TestAidlImportFlagsForIncludeDirs(t *testing.T) { + customizer := withFiles(map[string][]byte{ + "foo/Android.bp": []byte(` + aidl_interface { + name: "foo-iface", + local_include_dir: "src", + include_dirs: [ + "path1", + "path2/sub", + ], + srcs: [ + "src/foo/Foo.aidl", + ], + imports: [ + "bar-iface", + ], + versions: ["1", "2"], + } + aidl_interface { + name: "bar-iface", + local_include_dir: "src", + srcs: [ + "src/bar/Bar.aidl", + ], + } + `), + "foo/src/foo/Foo.aidl": nil, + "foo/src/bar/Bar.aidl": nil, + "foo/aidl_api/foo-iface/current/foo/Foo.aidl": nil, + "foo/aidl_api/foo-iface/1/foo/Foo.aidl": nil, + "foo/aidl_api/foo-iface/1/.hash": nil, + "foo/aidl_api/foo-iface/2/foo/Foo.aidl": nil, + "foo/aidl_api/foo-iface/2/.hash": nil, + }) + ctx, _ := testAidl(t, ``, customizer) + + // compile for older version + { + rule := ctx.ModuleForTests("foo-iface-V1-cpp-source", "").Output("foo/Foo.cpp") + imports := strings.Split(rule.Args["imports"], " ") + android.AssertArrayString(t, "should import foo/1(target) and bar/current(imported)", []string{ + "-Ifoo/aidl_api/foo-iface/1", + "-Ipath1", + "-Ipath2/sub", + "-Ifoo/aidl_api/bar-iface/current", + }, imports) + } + // compile for tot version + { + rule := ctx.ModuleForTests("foo-iface-V3-cpp-source", "").Output("foo/Foo.cpp") + imports := strings.Split(rule.Args["imports"], " ") + android.AssertArrayString(t, "aidlCompile should import ToT", []string{ + "-Ifoo/src", + "-Ipath1", + "-Ipath2/sub", + "-Ifoo/src", + }, imports) + } +} + +func TestSupportsGenruleAndFilegroup(t *testing.T) { + customizer := withFiles(map[string][]byte{ + "foo/Android.bp": []byte(` + aidl_interface { + name: "foo-iface", + local_include_dir: "src", + include_dirs: [ + "path1", + "path2/sub", + ], + srcs: [ + "src/foo/Foo.aidl", + ":filegroup1", + ":gen1", + ], + imports: [ + "bar-iface", + ], + versions: ["1"], + } + filegroup { + name: "filegroup1", + path: "filegroup/sub", + srcs: [ + "filegroup/sub/pkg/Bar.aidl", + ], + } + genrule { + name: "gen1", + cmd: "generate baz/Baz.aidl", + out: [ + "baz/Baz.aidl", + ] + } + aidl_interface { + name: "bar-iface", + local_include_dir: "src", + srcs: [ + "src/bar/Bar.aidl", + ], + } + `), + "foo/aidl_api/foo-iface/1/foo/Foo.aidl": nil, + "foo/aidl_api/foo-iface/1/.hash": nil, + "foo/filegroup/sub/pkg/Bar.aidl": nil, + "foo/src/foo/Foo.aidl": nil, + }) + ctx, _ := testAidl(t, ``, customizer) + + // aidlCompile for snapshots (v1) + { + rule := ctx.ModuleForTests("foo-iface-V1-cpp-source", "").Output("foo/Foo.cpp") + imports := strings.Split(rule.Args["imports"], " ") + android.AssertArrayString(t, "aidlCompile should import filegroup/genrule as well", []string{ + "-Ifoo/aidl_api/foo-iface/1", + "-Ipath1", + "-Ipath2/sub", + "-Ifoo/aidl_api/bar-iface/current", + }, imports) + } + // aidlCompile for ToT (v2) + { + rule := ctx.ModuleForTests("foo-iface-V2-cpp-source", "").Output("foo/Foo.cpp") + imports := strings.Split(rule.Args["imports"], " ") + android.AssertArrayString(t, "aidlCompile should import filegroup/genrule as well", []string{ + "-Ifoo/src", + "-Ifoo/filegroup/sub", + "-Iout/soong/.intermediates/foo/gen1/gen", + "-Ipath1", + "-Ipath2/sub", + "-Ifoo/src", + }, imports) + } + + // dumpapi + { + rule := ctx.ModuleForTests("foo-iface-api", "").Rule("aidlDumpApiRule") + android.AssertPathsRelativeToTopEquals(t, "dumpapi should dump srcs/filegroups/genrules", []string{ + "foo/src/foo/Foo.aidl", + "foo/filegroup/sub/pkg/Bar.aidl", + "out/soong/.intermediates/foo/gen1/gen/baz/Baz.aidl", + }, rule.Inputs) + + dumpDir := "out/soong/.intermediates/foo/foo-iface-api/dump" + android.AssertPathsRelativeToTopEquals(t, "dumpapi should dump with rel paths", []string{ + dumpDir + "/foo/Foo.aidl", + dumpDir + "/pkg/Bar.aidl", + dumpDir + "/baz/Baz.aidl", + dumpDir + "/.hash", + }, rule.Outputs.Paths()) + + imports := strings.Split(rule.Args["imports"], " ") + android.AssertArrayString(t, "dumpapi should import filegroup/genrule as well", []string{ + // these are from foo-iface.srcs + "-Ifoo/src", + "-Ifoo/filegroup/sub", + "-Iout/soong/.intermediates/foo/gen1/gen", + + // this is from bar-iface.srcs + "-Ifoo/src", + + // this is from foo-iface.Local_include_dir + "-Ifoo/src", + + // these are from foo-iface.include_dirs + "-Ipath1", + "-Ipath2/sub", + }, imports) + } +} + func TestAidlFlags(t *testing.T) { ctx, _ := testAidl(t, ` aidl_interface { |