diff options
| author | 2020-09-30 08:21:36 +0000 | |
|---|---|---|
| committer | 2020-09-30 08:21:36 +0000 | |
| commit | d2ff08710b539dc798c29828e639cf577dad40bf (patch) | |
| tree | 9567a3e8d17415e3acf06cfd1b1ef7a9fdde46f2 | |
| parent | 21de510915dadd0cdf223d1f3e0e3a19efac4096 (diff) | |
| parent | a6351caf1220538a61d03ab17efa8d85572d4bf9 (diff) | |
Merge changes Icbbf176c,I52beadc8
* changes:
rust: Add ref to generated sources (aidl, bindgen)
rust: refactor projectGeneratorSingleton
| -rw-r--r-- | rust/project_json.go | 100 | ||||
| -rw-r--r-- | rust/project_json_test.go | 39 | ||||
| -rw-r--r-- | rust/testing.go | 1 |
3 files changed, 98 insertions, 42 deletions
diff --git a/rust/project_json.go b/rust/project_json.go index 831047938..8d161b2d7 100644 --- a/rust/project_json.go +++ b/rust/project_json.go @@ -30,16 +30,6 @@ import ( // // $ SOONG_GEN_RUST_PROJECT=1 m nothing -func init() { - android.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton) -} - -func rustProjectGeneratorSingleton() android.Singleton { - return &projectGeneratorSingleton{} -} - -type projectGeneratorSingleton struct{} - const ( // Environment variables used to control the behavior of this singleton. envVariableCollectRustDeps = "SOONG_GEN_RUST_PROJECT" @@ -49,6 +39,7 @@ const ( // The format of rust-project.json is not yet finalized. A current description is available at: // https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/manual.adoc#non-cargo-based-projects type rustProjectDep struct { + // The Crate attribute is the index of the dependency in the Crates array in rustProjectJson. Crate int `json:"crate"` Name string `json:"name"` } @@ -71,12 +62,50 @@ type crateInfo struct { Deps map[string]int } -func mergeDependencies(ctx android.SingletonContext, project *rustProjectJson, - knownCrates map[string]crateInfo, module android.Module, - crate *rustProjectCrate, deps map[string]int) { +type projectGeneratorSingleton struct { + project rustProjectJson + knownCrates map[string]crateInfo +} + +func rustProjectGeneratorSingleton() android.Singleton { + return &projectGeneratorSingleton{} +} + +func init() { + android.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton) +} + +// librarySource finds the main source file (.rs) for a crate. +func librarySource(ctx android.SingletonContext, rModule *Module, rustLib *libraryDecorator) (string, bool) { + srcs := rustLib.baseCompiler.Properties.Srcs + if len(srcs) != 0 { + return path.Join(ctx.ModuleDir(rModule), srcs[0]), true + } + if !rustLib.source() { + return "", false + } + // It is a SourceProvider module. If this module is host only, uses the variation for the host. + // Otherwise, use the variation for the primary target. + switch rModule.hod { + case android.HostSupported: + case android.HostSupportedNoCross: + if rModule.Target().String() != ctx.Config().BuildOSTarget.String() { + return "", false + } + default: + if rModule.Target().String() != ctx.Config().Targets[android.Android][0].String() { + return "", false + } + } + src := rustLib.sourceProvider.Srcs()[0] + return src.String(), true +} + +func (singleton *projectGeneratorSingleton) mergeDependencies(ctx android.SingletonContext, + module android.Module, crate *rustProjectCrate, deps map[string]int) { ctx.VisitDirectDeps(module, func(child android.Module) { - childId, childCrateName, ok := appendLibraryAndDeps(ctx, project, knownCrates, child) + childId, childCrateName, ok := singleton.appendLibraryAndDeps(ctx, child) if !ok { return } @@ -88,12 +117,10 @@ func mergeDependencies(ctx android.SingletonContext, project *rustProjectJson, }) } -// appendLibraryAndDeps creates a rustProjectCrate for the module argument and -// appends it to the rustProjectJson struct. It visits the dependencies of the -// module depth-first. If the current module is already in knownCrates, its -// dependencies are merged. Returns a tuple (id, crate_name, ok). -func appendLibraryAndDeps(ctx android.SingletonContext, project *rustProjectJson, - knownCrates map[string]crateInfo, module android.Module) (int, string, bool) { +// appendLibraryAndDeps creates a rustProjectCrate for the module argument and appends it to singleton.project. +// It visits the dependencies of the module depth-first so the dependency ID can be added to the current module. If the +// current module is already in singleton.knownCrates, its dependencies are merged. Returns a tuple (id, crate_name, ok). +func (singleton *projectGeneratorSingleton) appendLibraryAndDeps(ctx android.SingletonContext, module android.Module) (int, string, bool) { rModule, ok := module.(*Module) if !ok { return 0, "", false @@ -107,46 +134,45 @@ func appendLibraryAndDeps(ctx android.SingletonContext, project *rustProjectJson } moduleName := ctx.ModuleName(module) crateName := rModule.CrateName() - if cInfo, ok := knownCrates[moduleName]; ok { + if cInfo, ok := singleton.knownCrates[moduleName]; ok { // We have seen this crate already; merge any new dependencies. - crate := project.Crates[cInfo.ID] - mergeDependencies(ctx, project, knownCrates, module, &crate, cInfo.Deps) - project.Crates[cInfo.ID] = crate + crate := singleton.project.Crates[cInfo.ID] + singleton.mergeDependencies(ctx, module, &crate, cInfo.Deps) + singleton.project.Crates[cInfo.ID] = crate return cInfo.ID, crateName, true } crate := rustProjectCrate{Deps: make([]rustProjectDep, 0), Cfgs: make([]string, 0)} - srcs := rustLib.baseCompiler.Properties.Srcs - if len(srcs) == 0 { + rootModule, ok := librarySource(ctx, rModule, rustLib) + if !ok { return 0, "", false } - crate.RootModule = path.Join(ctx.ModuleDir(rModule), srcs[0]) + crate.RootModule = rootModule crate.Edition = rustLib.baseCompiler.edition() deps := make(map[string]int) - mergeDependencies(ctx, project, knownCrates, module, &crate, deps) + singleton.mergeDependencies(ctx, module, &crate, deps) - id := len(project.Crates) - knownCrates[moduleName] = crateInfo{ID: id, Deps: deps} - project.Crates = append(project.Crates, crate) + id := len(singleton.project.Crates) + singleton.knownCrates[moduleName] = crateInfo{ID: id, Deps: deps} + singleton.project.Crates = append(singleton.project.Crates, crate) // rust-analyzer requires that all crates belong to at least one root: // https://github.com/rust-analyzer/rust-analyzer/issues/4735. - project.Roots = append(project.Roots, path.Dir(crate.RootModule)) + singleton.project.Roots = append(singleton.project.Roots, path.Dir(crate.RootModule)) return id, crateName, true } -func (r *projectGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) { +func (singleton *projectGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) { if !ctx.Config().IsEnvTrue(envVariableCollectRustDeps) { return } - project := rustProjectJson{} - knownCrates := make(map[string]crateInfo) + singleton.knownCrates = make(map[string]crateInfo) ctx.VisitAllModules(func(module android.Module) { - appendLibraryAndDeps(ctx, &project, knownCrates, module) + singleton.appendLibraryAndDeps(ctx, module) }) path := android.PathForOutput(ctx, rustProjectJsonFileName) - err := createJsonFile(project, path) + err := createJsonFile(singleton.project, path) if err != nil { ctx.Errorf(err.Error()) } diff --git a/rust/project_json_test.go b/rust/project_json_test.go index 85219404a..8c1c43623 100644 --- a/rust/project_json_test.go +++ b/rust/project_json_test.go @@ -18,6 +18,7 @@ import ( "encoding/json" "io/ioutil" "path/filepath" + "strings" "testing" "android/soong/android" @@ -100,22 +101,50 @@ func TestProjectJsonBindGen(t *testing.T) { rust_library { name: "liba", srcs: ["src/lib.rs"], - rlibs: ["libbindings"], + rlibs: ["libbindings1"], crate_name: "a" } rust_bindgen { - name: "libbindings", - crate_name: "bindings", - source_stem: "bindings", + name: "libbindings1", + crate_name: "bindings1", + source_stem: "bindings1", host_supported: true, wrapper_src: "src/any.h", } + rust_library_host { + name: "libb", + srcs: ["src/lib.rs"], + rustlibs: ["libbindings2"], + crate_name: "b" + } + rust_bindgen_host { + name: "libbindings2", + crate_name: "bindings2", + source_stem: "bindings2", + wrapper_src: "src/any.h", + } ` + GatherRequiredDepsForTest() fs := map[string][]byte{ "src/lib.rs": nil, } jsonContent := testProjectJson(t, bp, fs) - validateJsonCrates(t, jsonContent) + crates := validateJsonCrates(t, jsonContent) + for _, c := range crates { + crate, ok := c.(map[string]interface{}) + if !ok { + t.Fatalf("Unexpected type for crate: %v", c) + } + rootModule, ok := crate["root_module"].(string) + if !ok { + t.Fatalf("Unexpected type for root_module: %v", crate["root_module"]) + } + if strings.Contains(rootModule, "libbindings1") && !strings.Contains(rootModule, "android_arm64") { + t.Errorf("The source for libbindings1 does not contain android_arm64, got %v", rootModule) + } + if strings.Contains(rootModule, "libbindings2") && !strings.Contains(rootModule, "linux_glibc") { + t.Errorf("The source for libbindings2 does not contain linux_glibc, got %v", rootModule) + } + } } func TestProjectJsonMultiVersion(t *testing.T) { diff --git a/rust/testing.go b/rust/testing.go index ee303ed02..42b0da171 100644 --- a/rust/testing.go +++ b/rust/testing.go @@ -117,6 +117,7 @@ func CreateTestContext() *android.TestContext { ctx.RegisterModuleType("rust_binary", RustBinaryFactory) ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory) ctx.RegisterModuleType("rust_bindgen", RustBindgenFactory) + ctx.RegisterModuleType("rust_bindgen_host", RustBindgenHostFactory) ctx.RegisterModuleType("rust_test", RustTestFactory) ctx.RegisterModuleType("rust_test_host", RustTestHostFactory) ctx.RegisterModuleType("rust_library", RustLibraryFactory) |