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