You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
4.5 KiB
129 lines
4.5 KiB
// 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")
|
|
ai := lookupInterface(sp.properties.AidlInterfaceName, ctx.Config())
|
|
for _, dep := range sp.properties.Imports {
|
|
deps.Rustlibs = append(deps.Rustlibs, ai.getImportWithVersion(sp.properties.Version, dep, ctx.Config())+"-"+langRust)
|
|
}
|
|
|
|
// 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)
|
|
return module.Init()
|
|
}
|