| // Copyright (C) 2021 The Android Open Source Project |
| // |
| // 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 |
| |
| import ( |
| "android/soong/android" |
| "android/soong/rust" |
| |
| "strings" |
| |
| "github.com/google/blueprint" |
| "github.com/google/blueprint/proptools" |
| ) |
| |
| var ( |
| aidlRustGlueRule = pctx.StaticRule("aidlRustGlueRule", blueprint.RuleParams{ |
| Command: `${aidlRustGlueCmd} ${out} ${root} ${in} ${imports}`, |
| CommandDeps: []string{"${aidlRustGlueCmd}"}, |
| }, "root", "imports") |
| ) |
| |
| type aidlRustSourceProviderProperties struct { |
| SourceGen string `android:"path"` |
| Imports []string |
| Version string |
| AidlInterfaceName string |
| } |
| |
| type aidlRustSourceProvider struct { |
| *rust.BaseSourceProvider |
| |
| properties aidlRustSourceProviderProperties |
| } |
| |
| var aidlRustSourceTag = struct { |
| blueprint.DependencyTag |
| }{} |
| |
| func (sp *aidlRustSourceProvider) GenerateSource(ctx rust.ModuleContext, _ rust.PathDeps) android.Path { |
| sourceStem := proptools.String(sp.BaseSourceProvider.Properties.Source_stem) |
| topLevelOutputFile := android.PathForModuleOut(ctx, sourceStem+".rs") |
| |
| aidlGenModule := ctx.GetDirectDepWithTag(sp.properties.SourceGen, aidlRustSourceTag) |
| // Find the gen directory for the source module |
| srcGenDir := aidlGenModule.(*aidlGenRule).genOutDir |
| srcPaths := aidlGenModule.(*aidlGenRule).genOutputs.Paths() |
| |
| // In Rust, we import our dependency crates into `mangled`: |
| // use dependency::mangled::*; |
| // so we can use the crate:: Rust path prefix to refer to |
| // both crate-local and imported paths (from dependencies) |
| importFlags := make([]string, len(sp.properties.Imports)) |
| for i, dep := range trimVersionSuffixInList(sp.properties.Imports) { |
| importFlags[i] = "-I" + fixRustName(dep) |
| } |
| |
| // In Rust, we need to do some extra post-processing: |
| // emit a top-level foo.rs that includes all the generated .rs |
| // files verbatim ("glued" together). The generated glue file |
| // replicates the AIDL package hierarchy from the input |
| // .aidl files in two ways: |
| // * 1:1 mapping in the crate::aidl namespace, used by downstream users |
| // * mangled in the crate::mangled namespace, used internally |
| // to resolve AIDL package paths between dependencies |
| ctx.Build(pctx, android.BuildParams{ |
| Rule: aidlRustGlueRule, |
| Inputs: srcPaths, |
| Output: topLevelOutputFile, |
| Args: map[string]string{ |
| "root": srcGenDir.String(), |
| "imports": strings.Join(importFlags, " "), |
| }, |
| }) |
| |
| sp.BaseSourceProvider.OutputFiles = android.Paths{topLevelOutputFile} |
| return topLevelOutputFile |
| } |
| |
| func (sp *aidlRustSourceProvider) SourceProviderProps() []interface{} { |
| return append(sp.BaseSourceProvider.SourceProviderProps(), |
| &sp.properties) |
| } |
| |
| func (sp *aidlRustSourceProvider) SourceProviderDeps(ctx rust.DepsContext, deps rust.Deps) rust.Deps { |
| deps = sp.BaseSourceProvider.SourceProviderDeps(ctx, deps) |
| deps.Rustlibs = append(deps.Rustlibs, "libbinder_rs", "liblazy_static") |
| deps.Rustlibs = append(deps.Rustlibs, wrap("", getImportsWithVersion(ctx, sp.properties.AidlInterfaceName, sp.properties.Version), "-"+langRust)...) |
| deps.ProcMacros = append(deps.ProcMacros, "libasync_trait") |
| // Add a depencency to the source module (*-rust-source) directly via `ctx` because |
| // the source module is specific to aidlRustSourceProvider and we don't want the rust module |
| // to know about it. |
| ctx.AddDependency(ctx.Module(), aidlRustSourceTag, sp.properties.SourceGen) |
| |
| return deps |
| } |
| |
| func (sp *aidlRustSourceProvider) AndroidMk(ctx rust.AndroidMkContext, ret *android.AndroidMkEntries) { |
| ctx.SubAndroidMk(ret, sp.BaseSourceProvider) |
| ret.ExtraEntries = append(ret.ExtraEntries, |
| func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { |
| entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) |
| }) |
| } |
| |
| func aidlRustLibraryFactory() android.Module { |
| sourceProvider := &aidlRustSourceProvider{ |
| BaseSourceProvider: rust.NewSourceProvider(), |
| properties: aidlRustSourceProviderProperties{}, |
| } |
| |
| module := rust.NewSourceProviderModule(android.HostAndDeviceSupported, sourceProvider, false, false) |
| return module.Init() |
| } |