blob: f194354359eac85118bc0df0a9584cca79fe9142 [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 Ninja build actions for building Python program.
18
19import (
Nan Zhangd4e641b2017-07-12 12:55:28 -070020 "fmt"
Nan Zhangdb0b9a32017-02-27 10:12:13 -080021 "strings"
22
23 "android/soong/android"
24
25 "github.com/google/blueprint"
26 _ "github.com/google/blueprint/bootstrap"
27)
28
29var (
30 pctx = android.NewPackageContext("android/soong/python")
31
Nan Zhangd4e641b2017-07-12 12:55:28 -070032 host_par = pctx.AndroidStaticRule("host_par",
Nan Zhangdb0b9a32017-02-27 10:12:13 -080033 blueprint.RuleParams{
34 Command: `touch $initFile && ` +
35 `sed -e 's/%interpreter%/$interp/g' -e 's/%main%/$main/g' $template > $stub && ` +
36 `$parCmd -o $parFile $parArgs && echo '#!/usr/bin/env python' | cat - $parFile > $out && ` +
37 `chmod +x $out && (rm -f $initFile; rm -f $stub; rm -f $parFile)`,
38 CommandDeps: []string{"$parCmd", "$template"},
Nan Zhangdb0b9a32017-02-27 10:12:13 -080039 },
40 "initFile", "interp", "main", "template", "stub", "parCmd", "parFile", "parArgs")
Nan Zhangd4e641b2017-07-12 12:55:28 -070041
42 embedded_par = pctx.AndroidStaticRule("embedded_par",
43 blueprint.RuleParams{
44 Command: `touch $initFile && ` +
45 `echo '$main' > $entry_point && ` +
46 `$parCmd -o $parFile $parArgs && cat $launcher | cat - $parFile > $out && ` +
47 `chmod +x $out && (rm -f $initFile; rm -f $entry_point; rm -f $parFile)`,
48 CommandDeps: []string{"$parCmd"},
49 },
50 "initFile", "main", "entry_point", "parCmd", "parFile", "parArgs", "launcher")
Nan Zhangdb0b9a32017-02-27 10:12:13 -080051)
52
53func init() {
54 pctx.Import("github.com/google/blueprint/bootstrap")
55 pctx.Import("android/soong/common")
56
57 pctx.HostBinToolVariable("parCmd", "soong_zip")
58}
59
60type fileListSpec struct {
61 fileList android.Path
62 relativeRoot string
63}
64
65type parSpec struct {
66 rootPrefix string
67
68 fileListSpecs []fileListSpec
69}
70
71func (p parSpec) soongParArgs() string {
Nan Zhangd4e641b2017-07-12 12:55:28 -070072 ret := `-P ` + p.rootPrefix
Nan Zhangdb0b9a32017-02-27 10:12:13 -080073
74 for _, spec := range p.fileListSpecs {
Nan Zhangd4e641b2017-07-12 12:55:28 -070075 ret += ` -C ` + spec.relativeRoot + ` -l ` + spec.fileList.String()
Nan Zhangdb0b9a32017-02-27 10:12:13 -080076 }
77
78 return ret
79}
80
81func registerBuildActionForModuleFileList(ctx android.ModuleContext,
82 name string, files android.Paths) android.Path {
83 fileList := android.PathForModuleOut(ctx, name+".list")
84
85 content := []string{}
86 for _, file := range files {
87 content = append(content, file.String())
88 }
89
Colin Crossae887032017-10-23 17:16:14 -070090 ctx.Build(pctx, android.BuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -070091 Rule: android.WriteFile,
92 Description: "generate " + fileList.Rel(),
93 Output: fileList,
94 Implicits: files,
Nan Zhangdb0b9a32017-02-27 10:12:13 -080095 Args: map[string]string{
Nan Zhang27005112017-05-12 14:02:13 -070096 "content": strings.Join(content, `\n`),
Nan Zhangdb0b9a32017-02-27 10:12:13 -080097 },
98 })
99
100 return fileList
101}
102
Nan Zhangd4e641b2017-07-12 12:55:28 -0700103func registerBuildActionForParFile(ctx android.ModuleContext, embedded_launcher bool,
104 launcher_path android.Path, interpreter, main, binName string,
105 newPyPkgs []string, parSpecs []parSpec) android.Path {
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800106
Nan Zhangd4e641b2017-07-12 12:55:28 -0700107 // .intermediate output path for __init__.py
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800108 initFile := android.PathForModuleOut(ctx, initFileName).String()
109
Nan Zhangd4e641b2017-07-12 12:55:28 -0700110 // .intermediate output path for par file.
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800111 parFile := android.PathForModuleOut(ctx, binName+parFileExt)
112
Nan Zhangd4e641b2017-07-12 12:55:28 -0700113 // .intermediate output path for bin executable.
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800114 binFile := android.PathForModuleOut(ctx, binName)
115
116 // implicit dependency for parFile build action.
117 implicits := android.Paths{}
118 for _, p := range parSpecs {
119 for _, f := range p.fileListSpecs {
120 implicits = append(implicits, f.fileList)
121 }
122 }
123
124 parArgs := []string{}
Nan Zhangd4e641b2017-07-12 12:55:28 -0700125 parArgs = append(parArgs, `-P "" `+`-C `+strings.TrimSuffix(initFile, initFileName)+` -f `+initFile)
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800126 for _, pkg := range newPyPkgs {
Nan Zhangd4e641b2017-07-12 12:55:28 -0700127 parArgs = append(parArgs, `-P `+pkg+` -f `+initFile)
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800128 }
129 for _, p := range parSpecs {
130 parArgs = append(parArgs, p.soongParArgs())
131 }
132
Nan Zhangd4e641b2017-07-12 12:55:28 -0700133 if !embedded_launcher {
134 // the path of stub_template_host.txt from source tree.
135 template := android.PathForSource(ctx, stubTemplateHost)
136
137 // intermediate output path for __main__.py
138 stub := android.PathForModuleOut(ctx, mainFileName).String()
139
140 // added stub file to the soong_zip args.
141 parArgs = append(parArgs, `-P "" `+`-C `+strings.TrimSuffix(stub, mainFileName)+` -f `+stub)
142
Colin Crossae887032017-10-23 17:16:14 -0700143 ctx.Build(pctx, android.BuildParams{
Nan Zhangd4e641b2017-07-12 12:55:28 -0700144 Rule: host_par,
145 Description: "host python archive",
146 Output: binFile,
147 Implicits: implicits,
148 Args: map[string]string{
149 "initFile": initFile,
150 "interp": strings.Replace(interpreter, "/", `\/`, -1),
151 // we need remove "runfiles/" suffix since stub script starts
152 // searching for main file in each sub-dir of "runfiles" directory tree.
153 "main": strings.Replace(strings.TrimPrefix(main, runFiles+"/"),
154 "/", `\/`, -1),
155 "template": template.String(),
156 "stub": stub,
157 "parFile": parFile.String(),
158 "parArgs": strings.Join(parArgs, " "),
159 },
160 })
161 } else {
162 // added launcher_path to the implicits Ninja dependencies.
163 implicits = append(implicits, launcher_path)
164
165 // .intermediate output path for entry_point.txt
166 entryPoint := android.PathForModuleOut(ctx, entryPointFile).String()
167
168 // added entry_point file to the soong_zip args.
169 parArgs = append(parArgs, `-P "" `+`-C `+fmt.Sprintf(
170 "%q", strings.TrimSuffix(entryPoint, entryPointFile))+` -f `+entryPoint)
171
Colin Crossae887032017-10-23 17:16:14 -0700172 ctx.Build(pctx, android.BuildParams{
Nan Zhangd4e641b2017-07-12 12:55:28 -0700173 Rule: embedded_par,
174 Description: "embedded python archive",
175 Output: binFile,
176 Implicits: implicits,
177 Args: map[string]string{
178 "initFile": initFile,
179 "main": main,
180 "entry_point": entryPoint,
181 "parFile": parFile.String(),
182 "parArgs": strings.Join(parArgs, " "),
183 "launcher": launcher_path.String(),
184 },
185 })
186 }
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800187
188 return binFile
189}