diff options
author | Nan Zhang <nanzhang@google.com> | 2017-05-10 13:37:54 -0700 |
---|---|---|
committer | Nan Zhang <nanzhang@google.com> | 2017-05-17 11:26:00 -0700 |
commit | 5323f8e32f9e08def4a68608510062c464ed4c1e (patch) | |
tree | 5c44e3cc7343a74e054171ee72c94856ce6257d1 /python | |
parent | 2c13abc95e3e2c6c12fff6aa42262ef3296c2a1b (diff) | |
download | build_soong-5323f8e32f9e08def4a68608510062c464ed4c1e.tar.gz build_soong-5323f8e32f9e08def4a68608510062c464ed4c1e.tar.bz2 build_soong-5323f8e32f9e08def4a68608510062c464ed4c1e.zip |
Add python_test_host module.
bug: 31676493
Test: created py_test modules in real folder. and ran 'mma'.
Change-Id: I22aa2fad74b11e4a31ea7a4c4a4f0ea64cd3fc94
Diffstat (limited to 'python')
-rw-r--r-- | python/androidmk.go | 74 | ||||
-rw-r--r-- | python/binary.go | 74 | ||||
-rw-r--r-- | python/installer.go | 39 | ||||
-rw-r--r-- | python/library.go | 4 | ||||
-rw-r--r-- | python/python.go | 36 | ||||
-rw-r--r-- | python/python_test.go | 2 | ||||
-rw-r--r-- | python/test.go | 54 |
7 files changed, 223 insertions, 60 deletions
diff --git a/python/androidmk.go b/python/androidmk.go new file mode 100644 index 00000000..0a79e736 --- /dev/null +++ b/python/androidmk.go @@ -0,0 +1,74 @@ +// 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 python + +import ( + "android/soong/android" + "fmt" + "io" + "path/filepath" + "strings" +) + +type subAndroidMkProvider interface { + AndroidMk(*pythonBaseModule, *android.AndroidMkData) +} + +func (p *pythonBaseModule) subAndroidMk(data *android.AndroidMkData, obj interface{}) { + if p.subAndroidMkOnce == nil { + p.subAndroidMkOnce = make(map[subAndroidMkProvider]bool) + } + if androidmk, ok := obj.(subAndroidMkProvider); ok { + if !p.subAndroidMkOnce[androidmk] { + p.subAndroidMkOnce[androidmk] = true + androidmk.AndroidMk(p, data) + } + } +} + +func (p *pythonBaseModule) AndroidMk() (ret android.AndroidMkData, err error) { + p.subAndroidMk(&ret, p.installer) + + return ret, nil +} + +func (p *pythonBinaryHostDecorator) AndroidMk(base *pythonBaseModule, ret *android.AndroidMkData) { + ret.Class = "EXECUTABLES" + base.subAndroidMk(ret, p.pythonDecorator.baseInstaller) +} + +func (p *pythonTestHostDecorator) AndroidMk(base *pythonBaseModule, ret *android.AndroidMkData) { + ret.Class = "NATIVE_TESTS" + base.subAndroidMk(ret, p.pythonDecorator.baseInstaller) +} + +func (installer *pythonInstaller) AndroidMk(base *pythonBaseModule, ret *android.AndroidMkData) { + // Soong installation is only supported for host modules. Have Make + // installation trigger Soong installation. + if base.Target().Os.Class == android.Host { + ret.OutputFile = android.OptionalPathForPath(installer.path) + } + + ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error { + path := installer.path.RelPathString() + dir, file := filepath.Split(path) + stem := strings.TrimSuffix(file, filepath.Ext(file)) + + fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+filepath.Ext(file)) + fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir)) + fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem) + return nil + }) +} diff --git a/python/binary.go b/python/binary.go index 4b4ccc28..81e8bd94 100644 --- a/python/binary.go +++ b/python/binary.go @@ -18,7 +18,6 @@ package python import ( "fmt" - "io" "path/filepath" "strings" @@ -31,7 +30,7 @@ func init() { android.RegisterModuleType("python_binary_host", PythonBinaryHostFactory) } -type PythonBinaryProperties struct { +type PythonBinaryBaseProperties struct { // the name of the source file that is the main entry point of the program. // this file must also be listed in srcs. // If left unspecified, module name is used instead. @@ -45,40 +44,53 @@ type PythonBinaryProperties struct { Suffix string } -type PythonBinary struct { +type pythonBinaryBase struct { pythonBaseModule - binaryProperties PythonBinaryProperties + binaryProperties PythonBinaryBaseProperties // soong_zip arguments from all its dependencies. depsParSpecs []parSpec // Python runfiles paths from all its dependencies. depsPyRunfiles []string +} - // the installation path for Python binary. - installPath android.OutputPath +type PythonBinaryHost struct { + pythonBinaryBase } -var _ PythonSubModule = (*PythonBinary)(nil) +var _ PythonSubModule = (*PythonBinaryHost)(nil) + +type pythonBinaryHostDecorator struct { + pythonDecorator +} + +func (p *pythonBinaryHostDecorator) install(ctx android.ModuleContext, file android.Path) { + p.pythonDecorator.baseInstaller.install(ctx, file) +} var ( stubTemplateHost = "build/soong/python/scripts/stub_template_host.txt" ) func PythonBinaryHostFactory() (blueprint.Module, []interface{}) { - module := &PythonBinary{} + decorator := &pythonBinaryHostDecorator{ + pythonDecorator: pythonDecorator{baseInstaller: NewPythonInstaller("bin")}} + + module := &PythonBinaryHost{} + module.pythonBaseModule.installer = decorator - return InitPythonBaseModule(&module.pythonBaseModule, module, android.HostSupportedNoCross, - &module.binaryProperties) + return InitPythonBaseModule(&module.pythonBinaryBase.pythonBaseModule, + &module.pythonBinaryBase, android.HostSupportedNoCross, &module.binaryProperties) } -func (p *PythonBinary) GeneratePythonBuildActions(ctx android.ModuleContext) { +func (p *pythonBinaryBase) GeneratePythonBuildActions(ctx android.ModuleContext) android.OptionalPath { p.pythonBaseModule.GeneratePythonBuildActions(ctx) // no Python source file for compiling par file. if len(p.pythonBaseModule.srcsPathMappings) == 0 && len(p.depsPyRunfiles) == 0 { - return + return android.OptionalPath{} } // the runfiles packages needs to be populated with "__init__.py". @@ -121,11 +133,11 @@ func (p *PythonBinary) GeneratePythonBuildActions(ctx android.ModuleContext) { main := p.getPyMainFile(ctx) if main == "" { - return + return android.OptionalPath{} } interp := p.getInterpreter(ctx) if interp == "" { - return + return android.OptionalPath{} } // we need remove "runfiles/" suffix since stub script starts @@ -134,13 +146,11 @@ func (p *PythonBinary) GeneratePythonBuildActions(ctx android.ModuleContext) { strings.TrimPrefix(main, runFiles+"/"), p.getStem(ctx), newPyPkgs, append(p.depsParSpecs, p.pythonBaseModule.parSpec)) - // install par file. - p.installPath = ctx.InstallFile( - android.PathForModuleInstall(ctx, "bin"), binFile) + return android.OptionalPathForPath(binFile) } // get interpreter path. -func (p *PythonBinary) getInterpreter(ctx android.ModuleContext) string { +func (p *pythonBinaryBase) getInterpreter(ctx android.ModuleContext) string { var interp string switch p.pythonBaseModule.properties.ActualVersion { case pyVersion2: @@ -156,7 +166,7 @@ func (p *PythonBinary) getInterpreter(ctx android.ModuleContext) string { } // find main program path within runfiles tree. -func (p *PythonBinary) getPyMainFile(ctx android.ModuleContext) string { +func (p *pythonBinaryBase) getPyMainFile(ctx android.ModuleContext) string { var main string if p.binaryProperties.Main == "" { main = p.BaseModuleName() + pyExt @@ -174,7 +184,7 @@ func (p *PythonBinary) getPyMainFile(ctx android.ModuleContext) string { return "" } -func (p *PythonBinary) getStem(ctx android.ModuleContext) string { +func (p *pythonBinaryBase) getStem(ctx android.ModuleContext) string { stem := ctx.ModuleName() if p.binaryProperties.Stem != "" { stem = p.binaryProperties.Stem @@ -209,27 +219,3 @@ func PathBeforeLastSlash(path string) string { } return "" } - -func (p *PythonBinary) GeneratePythonAndroidMk() (ret android.AndroidMkData, err error) { - // Soong installation is only supported for host modules. Have Make - // installation trigger Soong installation. - if p.pythonBaseModule.Target().Os.Class == android.Host { - ret.OutputFile = android.OptionalPathForPath(p.installPath) - } - ret.Class = "EXECUTABLES" - - ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error { - path := p.installPath.RelPathString() - dir, file := filepath.Split(path) - stem := strings.TrimSuffix(file, filepath.Ext(file)) - - fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+filepath.Ext(file)) - fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir)) - fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem) - - return nil - }) - - return - -} diff --git a/python/installer.go b/python/installer.go new file mode 100644 index 00000000..9c12f5f7 --- /dev/null +++ b/python/installer.go @@ -0,0 +1,39 @@ +// 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 python + +import ( + "android/soong/android" +) + +// This file handles installing python executables into their final location + +type pythonInstaller struct { + dir string + + path android.OutputPath +} + +func NewPythonInstaller(dir string) *pythonInstaller { + return &pythonInstaller{ + dir: dir, + } +} + +var _ installer = (*pythonInstaller)(nil) + +func (installer *pythonInstaller) install(ctx android.ModuleContext, file android.Path) { + installer.path = ctx.InstallFile(android.PathForModuleInstall(ctx, installer.dir), file) +} diff --git a/python/library.go b/python/library.go index 1deaeb8f..0b707566 100644 --- a/python/library.go +++ b/python/library.go @@ -37,7 +37,3 @@ func PythonLibraryHostFactory() (blueprint.Module, []interface{}) { return InitPythonBaseModule(&module.pythonBaseModule, module, android.HostSupportedNoCross) } - -func (p *PythonLibrary) GeneratePythonAndroidMk() (ret android.AndroidMkData, err error) { - return -} diff --git a/python/python.go b/python/python.go index 1c74c9af..ab80e4d2 100644 --- a/python/python.go +++ b/python/python.go @@ -110,11 +110,15 @@ type pythonBaseModule struct { // the soong_zip arguments for zipping current module source/data files. parSpec parSpec + + // the installer might be nil. + installer installer + + subAndroidMkOnce map[subAndroidMkProvider]bool } type PythonSubModule interface { - GeneratePythonBuildActions(ctx android.ModuleContext) - GeneratePythonAndroidMk() (ret android.AndroidMkData, err error) + GeneratePythonBuildActions(ctx android.ModuleContext) android.OptionalPath } type PythonDependency interface { @@ -123,6 +127,14 @@ type PythonDependency interface { GetParSpec() parSpec } +type pythonDecorator struct { + baseInstaller *pythonInstaller +} + +type installer interface { + install(ctx android.ModuleContext, path android.Path) +} + func (p *pythonBaseModule) GetSrcsPathMappings() []pathMapping { return p.srcsPathMappings } @@ -246,10 +258,14 @@ func uniqueLibs(ctx android.BottomUpMutatorContext, } func (p *pythonBaseModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { - p.subModule.GeneratePythonBuildActions(ctx) + installSource := p.subModule.GeneratePythonBuildActions(ctx) + + if p.installer != nil && installSource.Valid() { + p.installer.install(ctx, installSource.Path()) + } } -func (p *pythonBaseModule) GeneratePythonBuildActions(ctx android.ModuleContext) { +func (p *pythonBaseModule) GeneratePythonBuildActions(ctx android.ModuleContext) android.OptionalPath { // expand python files from "srcs" property. srcs := p.properties.Srcs switch p.properties.ActualVersion { @@ -277,7 +293,7 @@ func (p *pythonBaseModule) GeneratePythonBuildActions(ctx android.ModuleContext) strings.HasPrefix(pkg_path, "/") { ctx.PropertyErrorf("pkg_path", "%q is not a valid format.", p.properties.Pkg_path) - return + return android.OptionalPath{} } // pkg_path starts from "runfiles/" implicitly. pkg_path = filepath.Join(runFiles, pkg_path) @@ -291,6 +307,8 @@ func (p *pythonBaseModule) GeneratePythonBuildActions(ctx android.ModuleContext) p.parSpec = p.dumpFileList(ctx, pkg_path) p.uniqWholeRunfilesTree(ctx) + + return android.OptionalPath{} } // generate current module unique pathMappings: <dest: runfiles_path, src: source_path> @@ -409,7 +427,7 @@ func (p *pythonBaseModule) uniqWholeRunfilesTree(ctx android.ModuleContext) { } // binary needs the Python runfiles paths from all its // dependencies to fill __init__.py in each runfiles dir. - if sub, ok := p.subModule.(*PythonBinary); ok { + if sub, ok := p.subModule.(*pythonBinaryBase); ok { sub.depsPyRunfiles = append(sub.depsPyRunfiles, path.dest) } } @@ -421,7 +439,7 @@ func (p *pythonBaseModule) uniqWholeRunfilesTree(ctx android.ModuleContext) { } // binary needs the soong_zip arguments from all its // dependencies to generate executable par file. - if sub, ok := p.subModule.(*PythonBinary); ok { + if sub, ok := p.subModule.(*pythonBinaryBase); ok { sub.depsParSpecs = append(sub.depsParSpecs, dep.GetParSpec()) } } @@ -442,7 +460,3 @@ func fillInMap(ctx android.ModuleContext, m map[string]string, return true } - -func (p *pythonBaseModule) AndroidMk() (ret android.AndroidMkData, err error) { - return p.subModule.GeneratePythonAndroidMk() -} diff --git a/python/python_test.go b/python/python_test.go index c6b84519..3f719f8e 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -370,7 +370,7 @@ func expectModule(t *testing.T, ctx *blueprint.Context, buildDir, name, variant if !baseOk { t.Fatalf("%s is not Python module!", name) } - sub, subOk := base.subModule.(*PythonBinary) + sub, subOk := base.subModule.(*pythonBinaryBase) if !subOk { t.Fatalf("%s is not Python binary!", name) } diff --git a/python/test.go b/python/test.go new file mode 100644 index 00000000..83184383 --- /dev/null +++ b/python/test.go @@ -0,0 +1,54 @@ +// 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 python + +import ( + "android/soong/android" + "path/filepath" + + "github.com/google/blueprint" +) + +// This file contains the module types for building Python test. + +func init() { + android.RegisterModuleType("python_test_host", PythonTestHostFactory) +} + +type PythonTestHost struct { + pythonBinaryBase +} + +var _ PythonSubModule = (*PythonTestHost)(nil) + +type pythonTestHostDecorator struct { + pythonDecorator +} + +func (p *pythonTestHostDecorator) install(ctx android.ModuleContext, file android.Path) { + p.pythonDecorator.baseInstaller.dir = filepath.Join("nativetest", ctx.ModuleName()) + p.pythonDecorator.baseInstaller.install(ctx, file) +} + +func PythonTestHostFactory() (blueprint.Module, []interface{}) { + decorator := &pythonTestHostDecorator{ + pythonDecorator: pythonDecorator{baseInstaller: NewPythonInstaller("nativetest")}} + + module := &PythonBinaryHost{} + module.pythonBaseModule.installer = decorator + + return InitPythonBaseModule(&module.pythonBinaryBase.pythonBaseModule, + &module.pythonBinaryBase, android.HostSupportedNoCross, &module.binaryProperties) +} |