• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2020 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 android
16
17import (
18	"strings"
19	"sync"
20
21	"github.com/google/blueprint"
22)
23
24var phonyMapOnceKey = NewOnceKey("phony")
25
26type phonyMap map[string]Paths
27
28var phonyMapLock sync.Mutex
29
30type ModulePhonyInfo struct {
31	Phonies map[string]Paths
32}
33
34var ModulePhonyProvider = blueprint.NewProvider[ModulePhonyInfo]()
35
36func getSingletonPhonyMap(config Config) phonyMap {
37	return config.Once(phonyMapOnceKey, func() interface{} {
38		return make(phonyMap)
39	}).(phonyMap)
40}
41
42func addSingletonPhony(config Config, name string, deps ...Path) {
43	phonyMap := getSingletonPhonyMap(config)
44	phonyMapLock.Lock()
45	defer phonyMapLock.Unlock()
46	phonyMap[name] = append(phonyMap[name], deps...)
47}
48
49type phonySingleton struct {
50	phonyMap  phonyMap
51	phonyList []string
52}
53
54var _ SingletonMakeVarsProvider = (*phonySingleton)(nil)
55
56func (p *phonySingleton) GenerateBuildActions(ctx SingletonContext) {
57	p.phonyMap = getSingletonPhonyMap(ctx.Config())
58	ctx.VisitAllModuleProxies(func(m ModuleProxy) {
59		if info, ok := OtherModuleProvider(ctx, m, ModulePhonyProvider); ok {
60			for k, v := range info.Phonies {
61				p.phonyMap[k] = append(p.phonyMap[k], v...)
62			}
63		}
64	})
65
66	p.phonyList = SortedKeys(p.phonyMap)
67	for _, phony := range p.phonyList {
68		p.phonyMap[phony] = SortedUniquePaths(p.phonyMap[phony])
69	}
70
71	if !ctx.Config().KatiEnabled() {
72		// In soong-only builds, the phonies can conflict with dist targets that will
73		// be generated in the packaging step. Instead of emitting a blueprint/ninja phony directly,
74		// create a makefile that defines the phonies that will be included in the packaging step.
75		// Make will dedup the phonies there.
76		var buildPhonyFileContents strings.Builder
77		for _, phony := range p.phonyList {
78			buildPhonyFileContents.WriteString(".PHONY: ")
79			buildPhonyFileContents.WriteString(phony)
80			buildPhonyFileContents.WriteString("\n")
81			buildPhonyFileContents.WriteString(phony)
82			buildPhonyFileContents.WriteString(":")
83			for _, dep := range p.phonyMap[phony] {
84				buildPhonyFileContents.WriteString(" ")
85				buildPhonyFileContents.WriteString(dep.String())
86			}
87			buildPhonyFileContents.WriteString("\n")
88		}
89		buildPhonyFile := PathForOutput(ctx, "soong_phony_targets.mk")
90		writeValueIfChanged(ctx, absolutePath(buildPhonyFile.String()), buildPhonyFileContents.String())
91	}
92}
93
94func (p phonySingleton) MakeVars(ctx MakeVarsContext) {
95	for _, phony := range p.phonyList {
96		ctx.Phony(phony, p.phonyMap[phony]...)
97	}
98}
99
100func phonySingletonFactory() Singleton {
101	return &phonySingleton{}
102}
103