Define Soong phony rules in Make am: c3d87d3112
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1325397 Change-Id: Ia6a1f96c75c660525127c25472327dd78ba58124
This commit is contained in:
commit
970fd93b92
|
@ -36,6 +36,7 @@ bootstrap_go_package {
|
|||
"package_ctx.go",
|
||||
"path_properties.go",
|
||||
"paths.go",
|
||||
"phony.go",
|
||||
"prebuilt.go",
|
||||
"proto.go",
|
||||
"register.go",
|
||||
|
|
|
@ -17,12 +17,11 @@ package android
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
"github.com/google/blueprint/proptools"
|
||||
)
|
||||
|
||||
|
@ -84,6 +83,11 @@ type MakeVarsContext interface {
|
|||
// builder whenever a file matching the pattern as added or removed, without rerunning if a
|
||||
// file that does not match the pattern is added to a searched directory.
|
||||
GlobWithDeps(pattern string, excludes []string) ([]string, error)
|
||||
|
||||
// Phony creates a phony rule in Make, which will allow additional DistForGoal
|
||||
// dependencies to be added to it. Phony can be called on the same name multiple
|
||||
// times to add additional dependencies.
|
||||
Phony(names string, deps ...Path)
|
||||
}
|
||||
|
||||
var _ PathContext = MakeVarsContext(nil)
|
||||
|
@ -130,9 +134,10 @@ var makeVarsProviders []makeVarsProvider
|
|||
|
||||
type makeVarsContext struct {
|
||||
SingletonContext
|
||||
config Config
|
||||
pctx PackageContext
|
||||
vars []makeVarsVariable
|
||||
config Config
|
||||
pctx PackageContext
|
||||
vars []makeVarsVariable
|
||||
phonies []phony
|
||||
}
|
||||
|
||||
var _ MakeVarsContext = &makeVarsContext{}
|
||||
|
@ -144,6 +149,11 @@ type makeVarsVariable struct {
|
|||
strict bool
|
||||
}
|
||||
|
||||
type phony struct {
|
||||
name string
|
||||
deps []string
|
||||
}
|
||||
|
||||
func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
||||
if !ctx.Config().EmbeddedInMake() {
|
||||
return
|
||||
|
@ -152,11 +162,15 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
outFile := absolutePath(PathForOutput(ctx,
|
||||
"make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
|
||||
|
||||
lateOutFile := absolutePath(PathForOutput(ctx,
|
||||
"late"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
|
||||
|
||||
if ctx.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
vars := []makeVarsVariable{}
|
||||
var phonies []phony
|
||||
for _, provider := range makeVarsProviders {
|
||||
mctx := &makeVarsContext{
|
||||
SingletonContext: ctx,
|
||||
|
@ -166,6 +180,7 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
provider.call(mctx)
|
||||
|
||||
vars = append(vars, mctx.vars...)
|
||||
phonies = append(phonies, mctx.phonies...)
|
||||
}
|
||||
|
||||
if ctx.Failed() {
|
||||
|
@ -174,17 +189,16 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
|
||||
outBytes := s.writeVars(vars)
|
||||
|
||||
if _, err := os.Stat(absolutePath(outFile)); err == nil {
|
||||
if data, err := ioutil.ReadFile(absolutePath(outFile)); err == nil {
|
||||
if bytes.Equal(data, outBytes) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(absolutePath(outFile), outBytes, 0666); err != nil {
|
||||
if err := pathtools.WriteFileIfChanged(outFile, outBytes, 0666); err != nil {
|
||||
ctx.Errorf(err.Error())
|
||||
}
|
||||
|
||||
lateOutBytes := s.writeLate(phonies)
|
||||
|
||||
if err := pathtools.WriteFileIfChanged(lateOutFile, lateOutBytes, 0666); err != nil {
|
||||
ctx.Errorf(err.Error())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *makeVarsSingleton) writeVars(vars []makeVarsVariable) []byte {
|
||||
|
@ -263,6 +277,26 @@ my_check_failed :=
|
|||
|
||||
fmt.Fprintln(buf, "\nsoong-compare-var :=")
|
||||
|
||||
fmt.Fprintln(buf)
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func (s *makeVarsSingleton) writeLate(phonies []phony) []byte {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
fmt.Fprint(buf, `# Autogenerated file
|
||||
|
||||
# Values written by Soong read after parsing all Android.mk files.
|
||||
|
||||
|
||||
`)
|
||||
|
||||
for _, phony := range phonies {
|
||||
fmt.Fprintf(buf, ".PHONY: %s\n", phony.name)
|
||||
fmt.Fprintf(buf, "%s: %s\n", phony.name, strings.Join(phony.deps, "\\\n "))
|
||||
}
|
||||
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
|
@ -299,6 +333,10 @@ func (c *makeVarsContext) addVariable(name, ninjaStr string, strict, sort bool)
|
|||
c.addVariableRaw(name, value, strict, sort)
|
||||
}
|
||||
|
||||
func (c *makeVarsContext) addPhony(name string, deps []string) {
|
||||
c.phonies = append(c.phonies, phony{name, deps})
|
||||
}
|
||||
|
||||
func (c *makeVarsContext) Strict(name, ninjaStr string) {
|
||||
c.addVariable(name, ninjaStr, true, false)
|
||||
}
|
||||
|
@ -318,3 +356,7 @@ func (c *makeVarsContext) CheckSorted(name, ninjaStr string) {
|
|||
func (c *makeVarsContext) CheckRaw(name, value string) {
|
||||
c.addVariableRaw(name, value, false, false)
|
||||
}
|
||||
|
||||
func (c *makeVarsContext) Phony(name string, deps ...Path) {
|
||||
c.addPhony(name, Paths(deps).Strings())
|
||||
}
|
||||
|
|
|
@ -207,6 +207,10 @@ type ModuleContext interface {
|
|||
// Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
|
||||
// and performs more verification.
|
||||
Build(pctx PackageContext, params BuildParams)
|
||||
// Phony creates a Make-style phony rule, a rule with no commands that can depend on other
|
||||
// phony rules or real files. Phony can be called on the same name multiple times to add
|
||||
// additional dependencies.
|
||||
Phony(phony string, deps ...Path)
|
||||
|
||||
PrimaryModule() Module
|
||||
FinalModule() Module
|
||||
|
@ -722,6 +726,7 @@ type ModuleBase struct {
|
|||
installFiles InstallPaths
|
||||
checkbuildFiles Paths
|
||||
noticeFiles Paths
|
||||
phonies map[string]Paths
|
||||
|
||||
// Used by buildTargetSingleton to create checkbuild and per-directory build targets
|
||||
// Only set on the final variant of each module
|
||||
|
@ -1093,26 +1098,17 @@ func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
|
|||
}
|
||||
|
||||
if len(allInstalledFiles) > 0 {
|
||||
name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-install")
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Output: name,
|
||||
Implicits: allInstalledFiles.Paths(),
|
||||
Default: !ctx.Config().EmbeddedInMake(),
|
||||
})
|
||||
deps = append(deps, name)
|
||||
m.installTarget = name
|
||||
name := namespacePrefix + ctx.ModuleName() + "-install"
|
||||
ctx.Phony(name, allInstalledFiles.Paths()...)
|
||||
m.installTarget = PathForPhony(ctx, name)
|
||||
deps = append(deps, m.installTarget)
|
||||
}
|
||||
|
||||
if len(allCheckbuildFiles) > 0 {
|
||||
name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+"-checkbuild")
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Output: name,
|
||||
Implicits: allCheckbuildFiles,
|
||||
})
|
||||
deps = append(deps, name)
|
||||
m.checkbuildTarget = name
|
||||
name := namespacePrefix + ctx.ModuleName() + "-checkbuild"
|
||||
ctx.Phony(name, allCheckbuildFiles...)
|
||||
m.checkbuildTarget = PathForPhony(ctx, name)
|
||||
deps = append(deps, m.checkbuildTarget)
|
||||
}
|
||||
|
||||
if len(deps) > 0 {
|
||||
|
@ -1121,12 +1117,7 @@ func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
|
|||
suffix = "-soong"
|
||||
}
|
||||
|
||||
name := PathForPhony(ctx, namespacePrefix+ctx.ModuleName()+suffix)
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Outputs: []WritablePath{name},
|
||||
Implicits: deps,
|
||||
})
|
||||
ctx.Phony(namespacePrefix+ctx.ModuleName()+suffix, deps...)
|
||||
|
||||
m.blueprintDir = ctx.ModuleDir()
|
||||
}
|
||||
|
@ -1313,6 +1304,9 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
|
|||
m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
|
||||
m.initRcPaths = PathsForModuleSrc(ctx, m.commonProperties.Init_rc)
|
||||
m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments)
|
||||
for k, v := range ctx.phonies {
|
||||
m.phonies[k] = append(m.phonies[k], v...)
|
||||
}
|
||||
} else if ctx.Config().AllowMissingDependencies() {
|
||||
// If the module is not enabled it will not create any build rules, nothing will call
|
||||
// ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
|
||||
|
@ -1460,6 +1454,7 @@ type moduleContext struct {
|
|||
installFiles InstallPaths
|
||||
checkbuildFiles Paths
|
||||
module Module
|
||||
phonies map[string]Paths
|
||||
|
||||
// For tests
|
||||
buildParams []BuildParams
|
||||
|
@ -1574,6 +1569,11 @@ func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
|
|||
|
||||
m.bp.Build(pctx.PackageContext, convertBuildParams(params))
|
||||
}
|
||||
|
||||
func (m *moduleContext) Phony(name string, deps ...Path) {
|
||||
addPhony(m.config, name, deps...)
|
||||
}
|
||||
|
||||
func (m *moduleContext) GetMissingDependencies() []string {
|
||||
var missingDeps []string
|
||||
missingDeps = append(missingDeps, m.Module().base().commonProperties.MissingDeps...)
|
||||
|
@ -2233,9 +2233,8 @@ type buildTargetSingleton struct{}
|
|||
func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
|
||||
var checkbuildDeps Paths
|
||||
|
||||
mmTarget := func(dir string) WritablePath {
|
||||
return PathForPhony(ctx,
|
||||
"MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
|
||||
mmTarget := func(dir string) string {
|
||||
return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1)
|
||||
}
|
||||
|
||||
modulesInDir := make(map[string]Paths)
|
||||
|
@ -2261,11 +2260,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
}
|
||||
|
||||
// Create a top-level checkbuild target that depends on all modules
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Output: PathForPhony(ctx, "checkbuild"+suffix),
|
||||
Implicits: checkbuildDeps,
|
||||
})
|
||||
ctx.Phony("checkbuild"+suffix, checkbuildDeps...)
|
||||
|
||||
// Make will generate the MODULES-IN-* targets
|
||||
if ctx.Config().EmbeddedInMake() {
|
||||
|
@ -2289,7 +2284,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
for _, dir := range dirs {
|
||||
p := parentDir(dir)
|
||||
if p != "." && p != "/" {
|
||||
modulesInDir[p] = append(modulesInDir[p], mmTarget(dir))
|
||||
modulesInDir[p] = append(modulesInDir[p], PathForPhony(ctx, mmTarget(dir)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2297,14 +2292,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
// depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
|
||||
// files.
|
||||
for _, dir := range dirs {
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Output: mmTarget(dir),
|
||||
Implicits: modulesInDir[dir],
|
||||
// HACK: checkbuild should be an optional build, but force it
|
||||
// enabled for now in standalone builds
|
||||
Default: !ctx.Config().EmbeddedInMake(),
|
||||
})
|
||||
ctx.Phony(mmTarget(dir), modulesInDir[dir]...)
|
||||
}
|
||||
|
||||
// Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
|
||||
|
@ -2331,23 +2319,15 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
continue
|
||||
}
|
||||
|
||||
name := PathForPhony(ctx, className+"-"+os.Name)
|
||||
osClass[className] = append(osClass[className], name)
|
||||
name := className + "-" + os.Name
|
||||
osClass[className] = append(osClass[className], PathForPhony(ctx, name))
|
||||
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Output: name,
|
||||
Implicits: deps,
|
||||
})
|
||||
ctx.Phony(name, deps...)
|
||||
}
|
||||
|
||||
// Wrap those into host|host-cross|target phony rules
|
||||
for _, class := range SortedStringKeys(osClass) {
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Output: PathForPhony(ctx, class),
|
||||
Implicits: osClass[class],
|
||||
})
|
||||
ctx.Phony(class, osClass[class]...)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
// Copyright 2020 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package android
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
var phonyMapOnceKey = NewOnceKey("phony")
|
||||
|
||||
type phonyMap map[string]Paths
|
||||
|
||||
var phonyMapLock sync.Mutex
|
||||
|
||||
func getPhonyMap(config Config) phonyMap {
|
||||
return config.Once(phonyMapOnceKey, func() interface{} {
|
||||
return make(phonyMap)
|
||||
}).(phonyMap)
|
||||
}
|
||||
|
||||
func addPhony(config Config, name string, deps ...Path) {
|
||||
phonyMap := getPhonyMap(config)
|
||||
phonyMapLock.Lock()
|
||||
defer phonyMapLock.Unlock()
|
||||
phonyMap[name] = append(phonyMap[name], deps...)
|
||||
}
|
||||
|
||||
type phonySingleton struct {
|
||||
phonyMap phonyMap
|
||||
phonyList []string
|
||||
}
|
||||
|
||||
var _ SingletonMakeVarsProvider = (*phonySingleton)(nil)
|
||||
|
||||
func (p *phonySingleton) GenerateBuildActions(ctx SingletonContext) {
|
||||
p.phonyMap = getPhonyMap(ctx.Config())
|
||||
p.phonyList = SortedStringKeys(p.phonyMap)
|
||||
for _, phony := range p.phonyList {
|
||||
p.phonyMap[phony] = SortedUniquePaths(p.phonyMap[phony])
|
||||
}
|
||||
|
||||
if !ctx.Config().EmbeddedInMake() {
|
||||
for _, phony := range p.phonyList {
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Outputs: []WritablePath{PathForPhony(ctx, phony)},
|
||||
Implicits: p.phonyMap[phony],
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p phonySingleton) MakeVars(ctx MakeVarsContext) {
|
||||
for _, phony := range p.phonyList {
|
||||
ctx.Phony(phony, p.phonyMap[phony]...)
|
||||
}
|
||||
}
|
||||
|
||||
func phonySingletonFactory() Singleton {
|
||||
return &phonySingleton{}
|
||||
}
|
|
@ -104,6 +104,9 @@ func (ctx *Context) Register() {
|
|||
|
||||
registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps)
|
||||
|
||||
// Register phony just before makevars so it can write out its phony rules as Make rules
|
||||
ctx.RegisterSingletonType("phony", SingletonFactoryAdaptor(phonySingletonFactory))
|
||||
|
||||
// Register makevars after other singletons so they can export values through makevars
|
||||
ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc))
|
||||
|
||||
|
|
|
@ -36,6 +36,12 @@ type SingletonContext interface {
|
|||
Variable(pctx PackageContext, name, value string)
|
||||
Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
|
||||
Build(pctx PackageContext, params BuildParams)
|
||||
|
||||
// Phony creates a Make-style phony rule, a rule with no commands that can depend on other
|
||||
// phony rules or real files. Phony can be called on the same name multiple times to add
|
||||
// additional dependencies.
|
||||
Phony(name string, deps ...Path)
|
||||
|
||||
RequireNinjaVersion(major, minor, micro int)
|
||||
|
||||
// SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable
|
||||
|
@ -156,6 +162,10 @@ func (s *singletonContextAdaptor) Build(pctx PackageContext, params BuildParams)
|
|||
|
||||
}
|
||||
|
||||
func (s *singletonContextAdaptor) Phony(name string, deps ...Path) {
|
||||
addPhony(s.Config(), name, deps...)
|
||||
}
|
||||
|
||||
func (s *singletonContextAdaptor) SetNinjaBuildDir(pctx PackageContext, value string) {
|
||||
s.SingletonContext.SetNinjaBuildDir(pctx.PackageContext, value)
|
||||
}
|
||||
|
|
|
@ -69,9 +69,5 @@ func (c *docsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||
})
|
||||
|
||||
// Add a phony target for building the documentation
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Output: PathForPhony(ctx, "soong_docs"),
|
||||
Input: docsFile,
|
||||
})
|
||||
ctx.Phony("soong_docs", docsFile)
|
||||
}
|
||||
|
|
7
cc/cc.go
7
cc/cc.go
|
@ -3223,12 +3223,7 @@ func (ks *kytheExtractAllSingleton) GenerateBuildActions(ctx android.SingletonCo
|
|||
})
|
||||
// TODO(asmundak): Perhaps emit a rule to output a warning if there were no xrefTargets
|
||||
if len(xrefTargets) > 0 {
|
||||
ctx.Build(pctx, android.BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Output: android.PathForPhony(ctx, "xref_cxx"),
|
||||
Inputs: xrefTargets,
|
||||
//Default: true,
|
||||
})
|
||||
ctx.Phony("xref_cxx", xrefTargets...)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2874,11 +2874,7 @@ func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonC
|
|||
})
|
||||
// TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
|
||||
if len(xrefTargets) > 0 {
|
||||
ctx.Build(pctx, android.BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Output: android.PathForPhony(ctx, "xref_java"),
|
||||
Inputs: xrefTargets,
|
||||
})
|
||||
ctx.Phony("xref_java", xrefTargets...)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue