Install android_app_set modules in Soong

Add support for installing extra files from a zip file when installing
a primary file, and use it to support installing android_app_set modules,
which install a primary APK and then an unknown set of additional splits
APKs.

Test: app_set_test.go
Test: install test android_app_set
Bug: 204136549
Change-Id: Ia92f7e5c427adcef3bcf59c82a2f83450905c01d
This commit is contained in:
Colin Cross
2021-11-12 17:41:02 -08:00
parent ffbcd1d8a0
commit 50ed1f9ccb
4 changed files with 63 additions and 11 deletions

View File

@@ -52,10 +52,10 @@ var (
// A copy rule. // A copy rule.
Cp = pctx.AndroidStaticRule("Cp", Cp = pctx.AndroidStaticRule("Cp",
blueprint.RuleParams{ blueprint.RuleParams{
Command: "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out", Command: "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out$extraCmds",
Description: "cp $out", Description: "cp $out",
}, },
"cpFlags") "cpFlags", "extraCmds")
// A copy rule that only updates the output if it changed. // A copy rule that only updates the output if it changed.
CpIfChanged = pctx.AndroidStaticRule("CpIfChanged", CpIfChanged = pctx.AndroidStaticRule("CpIfChanged",
@@ -68,10 +68,10 @@ var (
CpExecutable = pctx.AndroidStaticRule("CpExecutable", CpExecutable = pctx.AndroidStaticRule("CpExecutable",
blueprint.RuleParams{ blueprint.RuleParams{
Command: "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out && chmod +x $out", Command: "rm -f $out && cp $cpPreserveSymlinks $cpFlags $in $out && chmod +x $out$extraCmds",
Description: "cp $out", Description: "cp $out",
}, },
"cpFlags") "cpFlags", "extraCmds")
// A timestamp touch rule. // A timestamp touch rule.
Touch = pctx.AndroidStaticRule("Touch", Touch = pctx.AndroidStaticRule("Touch",

View File

@@ -456,6 +456,9 @@ func (s *makeVarsSingleton) writeInstalls(installs, symlinks []katiInstall) []by
for _, dep := range install.implicitDeps { for _, dep := range install.implicitDeps {
fmt.Fprintf(buf, " %s", dep.String()) fmt.Fprintf(buf, " %s", dep.String())
} }
if extraFiles := install.extraFiles; extraFiles != nil {
fmt.Fprintf(buf, " %s", extraFiles.zip.String())
}
if len(install.orderOnlyDeps) > 0 { if len(install.orderOnlyDeps) > 0 {
fmt.Fprintf(buf, " |") fmt.Fprintf(buf, " |")
} }
@@ -463,12 +466,14 @@ func (s *makeVarsSingleton) writeInstalls(installs, symlinks []katiInstall) []by
fmt.Fprintf(buf, " %s", dep.String()) fmt.Fprintf(buf, " %s", dep.String())
} }
fmt.Fprintln(buf) fmt.Fprintln(buf)
fmt.Fprintln(buf, "\t@echo \"Install $@\"")
fmt.Fprintf(buf, "\trm -f $@ && cp -f %s $< $@", preserveSymlinksFlag) fmt.Fprintf(buf, "\trm -f $@ && cp -f %s $< $@\n", preserveSymlinksFlag)
if install.executable { if install.executable {
fmt.Fprintf(buf, " && chmod +x $@") fmt.Fprintf(buf, "\tchmod +x $@\n")
}
if extraFiles := install.extraFiles; extraFiles != nil {
fmt.Fprintf(buf, "\tunzip -qDD -d '%s' '%s'\n", extraFiles.dir.String(), extraFiles.zip.String())
} }
fmt.Fprintln(buf)
fmt.Fprintln(buf) fmt.Fprintln(buf)
} }
@@ -504,6 +509,7 @@ func (s *makeVarsSingleton) writeInstalls(installs, symlinks []katiInstall) []by
fromStr = symlink.absFrom fromStr = symlink.absFrom
} }
fmt.Fprintln(buf, "\t@echo \"Symlink $@\"")
fmt.Fprintf(buf, "\trm -f $@ && ln -sfn %s $@", fromStr) fmt.Fprintf(buf, "\trm -f $@ && ln -sfn %s $@", fromStr)
fmt.Fprintln(buf) fmt.Fprintln(buf)
fmt.Fprintln(buf) fmt.Fprintln(buf)

View File

