blob: 62234486f4c4c43bda395ab22121c559efb7eb74 [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"},
38 Description: "build par $out",
39 },
40 "initFile", "interp", "main", "template", "stub", "parCmd", "parFile", "parArgs")
41)
42
43func init() {
44 pctx.Import("github.com/google/blueprint/bootstrap")
45 pctx.Import("android/soong/common")
46
47 pctx.HostBinToolVariable("parCmd", "soong_zip")
48}
49
50type fileListSpec struct {
51 fileList android.Path
52 relativeRoot string
53}
54
55type parSpec struct {
56 rootPrefix string
57
58 fileListSpecs []fileListSpec
59}
60
61func (p parSpec) soongParArgs() string {
62 ret := "-P " + p.rootPrefix
63
64 for _, spec := range p.fileListSpecs {
65 ret += " -C " + spec.relativeRoot + " -l " + spec.fileList.String()
66 }
67
68 return ret
69}
70
71func registerBuildActionForModuleFileList(ctx android.ModuleContext,
72 name string, files android.Paths) android.Path {
73 fileList := android.PathForModuleOut(ctx, name+".list")
74
75 content := []string{}
76 for _, file := range files {
77 content = append(content, file.String())
78 }
79
80 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
81 Rule: android.WriteFile,
82 Output: fileList,
83 Implicits: files,
84 Args: map[string]string{
85 "content": strings.Join(content, "\n"),
86 },
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{
129 Rule: par,
130 Output: binFile,
131 Implicits: implicits,
132 Args: map[string]string{
133 "initFile": initFile,
134 // the "\" isn't being interpreted by regex parser, it's being
135 // interpreted in the string literal.
136 "interp": strings.Replace(interpreter, "/", `\/`, -1),
137 "main": strings.Replace(main, "/", `\/`, -1),
138 "template": template.String(),
139 "stub": stub,
140 "parFile": parFile.String(),
141 "parArgs": strings.Join(parArgs, " "),
142 },
143 })
144
145 return binFile
146}