blob: b823fcb9d6bbf806d5847476b4d1ca7ca73e59c3 [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 (
20 "strings"
21
22 "android/soong/android"
23
24 "github.com/google/blueprint"
25 _ "github.com/google/blueprint/bootstrap"
26)
27
28var (
29 pctx = android.NewPackageContext("android/soong/python")
30
31 par = pctx.AndroidStaticRule("par",
32 blueprint.RuleParams{
33 Command: `touch $initFile && ` +
34 `sed -e 's/%interpreter%/$interp/g' -e 's/%main%/$main/g' $template > $stub && ` +
35 `$parCmd -o $parFile $parArgs && echo '#!/usr/bin/env python' | cat - $parFile > $out && ` +
36 `chmod +x $out && (rm -f $initFile; rm -f $stub; rm -f $parFile)`,
37 CommandDeps: []string{"$parCmd", "$template"},
Nan Zhangdb0b9a32017-02-27 10:12:13 -080038 },
39 "initFile", "interp", "main", "template", "stub", "parCmd", "parFile", "parArgs")
40)
41
42func init() {
43 pctx.Import("github.com/google/blueprint/bootstrap")
44 pctx.Import("android/soong/common")
45
46 pctx.HostBinToolVariable("parCmd", "soong_zip")
47}
48
49type fileListSpec struct {
50 fileList android.Path
51 relativeRoot string
52}
53
54type parSpec struct {
55 rootPrefix string
56
57 fileListSpecs []fileListSpec
58}
59
60func (p parSpec) soongParArgs() string {
61 ret := "-P " + p.rootPrefix
62
63 for _, spec := range p.fileListSpecs {
64 ret += " -C " + spec.relativeRoot + " -l " + spec.fileList.String()
65 }
66
67 return ret
68}
69
70func registerBuildActionForModuleFileList(ctx android.ModuleContext,
71 name string, files android.Paths) android.Path {
72 fileList := android.PathForModuleOut(ctx, name+".list")
73
74 content := []string{}
75 for _, file := range files {
76 content = append(content, file.String())
77 }
78
79 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -070080 Rule: android.WriteFile,
81 Description: "generate " + fileList.Rel(),
82 Output: fileList,
83 Implicits: files,
Nan Zhangdb0b9a32017-02-27 10:12:13 -080084 Args: map[string]string{
Nan Zhang27005112017-05-12 14:02:13 -070085 "content": strings.Join(content, `\n`),
Nan Zhangdb0b9a32017-02-27 10:12:13 -080086 },
87 })
88
89 return fileList
90}
91
92func registerBuildActionForParFile(ctx android.ModuleContext,
93 interpreter, main, binName string, newPyPkgs []string, parSpecs []parSpec) android.Path {
94
95 // intermediate output path for __init__.py
96 initFile := android.PathForModuleOut(ctx, initFileName).String()
97
98 // the path of stub_template_host.txt from source tree.
99 template := android.PathForSource(ctx, stubTemplateHost)
100
101 // intermediate output path for __main__.py
102 stub := android.PathForModuleOut(ctx, mainFileName).String()
103
104 // intermediate output path for par file.
105 parFile := android.PathForModuleOut(ctx, binName+parFileExt)
106
107 // intermediate output path for bin executable.
108 binFile := android.PathForModuleOut(ctx, binName)
109
110 // implicit dependency for parFile build action.
111 implicits := android.Paths{}
112 for _, p := range parSpecs {
113 for _, f := range p.fileListSpecs {
114 implicits = append(implicits, f.fileList)
115 }
116 }
117
118 parArgs := []string{}
119 parArgs = append(parArgs, "-C "+strings.TrimSuffix(stub, mainFileName)+" -f "+stub)
120 parArgs = append(parArgs, "-C "+strings.TrimSuffix(initFile, initFileName)+" -f "+initFile)
121 for _, pkg := range newPyPkgs {
122 parArgs = append(parArgs, "-P "+pkg+" -f "+initFile)
123 }
124 for _, p := range parSpecs {
125 parArgs = append(parArgs, p.soongParArgs())
126 }
127
128 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700129 Rule: par,
130 Description: "python archive",
131 Output: binFile,
132 Implicits: implicits,
Nan Zhangdb0b9a32017-02-27 10:12:13 -0800133 Args: map[string]string{
134 "initFile": initFile,
135 // the "\" isn't being interpreted by regex parser, it's being
136 // interpreted in the string literal.
137 "interp": strings.Replace(interpreter, "/", `\/`, -1),
138 "main": strings.Replace(main, "/", `\/`, -1),
139 "template": template.String(),
140 "stub": stub,
141 "parFile": parFile.String(),
142 "parArgs": strings.Join(parArgs, " "),
143 },
144 })
145
146 return binFile
147}