@@ -381,6 +381,16 @@ type ModuleContext interface {
// for which IsInstallDepNeeded returns true. // for which IsInstallDepNeeded returns true.
InstallFile(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath InstallFile(installPath InstallPath, name string, srcPath Path, deps ...Path) InstallPath
// InstallFileWithExtraFilesZip creates a rule to copy srcPath to name in the installPath
// directory, and also unzip a zip file containing extra files to install into the same
// directory.
//
// The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
// installed file will be returned by PackagingSpecs() on this module or by
// TransitivePackagingSpecs() on modules that depend on this module through dependency tags
// for which IsInstallDepNeeded returns true.
InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path, extraZip Path, deps ...Path) InstallPath
// InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath // InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath
// directory. // directory.
// //
@@ -2235,10 +2245,16 @@ type katiInstall struct {
implicitDeps Paths implicitDeps Paths
orderOnlyDeps Paths orderOnlyDeps Paths
executable bool executable bool
extraFiles *extraFilesZip
absFrom string absFrom string
} }
type extraFilesZip struct {
zip Path
dir InstallPath
}
type katiInstalls []katiInstall type katiInstalls []katiInstall
// BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a // BuiltInstalled returns the katiInstalls in the form used by $(call copy-many-files) in Make, a
@@ -2852,12 +2868,20 @@ func (m *moduleContext) skipInstall() bool {
func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path, func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
deps ...Path) InstallPath { deps ...Path) InstallPath {
return m.installFile(installPath, name, srcPath, deps, false) return m.installFile(installPath, name, srcPath, deps, false, nil)
} }
func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path, func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
deps ...Path) InstallPath { deps ...Path) InstallPath {
return m.installFile(installPath, name, srcPath, deps, true) return m.installFile(installPath, name, srcPath, deps, true, nil)
}
func (m *moduleContext) InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path,
extraZip Path, deps ...Path) InstallPath {
return m.installFile(installPath, name, srcPath, deps, false, &extraFilesZip{
zip: extraZip,
dir: installPath,
})
} }
func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec { func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec {
@@ -2878,7 +2902,8 @@ func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, e
return spec return spec
} }
func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []Path, executable bool) InstallPath { func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []Path,
executable bool, extraZip *extraFilesZip) InstallPath {
fullInstallPath := installPath.Join(m, name) fullInstallPath := installPath.Join(m, name)
m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false) m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false)
@@ -2906,6 +2931,7 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
implicitDeps: implicitDeps, implicitDeps: implicitDeps,
orderOnlyDeps: orderOnlyDeps, orderOnlyDeps: orderOnlyDeps,
executable: executable, executable: executable,
extraFiles: extraZip,
}) })
} else { } else {
rule := Cp rule := Cp
@@ -2913,6 +2939,13 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
rule = CpExecutable rule = CpExecutable
} }
extraCmds := ""
if extraZip != nil {
extraCmds += fmt.Sprintf(" && unzip -qDD -d '%s' '%s'",
extraZip.dir.String(), extraZip.zip.String())
implicitDeps = append(implicitDeps, extraZip.zip)
}
m.Build(pctx, BuildParams{ m.Build(pctx, BuildParams{
Rule: rule, Rule: rule,
Description: "install " + fullInstallPath.Base(), Description: "install " + fullInstallPath.Base(),
@@ -2921,6 +2954,9 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
Implicits: implicitDeps, Implicits: implicitDeps,
OrderOnly: orderOnlyDeps, OrderOnly: orderOnlyDeps,
Default: !m.Config().KatiEnabled(), Default: !m.Config().KatiEnabled(),
Args: map[string]string{
"extraCmds": extraCmds,
},
}) })
} }

View File

@@ -143,8 +143,18 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext)
"zip": as.packedOutput.String(), "zip": as.packedOutput.String(),
}, },
}) })
var installDir android.InstallPath
if as.Privileged() {
installDir = android.PathForModuleInstall(ctx, "priv-app", as.BaseModuleName())
} else {
installDir = android.PathForModuleInstall(ctx, "app", as.BaseModuleName())
}
ctx.InstallFileWithExtraFilesZip(installDir, as.BaseModuleName()+".apk", as.primaryOutput, as.packedOutput)
} }
func (as *AndroidAppSet) InstallBypassMake() bool { return true }
// android_app_set extracts a set of APKs based on the target device // android_app_set extracts a set of APKs based on the target device
// configuration and installs this set as "split APKs". // configuration and installs this set as "split APKs".
// The extracted set always contains an APK whose name is // The extracted set always contains an APK whose name is