xref: /aosp_15_r20/build/soong/android/makevars.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2016 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage android
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"bytes"
19*333d2b36SAndroid Build Coastguard Worker	"cmp"
20*333d2b36SAndroid Build Coastguard Worker	"fmt"
21*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
22*333d2b36SAndroid Build Coastguard Worker	"runtime"
23*333d2b36SAndroid Build Coastguard Worker	"slices"
24*333d2b36SAndroid Build Coastguard Worker	"sort"
25*333d2b36SAndroid Build Coastguard Worker	"strings"
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
28*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/pathtools"
29*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
30*333d2b36SAndroid Build Coastguard Worker)
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Workerfunc init() {
33*333d2b36SAndroid Build Coastguard Worker	RegisterMakeVarsProvider(pctx, androidMakeVarsProvider)
34*333d2b36SAndroid Build Coastguard Worker}
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Workerfunc androidMakeVarsProvider(ctx MakeVarsContext) {
37*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("MIN_SUPPORTED_SDK_VERSION", ctx.Config().MinSupportedSdkVersion().String())
38*333d2b36SAndroid Build Coastguard Worker}
39*333d2b36SAndroid Build Coastguard Worker
40*333d2b36SAndroid Build Coastguard Worker// /////////////////////////////////////////////////////////////////////////////
41*333d2b36SAndroid Build Coastguard Worker
42*333d2b36SAndroid Build Coastguard Worker// BaseMakeVarsContext contains the common functions for other packages to use
43*333d2b36SAndroid Build Coastguard Worker// to declare make variables
44*333d2b36SAndroid Build Coastguard Workertype BaseMakeVarsContext interface {
45*333d2b36SAndroid Build Coastguard Worker	Config() Config
46*333d2b36SAndroid Build Coastguard Worker	DeviceConfig() DeviceConfig
47*333d2b36SAndroid Build Coastguard Worker	AddNinjaFileDeps(deps ...string)
48*333d2b36SAndroid Build Coastguard Worker
49*333d2b36SAndroid Build Coastguard Worker	Failed() bool
50*333d2b36SAndroid Build Coastguard Worker
51*333d2b36SAndroid Build Coastguard Worker	// These are equivalent to Strict and Check, but do not attempt to
52*333d2b36SAndroid Build Coastguard Worker	// evaluate the values before writing them to the Makefile. They can
53*333d2b36SAndroid Build Coastguard Worker	// be used when all ninja variables have already been evaluated through
54*333d2b36SAndroid Build Coastguard Worker	// Eval().
55*333d2b36SAndroid Build Coastguard Worker	StrictRaw(name, value string)
56*333d2b36SAndroid Build Coastguard Worker	CheckRaw(name, value string)
57*333d2b36SAndroid Build Coastguard Worker
58*333d2b36SAndroid Build Coastguard Worker	// GlobWithDeps returns a list of files that match the specified pattern but do not match any
59*333d2b36SAndroid Build Coastguard Worker	// of the patterns in excludes.  It also adds efficient dependencies to rerun the primary
60*333d2b36SAndroid Build Coastguard Worker	// builder whenever a file matching the pattern as added or removed, without rerunning if a
61*333d2b36SAndroid Build Coastguard Worker	// file that does not match the pattern is added to a searched directory.
62*333d2b36SAndroid Build Coastguard Worker	GlobWithDeps(pattern string, excludes []string) ([]string, error)
63*333d2b36SAndroid Build Coastguard Worker
64*333d2b36SAndroid Build Coastguard Worker	// Phony creates a phony rule in Make, which will allow additional DistForGoal
65*333d2b36SAndroid Build Coastguard Worker	// dependencies to be added to it.  Phony can be called on the same name multiple
66*333d2b36SAndroid Build Coastguard Worker	// times to add additional dependencies.
67*333d2b36SAndroid Build Coastguard Worker	Phony(names string, deps ...Path)
68*333d2b36SAndroid Build Coastguard Worker
69*333d2b36SAndroid Build Coastguard Worker	// DistForGoal creates a rule to copy one or more Paths to the artifacts
70*333d2b36SAndroid Build Coastguard Worker	// directory on the build server when the specified goal is built.
71*333d2b36SAndroid Build Coastguard Worker	DistForGoal(goal string, paths ...Path)
72*333d2b36SAndroid Build Coastguard Worker
73*333d2b36SAndroid Build Coastguard Worker	// DistForGoalWithFilename creates a rule to copy a Path to the artifacts
74*333d2b36SAndroid Build Coastguard Worker	// directory on the build server with the given filename when the specified
75*333d2b36SAndroid Build Coastguard Worker	// goal is built.
76*333d2b36SAndroid Build Coastguard Worker	DistForGoalWithFilename(goal string, path Path, filename string)
77*333d2b36SAndroid Build Coastguard Worker
78*333d2b36SAndroid Build Coastguard Worker	// DistForGoals creates a rule to copy one or more Paths to the artifacts
79*333d2b36SAndroid Build Coastguard Worker	// directory on the build server when any of the specified goals are built.
80*333d2b36SAndroid Build Coastguard Worker	DistForGoals(goals []string, paths ...Path)
81*333d2b36SAndroid Build Coastguard Worker
82*333d2b36SAndroid Build Coastguard Worker	// DistForGoalsWithFilename creates a rule to copy a Path to the artifacts
83*333d2b36SAndroid Build Coastguard Worker	// directory on the build server with the given filename when any of the
84*333d2b36SAndroid Build Coastguard Worker	// specified goals are built.
85*333d2b36SAndroid Build Coastguard Worker	DistForGoalsWithFilename(goals []string, path Path, filename string)
86*333d2b36SAndroid Build Coastguard Worker}
87*333d2b36SAndroid Build Coastguard Worker
88*333d2b36SAndroid Build Coastguard Worker// MakeVarsContext contains the set of functions available for MakeVarsProvider
89*333d2b36SAndroid Build Coastguard Worker// and SingletonMakeVarsProvider implementations.
90*333d2b36SAndroid Build Coastguard Workertype MakeVarsContext interface {
91*333d2b36SAndroid Build Coastguard Worker	BaseMakeVarsContext
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Worker	ModuleName(module blueprint.Module) string
94*333d2b36SAndroid Build Coastguard Worker	ModuleDir(module blueprint.Module) string
95*333d2b36SAndroid Build Coastguard Worker	ModuleSubDir(module blueprint.Module) string
96*333d2b36SAndroid Build Coastguard Worker	ModuleType(module blueprint.Module) string
97*333d2b36SAndroid Build Coastguard Worker	otherModuleProvider(module blueprint.Module, key blueprint.AnyProviderKey) (any, bool)
98*333d2b36SAndroid Build Coastguard Worker	BlueprintFile(module blueprint.Module) string
99*333d2b36SAndroid Build Coastguard Worker
100*333d2b36SAndroid Build Coastguard Worker	ModuleErrorf(module blueprint.Module, format string, args ...interface{})
101*333d2b36SAndroid Build Coastguard Worker	OtherModulePropertyErrorf(module Module, property, format string, args ...interface{})
102*333d2b36SAndroid Build Coastguard Worker	Errorf(format string, args ...interface{})
103*333d2b36SAndroid Build Coastguard Worker
104*333d2b36SAndroid Build Coastguard Worker	VisitAllModules(visit func(Module))
105*333d2b36SAndroid Build Coastguard Worker	VisitAllModulesIf(pred func(Module) bool, visit func(Module))
106*333d2b36SAndroid Build Coastguard Worker
107*333d2b36SAndroid Build Coastguard Worker	// Verify the make variable matches the Soong version, fail the build
108*333d2b36SAndroid Build Coastguard Worker	// if it does not. If the make variable is empty, just set it.
109*333d2b36SAndroid Build Coastguard Worker	Strict(name, ninjaStr string)
110*333d2b36SAndroid Build Coastguard Worker	// Check to see if the make variable matches the Soong version, warn if
111*333d2b36SAndroid Build Coastguard Worker	// it does not. If the make variable is empty, just set it.
112*333d2b36SAndroid Build Coastguard Worker	Check(name, ninjaStr string)
113*333d2b36SAndroid Build Coastguard Worker
114*333d2b36SAndroid Build Coastguard Worker	// These are equivalent to the above, but sort the make and soong
115*333d2b36SAndroid Build Coastguard Worker	// variables before comparing them. They also show the unique entries
116*333d2b36SAndroid Build Coastguard Worker	// in each list when displaying the difference, instead of the entire
117*333d2b36SAndroid Build Coastguard Worker	// string.
118*333d2b36SAndroid Build Coastguard Worker	StrictSorted(name, ninjaStr string)
119*333d2b36SAndroid Build Coastguard Worker	CheckSorted(name, ninjaStr string)
120*333d2b36SAndroid Build Coastguard Worker
121*333d2b36SAndroid Build Coastguard Worker	// Evaluates a ninja string and returns the result. Used if more
122*333d2b36SAndroid Build Coastguard Worker	// complicated modification needs to happen before giving it to Make.
123*333d2b36SAndroid Build Coastguard Worker	Eval(ninjaStr string) (string, error)
124*333d2b36SAndroid Build Coastguard Worker}
125*333d2b36SAndroid Build Coastguard Worker
126*333d2b36SAndroid Build Coastguard Worker// MakeVarsModuleContext contains the set of functions available for modules
127*333d2b36SAndroid Build Coastguard Worker// implementing the ModuleMakeVarsProvider interface.
128*333d2b36SAndroid Build Coastguard Workertype MakeVarsModuleContext interface {
129*333d2b36SAndroid Build Coastguard Worker	BaseMakeVarsContext
130*333d2b36SAndroid Build Coastguard Worker}
131*333d2b36SAndroid Build Coastguard Worker
132*333d2b36SAndroid Build Coastguard Workervar _ PathContext = MakeVarsContext(nil)
133*333d2b36SAndroid Build Coastguard Worker
134*333d2b36SAndroid Build Coastguard Workertype MakeVarsProvider func(ctx MakeVarsContext)
135*333d2b36SAndroid Build Coastguard Worker
136*333d2b36SAndroid Build Coastguard Workerfunc RegisterMakeVarsProvider(pctx PackageContext, provider MakeVarsProvider) {
137*333d2b36SAndroid Build Coastguard Worker	makeVarsInitProviders = append(makeVarsInitProviders, makeVarsProvider{pctx, provider})
138*333d2b36SAndroid Build Coastguard Worker}
139*333d2b36SAndroid Build Coastguard Worker
140*333d2b36SAndroid Build Coastguard Worker// SingletonMakeVarsProvider is a Singleton with an extra method to provide extra values to be exported to Make.
141*333d2b36SAndroid Build Coastguard Workertype SingletonMakeVarsProvider interface {
142*333d2b36SAndroid Build Coastguard Worker	// MakeVars uses a MakeVarsContext to provide extra values to be exported to Make.
143*333d2b36SAndroid Build Coastguard Worker	MakeVars(ctx MakeVarsContext)
144*333d2b36SAndroid Build Coastguard Worker}
145*333d2b36SAndroid Build Coastguard Worker
146*333d2b36SAndroid Build Coastguard Workervar singletonMakeVarsProvidersKey = NewOnceKey("singletonMakeVarsProvidersKey")
147*333d2b36SAndroid Build Coastguard Worker
148*333d2b36SAndroid Build Coastguard Workerfunc getSingletonMakevarsProviders(config Config) *[]makeVarsProvider {
149*333d2b36SAndroid Build Coastguard Worker	return config.Once(singletonMakeVarsProvidersKey, func() interface{} {
150*333d2b36SAndroid Build Coastguard Worker		return &[]makeVarsProvider{}
151*333d2b36SAndroid Build Coastguard Worker	}).(*[]makeVarsProvider)
152*333d2b36SAndroid Build Coastguard Worker}
153*333d2b36SAndroid Build Coastguard Worker
154*333d2b36SAndroid Build Coastguard Worker// registerSingletonMakeVarsProvider adds a singleton that implements SingletonMakeVarsProvider to
155*333d2b36SAndroid Build Coastguard Worker// the list of MakeVarsProviders to run.
156*333d2b36SAndroid Build Coastguard Workerfunc registerSingletonMakeVarsProvider(config Config, singleton SingletonMakeVarsProvider) {
157*333d2b36SAndroid Build Coastguard Worker	// Singletons are registered on the Context and may be different between different Contexts,
158*333d2b36SAndroid Build Coastguard Worker	// for example when running multiple tests.  Store the SingletonMakeVarsProviders in the
159*333d2b36SAndroid Build Coastguard Worker	// Config so they are attached to the Context.
160*333d2b36SAndroid Build Coastguard Worker	singletonMakeVarsProviders := getSingletonMakevarsProviders(config)
161*333d2b36SAndroid Build Coastguard Worker
162*333d2b36SAndroid Build Coastguard Worker	*singletonMakeVarsProviders = append(*singletonMakeVarsProviders,
163*333d2b36SAndroid Build Coastguard Worker		makeVarsProvider{pctx, singletonMakeVarsProviderAdapter(singleton)})
164*333d2b36SAndroid Build Coastguard Worker}
165*333d2b36SAndroid Build Coastguard Worker
166*333d2b36SAndroid Build Coastguard Worker// singletonMakeVarsProviderAdapter converts a SingletonMakeVarsProvider to a MakeVarsProvider.
167*333d2b36SAndroid Build Coastguard Workerfunc singletonMakeVarsProviderAdapter(singleton SingletonMakeVarsProvider) MakeVarsProvider {
168*333d2b36SAndroid Build Coastguard Worker	return func(ctx MakeVarsContext) { singleton.MakeVars(ctx) }
169*333d2b36SAndroid Build Coastguard Worker}
170*333d2b36SAndroid Build Coastguard Worker
171*333d2b36SAndroid Build Coastguard Worker// ModuleMakeVarsProvider is a Module with an extra method to provide extra values to be exported to Make.
172*333d2b36SAndroid Build Coastguard Workertype ModuleMakeVarsProvider interface {
173*333d2b36SAndroid Build Coastguard Worker	Module
174*333d2b36SAndroid Build Coastguard Worker
175*333d2b36SAndroid Build Coastguard Worker	// MakeVars uses a MakeVarsModuleContext to provide extra values to be exported to Make.
176*333d2b36SAndroid Build Coastguard Worker	MakeVars(ctx MakeVarsModuleContext)
177*333d2b36SAndroid Build Coastguard Worker}
178*333d2b36SAndroid Build Coastguard Worker
179*333d2b36SAndroid Build Coastguard Worker// /////////////////////////////////////////////////////////////////////////////
180*333d2b36SAndroid Build Coastguard Worker
181*333d2b36SAndroid Build Coastguard Workerfunc makeVarsSingletonFunc() Singleton {
182*333d2b36SAndroid Build Coastguard Worker	return &makeVarsSingleton{}
183*333d2b36SAndroid Build Coastguard Worker}
184*333d2b36SAndroid Build Coastguard Worker
185*333d2b36SAndroid Build Coastguard Workertype makeVarsSingleton struct {
186*333d2b36SAndroid Build Coastguard Worker	varsForTesting     []makeVarsVariable
187*333d2b36SAndroid Build Coastguard Worker	installsForTesting []byte
188*333d2b36SAndroid Build Coastguard Worker}
189*333d2b36SAndroid Build Coastguard Worker
190*333d2b36SAndroid Build Coastguard Workertype makeVarsProvider struct {
191*333d2b36SAndroid Build Coastguard Worker	pctx PackageContext
192*333d2b36SAndroid Build Coastguard Worker	call MakeVarsProvider
193*333d2b36SAndroid Build Coastguard Worker}
194*333d2b36SAndroid Build Coastguard Worker
195*333d2b36SAndroid Build Coastguard Worker// Collection of makevars providers that are registered in init() methods.
196*333d2b36SAndroid Build Coastguard Workervar makeVarsInitProviders []makeVarsProvider
197*333d2b36SAndroid Build Coastguard Worker
198*333d2b36SAndroid Build Coastguard Workertype makeVarsContext struct {
199*333d2b36SAndroid Build Coastguard Worker	SingletonContext
200*333d2b36SAndroid Build Coastguard Worker	config  Config
201*333d2b36SAndroid Build Coastguard Worker	pctx    PackageContext
202*333d2b36SAndroid Build Coastguard Worker	vars    []makeVarsVariable
203*333d2b36SAndroid Build Coastguard Worker	phonies []phony
204*333d2b36SAndroid Build Coastguard Worker	dists   []dist
205*333d2b36SAndroid Build Coastguard Worker}
206*333d2b36SAndroid Build Coastguard Worker
207*333d2b36SAndroid Build Coastguard Workervar _ MakeVarsContext = &makeVarsContext{}
208*333d2b36SAndroid Build Coastguard Worker
209*333d2b36SAndroid Build Coastguard Workertype makeVarsVariable struct {
210*333d2b36SAndroid Build Coastguard Worker	name   string
211*333d2b36SAndroid Build Coastguard Worker	value  string
212*333d2b36SAndroid Build Coastguard Worker	sort   bool
213*333d2b36SAndroid Build Coastguard Worker	strict bool
214*333d2b36SAndroid Build Coastguard Worker}
215*333d2b36SAndroid Build Coastguard Worker
216*333d2b36SAndroid Build Coastguard Workertype phony struct {
217*333d2b36SAndroid Build Coastguard Worker	name string
218*333d2b36SAndroid Build Coastguard Worker	deps []string
219*333d2b36SAndroid Build Coastguard Worker}
220*333d2b36SAndroid Build Coastguard Worker
221*333d2b36SAndroid Build Coastguard Workertype dist struct {
222*333d2b36SAndroid Build Coastguard Worker	goals []string
223*333d2b36SAndroid Build Coastguard Worker	paths []string
224*333d2b36SAndroid Build Coastguard Worker}
225*333d2b36SAndroid Build Coastguard Worker
226*333d2b36SAndroid Build Coastguard Workerfunc (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
227*333d2b36SAndroid Build Coastguard Worker	if !ctx.Config().KatiEnabled() {
228*333d2b36SAndroid Build Coastguard Worker		return
229*333d2b36SAndroid Build Coastguard Worker	}
230*333d2b36SAndroid Build Coastguard Worker
231*333d2b36SAndroid Build Coastguard Worker	outFile := absolutePath(PathForOutput(ctx,
232*333d2b36SAndroid Build Coastguard Worker		"make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
233*333d2b36SAndroid Build Coastguard Worker
234*333d2b36SAndroid Build Coastguard Worker	lateOutFile := absolutePath(PathForOutput(ctx,
235*333d2b36SAndroid Build Coastguard Worker		"late"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
236*333d2b36SAndroid Build Coastguard Worker
237*333d2b36SAndroid Build Coastguard Worker	installsFile := absolutePath(PathForOutput(ctx,
238*333d2b36SAndroid Build Coastguard Worker		"installs"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
239*333d2b36SAndroid Build Coastguard Worker
240*333d2b36SAndroid Build Coastguard Worker	if ctx.Failed() {
241*333d2b36SAndroid Build Coastguard Worker		return
242*333d2b36SAndroid Build Coastguard Worker	}
243*333d2b36SAndroid Build Coastguard Worker
244*333d2b36SAndroid Build Coastguard Worker	var vars []makeVarsVariable
245*333d2b36SAndroid Build Coastguard Worker	var dists []dist
246*333d2b36SAndroid Build Coastguard Worker	var phonies []phony
247*333d2b36SAndroid Build Coastguard Worker	var katiInstalls []katiInstall
248*333d2b36SAndroid Build Coastguard Worker	var katiInitRcInstalls []katiInstall
249*333d2b36SAndroid Build Coastguard Worker	var katiVintfManifestInstalls []katiInstall
250*333d2b36SAndroid Build Coastguard Worker	var katiSymlinks []katiInstall
251*333d2b36SAndroid Build Coastguard Worker
252*333d2b36SAndroid Build Coastguard Worker	providers := append([]makeVarsProvider(nil), makeVarsInitProviders...)
253*333d2b36SAndroid Build Coastguard Worker	providers = append(providers, *getSingletonMakevarsProviders(ctx.Config())...)
254*333d2b36SAndroid Build Coastguard Worker
255*333d2b36SAndroid Build Coastguard Worker	for _, provider := range providers {
256*333d2b36SAndroid Build Coastguard Worker		mctx := &makeVarsContext{
257*333d2b36SAndroid Build Coastguard Worker			SingletonContext: ctx,
258*333d2b36SAndroid Build Coastguard Worker			pctx:             provider.pctx,
259*333d2b36SAndroid Build Coastguard Worker		}
260*333d2b36SAndroid Build Coastguard Worker
261*333d2b36SAndroid Build Coastguard Worker		provider.call(mctx)
262*333d2b36SAndroid Build Coastguard Worker
263*333d2b36SAndroid Build Coastguard Worker		vars = append(vars, mctx.vars...)
264*333d2b36SAndroid Build Coastguard Worker		phonies = append(phonies, mctx.phonies...)
265*333d2b36SAndroid Build Coastguard Worker		dists = append(dists, mctx.dists...)
266*333d2b36SAndroid Build Coastguard Worker	}
267*333d2b36SAndroid Build Coastguard Worker
268*333d2b36SAndroid Build Coastguard Worker	ctx.VisitAllModules(func(m Module) {
269*333d2b36SAndroid Build Coastguard Worker		if provider, ok := m.(ModuleMakeVarsProvider); ok && m.Enabled(ctx) {
270*333d2b36SAndroid Build Coastguard Worker			mctx := &makeVarsContext{
271*333d2b36SAndroid Build Coastguard Worker				SingletonContext: ctx,
272*333d2b36SAndroid Build Coastguard Worker			}
273*333d2b36SAndroid Build Coastguard Worker
274*333d2b36SAndroid Build Coastguard Worker			provider.MakeVars(mctx)
275*333d2b36SAndroid Build Coastguard Worker
276*333d2b36SAndroid Build Coastguard Worker			vars = append(vars, mctx.vars...)
277*333d2b36SAndroid Build Coastguard Worker			phonies = append(phonies, mctx.phonies...)
278*333d2b36SAndroid Build Coastguard Worker			dists = append(dists, mctx.dists...)
279*333d2b36SAndroid Build Coastguard Worker		}
280*333d2b36SAndroid Build Coastguard Worker
281*333d2b36SAndroid Build Coastguard Worker		if m.ExportedToMake() {
282*333d2b36SAndroid Build Coastguard Worker			info := OtherModuleProviderOrDefault(ctx, m, InstallFilesProvider)
283*333d2b36SAndroid Build Coastguard Worker			katiInstalls = append(katiInstalls, info.KatiInstalls...)
284*333d2b36SAndroid Build Coastguard Worker			katiInitRcInstalls = append(katiInitRcInstalls, info.KatiInitRcInstalls...)
285*333d2b36SAndroid Build Coastguard Worker			katiVintfManifestInstalls = append(katiVintfManifestInstalls, info.KatiVintfInstalls...)
286*333d2b36SAndroid Build Coastguard Worker			katiSymlinks = append(katiSymlinks, info.KatiSymlinks...)
287*333d2b36SAndroid Build Coastguard Worker		}
288*333d2b36SAndroid Build Coastguard Worker	})
289*333d2b36SAndroid Build Coastguard Worker
290*333d2b36SAndroid Build Coastguard Worker	compareKatiInstalls := func(a, b katiInstall) int {
291*333d2b36SAndroid Build Coastguard Worker		aTo, bTo := a.to.String(), b.to.String()
292*333d2b36SAndroid Build Coastguard Worker		if cmpTo := cmp.Compare(aTo, bTo); cmpTo != 0 {
293*333d2b36SAndroid Build Coastguard Worker			return cmpTo
294*333d2b36SAndroid Build Coastguard Worker		}
295*333d2b36SAndroid Build Coastguard Worker
296*333d2b36SAndroid Build Coastguard Worker		aFrom, bFrom := a.from.String(), b.from.String()
297*333d2b36SAndroid Build Coastguard Worker		return cmp.Compare(aFrom, bFrom)
298*333d2b36SAndroid Build Coastguard Worker	}
299*333d2b36SAndroid Build Coastguard Worker
300*333d2b36SAndroid Build Coastguard Worker	slices.SortFunc(katiInitRcInstalls, compareKatiInstalls)
301*333d2b36SAndroid Build Coastguard Worker	katiInitRcInstalls = slices.CompactFunc(katiInitRcInstalls, func(a, b katiInstall) bool {
302*333d2b36SAndroid Build Coastguard Worker		return compareKatiInstalls(a, b) == 0
303*333d2b36SAndroid Build Coastguard Worker	})
304*333d2b36SAndroid Build Coastguard Worker	katiInstalls = append(katiInstalls, katiInitRcInstalls...)
305*333d2b36SAndroid Build Coastguard Worker
306*333d2b36SAndroid Build Coastguard Worker	slices.SortFunc(katiVintfManifestInstalls, compareKatiInstalls)
307*333d2b36SAndroid Build Coastguard Worker	katiVintfManifestInstalls = slices.CompactFunc(katiVintfManifestInstalls, func(a, b katiInstall) bool {
308*333d2b36SAndroid Build Coastguard Worker		return compareKatiInstalls(a, b) == 0
309*333d2b36SAndroid Build Coastguard Worker	})
310*333d2b36SAndroid Build Coastguard Worker
311*333d2b36SAndroid Build Coastguard Worker	if ctx.Failed() {
312*333d2b36SAndroid Build Coastguard Worker		return
313*333d2b36SAndroid Build Coastguard Worker	}
314*333d2b36SAndroid Build Coastguard Worker
315*333d2b36SAndroid Build Coastguard Worker	sort.Slice(vars, func(i, j int) bool {
316*333d2b36SAndroid Build Coastguard Worker		return vars[i].name < vars[j].name
317*333d2b36SAndroid Build Coastguard Worker	})
318*333d2b36SAndroid Build Coastguard Worker	sort.Slice(phonies, func(i, j int) bool {
319*333d2b36SAndroid Build Coastguard Worker		return phonies[i].name < phonies[j].name
320*333d2b36SAndroid Build Coastguard Worker	})
321*333d2b36SAndroid Build Coastguard Worker	lessArr := func(a, b []string) bool {
322*333d2b36SAndroid Build Coastguard Worker		if len(a) == len(b) {
323*333d2b36SAndroid Build Coastguard Worker			for i := range a {
324*333d2b36SAndroid Build Coastguard Worker				if a[i] < b[i] {
325*333d2b36SAndroid Build Coastguard Worker					return true
326*333d2b36SAndroid Build Coastguard Worker				}
327*333d2b36SAndroid Build Coastguard Worker			}
328*333d2b36SAndroid Build Coastguard Worker			return false
329*333d2b36SAndroid Build Coastguard Worker		}
330*333d2b36SAndroid Build Coastguard Worker		return len(a) < len(b)
331*333d2b36SAndroid Build Coastguard Worker	}
332*333d2b36SAndroid Build Coastguard Worker	sort.Slice(dists, func(i, j int) bool {
333*333d2b36SAndroid Build Coastguard Worker		return lessArr(dists[i].goals, dists[j].goals) || lessArr(dists[i].paths, dists[j].paths)
334*333d2b36SAndroid Build Coastguard Worker	})
335*333d2b36SAndroid Build Coastguard Worker
336*333d2b36SAndroid Build Coastguard Worker	outBytes := s.writeVars(vars)
337*333d2b36SAndroid Build Coastguard Worker
338*333d2b36SAndroid Build Coastguard Worker	if err := pathtools.WriteFileIfChanged(outFile, outBytes, 0666); err != nil {
339*333d2b36SAndroid Build Coastguard Worker		ctx.Errorf(err.Error())
340*333d2b36SAndroid Build Coastguard Worker	}
341*333d2b36SAndroid Build Coastguard Worker
342*333d2b36SAndroid Build Coastguard Worker	lateOutBytes := s.writeLate(phonies, dists)
343*333d2b36SAndroid Build Coastguard Worker
344*333d2b36SAndroid Build Coastguard Worker	if err := pathtools.WriteFileIfChanged(lateOutFile, lateOutBytes, 0666); err != nil {
345*333d2b36SAndroid Build Coastguard Worker		ctx.Errorf(err.Error())
346*333d2b36SAndroid Build Coastguard Worker	}
347*333d2b36SAndroid Build Coastguard Worker
348*333d2b36SAndroid Build Coastguard Worker	installsBytes := s.writeInstalls(katiInstalls, katiSymlinks, katiVintfManifestInstalls)
349*333d2b36SAndroid Build Coastguard Worker	if err := pathtools.WriteFileIfChanged(installsFile, installsBytes, 0666); err != nil {
350*333d2b36SAndroid Build Coastguard Worker		ctx.Errorf(err.Error())
351*333d2b36SAndroid Build Coastguard Worker	}
352*333d2b36SAndroid Build Coastguard Worker
353*333d2b36SAndroid Build Coastguard Worker	// Only save state for tests when testing.
354*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().RunningInsideUnitTest() {
355*333d2b36SAndroid Build Coastguard Worker		s.varsForTesting = vars
356*333d2b36SAndroid Build Coastguard Worker		s.installsForTesting = installsBytes
357*333d2b36SAndroid Build Coastguard Worker	}
358*333d2b36SAndroid Build Coastguard Worker}
359*333d2b36SAndroid Build Coastguard Worker
360*333d2b36SAndroid Build Coastguard Workerfunc (s *makeVarsSingleton) writeVars(vars []makeVarsVariable) []byte {
361*333d2b36SAndroid Build Coastguard Worker	buf := &bytes.Buffer{}
362*333d2b36SAndroid Build Coastguard Worker
363*333d2b36SAndroid Build Coastguard Worker	fmt.Fprint(buf, `# Autogenerated file
364*333d2b36SAndroid Build Coastguard Worker
365*333d2b36SAndroid Build Coastguard Worker# Compares SOONG_$(1) against $(1), and warns if they are not equal.
366*333d2b36SAndroid Build Coastguard Worker#
367*333d2b36SAndroid Build Coastguard Worker# If the original variable is empty, then just set it to the SOONG_ version.
368*333d2b36SAndroid Build Coastguard Worker#
369*333d2b36SAndroid Build Coastguard Worker# $(1): Name of the variable to check
370*333d2b36SAndroid Build Coastguard Worker# $(2): If not-empty, sort the values before comparing
371*333d2b36SAndroid Build Coastguard Worker# $(3): Extra snippet to run if it does not match
372*333d2b36SAndroid Build Coastguard Workerdefine soong-compare-var
373*333d2b36SAndroid Build Coastguard Workerifneq ($$($(1)),)
374*333d2b36SAndroid Build Coastguard Worker  my_val_make := $$(strip $(if $(2),$$(sort $$($(1))),$$($(1))))
375*333d2b36SAndroid Build Coastguard Worker  my_val_soong := $(if $(2),$$(sort $$(SOONG_$(1))),$$(SOONG_$(1)))
376*333d2b36SAndroid Build Coastguard Worker  ifneq ($$(my_val_make),$$(my_val_soong))
377*333d2b36SAndroid Build Coastguard Worker    $$(warning $(1) does not match between Make and Soong:)
378*333d2b36SAndroid Build Coastguard Worker    $(if $(2),$$(warning Make  adds: $$(filter-out $$(my_val_soong),$$(my_val_make))),$$(warning Make : $$(my_val_make)))
379*333d2b36SAndroid Build Coastguard Worker    $(if $(2),$$(warning Soong adds: $$(filter-out $$(my_val_make),$$(my_val_soong))),$$(warning Soong: $$(my_val_soong)))
380*333d2b36SAndroid Build Coastguard Worker    $(3)
381*333d2b36SAndroid Build Coastguard Worker  endif
382*333d2b36SAndroid Build Coastguard Worker  my_val_make :=
383*333d2b36SAndroid Build Coastguard Worker  my_val_soong :=
384*333d2b36SAndroid Build Coastguard Workerelse
385*333d2b36SAndroid Build Coastguard Worker  $(1) := $$(SOONG_$(1))
386*333d2b36SAndroid Build Coastguard Workerendif
387*333d2b36SAndroid Build Coastguard Worker.KATI_READONLY := $(1) SOONG_$(1)
388*333d2b36SAndroid Build Coastguard Workerendef
389*333d2b36SAndroid Build Coastguard Worker
390*333d2b36SAndroid Build Coastguard Workermy_check_failed := false
391*333d2b36SAndroid Build Coastguard Worker
392*333d2b36SAndroid Build Coastguard Worker`)
393*333d2b36SAndroid Build Coastguard Worker
394*333d2b36SAndroid Build Coastguard Worker	// Write all the strict checks out first so that if one of them errors,
395*333d2b36SAndroid Build Coastguard Worker	// we get all of the strict errors printed, but not the non-strict
396*333d2b36SAndroid Build Coastguard Worker	// warnings.
397*333d2b36SAndroid Build Coastguard Worker	for _, v := range vars {
398*333d2b36SAndroid Build Coastguard Worker		if !v.strict {
399*333d2b36SAndroid Build Coastguard Worker			continue
400*333d2b36SAndroid Build Coastguard Worker		}
401*333d2b36SAndroid Build Coastguard Worker
402*333d2b36SAndroid Build Coastguard Worker		sort := ""
403*333d2b36SAndroid Build Coastguard Worker		if v.sort {
404*333d2b36SAndroid Build Coastguard Worker			sort = "true"
405*333d2b36SAndroid Build Coastguard Worker		}
406*333d2b36SAndroid Build Coastguard Worker
407*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "SOONG_%s := %s\n", v.name, v.value)
408*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "$(eval $(call soong-compare-var,%s,%s,my_check_failed := true))\n\n", v.name, sort)
409*333d2b36SAndroid Build Coastguard Worker	}
410*333d2b36SAndroid Build Coastguard Worker
411*333d2b36SAndroid Build Coastguard Worker	fmt.Fprint(buf, `
412*333d2b36SAndroid Build Coastguard Workerifneq ($(my_check_failed),false)
413*333d2b36SAndroid Build Coastguard Worker  $(error Soong variable check failed)
414*333d2b36SAndroid Build Coastguard Workerendif
415*333d2b36SAndroid Build Coastguard Workermy_check_failed :=
416*333d2b36SAndroid Build Coastguard Worker
417*333d2b36SAndroid Build Coastguard Worker
418*333d2b36SAndroid Build Coastguard Worker`)
419*333d2b36SAndroid Build Coastguard Worker
420*333d2b36SAndroid Build Coastguard Worker	for _, v := range vars {
421*333d2b36SAndroid Build Coastguard Worker		if v.strict {
422*333d2b36SAndroid Build Coastguard Worker			continue
423*333d2b36SAndroid Build Coastguard Worker		}
424*333d2b36SAndroid Build Coastguard Worker
425*333d2b36SAndroid Build Coastguard Worker		sort := ""
426*333d2b36SAndroid Build Coastguard Worker		if v.sort {
427*333d2b36SAndroid Build Coastguard Worker			sort = "true"
428*333d2b36SAndroid Build Coastguard Worker		}
429*333d2b36SAndroid Build Coastguard Worker
430*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "SOONG_%s := %s\n", v.name, v.value)
431*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "$(eval $(call soong-compare-var,%s,%s))\n\n", v.name, sort)
432*333d2b36SAndroid Build Coastguard Worker	}
433*333d2b36SAndroid Build Coastguard Worker
434*333d2b36SAndroid Build Coastguard Worker	fmt.Fprintln(buf, "\nsoong-compare-var :=")
435*333d2b36SAndroid Build Coastguard Worker
436*333d2b36SAndroid Build Coastguard Worker	fmt.Fprintln(buf)
437*333d2b36SAndroid Build Coastguard Worker
438*333d2b36SAndroid Build Coastguard Worker	return buf.Bytes()
439*333d2b36SAndroid Build Coastguard Worker}
440*333d2b36SAndroid Build Coastguard Worker
441*333d2b36SAndroid Build Coastguard Workerfunc (s *makeVarsSingleton) writeLate(phonies []phony, dists []dist) []byte {
442*333d2b36SAndroid Build Coastguard Worker	buf := &bytes.Buffer{}
443*333d2b36SAndroid Build Coastguard Worker
444*333d2b36SAndroid Build Coastguard Worker	fmt.Fprint(buf, `# Autogenerated file
445*333d2b36SAndroid Build Coastguard Worker
446*333d2b36SAndroid Build Coastguard Worker# Values written by Soong read after parsing all Android.mk files.
447*333d2b36SAndroid Build Coastguard Worker
448*333d2b36SAndroid Build Coastguard Worker
449*333d2b36SAndroid Build Coastguard Worker`)
450*333d2b36SAndroid Build Coastguard Worker
451*333d2b36SAndroid Build Coastguard Worker	for _, phony := range phonies {
452*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, ".PHONY: %s\n", phony.name)
453*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "%s: %s\n", phony.name, strings.Join(phony.deps, "\\\n  "))
454*333d2b36SAndroid Build Coastguard Worker	}
455*333d2b36SAndroid Build Coastguard Worker
456*333d2b36SAndroid Build Coastguard Worker	fmt.Fprintln(buf)
457*333d2b36SAndroid Build Coastguard Worker
458*333d2b36SAndroid Build Coastguard Worker	for _, dist := range dists {
459*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, ".PHONY: %s\n", strings.Join(dist.goals, " "))
460*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "$(call dist-for-goals,%s,%s)\n",
461*333d2b36SAndroid Build Coastguard Worker			strings.Join(dist.goals, " "), strings.Join(dist.paths, " "))
462*333d2b36SAndroid Build Coastguard Worker	}
463*333d2b36SAndroid Build Coastguard Worker
464*333d2b36SAndroid Build Coastguard Worker	return buf.Bytes()
465*333d2b36SAndroid Build Coastguard Worker}
466*333d2b36SAndroid Build Coastguard Worker
467*333d2b36SAndroid Build Coastguard Worker// writeInstalls writes the list of install rules generated by Soong to a makefile.  The rules
468*333d2b36SAndroid Build Coastguard Worker// are exported to Make instead of written directly to the ninja file so that main.mk can add
469*333d2b36SAndroid Build Coastguard Worker// the dependencies from the `required` property that are hard to resolve in Soong.
470*333d2b36SAndroid Build Coastguard Workerfunc (s *makeVarsSingleton) writeInstalls(installs, symlinks, katiVintfManifestInstalls []katiInstall) []byte {
471*333d2b36SAndroid Build Coastguard Worker	buf := &bytes.Buffer{}
472*333d2b36SAndroid Build Coastguard Worker
473*333d2b36SAndroid Build Coastguard Worker	fmt.Fprint(buf, `# Autogenerated file
474*333d2b36SAndroid Build Coastguard Worker
475*333d2b36SAndroid Build Coastguard Worker# Values written by Soong to generate install rules that can be amended by Kati.
476*333d2b36SAndroid Build Coastguard Worker
477*333d2b36SAndroid Build Coastguard WorkerEXTRA_INSTALL_ZIPS :=
478*333d2b36SAndroid Build Coastguard Worker`)
479*333d2b36SAndroid Build Coastguard Worker
480*333d2b36SAndroid Build Coastguard Worker	preserveSymlinksFlag := "-d"
481*333d2b36SAndroid Build Coastguard Worker	if runtime.GOOS == "darwin" {
482*333d2b36SAndroid Build Coastguard Worker		preserveSymlinksFlag = "-R"
483*333d2b36SAndroid Build Coastguard Worker	}
484*333d2b36SAndroid Build Coastguard Worker
485*333d2b36SAndroid Build Coastguard Worker	for _, install := range installs {
486*333d2b36SAndroid Build Coastguard Worker		// Write a rule for each install request in the form:
487*333d2b36SAndroid Build Coastguard Worker		//  to: from [ deps ] [ | order only deps ]
488*333d2b36SAndroid Build Coastguard Worker		//       cp -f -d $< $@ [ && chmod +x $@ ]
489*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "%s: %s", install.to.String(), install.from.String())
490*333d2b36SAndroid Build Coastguard Worker		for _, dep := range install.implicitDeps {
491*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, " %s", dep.String())
492*333d2b36SAndroid Build Coastguard Worker		}
493*333d2b36SAndroid Build Coastguard Worker		if extraFiles := install.extraFiles; extraFiles != nil {
494*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, " %s", extraFiles.zip.String())
495*333d2b36SAndroid Build Coastguard Worker		}
496*333d2b36SAndroid Build Coastguard Worker		if len(install.orderOnlyDeps) > 0 {
497*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, " |")
498*333d2b36SAndroid Build Coastguard Worker		}
499*333d2b36SAndroid Build Coastguard Worker		for _, dep := range install.orderOnlyDeps {
500*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, " %s", dep.String())
501*333d2b36SAndroid Build Coastguard Worker		}
502*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf)
503*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf, "\t@echo \"Install: $@\"")
504*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "\trm -f $@ && cp -f %s $< $@\n", preserveSymlinksFlag)
505*333d2b36SAndroid Build Coastguard Worker		if install.executable {
506*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, "\tchmod +x $@\n")
507*333d2b36SAndroid Build Coastguard Worker		}
508*333d2b36SAndroid Build Coastguard Worker		if extraFiles := install.extraFiles; extraFiles != nil {
509*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, "\t( unzip -qDD -d '%s' '%s' 2>&1 | grep -v \"zipfile is empty\"; exit $${PIPESTATUS[0]} ) || \\\n", extraFiles.dir.String(), extraFiles.zip.String())
510*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, "\t  ( code=$$?; if [ $$code -ne 0 -a $$code -ne 1 ]; then exit $$code; fi )\n")
511*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, "EXTRA_INSTALL_ZIPS += %s:%s:%s\n", install.to.String(), extraFiles.dir.String(), extraFiles.zip.String())
512*333d2b36SAndroid Build Coastguard Worker		}
513*333d2b36SAndroid Build Coastguard Worker
514*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf)
515*333d2b36SAndroid Build Coastguard Worker	}
516*333d2b36SAndroid Build Coastguard Worker	fmt.Fprintf(buf, ".KATI_READONLY := EXTRA_INSTALL_ZIPS\n")
517*333d2b36SAndroid Build Coastguard Worker	fmt.Fprintf(buf, "$(KATI_visibility_prefix EXTRA_INSTALL_ZIPS,build/make/core/Makefile)\n")
518*333d2b36SAndroid Build Coastguard Worker
519*333d2b36SAndroid Build Coastguard Worker	for _, symlink := range symlinks {
520*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "%s:", symlink.to.String())
521*333d2b36SAndroid Build Coastguard Worker		if symlink.from != nil {
522*333d2b36SAndroid Build Coastguard Worker			// The katiVintfManifestInstall doesn't need updating when the target is modified, but we sometimes
523*333d2b36SAndroid Build Coastguard Worker			// have a dependency on a katiVintfManifestInstall to a binary instead of to the binary directly, and
524*333d2b36SAndroid Build Coastguard Worker			// the mtime of the katiVintfManifestInstall must be updated when the binary is modified, so use a
525*333d2b36SAndroid Build Coastguard Worker			// normal dependency here instead of an order-only dependency.
526*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, " %s", symlink.from.String())
527*333d2b36SAndroid Build Coastguard Worker		}
528*333d2b36SAndroid Build Coastguard Worker		for _, dep := range symlink.implicitDeps {
529*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, " %s", dep.String())
530*333d2b36SAndroid Build Coastguard Worker		}
531*333d2b36SAndroid Build Coastguard Worker		if len(symlink.orderOnlyDeps) > 0 {
532*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, " |")
533*333d2b36SAndroid Build Coastguard Worker		}
534*333d2b36SAndroid Build Coastguard Worker		for _, dep := range symlink.orderOnlyDeps {
535*333d2b36SAndroid Build Coastguard Worker			fmt.Fprintf(buf, " %s", dep.String())
536*333d2b36SAndroid Build Coastguard Worker		}
537*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf)
538*333d2b36SAndroid Build Coastguard Worker
539*333d2b36SAndroid Build Coastguard Worker		fromStr := ""
540*333d2b36SAndroid Build Coastguard Worker		if symlink.from != nil {
541*333d2b36SAndroid Build Coastguard Worker			rel, err := filepath.Rel(filepath.Dir(symlink.to.String()), symlink.from.String())
542*333d2b36SAndroid Build Coastguard Worker			if err != nil {
543*333d2b36SAndroid Build Coastguard Worker				panic(fmt.Errorf("failed to find relative path for katiVintfManifestInstall from %q to %q: %w",
544*333d2b36SAndroid Build Coastguard Worker					symlink.from.String(), symlink.to.String(), err))
545*333d2b36SAndroid Build Coastguard Worker			}
546*333d2b36SAndroid Build Coastguard Worker			fromStr = rel
547*333d2b36SAndroid Build Coastguard Worker		} else {
548*333d2b36SAndroid Build Coastguard Worker			fromStr = symlink.absFrom
549*333d2b36SAndroid Build Coastguard Worker		}
550*333d2b36SAndroid Build Coastguard Worker
551*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf, "\t@echo \"Symlink: $@\"")
552*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "\trm -f $@ && ln -sfn %s $@", fromStr)
553*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf)
554*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf)
555*333d2b36SAndroid Build Coastguard Worker	}
556*333d2b36SAndroid Build Coastguard Worker
557*333d2b36SAndroid Build Coastguard Worker	for _, install := range katiVintfManifestInstalls {
558*333d2b36SAndroid Build Coastguard Worker		// Write a rule for each vintf install request that calls the copy-vintf-manifest-chedk make function.
559*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintf(buf, "$(eval $(call copy-vintf-manifest-checked, %s, %s))\n", install.from.String(), install.to.String())
560*333d2b36SAndroid Build Coastguard Worker
561*333d2b36SAndroid Build Coastguard Worker		if len(install.implicitDeps) > 0 {
562*333d2b36SAndroid Build Coastguard Worker			panic(fmt.Errorf("unsupported implicitDeps %q in vintf install rule %q", install.implicitDeps, install.to))
563*333d2b36SAndroid Build Coastguard Worker		}
564*333d2b36SAndroid Build Coastguard Worker		if len(install.orderOnlyDeps) > 0 {
565*333d2b36SAndroid Build Coastguard Worker			panic(fmt.Errorf("unsupported orderOnlyDeps %q in vintf install rule %q", install.orderOnlyDeps, install.to))
566*333d2b36SAndroid Build Coastguard Worker		}
567*333d2b36SAndroid Build Coastguard Worker
568*333d2b36SAndroid Build Coastguard Worker		fmt.Fprintln(buf)
569*333d2b36SAndroid Build Coastguard Worker	}
570*333d2b36SAndroid Build Coastguard Worker	return buf.Bytes()
571*333d2b36SAndroid Build Coastguard Worker}
572*333d2b36SAndroid Build Coastguard Worker
573*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) DeviceConfig() DeviceConfig {
574*333d2b36SAndroid Build Coastguard Worker	return DeviceConfig{c.Config().deviceConfig}
575*333d2b36SAndroid Build Coastguard Worker}
576*333d2b36SAndroid Build Coastguard Worker
577*333d2b36SAndroid Build Coastguard Workervar ninjaDescaper = strings.NewReplacer("$$", "$")
578*333d2b36SAndroid Build Coastguard Worker
579*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) Eval(ninjaStr string) (string, error) {
580*333d2b36SAndroid Build Coastguard Worker	s, err := c.SingletonContext.Eval(c.pctx, ninjaStr)
581*333d2b36SAndroid Build Coastguard Worker	if err != nil {
582*333d2b36SAndroid Build Coastguard Worker		return "", err
583*333d2b36SAndroid Build Coastguard Worker	}
584*333d2b36SAndroid Build Coastguard Worker	// SingletonContext.Eval returns an exapnded string that is valid for a ninja file, de-escape $$ to $ for use
585*333d2b36SAndroid Build Coastguard Worker	// in a Makefile
586*333d2b36SAndroid Build Coastguard Worker	return ninjaDescaper.Replace(s), nil
587*333d2b36SAndroid Build Coastguard Worker}
588*333d2b36SAndroid Build Coastguard Worker
589*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) addVariableRaw(name, value string, strict, sort bool) {
590*333d2b36SAndroid Build Coastguard Worker	c.vars = append(c.vars, makeVarsVariable{
591*333d2b36SAndroid Build Coastguard Worker		name:   name,
592*333d2b36SAndroid Build Coastguard Worker		value:  value,
593*333d2b36SAndroid Build Coastguard Worker		strict: strict,
594*333d2b36SAndroid Build Coastguard Worker		sort:   sort,
595*333d2b36SAndroid Build Coastguard Worker	})
596*333d2b36SAndroid Build Coastguard Worker}
597*333d2b36SAndroid Build Coastguard Worker
598*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) addVariable(name, ninjaStr string, strict, sort bool) {
599*333d2b36SAndroid Build Coastguard Worker	value, err := c.Eval(ninjaStr)
600*333d2b36SAndroid Build Coastguard Worker	if err != nil {
601*333d2b36SAndroid Build Coastguard Worker		c.SingletonContext.Errorf(err.Error())
602*333d2b36SAndroid Build Coastguard Worker	}
603*333d2b36SAndroid Build Coastguard Worker	c.addVariableRaw(name, value, strict, sort)
604*333d2b36SAndroid Build Coastguard Worker}
605*333d2b36SAndroid Build Coastguard Worker
606*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) addPhony(name string, deps []string) {
607*333d2b36SAndroid Build Coastguard Worker	c.phonies = append(c.phonies, phony{name, deps})
608*333d2b36SAndroid Build Coastguard Worker}
609*333d2b36SAndroid Build Coastguard Worker
610*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) addDist(goals []string, paths []string) {
611*333d2b36SAndroid Build Coastguard Worker	c.dists = append(c.dists, dist{
612*333d2b36SAndroid Build Coastguard Worker		goals: goals,
613*333d2b36SAndroid Build Coastguard Worker		paths: paths,
614*333d2b36SAndroid Build Coastguard Worker	})
615*333d2b36SAndroid Build Coastguard Worker}
616*333d2b36SAndroid Build Coastguard Worker
617*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) Strict(name, ninjaStr string) {
618*333d2b36SAndroid Build Coastguard Worker	c.addVariable(name, ninjaStr, true, false)
619*333d2b36SAndroid Build Coastguard Worker}
620*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) StrictSorted(name, ninjaStr string) {
621*333d2b36SAndroid Build Coastguard Worker	c.addVariable(name, ninjaStr, true, true)
622*333d2b36SAndroid Build Coastguard Worker}
623*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) StrictRaw(name, value string) {
624*333d2b36SAndroid Build Coastguard Worker	c.addVariableRaw(name, value, true, false)
625*333d2b36SAndroid Build Coastguard Worker}
626*333d2b36SAndroid Build Coastguard Worker
627*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) Check(name, ninjaStr string) {
628*333d2b36SAndroid Build Coastguard Worker	c.addVariable(name, ninjaStr, false, false)
629*333d2b36SAndroid Build Coastguard Worker}
630*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) CheckSorted(name, ninjaStr string) {
631*333d2b36SAndroid Build Coastguard Worker	c.addVariable(name, ninjaStr, false, true)
632*333d2b36SAndroid Build Coastguard Worker}
633*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) CheckRaw(name, value string) {
634*333d2b36SAndroid Build Coastguard Worker	c.addVariableRaw(name, value, false, false)
635*333d2b36SAndroid Build Coastguard Worker}
636*333d2b36SAndroid Build Coastguard Worker
637*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) Phony(name string, deps ...Path) {
638*333d2b36SAndroid Build Coastguard Worker	c.addPhony(name, Paths(deps).Strings())
639*333d2b36SAndroid Build Coastguard Worker}
640*333d2b36SAndroid Build Coastguard Worker
641*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) DistForGoal(goal string, paths ...Path) {
642*333d2b36SAndroid Build Coastguard Worker	c.DistForGoals([]string{goal}, paths...)
643*333d2b36SAndroid Build Coastguard Worker}
644*333d2b36SAndroid Build Coastguard Worker
645*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) DistForGoalWithFilename(goal string, path Path, filename string) {
646*333d2b36SAndroid Build Coastguard Worker	c.DistForGoalsWithFilename([]string{goal}, path, filename)
647*333d2b36SAndroid Build Coastguard Worker}
648*333d2b36SAndroid Build Coastguard Worker
649*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) DistForGoals(goals []string, paths ...Path) {
650*333d2b36SAndroid Build Coastguard Worker	c.addDist(goals, Paths(paths).Strings())
651*333d2b36SAndroid Build Coastguard Worker}
652*333d2b36SAndroid Build Coastguard Worker
653*333d2b36SAndroid Build Coastguard Workerfunc (c *makeVarsContext) DistForGoalsWithFilename(goals []string, path Path, filename string) {
654*333d2b36SAndroid Build Coastguard Worker	c.addDist(goals, []string{path.String() + ":" + filename})
655*333d2b36SAndroid Build Coastguard Worker}
656