github.com/westcoastroms/westcoastroms-build@v0.0.0-20190928114312-2350e5a73030/build/soong/python/builder.go (about) 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 15 package python 16 17 // This file contains Ninja build actions for building Python program. 18 19 import ( 20 "fmt" 21 "strings" 22 23 "android/soong/android" 24 25 "github.com/google/blueprint" 26 _ "github.com/google/blueprint/bootstrap" 27 ) 28 29 var ( 30 pctx = android.NewPackageContext("android/soong/python") 31 32 host_par = pctx.AndroidStaticRule("host_par", 33 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"}, 39 }, 40 "initFile", "interp", "main", "template", "stub", "parCmd", "parFile", "parArgs") 41 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") 51 ) 52 53 func init() { 54 pctx.Import("github.com/google/blueprint/bootstrap") 55 pctx.Import("android/soong/common") 56 57 pctx.HostBinToolVariable("parCmd", "soong_zip") 58 } 59 60 type fileListSpec struct { 61 fileList android.Path 62 relativeRoot string 63 } 64 65 type parSpec struct { 66 rootPrefix string 67 68 fileListSpecs []fileListSpec 69 } 70 71 func (p parSpec) soongParArgs() string { 72 ret := `-P ` + p.rootPrefix 73 74 for _, spec := range p.fileListSpecs { 75 ret += ` -C ` + spec.relativeRoot + ` -l ` + spec.fileList.String() 76 } 77 78 return ret 79 } 80 81 func 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 90 ctx.Build(pctx, android.BuildParams{ 91 Rule: android.WriteFile, 92 Description: "generate " + fileList.Rel(), 93 Output: fileList, 94 Implicits: files, 95 Args: map[string]string{ 96 "content": strings.Join(content, `\n`), 97 }, 98 }) 99 100 return fileList 101 } 102 103 func registerBuildActionForParFile(ctx android.ModuleContext, embedded_launcher bool, 104 launcher_path android.Path, interpreter, main, binName string, 105 newPyPkgs []string, parSpecs []parSpec) android.Path { 106 107 // .intermediate output path for __init__.py 108 initFile := android.PathForModuleOut(ctx, initFileName).String() 109 110 // .intermediate output path for par file. 111 parFile := android.PathForModuleOut(ctx, binName+parFileExt) 112 113 // .intermediate output path for bin executable. 114 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{} 125 parArgs = append(parArgs, `-P "" `+`-C `+strings.TrimSuffix(initFile, initFileName)+` -f `+initFile) 126 for _, pkg := range newPyPkgs { 127 parArgs = append(parArgs, `-P `+pkg+` -f `+initFile) 128 } 129 for _, p := range parSpecs { 130 parArgs = append(parArgs, p.soongParArgs()) 131 } 132 133 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 143 ctx.Build(pctx, android.BuildParams{ 144 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 172 ctx.Build(pctx, android.BuildParams{ 173 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 } 187 188 return binFile 189 }