blob: 416a7eec0bd43c2eb64930f86a7cf59c188084a9 [file] [log] [blame]
Nan Zhangdb0b9a32017-02-27 10:12:13 -08001// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package python
16
17// This file contains the module types for building Python binary.
18
19import (
20 "fmt"
Nan Zhangdb0b9a32017-02-27 10:12:13 -080021
Nan Zhangdb0b9a32017-02-27 10:12:13 -080022 "android/soong/android"
23)
24
25func init() {
26 android.RegisterModuleType("python_binary_host", PythonBinaryHostFactory)
27}
28
Nan Zhangd4e641b2017-07-12 12:55:28 -070029type BinaryProperties struct {
Nan Zhangdb0b9a32017-02-27 10:12:13 -080030 // the name of the source file that is the main entry point of the program.
31 // this file must also be listed in srcs.
32 // If left unspecified, module name is used instead.
33 // If name doesn’t match any filename in srcs, main must be specified.
Nan Zhangea568a42017-11-08 21:20:04 -080034 Main *string `android:"arch_variant"`
Nan Zhangdb0b9a32017-02-27 10:12:13 -080035
36 // set the name of the output binary.
Nan Zhangea568a42017-11-08 21:20:04 -080037 Stem *string `android:"arch_variant"`
Nan Zhangdb0b9a32017-02-27 10:12:13 -080038
39 // append to the name of the output binary.
Nan Zhangea568a42017-11-08 21:20:04 -080040 Suffix *string `android:"arch_variant"`
Nan Zhangc9c6cb72017-11-03 16:54:05 -070041
42 // list of compatibility suites (for example "cts", "vts") that the module should be
43 // installed into.
44 Test_suites []string `android:"arch_variant"`
Dan Willemsen6ca390f2019-02-14 23:17:08 -080045
46 // whether to use `main` when starting the executable. The default is true, when set to
47 // false it will act much like the normal `python` executable, but with the sources and
48 // libraries automatically included in the PYTHONPATH.
49 Autorun *bool `android:"arch_variant"`
Dan Shi6ffaaa82019-09-26 11:41:36 -070050
51 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
52 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
53 // explicitly.
54 Auto_gen_config *bool
Nan Zhangdb0b9a32017-02-27 10:12:13 -080055}
56
Nan Zhangd4e641b2017-07-12 12:55:28 -070057type binaryDecorator struct {
58 binaryProperties BinaryProperties
Nan Zhangdb0b9a32017-02-27 10:12:13 -080059
Nan Zhangd9ec5e72017-12-01 20:00:31 +000060 *pythonInstaller
Nan Zhangdb0b9a32017-02-27 10:12:13 -080061}
62
Nan Zhangd4e641b2017-07-12 12:55:28 -070063type IntermPathProvider interface {
64 IntermPathForModuleOut() android.OptionalPath
Nan Zhang5323f8e2017-05-10 13:37:54 -070065}
66
Nan Zhangdb0b9a32017-02-27 10:12:13 -080067var (
Liz Kammerdd849a82020-06-12 16:38:45 -070068 StubTemplateHost = "build/soong/python/scripts/stub_template_host.txt"
Nan Zhangdb0b9a32017-02-27 10:12:13 -080069)
70
Nan Zhangd4e641b2017-07-12 12:55:28 -070071func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
72 module := newModule(hod, android.MultilibFirst)
Nan Zhangd9ec5e72017-12-01 20:00:31 +000073 decorator := &binaryDecorator{pythonInstaller: NewPythonInstaller("bin", "")}
Nan Zhangdb0b9a32017-02-27 10:12:13 -080074
Nan Zhangd4e641b2017-07-12 12:55:28 -070075 module.bootstrapper = decorator
76 module.installer = decorator
Nan Zhang5323f8e2017-05-10 13:37:54 -070077
Nan Zhangd4e641b2017-07-12 12:55:28 -070078 return module, decorator
Nan Zhangdb0b9a32017-02-27 10:12:13 -080079}
80
Nan Zhangd4e641b2017-07-12 12:55:28 -070081func PythonBinaryHostFactory() android.Module {
Jiyong Park1613e552020-09-14 19:43:17 +090082 module, _ := NewBinary(android.HostSupported)
Nan Zhangdb0b9a32017-02-27 10:12:13 -080083
Liz Kammerd737d022020-11-16 15:42:51 -080084 return module.init()
Nan Zhangd4e641b2017-07-12 12:55:28 -070085}
86
Dan Willemsen6ca390f2019-02-14 23:17:08 -080087func (binary *binaryDecorator) autorun() bool {
88 return BoolDefault(binary.binaryProperties.Autorun, true)
89}
90
Nan Zhangd4e641b2017-07-12 12:55:28 -070091func (binary *binaryDecorator) bootstrapperProps() []interface{} {
92 return []interface{}{&binary.binaryProperties}
93}
94
Nan Zhang1db85402017-12-18 13:20:23 -080095func (binary *binaryDecorator) bootstrap(ctx android.ModuleContext, actualVersion string,
96 embeddedLauncher bool, srcsPathMappings []pathMapping, srcsZip android.Path,
97 depsSrcsZips android.Paths) android.OptionalPath {
Nan Zhangdb0b9a32017-02-27 10:12:13 -080098
Dan Willemsen6ca390f2019-02-14 23:17:08 -080099 main := ""
100 if binary.autorun() {
101 main = binary.getPyMainFile(ctx, srcsPathMappings)
102 }
Nan Zhangd4e641b2017-07-12 12:55:28 -0700103
Nan Zhangcba97e62018-09-26 15:14:10 -0700104 var launcherPath android.OptionalPath
Nan Zhang1db85402017-12-18 13:20:23 -0800105 if embeddedLauncher {
Colin Crossee6143c2017-12-30 17:54:27 -0800106 ctx.VisitDirectDepsWithTag(launcherTag, func(m android.Module) {
Nan Zhangd4e641b2017-07-12 12:55:28 -0700107 if provider, ok := m.(IntermPathProvider); ok {
Nan Zhangcba97e62018-09-26 15:14:10 -0700108 if launcherPath.Valid() {
Nan Zhangd4e641b2017-07-12 12:55:28 -0700109 panic(fmt.Errorf("launcher path was found before: %q",
Nan Zhang1db85402017-12-18 13:20:23 -0800110 launcherPath))
Nan Zhangd4e641b2017-07-12 12:55:28 -0700111 }
Nan Zhangcba97e62018-09-26 15:14:10 -0700112 launcherPath = provider.IntermPathForModuleOut()
Nan Zhangd4e641b2017-07-12 12:55:28 -0700113 }
114 })
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800115 }
116
Nan Zhang1db85402017-12-18 13:20:23 -0800117 binFile := registerBuildActionForParFile(ctx, embeddedLauncher, launcherPath,
118 binary.getHostInterpreterName(ctx, actualVersion),
119 main, binary.getStem(ctx), append(android.Paths{srcsZip}, depsSrcsZips...))
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800120
Nan Zhang5323f8e2017-05-10 13:37:54 -0700121 return android.OptionalPathForPath(binFile)
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800122}
123
Nan Zhangd4e641b2017-07-12 12:55:28 -0700124// get host interpreter name.
125func (binary *binaryDecorator) getHostInterpreterName(ctx android.ModuleContext,
Nan Zhang1db85402017-12-18 13:20:23 -0800126 actualVersion string) string {
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800127 var interp string
Nan Zhang1db85402017-12-18 13:20:23 -0800128 switch actualVersion {
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800129 case pyVersion2:
Dan Willemsen7d1681a2017-09-25 13:47:40 -0700130 interp = "python2.7"
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800131 case pyVersion3:
132 interp = "python3"
133 default:
134 panic(fmt.Errorf("unknown Python actualVersion: %q for module: %q.",
Nan Zhang1db85402017-12-18 13:20:23 -0800135 actualVersion, ctx.ModuleName()))
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800136 }
137
138 return interp
139}
140
141// find main program path within runfiles tree.
Nan Zhangd4e641b2017-07-12 12:55:28 -0700142func (binary *binaryDecorator) getPyMainFile(ctx android.ModuleContext,
143 srcsPathMappings []pathMapping) string {
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800144 var main string
Nan Zhangea568a42017-11-08 21:20:04 -0800145 if String(binary.binaryProperties.Main) == "" {
Nan Zhangd4e641b2017-07-12 12:55:28 -0700146 main = ctx.ModuleName() + pyExt
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800147 } else {
Nan Zhangea568a42017-11-08 21:20:04 -0800148 main = String(binary.binaryProperties.Main)
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800149 }
150
Nan Zhangd4e641b2017-07-12 12:55:28 -0700151 for _, path := range srcsPathMappings {
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800152 if main == path.src.Rel() {
153 return path.dest
154 }
155 }
156 ctx.PropertyErrorf("main", "%q is not listed in srcs.", main)
157
158 return ""
159}
160
Nan Zhangd4e641b2017-07-12 12:55:28 -0700161func (binary *binaryDecorator) getStem(ctx android.ModuleContext) string {
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800162 stem := ctx.ModuleName()
Nan Zhangea568a42017-11-08 21:20:04 -0800163 if String(binary.binaryProperties.Stem) != "" {
164 stem = String(binary.binaryProperties.Stem)
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800165 }
166
Nan Zhangea568a42017-11-08 21:20:04 -0800167 return stem + String(binary.binaryProperties.Suffix)
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800168}