1// 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 zip = pctx.AndroidStaticRule("zip", 32 blueprint.RuleParams{ 33 Command: `$parCmd -o $out $args`, 34 CommandDeps: []string{"$parCmd"}, 35 }, 36 "args") 37 38 combineZip = pctx.AndroidStaticRule("combineZip", 39 blueprint.RuleParams{ 40 Command: `$mergeParCmd $out $in`, 41 CommandDeps: []string{"$mergeParCmd"}, 42 }, 43 ) 44 45 hostPar = pctx.AndroidStaticRule("hostPar", 46 blueprint.RuleParams{ 47 Command: `sed -e 's/%interpreter%/$interp/g' -e 's/%main%/$main/g' $template > $stub && ` + 48 `echo "#!/usr/bin/env python" >${out}.prefix &&` + 49 `$mergeParCmd -p --prefix ${out}.prefix -pm $stub $out $srcsZips && ` + 50 `chmod +x $out && (rm -f $stub; rm -f ${out}.prefix)`, 51 CommandDeps: []string{"$mergeParCmd"}, 52 }, 53 "interp", "main", "template", "stub", "srcsZips") 54 55 embeddedPar = pctx.AndroidStaticRule("embeddedPar", 56 blueprint.RuleParams{ 57 Command: `rm -f $out.main && ` + 58 `sed 's/ENTRY_POINT/$main/' build/soong/python/scripts/main.py >$out.main &&` + 59 `$mergeParCmd -p -pm $out.main --prefix $launcher $out $srcsZips && ` + 60 `chmod +x $out && rm -rf $out.main`, 61 CommandDeps: []string{"$mergeParCmd", "$parCmd", "build/soong/python/scripts/main.py"}, 62 }, 63 "main", "srcsZips", "launcher") 64 65 embeddedParNoMain = pctx.AndroidStaticRule("embeddedParNoMain", 66 blueprint.RuleParams{ 67 Command: `$mergeParCmd -p --prefix $launcher $out $srcsZips && ` + 68 `chmod +x $out`, 69 CommandDeps: []string{"$mergeParCmd"}, 70 }, 71 "srcsZips", "launcher") 72) 73 74func init() { 75 pctx.Import("github.com/google/blueprint/bootstrap") 76 pctx.Import("android/soong/android") 77 78 pctx.HostBinToolVariable("parCmd", "soong_zip") 79 pctx.HostBinToolVariable("mergeParCmd", "merge_zips") 80} 81 82func registerBuildActionForParFile(ctx android.ModuleContext, embeddedLauncher bool, 83 launcherPath android.OptionalPath, interpreter, main, binName string, 84 srcsZips android.Paths) android.Path { 85 86 // .intermediate output path for bin executable. 87 binFile := android.PathForModuleOut(ctx, binName) 88 89 // implicit dependency for parFile build action. 90 implicits := srcsZips 91 92 if !embeddedLauncher { 93 // the path of stub_template_host.txt from source tree. 94 template := android.PathForSource(ctx, stubTemplateHost) 95 implicits = append(implicits, template) 96 97 // intermediate output path for __main__.py 98 stub := android.PathForModuleOut(ctx, mainFileName).String() 99 100 ctx.Build(pctx, android.BuildParams{ 101 Rule: hostPar, 102 Description: "host python archive", 103 Output: binFile, 104 Implicits: implicits, 105 Args: map[string]string{ 106 "interp": strings.Replace(interpreter, "/", `\/`, -1), 107 "main": strings.Replace(main, "/", `\/`, -1), 108 "template": template.String(), 109 "stub": stub, 110 "srcsZips": strings.Join(srcsZips.Strings(), " "), 111 }, 112 }) 113 } else if launcherPath.Valid() { 114 // added launcherPath to the implicits Ninja dependencies. 115 implicits = append(implicits, launcherPath.Path()) 116 117 if main == "" { 118 ctx.Build(pctx, android.BuildParams{ 119 Rule: embeddedParNoMain, 120 Description: "embedded python archive", 121 Output: binFile, 122 Implicits: implicits, 123 Args: map[string]string{ 124 "srcsZips": strings.Join(srcsZips.Strings(), " "), 125 "launcher": launcherPath.String(), 126 }, 127 }) 128 } else { 129 ctx.Build(pctx, android.BuildParams{ 130 Rule: embeddedPar, 131 Description: "embedded python archive", 132 Output: binFile, 133 Implicits: implicits, 134 Args: map[string]string{ 135 "main": strings.Replace(strings.TrimSuffix(main, pyExt), "/", ".", -1), 136 "srcsZips": strings.Join(srcsZips.Strings(), " "), 137 "launcher": launcherPath.String(), 138 }, 139 }) 140 } 141 } 142 143 return binFile 144} 145