From 178d5fefc0cea9d0f031c0bdee125b9d960f32c3 Mon Sep 17 00:00:00 2001 From: Jeff Gaston Date: Wed, 29 Nov 2017 23:54:03 +0000 Subject: [PATCH] Revert "Soong support for namespaces" This reverts commit 63a250a336a1b910836eeb4caebcf5b4f8d91c2a. Reason for revert: Some failures: namespace_test.go:648: dir1/Blueprints:2:4: a namespace must be the first module in the file such as New Build Breakage: aosp-master/build_test @ 4475274 Change-Id: I1b5db8eb934e51ff22241bfca44199d886b1393b --- Android.bp | 2 - android/androidmk.go | 6 - android/module.go | 14 +- android/mutator.go | 1 - android/namespace.go | 402 ----------------------- android/namespace_test.go | 652 -------------------------------------- android/testing.go | 9 +- android/variable.go | 2 - cmd/soong_build/main.go | 19 +- ui/build/dumpvars.go | 1 - 10 files changed, 6 insertions(+), 1102 deletions(-) delete mode 100644 android/namespace.go delete mode 100644 android/namespace_test.go diff --git a/Android.bp b/Android.bp index b9414cede..6d2b80494 100644 --- a/Android.bp +++ b/Android.bp @@ -50,7 +50,6 @@ bootstrap_go_package { "android/makevars.go", "android/module.go", "android/mutator.go", - "android/namespace.go", "android/onceper.go", "android/package_ctx.go", "android/paths.go", @@ -68,7 +67,6 @@ bootstrap_go_package { testSrcs: [ "android/config_test.go", "android/expand_test.go", - "android/namespace_test.go", "android/paths_test.go", "android/prebuilt_test.go", "android/util_test.go", diff --git a/android/androidmk.go b/android/androidmk.go index dd412d782..aff43fab2 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -159,12 +159,6 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.M return nil } - if !amod.commonProperties.NamespaceExportedToMake { - // TODO(jeffrygaston) do we want to validate that there are no modules being - // exported to Kati that depend on this module? - return nil - } - data := provider.AndroidMk() if data.Include == "" { diff --git a/android/module.go b/android/module.go index 1608f4b91..0eb48203e 100644 --- a/android/module.go +++ b/android/module.go @@ -211,8 +211,6 @@ type commonProperties struct { ArchSpecific bool `blueprint:"mutated"` SkipInstall bool `blueprint:"mutated"` - - NamespaceExportedToMake bool `blueprint:"mutated"` } type hostAndDeviceProperties struct { @@ -478,13 +476,8 @@ func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) { var deps Paths - namespacePrefix := ctx.Namespace().(*Namespace).id - if namespacePrefix != "" { - namespacePrefix = namespacePrefix + "-" - } - if len(allInstalledFiles) > 0 { - name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install") + name := PathForPhony(ctx, ctx.ModuleName()+"-install") ctx.Build(pctx, BuildParams{ Rule: blueprint.Phony, Output: name, @@ -496,7 +489,7 @@ func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) { } if len(allCheckbuildFiles) > 0 { - name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild") + name := PathForPhony(ctx, ctx.ModuleName()+"-checkbuild") ctx.Build(pctx, BuildParams{ Rule: blueprint.Phony, Output: name, @@ -512,10 +505,9 @@ func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) { suffix = "-soong" } - name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix) ctx.Build(pctx, BuildParams{ Rule: blueprint.Phony, - Outputs: []WritablePath{name}, + Output: PathForPhony(ctx, ctx.ModuleName()+suffix), Implicits: deps, }) diff --git a/android/mutator.go b/android/mutator.go index 3c6e3e371..cc3f1f3b5 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -86,7 +86,6 @@ func registerArchMutator(ctx RegisterMutatorsContext) { } var preDeps = []RegisterMutatorFunc{ - RegisterNamespaceMutator, registerArchMutator, } diff --git a/android/namespace.go b/android/namespace.go deleted file mode 100644 index 5f7e96201..000000000 --- a/android/namespace.go +++ /dev/null @@ -1,402 +0,0 @@ -// Copyright 2017 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 android - -import ( - "fmt" - "path/filepath" - "sort" - "strconv" - "strings" - "sync" - "sync/atomic" - - "github.com/google/blueprint" -) - -// This file implements namespaces -const ( - namespacePrefix = "//" - modulePrefix = ":" -) - -func init() { - RegisterModuleType("soong_namespace", NamespaceFactory) -} - -// threadsafe sorted list -type sortedNamespaces struct { - lock sync.Mutex - items []*Namespace - sorted bool -} - -func (s *sortedNamespaces) add(namespace *Namespace) { - s.lock.Lock() - defer s.lock.Unlock() - if s.sorted { - panic("It is not supported to call sortedNamespaces.add() after sortedNamespaces.sortedItems()") - } - s.items = append(s.items, namespace) -} - -func (s *sortedNamespaces) sortedItems() []*Namespace { - s.lock.Lock() - defer s.lock.Unlock() - if !s.sorted { - less := func(i int, j int) bool { - return s.items[i].Path < s.items[j].Path - } - sort.Slice(s.items, less) - s.sorted = true - } - return s.items -} - -// A NameResolver implements blueprint.NameInterface, and implements the logic to -// find a module from namespaces based on a query string. -// A query string can be a module name or can be be "//namespace_path:module_path" -type NameResolver struct { - rootNamespace *Namespace - - // id counter for atomic.AddInt32 - numNamespaces int32 - - // All namespaces, without duplicates. - sortedNamespaces sortedNamespaces - - // Map from dir to namespace. Will have duplicates if two dirs are part of the same namespace. - namespacesByDir sync.Map // if generics were supported, this would be sync.Map[string]*Namespace - - // func telling whether to export a namespace to Kati - namespaceExportFilter func(*Namespace) bool -} - -func NewNameResolver(namespaceExportFilter func(*Namespace) bool) *NameResolver { - namespacesByDir := sync.Map{} - - r := &NameResolver{ - namespacesByDir: namespacesByDir, - namespaceExportFilter: namespaceExportFilter, - } - r.rootNamespace = r.newNamespace(".") - r.rootNamespace.visibleNamespaces = []*Namespace{r.rootNamespace} - r.addNamespace(r.rootNamespace) - - return r -} - -func (r *NameResolver) newNamespace(path string) *Namespace { - namespace := NewNamespace(path) - - namespace.exportToKati = r.namespaceExportFilter(namespace) - - nextId := atomic.AddInt32(&r.numNamespaces, 1) - id := nextId - 1 - stringId := "" - if id > 0 { - stringId = strconv.Itoa(int(id)) - } - namespace.id = stringId - - return namespace -} - -func (r *NameResolver) addNewNamespaceForModule(module *NamespaceModule, dir string) error { - namespace := r.newNamespace(dir) - module.namespace = namespace - module.resolver = r - namespace.importedNamespaceNames = module.properties.Imports - return r.addNamespace(namespace) -} - -func (r *NameResolver) addNamespace(namespace *Namespace) (err error) { - existingNamespace, exists := r.namespaceAt(namespace.Path) - if exists { - if existingNamespace.Path == namespace.Path { - return fmt.Errorf("namespace %v already exists", namespace.Path) - } else { - // It would probably confuse readers if namespaces were declared anywhere but - // the top of the file, so we forbid declaring namespaces after anything else. - return fmt.Errorf("a namespace must be the first module in the file") - } - } - r.sortedNamespaces.add(namespace) - - r.namespacesByDir.Store(namespace.Path, namespace) - return nil -} - -// non-recursive check for namespace -func (r *NameResolver) namespaceAt(path string) (namespace *Namespace, found bool) { - mapVal, found := r.namespacesByDir.Load(path) - if !found { - return nil, false - } - return mapVal.(*Namespace), true -} - -// recursive search upward for a namespace -func (r *NameResolver) findNamespace(path string) (namespace *Namespace) { - namespace, found := r.namespaceAt(path) - if found { - return namespace - } - parentDir := filepath.Dir(path) - if parentDir == path { - return nil - } - namespace = r.findNamespace(parentDir) - r.namespacesByDir.Store(path, namespace) - return namespace -} - -func (r *NameResolver) NewModule(ctx blueprint.NamespaceContext, moduleGroup blueprint.ModuleGroup, module blueprint.Module) (namespace blueprint.Namespace, errs []error) { - // if this module is a namespace, then save it to our list of namespaces - newNamespace, ok := module.(*NamespaceModule) - if ok { - err := r.addNewNamespaceForModule(newNamespace, ctx.ModuleDir()) - if err != nil { - return nil, []error{err} - } - return nil, nil - } - - // if this module is not a namespace, then save it into the appropriate namespace - ns := r.findNamespaceFromCtx(ctx) - - _, errs = ns.moduleContainer.NewModule(ctx, moduleGroup, module) - if len(errs) > 0 { - return nil, errs - } - - amod, ok := module.(Module) - if ok { - // inform the module whether its namespace is one that we want to export to Make - amod.base().commonProperties.NamespaceExportedToMake = ns.exportToKati - } - - return ns, nil -} - -func (r *NameResolver) AllModules() []blueprint.ModuleGroup { - childLists := [][]blueprint.ModuleGroup{} - totalCount := 0 - for _, namespace := range r.sortedNamespaces.sortedItems() { - newModules := namespace.moduleContainer.AllModules() - totalCount += len(newModules) - childLists = append(childLists, newModules) - } - - allModules := make([]blueprint.ModuleGroup, 0, totalCount) - for _, childList := range childLists { - allModules = append(allModules, childList...) - } - return allModules -} - -// parses a fully-qualified path (like "//namespace_path:module_name") into a namespace name and a -// module name -func (r *NameResolver) parseFullyQualifiedName(name string) (namespaceName string, moduleName string, ok bool) { - if !strings.HasPrefix(name, namespacePrefix) { - return "", "", false - } - name = strings.TrimPrefix(name, namespacePrefix) - components := strings.Split(name, modulePrefix) - if len(components) != 2 { - return "", "", false - } - return components[0], components[1], true - -} - -func (r *NameResolver) getNamespacesToSearchForModule(sourceNamespace *Namespace) (searchOrder []*Namespace) { - return sourceNamespace.visibleNamespaces -} - -func (r *NameResolver) ModuleFromName(name string, namespace blueprint.Namespace) (group blueprint.ModuleGroup, found bool) { - // handle fully qualified references like "//namespace_path:module_name" - nsName, moduleName, isAbs := r.parseFullyQualifiedName(name) - if isAbs { - namespace, found := r.namespaceAt(nsName) - if !found { - return blueprint.ModuleGroup{}, false - } - container := namespace.moduleContainer - return container.ModuleFromName(moduleName, nil) - } - for _, candidate := range r.getNamespacesToSearchForModule(namespace.(*Namespace)) { - group, found = candidate.moduleContainer.ModuleFromName(name, nil) - if found { - return group, true - } - } - return blueprint.ModuleGroup{}, false - -} - -func (r *NameResolver) Rename(oldName string, newName string, namespace blueprint.Namespace) []error { - oldNs := r.findNamespace(oldName) - newNs := r.findNamespace(newName) - if oldNs != newNs { - return []error{fmt.Errorf("cannot rename %v to %v because the destination is outside namespace %v", oldName, newName, oldNs.Path)} - } - - oldName, err := filepath.Rel(oldNs.Path, oldName) - if err != nil { - panic(err) - } - newName, err = filepath.Rel(newNs.Path, newName) - if err != nil { - panic(err) - } - - return oldNs.moduleContainer.Rename(oldName, newName, nil) -} - -// resolve each element of namespace.importedNamespaceNames and put the result in namespace.visibleNamespaces -func (r *NameResolver) FindNamespaceImports(namespace *Namespace) (err error) { - namespace.visibleNamespaces = make([]*Namespace, 0, 2+len(namespace.importedNamespaceNames)) - // search itself first - namespace.visibleNamespaces = append(namespace.visibleNamespaces, namespace) - // search its imports next - for _, name := range namespace.importedNamespaceNames { - imp, ok := r.namespaceAt(name) - if !ok { - return fmt.Errorf("namespace %v does not exist", name) - } - namespace.visibleNamespaces = append(namespace.visibleNamespaces, imp) - } - // search the root namespace last - namespace.visibleNamespaces = append(namespace.visibleNamespaces, r.rootNamespace) - return nil -} - -func (r *NameResolver) MissingDependencyError(depender string, dependerNamespace blueprint.Namespace, depName string) (err error) { - text := fmt.Sprintf("%q depends on undefined module %q", depender, depName) - - _, _, isAbs := r.parseFullyQualifiedName(depName) - if isAbs { - // if the user gave a fully-qualified name, we don't need to look for other - // modules that they might have been referring to - return fmt.Errorf(text) - } - - // determine which namespaces the module can be found in - foundInNamespaces := []string{} - for _, namespace := range r.sortedNamespaces.sortedItems() { - _, found := namespace.moduleContainer.ModuleFromName(depName, nil) - if found { - foundInNamespaces = append(foundInNamespaces, namespace.Path) - } - } - if len(foundInNamespaces) > 0 { - // determine which namespaces are visible to dependerNamespace - dependerNs := dependerNamespace.(*Namespace) - searched := r.getNamespacesToSearchForModule(dependerNs) - importedNames := []string{} - for _, ns := range searched { - importedNames = append(importedNames, ns.Path) - } - text += fmt.Sprintf("\nModule %q is defined in namespace %q which can read these %v namespaces: %q", depender, dependerNs.Path, len(importedNames), importedNames) - text += fmt.Sprintf("\nModule %q can be found in these namespaces: %q", depName, foundInNamespaces) - } - - return fmt.Errorf(text) -} - -func (r *NameResolver) GetNamespace(ctx blueprint.NamespaceContext) blueprint.Namespace { - return r.findNamespaceFromCtx(ctx) -} - -func (r *NameResolver) findNamespaceFromCtx(ctx blueprint.NamespaceContext) *Namespace { - return r.findNamespace(ctx.ModuleDir()) -} - -var _ blueprint.NameInterface = (*NameResolver)(nil) - -type Namespace struct { - blueprint.NamespaceMarker - Path string - - // a unique name (derived from the path), to be used in generating unique module names without - // repeating the entire module path - Shortname string - - // names of namespaces listed as imports by this namespace - importedNamespaceNames []string - // all namespaces that should be searched when a module in this namespace declares a dependency - visibleNamespaces []*Namespace - - id string - - exportToKati bool - - moduleContainer blueprint.NameInterface -} - -func NewNamespace(path string) *Namespace { - return &Namespace{Path: path, moduleContainer: blueprint.NewSimpleNameInterface()} -} - -var _ blueprint.Namespace = (*Namespace)(nil) - -type NamespaceModule struct { - ModuleBase - - namespace *Namespace - resolver *NameResolver - - properties struct { - Imports []string - } -} - -func (n *NamespaceModule) DepsMutator(context BottomUpMutatorContext) { -} - -func (n *NamespaceModule) GenerateAndroidBuildActions(ctx ModuleContext) { -} - -func (n *NamespaceModule) GenerateBuildActions(ctx blueprint.ModuleContext) { -} - -func (n *NamespaceModule) Name() (name string) { - return *n.nameProperties.Name -} - -func NamespaceFactory() Module { - module := &NamespaceModule{} - - name := "soong_namespace" - module.nameProperties.Name = &name - - module.AddProperties(&module.properties) - return module -} - -func RegisterNamespaceMutator(ctx RegisterMutatorsContext) { - ctx.BottomUp("namespace_deps", namespaceDeps) -} - -func namespaceDeps(ctx BottomUpMutatorContext) { - module, ok := ctx.Module().(*NamespaceModule) - if ok { - err := module.resolver.FindNamespaceImports(module.namespace) - if err != nil { - ctx.ModuleErrorf(err.Error()) - } - } -} diff --git a/android/namespace_test.go b/android/namespace_test.go deleted file mode 100644 index b10b5287e..000000000 --- a/android/namespace_test.go +++ /dev/null @@ -1,652 +0,0 @@ -// Copyright 2017 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 android - -import ( - "errors" - "io/ioutil" - "os" - "path/filepath" - "testing" - - "github.com/google/blueprint" -) - -func TestDependingOnModuleInSameNamespace(t *testing.T) { - ctx := setupTest(t, - map[string]string{ - "dir1": ` - soong_namespace { - } - test_module { - name: "a", - } - test_module { - name: "b", - deps: ["a"], - } - `, - }, - ) - - a := getModule(ctx, "a") - b := getModule(ctx, "b") - if !dependsOn(ctx, b, a) { - t.Errorf("module b does not depend on module a in the same namespace") - } -} - -func TestDependingOnModuleInRootNamespace(t *testing.T) { - ctx := setupTest(t, - map[string]string{ - ".": ` - test_module { - name: "b", - deps: ["a"], - } - test_module { - name: "a", - } - `, - }, - ) - - a := getModule(ctx, "a") - b := getModule(ctx, "b") - if !dependsOn(ctx, b, a) { - t.Errorf("module b in root namespace does not depend on module a in the root namespace") - } -} - -func TestImplicitlyImportRootNamespace(t *testing.T) { - _ = setupTest(t, - map[string]string{ - ".": ` - test_module { - name: "a", - } - `, - "dir1": ` - soong_namespace { - } - test_module { - name: "b", - deps: ["a"], - } - `, - }, - ) - - // setupTest will report any errors -} - -func TestDependingOnModuleInImportedNamespace(t *testing.T) { - ctx := setupTest(t, - map[string]string{ - "dir1": ` - soong_namespace { - } - test_module { - name: "a", - } - `, - "dir2": ` - soong_namespace { - imports: ["dir1"], - } - test_module { - name: "b", - deps: ["a"], - } - `, - }, - ) - - a := getModule(ctx, "a") - b := getModule(ctx, "b") - if !dependsOn(ctx, b, a) { - t.Errorf("module b does not depend on module a in the same namespace") - } -} - -func TestDependingOnModuleInNonImportedNamespace(t *testing.T) { - _, errs := setupTestExpectErrs( - map[string]string{ - "dir1": ` - soong_namespace { - } - test_module { - name: "a", - } - `, - "dir2": ` - soong_namespace { - } - test_module { - name: "a", - } - `, - "dir3": ` - soong_namespace { - } - test_module { - name: "b", - deps: ["a"], - } - `, - }, - ) - - expectedErrors := []error{ - errors.New( - `dir3/Blueprints:4:4: "b" depends on undefined module "a" -Module "b" is defined in namespace "dir3" which can read these 2 namespaces: ["dir3" "."] -Module "a" can be found in these namespaces: ["dir1" "dir2"]`), - } - - if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() { - t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs) - } -} - -func TestDependingOnModuleByFullyQualifiedReference(t *testing.T) { - ctx := setupTest(t, - map[string]string{ - "dir1": ` - soong_namespace { - } - test_module { - name: "a", - } - `, - "dir2": ` - soong_namespace { - } - test_module { - name: "b", - deps: ["//dir1:a"], - } - `, - }, - ) - a := getModule(ctx, "a") - b := getModule(ctx, "b") - if !dependsOn(ctx, b, a) { - t.Errorf("module b does not depend on module a") - } -} - -func TestSameNameInTwoNamespaces(t *testing.T) { - ctx := setupTest(t, - map[string]string{ - "dir1": ` - soong_namespace { - } - test_module { - name: "a", - id: "1", - } - test_module { - name: "b", - deps: ["a"], - id: "2", - } - `, - "dir2": ` - soong_namespace { - } - test_module { - name: "a", - id:"3", - } - test_module { - name: "b", - deps: ["a"], - id:"4", - } - `, - }, - ) - - one := findModuleById(ctx, "1") - two := findModuleById(ctx, "2") - three := findModuleById(ctx, "3") - four := findModuleById(ctx, "4") - if !dependsOn(ctx, two, one) { - t.Fatalf("Module 2 does not depend on module 1 in its namespace") - } - if dependsOn(ctx, two, three) { - t.Fatalf("Module 2 depends on module 3 in another namespace") - } - if !dependsOn(ctx, four, three) { - t.Fatalf("Module 4 does not depend on module 3 in its namespace") - } - if dependsOn(ctx, four, one) { - t.Fatalf("Module 4 depends on module 1 in another namespace") - } -} - -func TestSearchOrder(t *testing.T) { - ctx := setupTest(t, - map[string]string{ - "dir1": ` - soong_namespace { - } - test_module { - name: "a", - id: "1", - } - `, - "dir2": ` - soong_namespace { - } - test_module { - name: "a", - id:"2", - } - test_module { - name: "b", - id:"3", - } - `, - "dir3": ` - soong_namespace { - } - test_module { - name: "a", - id:"4", - } - test_module { - name: "b", - id:"5", - } - test_module { - name: "c", - id:"6", - } - `, - ".": ` - test_module { - name: "a", - id: "7", - } - test_module { - name: "b", - id: "8", - } - test_module { - name: "c", - id: "9", - } - test_module { - name: "d", - id: "10", - } - `, - "dir4": ` - soong_namespace { - imports: ["dir1", "dir2", "dir3"] - } - test_module { - name: "test_me", - id:"0", - deps: ["a", "b", "c", "d"], - } - `, - }, - ) - - testMe := findModuleById(ctx, "0") - if !dependsOn(ctx, testMe, findModuleById(ctx, "1")) { - t.Errorf("test_me doesn't depend on id 1") - } - if !dependsOn(ctx, testMe, findModuleById(ctx, "3")) { - t.Errorf("test_me doesn't depend on id 3") - } - if !dependsOn(ctx, testMe, findModuleById(ctx, "6")) { - t.Errorf("test_me doesn't depend on id 6") - } - if !dependsOn(ctx, testMe, findModuleById(ctx, "10")) { - t.Errorf("test_me doesn't depend on id 10") - } - if numDeps(ctx, testMe) != 4 { - t.Errorf("num dependencies of test_me = %v, not 4\n", numDeps(ctx, testMe)) - } -} - -func TestTwoNamespacesCanImportEachOther(t *testing.T) { - _ = setupTest(t, - map[string]string{ - "dir1": ` - soong_namespace { - imports: ["dir2"] - } - test_module { - name: "a", - } - test_module { - name: "c", - deps: ["b"], - } - `, - "dir2": ` - soong_namespace { - imports: ["dir1"], - } - test_module { - name: "b", - deps: ["a"], - } - `, - }, - ) - - // setupTest will report any errors -} - -func TestImportingNonexistentNamespace(t *testing.T) { - _, errs := setupTestExpectErrs( - map[string]string{ - "dir1": ` - soong_namespace { - imports: ["a_nonexistent_namespace"] - } - test_module { - name: "a", - deps: ["a_nonexistent_module"] - } - `, - }, - ) - - // should complain about the missing namespace and not complain about the unresolvable dependency - expectedErrors := []error{ - errors.New(`dir1/Blueprints:2:4: module "soong_namespace": namespace a_nonexistent_namespace does not exist`), - } - if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() { - t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs) - } -} - -func TestNamespacesDontInheritParentNamespaces(t *testing.T) { - _, errs := setupTestExpectErrs( - map[string]string{ - "dir1": ` - soong_namespace { - } - test_module { - name: "a", - } - `, - "dir1/subdir1": ` - soong_namespace { - } - test_module { - name: "b", - deps: ["a"], - } - `, - }, - ) - - expectedErrors := []error{ - errors.New(`dir1/subdir1/Blueprints:4:4: "b" depends on undefined module "a" -Module "b" is defined in namespace "dir1/subdir1" which can read these 2 namespaces: ["dir1/subdir1" "."] -Module "a" can be found in these namespaces: ["dir1"]`), - } - if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() { - t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs) - } -} - -func TestModulesDoReceiveParentNamespace(t *testing.T) { - _ = setupTest(t, - map[string]string{ - "dir1": ` - soong_namespace { - } - test_module { - name: "a", - } - `, - "dir1/subdir": ` - test_module { - name: "b", - deps: ["a"], - } - `, - }, - ) - - // setupTest will report any errors -} - -func TestNamespaceImportsNotTransitive(t *testing.T) { - _, errs := setupTestExpectErrs( - map[string]string{ - "dir1": ` - soong_namespace { - } - test_module { - name: "a", - } - `, - "dir2": ` - soong_namespace { - imports: ["dir1"], - } - test_module { - name: "b", - deps: ["a"], - } - `, - "dir3": ` - soong_namespace { - imports: ["dir2"], - } - test_module { - name: "c", - deps: ["a"], - } - `, - }, - ) - - expectedErrors := []error{ - errors.New(`dir3/Blueprints:5:4: "c" depends on undefined module "a" -Module "c" is defined in namespace "dir3" which can read these 3 namespaces: ["dir3" "dir2" "."] -Module "a" can be found in these namespaces: ["dir1"]`), - } - if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() { - t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs) - } -} - -func TestTwoNamepacesInSameDir(t *testing.T) { - _, errs := setupTestExpectErrs( - map[string]string{ - "dir1": ` - soong_namespace { - } - soong_namespace { - } - `, - }, - ) - - expectedErrors := []error{ - errors.New(`dir1/Blueprints:4:4: namespace dir1 already exists`), - } - if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() { - t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs) - } -} - -func TestNamespaceNotAtTopOfFile(t *testing.T) { - _, errs := setupTestExpectErrs( - map[string]string{ - "dir1": ` - test_module { - name: "a" - } - soong_namespace { - } - `, - }, - ) - - expectedErrors := []error{ - errors.New(`dir1/Blueprints:5:4: a namespace must be the first module in the file`), - } - if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() { - t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs) - } -} - -func TestTwoModulesWithSameNameInSameNamespace(t *testing.T) { - _, errs := setupTestExpectErrs( - map[string]string{ - "dir1": ` - soong_namespace { - } - test_module { - name: "a" - } - test_module { - name: "a" - } - `, - }, - ) - - expectedErrors := []error{ - errors.New(`dir1/Blueprints:7:4: module "a" already defined - dir1/Blueprints:4:4 <-- previous definition here`), - } - if len(errs) != 1 || errs[0].Error() != expectedErrors[0].Error() { - t.Errorf("Incorrect errors. Expected:\n%v\n, got:\n%v\n", expectedErrors, errs) - } -} - -// some utils to support the tests - -func mockFiles(bps map[string]string) (files map[string][]byte) { - files = make(map[string][]byte, len(bps)) - files["Blueprints"] = []byte("") - for dir, text := range bps { - files[filepath.Join(dir, "Blueprints")] = []byte(text) - } - return files -} - -func setupTestExpectErrs(bps map[string]string) (ctx *TestContext, errs []error) { - buildDir, err := ioutil.TempDir("", "soong_namespace_test") - if err != nil { - return nil, []error{err} - } - defer os.RemoveAll(buildDir) - - config := TestConfig(buildDir, nil) - - ctx = NewTestContext() - ctx.MockFileSystem(mockFiles(bps)) - ctx.RegisterModuleType("test_module", ModuleFactoryAdaptor(newTestModule)) - ctx.RegisterModuleType("soong_namespace", ModuleFactoryAdaptor(NamespaceFactory)) - ctx.PreDepsMutators(RegisterNamespaceMutator) - ctx.Register() - - _, errs = ctx.ParseBlueprintsFiles("Blueprints") - if len(errs) > 0 { - return ctx, errs - } - _, errs = ctx.PrepareBuildActions(config) - return ctx, errs -} - -func setupTest(t *testing.T, bps map[string]string) (ctx *TestContext) { - ctx, errs := setupTestExpectErrs(bps) - failIfErrored(t, errs) - return ctx -} - -func dependsOn(ctx *TestContext, module TestingModule, possibleDependency TestingModule) bool { - depends := false - visit := func(dependency blueprint.Module) { - if dependency == possibleDependency.module { - depends = true - } - } - ctx.VisitDirectDeps(module.module, visit) - return depends -} - -func numDeps(ctx *TestContext, module TestingModule) int { - count := 0 - visit := func(dependency blueprint.Module) { - count++ - } - ctx.VisitDirectDeps(module.module, visit) - return count -} - -func getModule(ctx *TestContext, moduleName string) TestingModule { - return ctx.ModuleForTests(moduleName, "") -} - -func findModuleById(ctx *TestContext, id string) (module TestingModule) { - visit := func(candidate blueprint.Module) { - testModule, ok := candidate.(*testModule) - if ok { - if testModule.properties.Id == id { - module = TestingModule{testModule} - } - } - } - ctx.VisitAllModules(visit) - return module -} - -type testModule struct { - ModuleBase - properties struct { - Deps []string - Id string - } -} - -func (m *testModule) DepsMutator(ctx BottomUpMutatorContext) { - for _, d := range m.properties.Deps { - ctx.AddDependency(ctx.Module(), nil, d) - } -} - -func (m *testModule) GenerateAndroidBuildActions(ModuleContext) { -} - -func newTestModule() Module { - m := &testModule{} - m.AddProperties(&m.properties) - InitAndroidModule(m) - return m -} - -func failIfErrored(t *testing.T, errs []error) { - if len(errs) > 0 { - for _, err := range errs { - t.Error(err) - } - t.FailNow() - } -} diff --git a/android/testing.go b/android/testing.go index 60189d3d9..03572b300 100644 --- a/android/testing.go +++ b/android/testing.go @@ -23,16 +23,9 @@ import ( ) func NewTestContext() *TestContext { - ctx := &TestContext{ + return &TestContext{ Context: blueprint.NewContext(), } - - namespaceExportFilter := func(namespace *Namespace) bool { - return true - } - ctx.SetNameInterface(NewNameResolver(namespaceExportFilter)) - - return ctx } func NewTestArchContext() *TestContext { diff --git a/android/variable.go b/android/variable.go index dc24c1be3..13b5abf26 100644 --- a/android/variable.go +++ b/android/variable.go @@ -190,8 +190,6 @@ type productVariables struct { DeviceKernelHeaders []string `json:",omitempty"` DistDir *string `json:",omitempty"` - - NamespacesToExport []string `json:",omitempty"` } func boolPtr(v bool) *bool { diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index ddde1c595..e15a6bdd1 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -25,22 +25,6 @@ import ( "android/soong/android" ) -func newNameResolver(config android.Config) *android.NameResolver { - namespacePathsToExport := make(map[string]bool) - - for _, namespaceName := range config.ProductVariables.NamespacesToExport { - namespacePathsToExport[namespaceName] = true - } - - namespacePathsToExport["."] = true // always export the root namespace - - exportFilter := func(namespace *android.Namespace) bool { - return namespacePathsToExport[namespace.Path] - } - - return android.NewNameResolver(exportFilter) -} - func main() { flag.Parse() @@ -56,7 +40,8 @@ func main() { os.Exit(1) } - ctx.SetNameInterface(newNameResolver(configuration)) + // Temporary hack + //ctx.SetIgnoreUnknownModuleTypes(true) ctx.SetAllowMissingDependencies(configuration.AllowMissingDependencies()) diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go index 96f2274f9..fb20d63bc 100644 --- a/ui/build/dumpvars.go +++ b/ui/build/dumpvars.go @@ -106,7 +106,6 @@ var BannerVars = []string{ "AUX_OS_VARIANT_LIST", "TARGET_BUILD_PDK", "PDK_FUSION_PLATFORM_ZIP", - "PRODUCT_SOONG_NAMESPACES", } func Banner(make_vars map[string]string) string {