From 367d89da7887825f74b0c9554b2e1b9619d94f08 Mon Sep 17 00:00:00 2001 From: Vinh Tran Date: Fri, 28 Apr 2023 11:21:25 -0400 Subject: [PATCH] Use aidl_library in cc libraries Introduce aidl.libs prop on cc libraries to pass in aidl_library. The goal is to eventually disallow aidl.include_dirs (a pattern for passing aidl headers dir for aidl compilation) and enforce aidl headers to be explicitly specified in Android.bp. Bug: 278704136 Test: go test Change-Id: Ia78bc11dfa12f47d2d1bb90dc65372ddb17f7e14 --- aidl_library/aidl_library.go | 4 + aidl_library/aidl_library_test.go | 4 - bp2build/cc_library_conversion_test.go | 142 +++++++++++++++++++------ cc/Android.bp | 2 +- cc/bp2build.go | 102 ++++++++++-------- cc/cc.go | 27 +++++ cc/cc_test.go | 78 +++++++++++++- cc/compiler.go | 20 +++- cc/gen.go | 33 ++++-- cc/library.go | 2 +- 10 files changed, 324 insertions(+), 90 deletions(-) diff --git a/aidl_library/aidl_library.go b/aidl_library/aidl_library.go index 9b5f0a814..8a84e6bfa 100644 --- a/aidl_library/aidl_library.go +++ b/aidl_library/aidl_library.go @@ -22,6 +22,10 @@ import ( "github.com/google/blueprint/proptools" ) +var PrepareForTestWithAidlLibrary = android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + registerAidlLibraryBuildComponents(ctx) +}) + func init() { registerAidlLibraryBuildComponents(android.InitRegistrationContext) } diff --git a/aidl_library/aidl_library_test.go b/aidl_library/aidl_library_test.go index 42fa5367e..d9b410acc 100644 --- a/aidl_library/aidl_library_test.go +++ b/aidl_library/aidl_library_test.go @@ -19,10 +19,6 @@ import ( "testing" ) -var PrepareForTestWithAidlLibrary = android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { - registerAidlLibraryBuildComponents(ctx) -}) - func TestAidlLibrary(t *testing.T) { t.Parallel() ctx := android.GroupFixturePreparers( diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 1b681efb0..e998ac8f4 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -18,6 +18,7 @@ import ( "fmt" "testing" + "android/soong/aidl_library" "android/soong/android" "android/soong/cc" ) @@ -63,6 +64,7 @@ func registerCcLibraryModuleTypes(ctx android.RegistrationContext) { ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory) ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory) ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory) + ctx.RegisterModuleType("aidl_library", aidl_library.AidlLibraryFactory) } func TestCcLibrarySimple(t *testing.T) { @@ -3315,6 +3317,46 @@ func TestCcLibraryArchVariantSuffix(t *testing.T) { }) } +func TestCcLibraryWithAidlLibrary(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library with aidl_library", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +aidl_library { + name: "A_aidl", + srcs: ["aidl/A.aidl"], + hdrs: ["aidl/Header.aidl"], + strip_import_prefix: "aidl", +} +cc_library { + name: "foo", + aidl: { + libs: ["A_aidl"], + } +}`, + ExpectedBazelTargets: []string{ + MakeBazelTargetNoRestrictions("aidl_library", "A_aidl", AttrNameToString{ + "srcs": `["aidl/A.aidl"]`, + "hdrs": `["aidl/Header.aidl"]`, + "strip_import_prefix": `"aidl"`, + "tags": `["apex_available=//apex_available:anyapex"]`, + }), + MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{ + "deps": `[":A_aidl"]`, + }), + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "implementation_whole_archive_deps": `[":foo_cc_aidl_library"]`, + "local_includes": `["."]`, + }), + }, + }) +} + func TestCcLibraryWithAidlSrcs(t *testing.T) { runCcLibraryTestCase(t, Bp2buildTestCase{ Description: "cc_library with aidl srcs", @@ -3397,37 +3439,77 @@ cc_library { } func TestCcLibraryWithExportAidlHeaders(t *testing.T) { - runCcLibraryTestCase(t, Bp2buildTestCase{ - Description: "cc_library with export aidl headers", - ModuleTypeUnderTest: "cc_library", - ModuleTypeUnderTestFactory: cc.LibraryFactory, - Blueprint: ` -cc_library { - name: "foo", - srcs: [ - "Foo.aidl", - ], - aidl: { - export_aidl_headers: true, - } -}`, - ExpectedBazelTargets: []string{ - MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{ - "srcs": `["Foo.aidl"]`, - }), - MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{ - "deps": `[":foo_aidl_library"]`, - }), - MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ - "whole_archive_deps": `[":foo_cc_aidl_library"]`, - "local_includes": `["."]`, - }), - MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ - "whole_archive_deps": `[":foo_cc_aidl_library"]`, - "local_includes": `["."]`, - }), + t.Parallel() + + expectedBazelTargets := []string{ + MakeBazelTarget("cc_aidl_library", "foo_cc_aidl_library", AttrNameToString{ + "deps": `[":foo_aidl_library"]`, + }), + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "whole_archive_deps": `[":foo_cc_aidl_library"]`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "whole_archive_deps": `[":foo_cc_aidl_library"]`, + "local_includes": `["."]`, + }), + } + testCases := []struct { + description string + bp string + expectedBazelTargets []string + }{ + { + description: "cc_library with aidl srcs and aidl.export_aidl_headers set", + bp: ` + cc_library { + name: "foo", + srcs: [ + "Foo.aidl", + ], + aidl: { + export_aidl_headers: true, + } + }`, + expectedBazelTargets: append( + expectedBazelTargets, + MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{ + "srcs": `["Foo.aidl"]`, + })), }, - }) + { + description: "cc_library with aidl.libs and aidl.export_aidl_headers set", + bp: ` + aidl_library { + name: "foo_aidl_library", + srcs: ["Foo.aidl"], + } + cc_library { + name: "foo", + aidl: { + libs: ["foo_aidl_library"], + export_aidl_headers: true, + } + }`, + expectedBazelTargets: append( + expectedBazelTargets, + MakeBazelTargetNoRestrictions("aidl_library", "foo_aidl_library", AttrNameToString{ + "srcs": `["Foo.aidl"]`, + "tags": `["apex_available=//apex_available:anyapex"]`, + }), + ), + }, + } + + for _, testCase := range testCases { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library with export aidl headers", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: testCase.bp, + ExpectedBazelTargets: testCase.expectedBazelTargets, + }) + } } func TestCcLibraryWithTargetApex(t *testing.T) { diff --git a/cc/Android.bp b/cc/Android.bp index be2cc5a34..f49dc1a9e 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -9,6 +9,7 @@ bootstrap_go_package { "blueprint", "blueprint-pathtools", "soong", + "soong-aidl-library", "soong-android", "soong-bazel", "soong-cc-config", @@ -22,7 +23,6 @@ bootstrap_go_package { srcs: [ "afdo.go", "fdo_profile.go", - "androidmk.go", "api_level.go", "bp2build.go", diff --git a/cc/bp2build.go b/cc/bp2build.go index cf5f74d4d..0f978a5ca 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -728,6 +728,8 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) compilerAttrs := compilerAttributes{} linkerAttrs := linkerAttributes{} + var aidlLibs bazel.LabelList + // Iterate through these axes in a deterministic order. This is required // because processing certain dependencies may result in concatenating // elements along other axes. (For example, processing NoConfig may result @@ -743,6 +745,7 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) compilerAttrs.lexopts.SetSelectValue(axis, cfg, baseCompilerProps.Lex.Flags) } (&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, cfg, baseCompilerProps) + aidlLibs.Append(android.BazelLabelForModuleDeps(ctx, baseCompilerProps.Aidl.Libs)) } var exportHdrs []string @@ -815,7 +818,14 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) (&linkerAttrs).wholeArchiveDeps.Add(protoDep.wholeStaticLib) (&linkerAttrs).implementationWholeArchiveDeps.Add(protoDep.implementationWholeStaticLib) - aidlDep := bp2buildCcAidlLibrary(ctx, module, compilerAttrs.aidlSrcs, linkerAttrs) + aidlDep := bp2buildCcAidlLibrary( + ctx, module, + compilerAttrs.aidlSrcs, + bazel.LabelListAttribute{ + Value: aidlLibs, + }, + linkerAttrs, + ) if aidlDep != nil { if lib, ok := module.linker.(*libraryDecorator); ok { if proptools.Bool(lib.Properties.Aidl.Export_aidl_headers) { @@ -912,11 +922,15 @@ func bp2buildFdoProfile( func bp2buildCcAidlLibrary( ctx android.Bp2buildMutatorContext, m *Module, - aidlLabelList bazel.LabelListAttribute, + aidlSrcs bazel.LabelListAttribute, + aidlLibs bazel.LabelListAttribute, linkerAttrs linkerAttributes, ) *bazel.LabelAttribute { - if !aidlLabelList.IsEmpty() { - aidlLibs, aidlSrcs := aidlLabelList.Partition(func(src bazel.Label) bool { + var aidlLibsFromSrcs, aidlFiles bazel.LabelListAttribute + apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.TopDownMutatorContext), ctx.Module()) + + if !aidlSrcs.IsEmpty() { + aidlLibsFromSrcs, aidlFiles = aidlSrcs.Partition(func(src bazel.Label) bool { if fg, ok := android.ToFileGroupAsLibrary(ctx, src.OriginalModuleName); ok && fg.ShouldConvertToAidlLibrary(ctx) { return true @@ -924,57 +938,61 @@ func bp2buildCcAidlLibrary( return false }) - apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.TopDownMutatorContext), ctx.Module()) - sdkAttrs := bp2BuildParseSdkAttributes(m) - - if !aidlSrcs.IsEmpty() { + if !aidlFiles.IsEmpty() { aidlLibName := m.Name() + "_aidl_library" ctx.CreateBazelTargetModule( bazel.BazelTargetModuleProperties{ Rule_class: "aidl_library", Bzl_load_location: "//build/bazel/rules/aidl:aidl_library.bzl", }, - android.CommonAttributes{Name: aidlLibName}, - &aidlLibraryAttributes{ - Srcs: aidlSrcs, + android.CommonAttributes{ + Name: aidlLibName, Tags: apexAvailableTags, }, - ) - aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}}) - } - - if !aidlLibs.IsEmpty() { - ccAidlLibrarylabel := m.Name() + "_cc_aidl_library" - // Since parent cc_library already has these dependencies, we can add them as implementation - // deps so that they don't re-export - implementationDeps := linkerAttrs.deps.Clone() - implementationDeps.Append(linkerAttrs.implementationDeps) - implementationDynamicDeps := linkerAttrs.dynamicDeps.Clone() - implementationDynamicDeps.Append(linkerAttrs.implementationDynamicDeps) - - ctx.CreateBazelTargetModule( - bazel.BazelTargetModuleProperties{ - Rule_class: "cc_aidl_library", - Bzl_load_location: "//build/bazel/rules/cc:cc_aidl_library.bzl", - }, - android.CommonAttributes{Name: ccAidlLibrarylabel}, - &ccAidlLibraryAttributes{ - Deps: aidlLibs, - Implementation_deps: *implementationDeps, - Implementation_dynamic_deps: *implementationDynamicDeps, - Tags: apexAvailableTags, - sdkAttributes: sdkAttrs, + &aidlLibraryAttributes{ + Srcs: aidlFiles, }, ) - label := &bazel.LabelAttribute{ - Value: &bazel.Label{ - Label: ":" + ccAidlLibrarylabel, - }, - } - return label + aidlLibsFromSrcs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}}) } } + allAidlLibs := aidlLibs.Clone() + allAidlLibs.Append(aidlLibsFromSrcs) + + if !allAidlLibs.IsEmpty() { + ccAidlLibrarylabel := m.Name() + "_cc_aidl_library" + // Since parent cc_library already has these dependencies, we can add them as implementation + // deps so that they don't re-export + implementationDeps := linkerAttrs.deps.Clone() + implementationDeps.Append(linkerAttrs.implementationDeps) + implementationDynamicDeps := linkerAttrs.dynamicDeps.Clone() + implementationDynamicDeps.Append(linkerAttrs.implementationDynamicDeps) + + sdkAttrs := bp2BuildParseSdkAttributes(m) + + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "cc_aidl_library", + Bzl_load_location: "//build/bazel/rules/cc:cc_aidl_library.bzl", + }, + android.CommonAttributes{Name: ccAidlLibrarylabel}, + &ccAidlLibraryAttributes{ + Deps: *allAidlLibs, + Implementation_deps: *implementationDeps, + Implementation_dynamic_deps: *implementationDynamicDeps, + Tags: apexAvailableTags, + sdkAttributes: sdkAttrs, + }, + ) + label := &bazel.LabelAttribute{ + Value: &bazel.Label{ + Label: ":" + ccAidlLibrarylabel, + }, + } + return label + } + return nil } diff --git a/cc/cc.go b/cc/cc.go index 7237686e4..f4b565550 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -27,6 +27,7 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/proptools" + "android/soong/aidl_library" "android/soong/android" "android/soong/bazel/cquery" "android/soong/cc/config" @@ -110,6 +111,9 @@ type Deps struct { // Used by DepsMutator to pass system_shared_libs information to check_elf_file.py. SystemSharedLibs []string + // Used by DepMutator to pass aidl_library modules to aidl compiler + AidlLibs []string + // If true, statically link the unwinder into native libraries/binaries. StaticUnwinderIfLegacy bool @@ -182,6 +186,9 @@ type PathDeps struct { // For Darwin builds, the path to the second architecture's output that should // be combined with this architectures's output into a FAT MachO file. DarwinSecondArchOutput android.OptionalPath + + // Paths to direct srcs and transitive include dirs from direct aidl_library deps + AidlLibraryInfos []aidl_library.AidlLibraryInfo } // LocalOrGlobalFlags contains flags that need to have values set globally by the build system or locally by the module @@ -765,6 +772,7 @@ var ( stubImplDepTag = dependencyTag{name: "stub_impl"} JniFuzzLibTag = dependencyTag{name: "jni_fuzz_lib_tag"} FdoProfileTag = dependencyTag{name: "fdo_profile"} + aidlLibraryTag = dependencyTag{name: "aidl_library"} ) func IsSharedDepTag(depTag blueprint.DependencyTag) bool { @@ -2751,6 +2759,14 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { } } + if len(deps.AidlLibs) > 0 { + actx.AddDependency( + c, + aidlLibraryTag, + deps.AidlLibs..., + ) + } + updateImportedLibraryDependency(ctx) } @@ -3055,6 +3071,17 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { return } + if depTag == aidlLibraryTag { + if ctx.OtherModuleHasProvider(dep, aidl_library.AidlLibraryProvider) { + depPaths.AidlLibraryInfos = append( + depPaths.AidlLibraryInfos, + ctx.OtherModuleProvider( + dep, + aidl_library.AidlLibraryProvider).(aidl_library.AidlLibraryInfo), + ) + } + } + ccDep, ok := dep.(LinkableInterface) if !ok { diff --git a/cc/cc_test.go b/cc/cc_test.go index f9e661ff2..d3d55e8ee 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -24,6 +24,7 @@ import ( "strings" "testing" + "android/soong/aidl_library" "android/soong/android" "android/soong/bazel/cquery" ) @@ -4418,9 +4419,65 @@ func TestStubsLibReexportsHeaders(t *testing.T) { } } +func TestAidlLibraryWithHeader(t *testing.T) { + t.Parallel() + ctx := android.GroupFixturePreparers( + prepareForCcTest, + aidl_library.PrepareForTestWithAidlLibrary, + android.MockFS{ + "package_bar/Android.bp": []byte(` + aidl_library { + name: "bar", + srcs: ["x/y/Bar.aidl"], + strip_import_prefix: "x", + } + `)}.AddToFixture(), + android.MockFS{ + "package_foo/Android.bp": []byte(` + aidl_library { + name: "foo", + srcs: ["a/b/Foo.aidl"], + strip_import_prefix: "a", + deps: ["bar"], + } + cc_library { + name: "libfoo", + aidl: { + libs: ["foo"], + } + } + `), + }.AddToFixture(), + ).RunTest(t).TestContext + + libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static") + manifest := android.RuleBuilderSboxProtoForTests(t, libfoo.Output("aidl.sbox.textproto")) + aidlCommand := manifest.Commands[0].GetCommand() + + expectedAidlFlags := "-Ipackage_foo/a -Ipackage_bar/x" + if !strings.Contains(aidlCommand, expectedAidlFlags) { + t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlags) + } + + outputs := strings.Join(libfoo.AllOutputs(), " ") + + android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl/b/BpFoo.h") + android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl/b/BnFoo.h") + android.AssertStringDoesContain(t, "aidl-generated header", outputs, "gen/aidl/b/Foo.h") + android.AssertStringDoesContain(t, "aidl-generated cpp", outputs, "b/Foo.cpp") + // Confirm that the aidl header doesn't get compiled to cpp and h files + android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl/y/BpBar.h") + android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl/y/BnBar.h") + android.AssertStringDoesNotContain(t, "aidl-generated header", outputs, "gen/aidl/y/Bar.h") + android.AssertStringDoesNotContain(t, "aidl-generated cpp", outputs, "y/Bar.cpp") +} + func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) { t.Parallel() - ctx := testCc(t, ` + ctx := android.GroupFixturePreparers( + prepareForCcTest, + aidl_library.PrepareForTestWithAidlLibrary, + ).RunTestWithBp(t, ` cc_library { name: "libfoo", srcs: ["a/Foo.aidl"], @@ -4705,7 +4762,15 @@ func TestIncludeDirsExporting(t *testing.T) { }) t.Run("ensure only aidl headers are exported", func(t *testing.T) { - ctx := testCc(t, genRuleModules+` + ctx := android.GroupFixturePreparers( + prepareForCcTest, + aidl_library.PrepareForTestWithAidlLibrary, + ).RunTestWithBp(t, ` + aidl_library { + name: "libfoo_aidl", + srcs: ["x/y/Bar.aidl"], + strip_import_prefix: "x", + } cc_library_shared { name: "libfoo", srcs: [ @@ -4714,10 +4779,11 @@ func TestIncludeDirsExporting(t *testing.T) { "a.proto", ], aidl: { + libs: ["libfoo_aidl"], export_aidl_headers: true, } } - `) + `).TestContext foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module() checkIncludeDirs(t, ctx, foo, expectedIncludeDirs(` @@ -4728,11 +4794,17 @@ func TestIncludeDirsExporting(t *testing.T) { .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/Bar.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BnBar.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BpBar.h `), expectedOrderOnlyDeps(` .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/Bar.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BnBar.h + .intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/y/BpBar.h `), ) }) diff --git a/cc/compiler.go b/cc/compiler.go index 88985b6f9..5da745e02 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -120,6 +120,9 @@ type BaseCompilerProperties struct { Lex *LexProperties Aidl struct { + // List of aidl_library modules + Libs []string + // list of directories that will be added to the aidl include paths. Include_dirs []string @@ -272,6 +275,7 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...) deps.GeneratedSources = removeListFromList(deps.GeneratedSources, compiler.Properties.Exclude_generated_sources) deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...) + deps.AidlLibs = append(deps.AidlLibs, compiler.Properties.Aidl.Libs...) android.ProtoDeps(ctx, &compiler.Proto) if compiler.hasSrcExt(".proto") { @@ -561,7 +565,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps "-I"+android.PathForModuleGen(ctx, "yacc", ctx.ModuleDir()).String()) } - if compiler.hasSrcExt(".aidl") { + if compiler.hasAidl(deps) { flags.aidlFlags = append(flags.aidlFlags, compiler.Properties.Aidl.Flags...) if len(compiler.Properties.Aidl.Local_include_dirs) > 0 { localAidlIncludeDirs := android.PathsForModuleSrc(ctx, compiler.Properties.Aidl.Local_include_dirs) @@ -572,6 +576,14 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs)) } + var rootAidlIncludeDirs android.Paths + for _, aidlLibraryInfo := range deps.AidlLibraryInfos { + rootAidlIncludeDirs = append(rootAidlIncludeDirs, aidlLibraryInfo.IncludeDirs.ToList()...) + } + if len(rootAidlIncludeDirs) > 0 { + flags.aidlFlags = append(flags.aidlFlags, includeDirsToFlags(rootAidlIncludeDirs)) + } + if proptools.BoolDefault(compiler.Properties.Aidl.Generate_traces, true) { flags.aidlFlags = append(flags.aidlFlags, "-t") } @@ -660,6 +672,10 @@ func ndkPathDeps(ctx ModuleContext) android.Paths { return nil } +func (compiler *baseCompiler) hasAidl(deps PathDeps) bool { + return len(deps.AidlLibraryInfos) > 0 || compiler.hasSrcExt(".aidl") +} + func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { pathDeps := deps.GeneratedDeps pathDeps = append(pathDeps, ndkPathDeps(ctx)...) @@ -668,7 +684,7 @@ func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathD srcs := append(android.Paths(nil), compiler.srcsBeforeGen...) - srcs, genDeps, info := genSources(ctx, srcs, buildFlags) + srcs, genDeps, info := genSources(ctx, deps.AidlLibraryInfos, srcs, buildFlags) pathDeps = append(pathDeps, genDeps...) compiler.pathDeps = pathDeps diff --git a/cc/gen.go b/cc/gen.go index dfbb177e6..dbb9560ba 100644 --- a/cc/gen.go +++ b/cc/gen.go @@ -18,7 +18,9 @@ import ( "path/filepath" "strings" + "android/soong/aidl_library" "android/soong/bazel" + "github.com/google/blueprint" "android/soong/android" @@ -124,11 +126,6 @@ func genAidl(ctx android.ModuleContext, rule *android.RuleBuilder, aidlFile andr headerBn := outDir.Join(ctx, aidlPackage, "Bn"+shortName+".h") headerBp := outDir.Join(ctx, aidlPackage, "Bp"+shortName+".h") - baseDir := strings.TrimSuffix(aidlFile.String(), aidlFile.Rel()) - if baseDir != "" { - aidlFlags += " -I" + baseDir - } - cmd := rule.Command() cmd.BuiltTool("aidl-cpp"). FlagWithDepFile("-d", depFile). @@ -282,7 +279,10 @@ type generatedSourceInfo struct { syspropOrderOnlyDeps android.Paths } -func genSources(ctx android.ModuleContext, srcFiles android.Paths, +func genSources( + ctx android.ModuleContext, + aidlLibraryInfos []aidl_library.AidlLibraryInfo, + srcFiles android.Paths, buildFlags builderFlags) (android.Paths, android.Paths, generatedSourceInfo) { var info generatedSourceInfo @@ -330,7 +330,8 @@ func genSources(ctx android.ModuleContext, srcFiles android.Paths, aidlRule = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "aidl"), android.PathForModuleGen(ctx, "aidl.sbox.textproto")) } - cppFile, aidlHeaders := genAidl(ctx, aidlRule, srcFile, buildFlags.aidlFlags) + baseDir := strings.TrimSuffix(srcFile.String(), srcFile.Rel()) + cppFile, aidlHeaders := genAidl(ctx, aidlRule, srcFile, buildFlags.aidlFlags+" -I"+baseDir) srcFiles[i] = cppFile info.aidlHeaders = append(info.aidlHeaders, aidlHeaders...) @@ -352,6 +353,24 @@ func genSources(ctx android.ModuleContext, srcFiles android.Paths, } } + for _, aidlLibraryInfo := range aidlLibraryInfos { + for _, aidlSrc := range aidlLibraryInfo.Srcs { + if aidlRule == nil { + // TODO(b/279960133): Sandbox inputs to ensure aidl headers are explicitly specified + aidlRule = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "aidl"), + android.PathForModuleGen(ctx, "aidl.sbox.textproto")) + } + cppFile, aidlHeaders := genAidl(ctx, aidlRule, aidlSrc, buildFlags.aidlFlags) + + srcFiles = append(srcFiles, cppFile) + info.aidlHeaders = append(info.aidlHeaders, aidlHeaders...) + // Use the generated headers as order only deps to ensure that they are up to date when + // needed. + // TODO: Reduce the size of the ninja file by using one order only dep for the whole rule + info.aidlOrderOnlyDeps = append(info.aidlOrderOnlyDeps, aidlHeaders...) + } + } + if aidlRule != nil { aidlRule.Build("aidl", "gen aidl") } diff --git a/cc/library.go b/cc/library.go index 13b333a12..ad4688fe6 100644 --- a/cc/library.go +++ b/cc/library.go @@ -2114,7 +2114,7 @@ func (library *libraryDecorator) link(ctx ModuleContext, // Optionally export aidl headers. if Bool(library.Properties.Aidl.Export_aidl_headers) { - if library.baseCompiler.hasSrcExt(".aidl") { + if library.baseCompiler.hasAidl(deps) { dir := android.PathForModuleGen(ctx, "aidl") library.reexportDirs(dir)