diff options
-rw-r--r-- | aidl_library/Android.bp | 32 | ||||
-rw-r--r-- | aidl_library/aidl_library.go | 120 | ||||
-rw-r--r-- | aidl_library/aidl_library_test.go | 126 |
3 files changed, 278 insertions, 0 deletions
diff --git a/aidl_library/Android.bp b/aidl_library/Android.bp new file mode 100644 index 000000000..ec2150427 --- /dev/null +++ b/aidl_library/Android.bp @@ -0,0 +1,32 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// 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. + +package { + default_applicable_licenses: ["Android-Apache-2.0"], +} + +bootstrap_go_package { + name: "soong-aidl-library", + pkgPath: "android/soong/aidl_library", + deps: [ + "soong-android", + ], + srcs: [ + "aidl_library.go", + ], + testSrcs: [ + "aidl_library_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/aidl_library/aidl_library.go b/aidl_library/aidl_library.go new file mode 100644 index 000000000..2a42170f2 --- /dev/null +++ b/aidl_library/aidl_library.go @@ -0,0 +1,120 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// 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. + +package aidl_library + +import ( + "android/soong/android" + + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" +) + +func init() { + registerAidlLibraryBuildComponents(android.InitRegistrationContext) +} + +func registerAidlLibraryBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("aidl_library", AidlLibraryFactory) +} + +type aidlLibraryProperties struct { + // srcs lists files that are included in this module for aidl compilation + Srcs []string `android:"path"` + + // hdrs lists the headers that are imported by srcs but are not compiled by aidl to language binding code + // hdrs is provided to support Bazel migration. It is a no-op until + // we enable input sandbox in aidl compilation action + Hdrs []string `android:"path"` + + // The prefix to strip from the paths of the .aidl files + // The remaining path is the package path of the aidl interface + Strip_import_prefix *string + + // List of aidl files or aidl_library depended on by the module + Deps []string `android:"arch_variant"` +} + +type AidlLibrary struct { + android.ModuleBase + properties aidlLibraryProperties +} + +type AidlLibraryInfo struct { + // The direct aidl files of the module + Srcs android.Paths + // The include dirs to the direct aidl files and those provided from aidl_library deps + IncludeDirs android.DepSet +} + +// AidlLibraryProvider provides the srcs and the transitive include dirs +var AidlLibraryProvider = blueprint.NewProvider(AidlLibraryInfo{}) + +func (lib *AidlLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { + includeDirsDepSetBuilder := android.NewDepSetBuilder(android.PREORDER) + + if len(lib.properties.Srcs) == 0 && len(lib.properties.Hdrs) == 0 { + ctx.ModuleErrorf("at least srcs or hdrs prop must be non-empty") + } + + srcs := android.PathsForModuleSrc(ctx, lib.properties.Srcs) + if lib.properties.Strip_import_prefix != nil { + srcs = android.PathsWithModuleSrcSubDir( + ctx, + srcs, + android.String(lib.properties.Strip_import_prefix)) + } + + includeDir := android.PathForModuleSrc( + ctx, + proptools.StringDefault(lib.properties.Strip_import_prefix, ""), + ) + + includeDirsDepSetBuilder.Direct(includeDir) + + for _, dep := range ctx.GetDirectDepsWithTag(aidlLibraryTag) { + if ctx.OtherModuleHasProvider(dep, AidlLibraryProvider) { + info := ctx.OtherModuleProvider(dep, AidlLibraryProvider).(AidlLibraryInfo) + includeDirsDepSetBuilder.Transitive(&info.IncludeDirs) + } + } + + // TODO(b/279960133) Propagate direct and transitive headers/srcs when aidl action sandboxes inputs + ctx.SetProvider(AidlLibraryProvider, AidlLibraryInfo{ + Srcs: srcs, + IncludeDirs: *includeDirsDepSetBuilder.Build(), + }) +} + +// aidl_library contains a list of .aidl files and the strip_import_prefix to +// to strip from the paths of the .aidl files. The sub-path left-over after stripping +// corresponds to the aidl package path the aidl interfaces are scoped in +func AidlLibraryFactory() android.Module { + module := &AidlLibrary{} + module.AddProperties(&module.properties) + android.InitAndroidModule(module) + return module +} + +type aidlDependencyTag struct { + blueprint.BaseDependencyTag +} + +var aidlLibraryTag = aidlDependencyTag{} + +func (lib *AidlLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { + for _, dep := range lib.properties.Deps { + ctx.AddDependency(lib, aidlLibraryTag, dep) + } +} diff --git a/aidl_library/aidl_library_test.go b/aidl_library/aidl_library_test.go new file mode 100644 index 000000000..42fa5367e --- /dev/null +++ b/aidl_library/aidl_library_test.go @@ -0,0 +1,126 @@ +// Copyright 2023 Google Inc. All rights reserved. +// +// 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. + +package aidl_library + +import ( + "android/soong/android" + "testing" +) + +var PrepareForTestWithAidlLibrary = android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { + registerAidlLibraryBuildComponents(ctx) +}) + +func TestAidlLibrary(t *testing.T) { + t.Parallel() + ctx := android.GroupFixturePreparers( + 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"], + hdrs: ["Header.aidl"], + strip_import_prefix: "a", + deps: ["bar"], + } + `), + }.AddToFixture(), + ).RunTest(t).TestContext + + foo := ctx.ModuleForTests("foo", "").Module().(*AidlLibrary) + actualInfo := ctx.ModuleProvider(foo, AidlLibraryProvider).(AidlLibraryInfo) + + android.AssertArrayString( + t, + "aidl include dirs", + []string{"package_foo/a", "package_bar/x"}, + actualInfo.IncludeDirs.ToList().Strings(), + ) + + android.AssertPathsRelativeToTopEquals( + t, + "aidl srcs paths", + []string{"package_foo/a/b/Foo.aidl"}, + actualInfo.Srcs, + ) +} + +func TestAidlLibraryWithoutStripImportPrefix(t *testing.T) { + t.Parallel() + ctx := android.GroupFixturePreparers( + PrepareForTestWithAidlLibrary, + android.MockFS{ + "package_bar/Android.bp": []byte(` + aidl_library { + name: "bar", + srcs: ["x/y/Bar.aidl"], + } + `), + }.AddToFixture(), + android.MockFS{ + "package_foo/Android.bp": []byte(` + aidl_library { + name: "foo", + srcs: ["a/b/Foo.aidl"], + hdrs: ["Header.aidl"], + deps: ["bar"], + } + `), + }.AddToFixture(), + ).RunTest(t).TestContext + + foo := ctx.ModuleForTests("foo", "").Module().(*AidlLibrary) + actualInfo := ctx.ModuleProvider(foo, AidlLibraryProvider).(AidlLibraryInfo) + + android.AssertArrayString( + t, + "aidl include dirs", + []string{"package_foo", "package_bar"}, + actualInfo.IncludeDirs.ToList().Strings(), + ) + + android.AssertPathsRelativeToTopEquals( + t, + "aidl srcs paths", + []string{"package_foo/a/b/Foo.aidl"}, + actualInfo.Srcs, + ) +} + +func TestAidlLibraryWithNoSrcsHdrsDeps(t *testing.T) { + t.Parallel() + android.GroupFixturePreparers( + PrepareForTestWithAidlLibrary, + android.MockFS{ + "package_bar/Android.bp": []byte(` + aidl_library { + name: "bar", + } + `), + }.AddToFixture(), + ). + ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("at least srcs or hdrs prop must be non-empty")). + RunTest(t) +} |