Merge "Export Soong install rules to Make" am: 1caea35278
am: 7f5f69f9ba
am: 5e5d6332b4
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1869552 Change-Id: Ifc2d7a00569bdb8dcef9853f27e07824cef3d59d
This commit is contained in:
@@ -516,6 +516,16 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint
|
|||||||
a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
|
a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
|
||||||
a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
|
a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
|
||||||
|
|
||||||
|
// If the install rule was generated by Soong tell Make about it.
|
||||||
|
if amod.InstallBypassMake() && len(base.katiInstalls) > 0 {
|
||||||
|
// Assume the primary install file is last since it probably needs to depend on any other
|
||||||
|
// installed files. If that is not the case we can add a method to specify the primary
|
||||||
|
// installed file.
|
||||||
|
a.SetPath("LOCAL_SOONG_INSTALLED_MODULE", base.katiInstalls[len(base.katiInstalls)-1].to)
|
||||||
|
a.SetString("LOCAL_SOONG_INSTALL_PAIRS", base.katiInstalls.BuiltInstalled())
|
||||||
|
a.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", base.katiSymlinks.InstallPaths().Paths())
|
||||||
|
}
|
||||||
|
|
||||||
if am, ok := mod.(ApexModule); ok {
|
if am, ok := mod.(ApexModule); ok {
|
||||||
a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
|
a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,8 @@ package android
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -222,6 +224,9 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||||||
lateOutFile := absolutePath(PathForOutput(ctx,
|
lateOutFile := absolutePath(PathForOutput(ctx,
|
||||||
"late"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
|
"late"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
|
||||||
|
|
||||||
|
installsFile := absolutePath(PathForOutput(ctx,
|
||||||
|
"installs"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
|
||||||
|
|
||||||
if ctx.Failed() {
|
if ctx.Failed() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -229,6 +234,8 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||||||
var vars []makeVarsVariable
|
var vars []makeVarsVariable
|
||||||
var dists []dist
|
var dists []dist
|
||||||
var phonies []phony
|
var phonies []phony
|
||||||
|
var katiInstalls []katiInstall
|
||||||
|
var katiSymlinks []katiInstall
|
||||||
|
|
||||||
providers := append([]makeVarsProvider(nil), makeVarsInitProviders...)
|
providers := append([]makeVarsProvider(nil), makeVarsInitProviders...)
|
||||||
providers = append(providers, *ctx.Config().Get(singletonMakeVarsProvidersKey).(*[]makeVarsProvider)...)
|
providers = append(providers, *ctx.Config().Get(singletonMakeVarsProvidersKey).(*[]makeVarsProvider)...)
|
||||||
@@ -258,6 +265,11 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||||||
phonies = append(phonies, mctx.phonies...)
|
phonies = append(phonies, mctx.phonies...)
|
||||||
dists = append(dists, mctx.dists...)
|
dists = append(dists, mctx.dists...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.ExportedToMake() {
|
||||||
|
katiInstalls = append(katiInstalls, m.base().katiInstalls...)
|
||||||
|
katiSymlinks = append(katiSymlinks, m.base().katiSymlinks...)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if ctx.Failed() {
|
if ctx.Failed() {
|
||||||
@@ -297,6 +309,10 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
|||||||
ctx.Errorf(err.Error())
|
ctx.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
installsBytes := s.writeInstalls(katiInstalls, katiSymlinks)
|
||||||
|
if err := pathtools.WriteFileIfChanged(installsFile, installsBytes, 0666); err != nil {
|
||||||
|
ctx.Errorf(err.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *makeVarsSingleton) writeVars(vars []makeVarsVariable) []byte {
|
func (s *makeVarsSingleton) writeVars(vars []makeVarsVariable) []byte {
|
||||||
@@ -405,6 +421,84 @@ func (s *makeVarsSingleton) writeLate(phonies []phony, dists []dist) []byte {
|
|||||||
return buf.Bytes()
|
return buf.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeInstalls writes the list of install rules generated by Soong to a makefile. The rules
|
||||||
|
// are exported to Make instead of written directly to the ninja file so that main.mk can add
|
||||||
|
// the dependencies from the `required` property that are hard to resolve in Soong.
|
||||||
|
func (s *makeVarsSingleton) writeInstalls(installs, symlinks []katiInstall) []byte {
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
|
||||||
|
fmt.Fprint(buf, `# Autogenerated file
|
||||||
|
|
||||||
|
# Values written by Soong to generate install rules that can be amended by Kati.
|
||||||
|
|
||||||
|
|
||||||
|
`)
|
||||||
|
|
||||||
|
preserveSymlinksFlag := "-d"
|
||||||
|
if runtime.GOOS == "darwin" {
|
||||||
|
preserveSymlinksFlag = "-R"
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, install := range installs {
|
||||||
|
// Write a rule for each install request in the form:
|
||||||
|
// to: from [ deps ] [ | order only deps ]
|
||||||
|
// cp -f -d $< $@ [ && chmod +x $@ ]
|
||||||
|
fmt.Fprintf(buf, "%s: %s", install.to.String(), install.from.String())
|
||||||
|
for _, dep := range install.implicitDeps {
|
||||||
|
fmt.Fprintf(buf, " %s", dep.String())
|
||||||
|
}
|
||||||
|
if len(install.orderOnlyDeps) > 0 {
|
||||||
|
fmt.Fprintf(buf, " |")
|
||||||
|
}
|
||||||
|
for _, dep := range install.orderOnlyDeps {
|
||||||
|
fmt.Fprintf(buf, " %s", dep.String())
|
||||||
|
}
|
||||||
|
fmt.Fprintln(buf)
|
||||||
|
|
||||||
|
fmt.Fprintf(buf, "\trm -f $@ && cp -f %s $< $@", preserveSymlinksFlag)
|
||||||
|
if install.executable {
|
||||||
|
fmt.Fprintf(buf, " && chmod +x $@")
|
||||||
|
}
|
||||||
|
fmt.Fprintln(buf)
|
||||||
|
fmt.Fprintln(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, symlink := range symlinks {
|
||||||
|
fmt.Fprintf(buf, "%s:", symlink.to.String())
|
||||||
|
for _, dep := range symlink.implicitDeps {
|
||||||
|
fmt.Fprintf(buf, " %s", dep.String())
|
||||||
|
}
|
||||||
|
if symlink.from != nil || len(symlink.orderOnlyDeps) > 0 {
|
||||||
|
fmt.Fprintf(buf, " |")
|
||||||
|
}
|
||||||
|
if symlink.from != nil {
|
||||||
|
fmt.Fprintf(buf, " %s", symlink.from.String())
|
||||||
|
}
|
||||||
|
for _, dep := range symlink.orderOnlyDeps {
|
||||||
|
fmt.Fprintf(buf, " %s", dep.String())
|
||||||
|
}
|
||||||
|
fmt.Fprintln(buf)
|
||||||
|
|
||||||
|
fromStr := ""
|
||||||
|
if symlink.from != nil {
|
||||||
|
rel, err := filepath.Rel(filepath.Dir(symlink.to.String()), symlink.from.String())
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("failed to find relative path for symlink from %q to %q: %w",
|
||||||
|
symlink.from.String(), symlink.to.String(), err))
|
||||||
|
}
|
||||||
|
fromStr = rel
|
||||||
|
} else {
|
||||||
|
fromStr = symlink.absFrom
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(buf, "\trm -f $@ && ln -sfn %s $@", fromStr)
|
||||||
|
fmt.Fprintln(buf)
|
||||||
|
fmt.Fprintln(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
func (c *makeVarsContext) DeviceConfig() DeviceConfig {
|
func (c *makeVarsContext) DeviceConfig() DeviceConfig {
|
||||||
return DeviceConfig{c.Config().deviceConfig}
|
return DeviceConfig{c.Config().deviceConfig}
|
||||||
}
|
}
|
||||||
|
@@ -1194,7 +1194,10 @@ type ModuleBase struct {
|
|||||||
packagingSpecs []PackagingSpec
|
packagingSpecs []PackagingSpec
|
||||||
packagingSpecsDepSet *packagingSpecsDepSet
|
packagingSpecsDepSet *packagingSpecsDepSet
|
||||||
noticeFiles Paths
|
noticeFiles Paths
|
||||||
phonies map[string]Paths
|
// katiInstalls tracks the install rules that were created by Soong but are being exported
|
||||||
|
// to Make to convert to ninja rules so that Make can add additional dependencies.
|
||||||
|
katiInstalls katiInstalls
|
||||||
|
katiSymlinks katiInstalls
|
||||||
|
|
||||||
// The files to copy to the dist as explicitly specified in the .bp file.
|
// The files to copy to the dist as explicitly specified in the .bp file.
|
||||||
distFiles TaggedDistFiles
|
distFiles TaggedDistFiles
|
||||||
@@ -2016,9 +2019,8 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
|
|||||||
m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
|
m.checkbuildFiles = append(m.checkbuildFiles, ctx.checkbuildFiles...)
|
||||||
m.tidyFiles = append(m.tidyFiles, ctx.tidyFiles...)
|
m.tidyFiles = append(m.tidyFiles, ctx.tidyFiles...)
|
||||||
m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...)
|
m.packagingSpecs = append(m.packagingSpecs, ctx.packagingSpecs...)
|
||||||
for k, v := range ctx.phonies {
|
m.katiInstalls = append(m.katiInstalls, ctx.katiInstalls...)
|
||||||
m.phonies[k] = append(m.phonies[k], v...)
|
m.katiSymlinks = append(m.katiSymlinks, ctx.katiSymlinks...)
|
||||||
}
|
|
||||||
} else if ctx.Config().AllowMissingDependencies() {
|
} else if ctx.Config().AllowMissingDependencies() {
|
||||||
// If the module is not enabled it will not create any build rules, nothing will call
|
// 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
|
// ctx.GetMissingDependencies(), and blueprint will consider the missing dependencies to be unhandled
|
||||||
@@ -2217,12 +2219,52 @@ type moduleContext struct {
|
|||||||
module Module
|
module Module
|
||||||
phonies map[string]Paths
|
phonies map[string]Paths
|
||||||
|
|
||||||
|
katiInstalls []katiInstall
|
||||||
|
katiSymlinks []katiInstall
|
||||||
|
|
||||||
// For tests
|
// For tests
|
||||||
buildParams []BuildParams
|
buildParams []BuildParams
|
||||||
ruleParams map[blueprint.Rule]blueprint.RuleParams
|
ruleParams map[blueprint.Rule]blueprint.RuleParams
|
||||||
variables map[string]string
|
variables map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// katiInstall stores a request from Soong to Make to create an install rule.
|
||||||
|
type katiInstall struct {
|
||||||
|
from Path
|
||||||
|
to InstallPath
|
||||||
|
implicitDeps Paths
|
||||||
|
orderOnlyDeps Paths
|
||||||
|
executable bool
|
||||||
|
|
||||||
|
absFrom string
|
||||||
|
}
|
||||||
|
|
||||||
|
type katiInstalls []katiInstall
|
||||||
|
|
||||||
|
// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
|
||||||
|
// space separated list of from:to tuples.
|
||||||
|
func (installs katiInstalls) BuiltInstalled() string {
|
||||||
|
sb := strings.Builder{}
|
||||||
|
for i, install := range installs {
|
||||||
|
if i != 0 {
|
||||||
|
sb.WriteRune(' ')
|
||||||
|
}
|
||||||
|
sb.WriteString(install.from.String())
|
||||||
|
sb.WriteRune(':')
|
||||||
|
sb.WriteString(install.to.String())
|
||||||
|
}
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstallPaths returns the install path of each entry.
|
||||||
|
func (installs katiInstalls) InstallPaths() InstallPaths {
|
||||||
|
paths := make(InstallPaths, 0, len(installs))
|
||||||
|
for _, install := range installs {
|
||||||
|
paths = append(paths, install.to)
|
||||||
|
}
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
|
func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
|
||||||
return pctx, BuildParams{
|
return pctx, BuildParams{
|
||||||
Rule: ErrorRule,
|
Rule: ErrorRule,
|
||||||
@@ -2854,20 +2896,33 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
|
|||||||
orderOnlyDeps = deps
|
orderOnlyDeps = deps
|
||||||
}
|
}
|
||||||
|
|
||||||
rule := Cp
|
if m.Config().KatiEnabled() && m.InstallBypassMake() {
|
||||||
if executable {
|
// When creating the install rule in Soong but embedding in Make, write the rule to a
|
||||||
rule = CpExecutable
|
// makefile instead of directly to the ninja file so that main.mk can add the
|
||||||
}
|
// dependencies from the `required` property that are hard to resolve in Soong.
|
||||||
|
m.katiInstalls = append(m.katiInstalls, katiInstall{
|
||||||
|
from: srcPath,
|
||||||
|
to: fullInstallPath,
|
||||||
|
implicitDeps: implicitDeps,
|
||||||
|
orderOnlyDeps: orderOnlyDeps,
|
||||||
|
executable: executable,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
rule := Cp
|
||||||
|
if executable {
|
||||||
|
rule = CpExecutable
|
||||||
|
}
|
||||||
|
|
||||||
m.Build(pctx, BuildParams{
|
m.Build(pctx, BuildParams{
|
||||||
Rule: rule,
|
Rule: rule,
|
||||||
Description: "install " + fullInstallPath.Base(),
|
Description: "install " + fullInstallPath.Base(),
|
||||||
Output: fullInstallPath,
|
Output: fullInstallPath,
|
||||||
Input: srcPath,
|
Input: srcPath,
|
||||||
Implicits: implicitDeps,
|
Implicits: implicitDeps,
|
||||||
OrderOnly: orderOnlyDeps,
|
OrderOnly: orderOnlyDeps,
|
||||||
Default: !m.Config().KatiEnabled(),
|
Default: !m.Config().KatiEnabled(),
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
m.installFiles = append(m.installFiles, fullInstallPath)
|
m.installFiles = append(m.installFiles, fullInstallPath)
|
||||||
}
|
}
|
||||||
@@ -2889,16 +2944,26 @@ func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, src
|
|||||||
}
|
}
|
||||||
if !m.skipInstall() {
|
if !m.skipInstall() {
|
||||||
|
|
||||||
m.Build(pctx, BuildParams{
|
if m.Config().KatiEnabled() && m.InstallBypassMake() {
|
||||||
Rule: Symlink,
|
// When creating the symlink rule in Soong but embedding in Make, write the rule to a
|
||||||
Description: "install symlink " + fullInstallPath.Base(),
|
// makefile instead of directly to the ninja file so that main.mk can add the
|
||||||
Output: fullInstallPath,
|
// dependencies from the `required` property that are hard to resolve in Soong.
|
||||||
Input: srcPath,
|
m.katiSymlinks = append(m.katiSymlinks, katiInstall{
|
||||||
Default: !m.Config().KatiEnabled(),
|
from: srcPath,
|
||||||
Args: map[string]string{
|
to: fullInstallPath,
|
||||||
"fromPath": relPath,
|
})
|
||||||
},
|
} else {
|
||||||
})
|
m.Build(pctx, BuildParams{
|
||||||
|
Rule: Symlink,
|
||||||
|
Description: "install symlink " + fullInstallPath.Base(),
|
||||||
|
Output: fullInstallPath,
|
||||||
|
Input: srcPath,
|
||||||
|
Default: !m.Config().KatiEnabled(),
|
||||||
|
Args: map[string]string{
|
||||||
|
"fromPath": relPath,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
m.installFiles = append(m.installFiles, fullInstallPath)
|
m.installFiles = append(m.installFiles, fullInstallPath)
|
||||||
m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
|
m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
|
||||||
@@ -2921,15 +2986,25 @@ func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name str
|
|||||||
m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
|
m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
|
||||||
|
|
||||||
if !m.skipInstall() {
|
if !m.skipInstall() {
|
||||||
m.Build(pctx, BuildParams{
|
if m.Config().KatiEnabled() && m.InstallBypassMake() {
|
||||||
Rule: Symlink,
|
// When creating the symlink rule in Soong but embedding in Make, write the rule to a
|
||||||
Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
|
// makefile instead of directly to the ninja file so that main.mk can add the
|
||||||
Output: fullInstallPath,
|
// dependencies from the `required` property that are hard to resolve in Soong.
|
||||||
Default: !m.Config().KatiEnabled(),
|
m.katiSymlinks = append(m.katiSymlinks, katiInstall{
|
||||||
Args: map[string]string{
|
absFrom: absPath,
|
||||||
"fromPath": absPath,
|
to: fullInstallPath,
|
||||||
},
|
})
|
||||||
})
|
} else {
|
||||||
|
m.Build(pctx, BuildParams{
|
||||||
|
Rule: Symlink,
|
||||||
|
Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
|
||||||
|
Output: fullInstallPath,
|
||||||
|
Default: !m.Config().KatiEnabled(),
|
||||||
|
Args: map[string]string{
|
||||||
|
"fromPath": absPath,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
m.installFiles = append(m.installFiles, fullInstallPath)
|
m.installFiles = append(m.installFiles, fullInstallPath)
|
||||||
}
|
}
|
||||||
|
@@ -212,13 +212,7 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext)
|
|||||||
installDeps = append(installDeps, installedData)
|
installDeps = append(installDeps, installedData)
|
||||||
}
|
}
|
||||||
|
|
||||||
installed := ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.combinedJar, installDeps...)
|
r.installFile = ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.combinedJar, installDeps...)
|
||||||
|
|
||||||
if r.ExportedToMake() {
|
|
||||||
// Soong handles installation here, but Make is usually what creates the phony rule that atest
|
|
||||||
// uses to build the module. Create it here for now.
|
|
||||||
ctx.Phony(ctx.ModuleName(), installed)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath,
|
func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath,
|
||||||
@@ -282,6 +276,10 @@ func (r *robolectricTest) generateRoboSrcJar(ctx android.ModuleContext, outputFi
|
|||||||
func (r *robolectricTest) AndroidMkEntries() []android.AndroidMkEntries {
|
func (r *robolectricTest) AndroidMkEntries() []android.AndroidMkEntries {
|
||||||
entriesList := r.Library.AndroidMkEntries()
|
entriesList := r.Library.AndroidMkEntries()
|
||||||
entries := &entriesList[0]
|
entries := &entriesList[0]
|
||||||
|
entries.ExtraEntries = append(entries.ExtraEntries,
|
||||||
|
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
|
||||||
|
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
|
||||||
|
})
|
||||||
|
|
||||||
entries.ExtraFooters = []android.AndroidMkExtraFootersFunc{
|
entries.ExtraFooters = []android.AndroidMkExtraFootersFunc{
|
||||||
func(w io.Writer, name, prefix, moduleDir string) {
|
func(w io.Writer, name, prefix, moduleDir string) {
|
||||||
|
Reference in New Issue
Block a user