Merge "Copy android-info.txt to PRODUCT_OUT" into main
diff --git a/android/androidmk.go b/android/androidmk.go
index 590cce3..9e721e1 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -701,11 +701,6 @@
type androidMkSingleton struct{}
func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
- // Skip if Soong wasn't invoked from Make.
- if !ctx.Config().KatiEnabled() {
- return
- }
-
var androidMkModulesList []blueprint.Module
ctx.VisitAllModulesBlueprint(func(module blueprint.Module) {
@@ -718,6 +713,12 @@
return ctx.ModuleName(androidMkModulesList[i]) < ctx.ModuleName(androidMkModulesList[j])
})
+ // If running in soong-only mode, do a different, more limited version of this singleton
+ if !ctx.Config().KatiEnabled() {
+ c.soongOnlyBuildActions(ctx, androidMkModulesList)
+ return
+ }
+
transMk := PathForOutput(ctx, "Android"+String(ctx.Config().productVariables.Make_suffix)+".mk")
if ctx.Failed() {
return
@@ -736,6 +737,97 @@
})
}
+// In soong-only mode, we don't do most of the androidmk stuff. But disted files are still largely
+// defined through the androidmk mechanisms, so this function is an alternate implementation of
+// the androidmk singleton that just focuses on getting the dist contributions
+func (c *androidMkSingleton) soongOnlyBuildActions(ctx SingletonContext, mods []blueprint.Module) {
+ allDistContributions := getDistContributionsFromMods(ctx, mods)
+
+ distMkFile := absolutePath(filepath.Join(ctx.Config().katiPackageMkDir(), "dist.mk"))
+
+ var goalOutputPairs []string
+ var buf strings.Builder
+ buf.WriteString("DIST_SRC_DST_PAIRS := $(sort")
+ for _, contributions := range allDistContributions {
+ for _, copiesForGoal := range contributions.copiesForGoals {
+ goals := strings.Fields(copiesForGoal.goals)
+ for _, copy := range copiesForGoal.copies {
+ for _, goal := range goals {
+ goalOutputPairs = append(goalOutputPairs, fmt.Sprintf("%s:%s", goal, copy.dest))
+ }
+ buf.WriteString(fmt.Sprintf(" %s:%s", copy.from.String(), copy.dest))
+ }
+ }
+ }
+ buf.WriteString(")\nDIST_GOAL_OUTPUT_PAIRS := $(sort ")
+ buf.WriteString(strings.Join(goalOutputPairs, " "))
+ buf.WriteString(")\n")
+
+ writeValueIfChanged(ctx, distMkFile, buf.String())
+}
+
+func writeValueIfChanged(ctx SingletonContext, path string, value string) {
+ if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
+ ctx.Errorf("%s\n", err)
+ return
+ }
+ previousValue := ""
+ rawPreviousValue, err := os.ReadFile(path)
+ if err == nil {
+ previousValue = string(rawPreviousValue)
+ }
+
+ if previousValue != value {
+ if err = os.WriteFile(path, []byte(value), 0666); err != nil {
+ ctx.Errorf("Failed to write: %v", err)
+ }
+ }
+}
+
+func getDistContributionsFromMods(ctx fillInEntriesContext, mods []blueprint.Module) []distContributions {
+ var allDistContributions []distContributions
+ for _, mod := range mods {
+ if amod, ok := mod.(Module); ok && shouldSkipAndroidMkProcessing(ctx, amod.base()) {
+ continue
+ }
+ if info, ok := OtherModuleProvider(ctx, mod, AndroidMkInfoProvider); ok {
+ if contribution := info.PrimaryInfo.getDistContributions(ctx, mod); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ for _, ei := range info.ExtraInfo {
+ if contribution := ei.getDistContributions(ctx, mod); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ }
+ } else {
+ switch x := mod.(type) {
+ case AndroidMkDataProvider:
+ data := x.AndroidMk()
+
+ if data.Include == "" {
+ data.Include = "$(BUILD_PREBUILT)"
+ }
+
+ data.fillInData(ctx, mod)
+ if contribution := data.Entries.getDistContributions(mod); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ case AndroidMkEntriesProvider:
+ entriesList := x.AndroidMkEntries()
+ for _, entries := range entriesList {
+ entries.fillInEntries(ctx, mod)
+ if contribution := entries.getDistContributions(mod); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ }
+ default:
+ // Not exported to make so no make variables to set.
+ }
+ }
+ }
+ return allDistContributions
+}
+
func translateAndroidMk(ctx SingletonContext, absMkFile string, moduleInfoJSONPath WritablePath, mods []blueprint.Module) error {
buf := &bytes.Buffer{}
diff --git a/android/config.go b/android/config.go
index e9cb2cd..87aacd5 100644
--- a/android/config.go
+++ b/android/config.go
@@ -83,6 +83,7 @@
OutDir string
SoongOutDir string
SoongVariables string
+ KatiSuffix string
ModuleGraphFile string
ModuleActionsFile string
@@ -349,6 +350,7 @@
// Changes behavior based on whether Kati runs after soong_build, or if soong_build
// runs standalone.
katiEnabled bool
+ katiSuffix string
captureBuild bool // true for tests, saves build parameters for each module
ignoreEnvironment bool // true for tests, returns empty from all Getenv calls
@@ -620,6 +622,7 @@
outDir: cmdArgs.OutDir,
soongOutDir: cmdArgs.SoongOutDir,
runGoTests: cmdArgs.RunGoTests,
+ katiSuffix: cmdArgs.KatiSuffix,
multilibConflicts: make(map[ArchType]bool),
moduleListFile: cmdArgs.ModuleListFile,
@@ -1512,6 +1515,10 @@
return c.productVariables.GetBuildFlagBool("RELEASE_BOARD_API_LEVEL_FROZEN")
}
+func (c *config) katiPackageMkDir() string {
+ return filepath.Join(c.soongOutDir, "kati_packaging"+c.katiSuffix)
+}
+
func (c *deviceConfig) Arches() []Arch {
var arches []Arch
for _, target := range c.config.Targets[Android] {
@@ -2182,7 +2189,7 @@
"RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "com.android.adservices",
"RELEASE_APEX_CONTRIBUTIONS_APPSEARCH": "com.android.appsearch",
"RELEASE_APEX_CONTRIBUTIONS_ART": "com.android.art",
- "RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH": "com.android.btservices",
+ "RELEASE_APEX_CONTRIBUTIONS_BLUETOOTH": "com.android.bt",
"RELEASE_APEX_CONTRIBUTIONS_CAPTIVEPORTALLOGIN": "",
"RELEASE_APEX_CONTRIBUTIONS_CELLBROADCAST": "com.android.cellbroadcast",
"RELEASE_APEX_CONTRIBUTIONS_CONFIGINFRASTRUCTURE": "com.android.configinfrastructure",
diff --git a/android/container_violations.go b/android/container_violations.go
index ba8f7d5..bca2b25 100644
--- a/android/container_violations.go
+++ b/android/container_violations.go
@@ -414,10 +414,6 @@
"framework", // cts -> unstable
},
- "CtsMediaBetterTogetherTestCases": {
- "framework", // cts -> unstable
- },
-
"CtsMediaCodecTestCases": {
"framework", // cts -> unstable
},
@@ -478,6 +474,11 @@
"framework", // cts -> unstable
},
+ // TODO(b/387499846): Remove once migrated to sdk_version.
+ "CtsMediaRouterTestCases": {
+ "framework", // cts -> unstable
+ },
+
"CtsMediaRouterHostSideTestBluetoothPermissionsApp": {
"framework", // cts -> unstable
},
@@ -490,6 +491,11 @@
"framework", // cts -> unstable
},
+ // TODO(b/387500109): Remove once migrated to sdk_version.
+ "CtsMediaSessionTestCases": {
+ "framework", // cts -> unstable
+ },
+
"CtsMediaV2TestCases": {
"framework", // cts -> unstable
},
@@ -907,10 +913,6 @@
"libnativeloader_vendor_shared_lib", // system -> vendor
},
- "MctsMediaBetterTogetherTestCases": {
- "framework", // cts -> unstable
- },
-
"MctsMediaCodecTestCases": {
"framework", // cts -> unstable
},
@@ -947,6 +949,16 @@
"framework", // cts -> unstable
},
+ // TODO(b/387499846): Remove once migrated to sdk_version.
+ "MctsMediaRouterTestCases": {
+ "framework", // cts -> unstable
+ },
+
+ // TODO(b/387500109): Remove once migrated to sdk_version.
+ "MctsMediaSessionTestCases": {
+ "framework", // cts -> unstable
+ },
+
"MctsMediaTranscodingTestCases": {
"framework", // cts -> unstable
},
diff --git a/android/module.go b/android/module.go
index b8f2cae..2f505aa 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1679,14 +1679,13 @@
}
})
- var deps Paths
-
var namespacePrefix string
nameSpace := ctx.Namespace().Path
if nameSpace != "." {
namespacePrefix = strings.ReplaceAll(nameSpace, "/", ".") + "-"
}
+ var deps Paths
var info FinalModuleBuildTargetsInfo
if len(allInstalledFiles) > 0 {
@@ -1853,9 +1852,9 @@
var SourceFilesInfoKey = blueprint.NewProvider[SourceFilesInfo]()
+// FinalModuleBuildTargetsInfo is used by buildTargetSingleton to create checkbuild and
+// per-directory build targets. Only set on the final variant of each module
type FinalModuleBuildTargetsInfo struct {
- // Used by buildTargetSingleton to create checkbuild and per-directory build targets
- // Only set on the final variant of each module
InstallTarget WritablePath
CheckbuildTarget WritablePath
BlueprintDir string
diff --git a/android/phony.go b/android/phony.go
index f8db88d..7bdd9d3 100644
--- a/android/phony.go
+++ b/android/phony.go
@@ -15,6 +15,7 @@
package android
import (
+ "strings"
"sync"
"github.com/google/blueprint"
@@ -68,13 +69,25 @@
}
if !ctx.Config().KatiEnabled() {
+ // In soong-only builds, the phonies can conflict with dist targets that will
+ // be generated in the packaging step. Instead of emitting a blueprint/ninja phony directly,
+ // create a makefile that defines the phonies that will be included in the packaging step.
+ // Make will dedup the phonies there.
+ var buildPhonyFileContents strings.Builder
for _, phony := range p.phonyList {
- ctx.Build(pctx, BuildParams{
- Rule: blueprint.Phony,
- Outputs: []WritablePath{PathForPhony(ctx, phony)},
- Implicits: p.phonyMap[phony],
- })
+ buildPhonyFileContents.WriteString(".PHONY: ")
+ buildPhonyFileContents.WriteString(phony)
+ buildPhonyFileContents.WriteString("\n")
+ buildPhonyFileContents.WriteString(phony)
+ buildPhonyFileContents.WriteString(":")
+ for _, dep := range p.phonyMap[phony] {
+ buildPhonyFileContents.WriteString(" ")
+ buildPhonyFileContents.WriteString(dep.String())
+ }
+ buildPhonyFileContents.WriteString("\n")
}
+ buildPhonyFile := PathForOutput(ctx, "soong_phony_targets.mk")
+ writeValueIfChanged(ctx, absolutePath(buildPhonyFile.String()), buildPhonyFileContents.String())
}
}
diff --git a/apex/apex.go b/apex/apex.go
index 7734391..d1d3d97 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1056,7 +1056,7 @@
"com.android.appsearch",
"com.android.art",
"com.android.art.debug",
- "com.android.btservices",
+ "com.android.bt",
"com.android.cellbroadcast",
"com.android.configinfrastructure",
"com.android.conscrypt",
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 6642023..cd4e9bd 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -64,6 +64,7 @@
flag.StringVar(&usedEnvFile, "used_env", "", "File containing used environment variables")
flag.StringVar(&cmdlineArgs.OutDir, "out", "", "the ninja builddir directory")
flag.StringVar(&cmdlineArgs.ModuleListFile, "l", "", "file that lists filepaths to parse")
+ flag.StringVar(&cmdlineArgs.KatiSuffix, "kati_suffix", "", "the suffix for kati and ninja files, so that different configurations don't clobber each other")
// Debug flags
flag.StringVar(&delveListen, "delve_listen", "", "Delve port to listen on for debugging")
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index fd8e915..5c3842a 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -15,6 +15,8 @@
package filesystem
import (
+ "strings"
+
"android/soong/android"
"github.com/google/blueprint"
@@ -79,6 +81,8 @@
}
addDependencyIfDefined(a.partitionProps.Boot_partition_name)
+ addDependencyIfDefined(a.partitionProps.Init_boot_partition_name)
+ addDependencyIfDefined(a.partitionProps.Vendor_boot_partition_name)
addDependencyIfDefined(a.partitionProps.System_partition_name)
addDependencyIfDefined(a.partitionProps.System_ext_partition_name)
addDependencyIfDefined(a.partitionProps.Product_partition_name)
@@ -88,6 +92,7 @@
addDependencyIfDefined(a.partitionProps.System_dlkm_partition_name)
addDependencyIfDefined(a.partitionProps.Vendor_dlkm_partition_name)
addDependencyIfDefined(a.partitionProps.Odm_dlkm_partition_name)
+ addDependencyIfDefined(a.partitionProps.Recovery_partition_name)
for _, vbmetaPartition := range a.partitionProps.Vbmeta_partitions {
ctx.AddDependency(ctx.Module(), filesystemDepTag, vbmetaPartition)
}
@@ -95,6 +100,30 @@
func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.buildTargetFilesZip(ctx)
+ var deps []android.Path
+ ctx.VisitDirectDepsWithTag(filesystemDepTag, func(m android.Module) {
+ imageOutput, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider)
+ if !ok {
+ ctx.ModuleErrorf("Partition module %s doesn't set OutputfilesProvider", m.Name())
+ }
+ if len(imageOutput.DefaultOutputFiles) != 1 {
+ ctx.ModuleErrorf("Partition module %s should provide exact 1 output file", m.Name())
+ }
+ deps = append(deps, imageOutput.DefaultOutputFiles[0])
+ })
+ out := android.PathForModuleOut(ctx, "out")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Output: out,
+ Implicits: deps,
+ })
+ ctx.SetOutputFiles(android.Paths{out}, "")
+ ctx.CheckbuildFile(out)
+}
+
+type targetFilesZipCopy struct {
+ srcModule *string
+ destSubdir string
}
func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) {
@@ -104,27 +133,55 @@
builder := android.NewRuleBuilder(pctx, ctx)
builder.Command().Textf("rm -rf %s", targetFilesDir.String())
builder.Command().Textf("mkdir -p %s", targetFilesDir.String())
- partitionToSubdir := map[*string]string{
- a.partitionProps.System_partition_name: "SYSTEM",
- a.partitionProps.System_ext_partition_name: "SYSTEM_EXT",
- a.partitionProps.Product_partition_name: "PRODUCT",
- a.partitionProps.Vendor_partition_name: "VENDOR",
- a.partitionProps.Odm_partition_name: "ODM",
- a.partitionProps.System_dlkm_partition_name: "SYSTEM_DLKM",
- a.partitionProps.Vendor_dlkm_partition_name: "VENDOR_DLKM",
- a.partitionProps.Odm_dlkm_partition_name: "ODM_DLKM",
+ toCopy := []targetFilesZipCopy{
+ targetFilesZipCopy{a.partitionProps.System_partition_name, "SYSTEM"},
+ targetFilesZipCopy{a.partitionProps.System_ext_partition_name, "SYSTEM_EXT"},
+ targetFilesZipCopy{a.partitionProps.Product_partition_name, "PRODUCT"},
+ targetFilesZipCopy{a.partitionProps.Vendor_partition_name, "VENDOR"},
+ targetFilesZipCopy{a.partitionProps.Odm_partition_name, "ODM"},
+ targetFilesZipCopy{a.partitionProps.System_dlkm_partition_name, "SYSTEM_DLKM"},
+ targetFilesZipCopy{a.partitionProps.Vendor_dlkm_partition_name, "VENDOR_DLKM"},
+ targetFilesZipCopy{a.partitionProps.Odm_dlkm_partition_name, "ODM_DLKM"},
+ targetFilesZipCopy{a.partitionProps.Init_boot_partition_name, "BOOT/RAMDISK"},
+ targetFilesZipCopy{a.partitionProps.Init_boot_partition_name, "INIT_BOOT/RAMDISK"},
+ targetFilesZipCopy{a.partitionProps.Vendor_boot_partition_name, "VENDOR_BOOT/RAMDISK"},
}
- for partition, subdir := range partitionToSubdir {
- if partition == nil {
+ // TODO: Handle cases where recovery files are copied to BOOT/ or RECOVERY/
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=6211-6219?q=core%2FMakefile&ss=android%2Fplatform%2Fsuperproject%2Fmain
+ if ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot() {
+ toCopy = append(toCopy, targetFilesZipCopy{a.partitionProps.Recovery_partition_name, "VENDOR_BOOT/RAMDISK"})
+ }
+
+ for _, zipCopy := range toCopy {
+ if zipCopy.srcModule == nil {
continue
}
- fsInfo := a.getFilesystemInfo(ctx, *partition)
+ fsInfo := a.getFilesystemInfo(ctx, *zipCopy.srcModule)
+ subdir := zipCopy.destSubdir
+ rootDirString := fsInfo.RootDir.String()
+ if subdir == "SYSTEM" {
+ rootDirString = rootDirString + "/system"
+ }
builder.Command().Textf("mkdir -p %s/%s", targetFilesDir.String(), subdir)
builder.Command().
BuiltTool("acp").
- Textf("-rd %s/. %s/%s", fsInfo.RootDir, targetFilesDir, subdir).
+ Textf("-rd %s/. %s/%s", rootDirString, targetFilesDir, subdir).
Implicit(fsInfo.Output) // so that the staging dir is built
+
}
+ // Copy cmdline files of boot images
+ if a.partitionProps.Vendor_boot_partition_name != nil {
+ bootImg := ctx.GetDirectDepWithTag(proptools.String(a.partitionProps.Vendor_boot_partition_name), filesystemDepTag)
+ bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider)
+ builder.Command().Textf("echo %s > %s/%s/cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir, "VENDOR_BOOT")
+ builder.Command().Textf("echo %s > %s/%s/vendor_cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir, "VENDOR_BOOT")
+ }
+ if a.partitionProps.Boot_partition_name != nil {
+ bootImg := ctx.GetDirectDepWithTag(proptools.String(a.partitionProps.Boot_partition_name), filesystemDepTag)
+ bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider)
+ builder.Command().Textf("echo %s > %s/%s/cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir, "BOOT")
+ }
+
builder.Command().
BuiltTool("soong_zip").
Text("-d").
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 36b1a18..00398b2 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -224,6 +224,25 @@
ctx.SetOutputFiles([]android.Path{output}, "")
b.output = output
+
+ // Set the Filesystem info of the ramdisk dependency.
+ // `android_device` will use this info to package `target_files.zip`
+ if ramdisk := proptools.String(b.properties.Ramdisk_module); ramdisk != "" {
+ ramdiskModule := ctx.GetDirectDepWithTag(ramdisk, bootimgRamdiskDep)
+ fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider)
+ android.SetProvider(ctx, FilesystemProvider, fsInfo)
+ }
+
+ // Set BootimgInfo for building target_files.zip
+ android.SetProvider(ctx, BootimgInfoProvider, BootimgInfo{
+ Cmdline: b.properties.Cmdline,
+ })
+}
+
+var BootimgInfoProvider = blueprint.NewProvider[BootimgInfo]()
+
+type BootimgInfo struct {
+ Cmdline []string
}
func (b *bootimg) buildBootImage(ctx android.ModuleContext, kernel android.Path) android.Path {
@@ -372,6 +391,10 @@
cmd.FlagWithArg("--rollback_index ", strconv.FormatInt(*b.properties.Avb_rollback_index, 10))
}
+ if !ctx.Config().KatiEnabled() {
+ copyImageFileToProductOut(ctx, builder, b.bootImageType.String(), output)
+ }
+
builder.Build("add_avb_footer", fmt.Sprintf("Adding avb footer to %s", b.BaseModuleName()))
return output
}
@@ -387,6 +410,10 @@
Implicits(toolDeps).
Output(output)
+ if !ctx.Config().KatiEnabled() {
+ copyImageFileToProductOut(ctx, builder, b.bootImageType.String(), output)
+ }
+
builder.Build("sign_bootimg", fmt.Sprintf("Signing %s", b.BaseModuleName()))
return output
}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 6dfbfd1..64b7931 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -593,11 +593,16 @@
}
func (f *filesystem) copyFilesToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) {
- if f.Name() != ctx.Config().SoongDefinedSystemImage() {
+ if !(f.Name() == ctx.Config().SoongDefinedSystemImage() || proptools.Bool(f.properties.Is_auto_generated)) {
return
}
installPath := android.PathForModuleInPartitionInstall(ctx, f.partitionName())
- builder.Command().Textf("cp -prf %s/* %s", rebasedDir, installPath)
+ builder.Command().Textf("rsync --checksum %s %s", rebasedDir, installPath)
+}
+
+func copyImageFileToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, partition string, output android.Path) {
+ copyDir := android.PathForModuleInPartitionInstall(ctx, "").Join(ctx, fmt.Sprintf("%s.img", partition))
+ builder.Command().Textf("rsync -a %s %s", output, copyDir)
}
func (f *filesystem) rootDirString() string {
@@ -651,6 +656,10 @@
Output(output).
Text(rootDir.String()) // directory where to find fs_config_files|dirs
+ if !ctx.Config().KatiEnabled() {
+ copyImageFileToProductOut(ctx, builder, f.partitionName(), output)
+ }
+
// rootDir is not deleted. Might be useful for quick inspection.
builder.Build("build_filesystem_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
@@ -1081,7 +1090,10 @@
modulesInPackageByName := make(map[string]bool)
deps := f.gatherFilteredPackagingSpecs(ctx)
- ctx.WalkDeps(func(child, parent android.Module) bool {
+ ctx.WalkDeps(func(child, _ android.Module) bool {
+ if !child.Enabled(ctx) {
+ return false
+ }
for _, ps := range android.OtherModuleProviderOrDefault(
ctx, child, android.InstallFilesProvider).PackagingSpecs {
if _, ok := deps[ps.RelPathInPackage()]; ok && ps.Partition() == f.PartitionType() {
@@ -1100,6 +1112,9 @@
var requireModules []android.Module
ctx.WalkDeps(func(child, parent android.Module) bool {
+ if !child.Enabled(ctx) {
+ return false
+ }
_, parentInPackage := modulesInPackageByModule[parent]
_, childInPackageName := modulesInPackageByName[child.Name()]
diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go
index 6a47859..c8b4675 100644
--- a/filesystem/vbmeta.go
+++ b/filesystem/vbmeta.go
@@ -281,6 +281,10 @@
FlagWithArg("-s ", strconv.Itoa(vbmetaMaxSize)).
Output(output)
+ if !ctx.Config().KatiEnabled() {
+ copyImageFileToProductOut(ctx, builder, v.partitionName(), output)
+ }
+
builder.Build("vbmeta", fmt.Sprintf("vbmeta %s", ctx.ModuleName()))
v.installDir = android.PathForModuleInstall(ctx, "etc")
diff --git a/java/app_import.go b/java/app_import.go
index f593c02..35a054f 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -43,6 +43,12 @@
Description: "Uncompress embedded JNI libs",
})
+ stripEmbeddedJniLibsUnusedArchRule = pctx.AndroidStaticRule("strip-embedded-jni-libs-from-unused-arch", blueprint.RuleParams{
+ Command: `${config.Zip2ZipCmd} -i $in -o $out -x 'lib/**/*.so' $extraArgs`,
+ CommandDeps: []string{"${config.Zip2ZipCmd}"},
+ Description: "Remove all JNI libs from unused architectures",
+ }, "extraArgs")
+
uncompressDexRule = pctx.AndroidStaticRule("uncompress-dex", blueprint.RuleParams{
Command: `if (zipinfo $in '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then ` +
`${config.Zip2ZipCmd} -i $in -o $out -0 'classes*.dex'` +
@@ -150,6 +156,9 @@
// the prebuilt is Name() without "prebuilt_" prefix
Source_module_name *string
+ // Whether stripping all libraries from unused architectures.
+ Strip_unused_jni_arch *bool
+
// Path to the .prebuilt_info file of the prebuilt app.
// In case of mainline modules, the .prebuilt_info file contains the build_id that was used
// to generate the prebuilt.
@@ -292,6 +301,26 @@
return shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &a.dexpreopter)
}
+func (a *AndroidAppImport) stripEmbeddedJniLibsUnusedArch(
+ ctx android.ModuleContext, inputPath android.Path, outputPath android.WritablePath) {
+ var wantedJniLibSlice []string
+ for _, target := range ctx.MultiTargets() {
+ supported_abis := target.Arch.Abi
+ for _, arch := range supported_abis {
+ wantedJniLibSlice = append(wantedJniLibSlice, " -X lib/"+arch+"/*.so")
+ }
+ }
+ wantedJniLibString := strings.Join(wantedJniLibSlice, " ")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: stripEmbeddedJniLibsUnusedArchRule,
+ Input: inputPath,
+ Output: outputPath,
+ Args: map[string]string{
+ "extraArgs": wantedJniLibString,
+ },
+ })
+}
+
func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.generateAndroidBuildActions(ctx)
}
@@ -347,6 +376,13 @@
jnisUncompressed := android.PathForModuleOut(ctx, "jnis-uncompressed", ctx.ModuleName()+".apk")
a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed)
+ // Strip all embedded JNI libs and include only required ones accordingly to the module's compile_multilib
+ if Bool(a.properties.Strip_unused_jni_arch) {
+ jnisStripped := android.PathForModuleOut(ctx, "jnis-stripped", ctx.ModuleName()+".apk")
+ a.stripEmbeddedJniLibsUnusedArch(ctx, jnisUncompressed, jnisStripped)
+ jnisUncompressed = jnisStripped
+ }
+
var pathFragments []string
relInstallPath := String(a.properties.Relative_install_path)
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index d09a02e..152eb1e 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -172,7 +172,7 @@
// Do not add implLibModule to allModules as the impl lib is only used to collect the
// transitive source files
var implLibModule []android.Module
- ctx.VisitDirectDepsWithTag(implLibraryTag, func(m android.Module) {
+ ctx.VisitDirectDepsWithTag(platformBootclasspathImplLibDepTag, func(m android.Module) {
implLibModule = append(implLibModule, m)
})
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index f2768db..1f691a0 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -30,18 +30,23 @@
preparer := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
FixtureConfigureBootJars("platform:foo", "system_ext:bar"),
+ android.FixtureMergeMockFs(android.MockFS{
+ "api/current.txt": nil,
+ "api/removed.txt": nil,
+ }),
android.FixtureWithRootAndroidBp(`
platform_bootclasspath {
name: "platform-bootclasspath",
}
- java_library {
+ java_sdk_library {
name: "bar",
srcs: ["a.java"],
system_modules: "none",
sdk_version: "none",
compile_dex: true,
system_ext_specific: true,
+ unsafe_ignore_missing_latest_api: true,
}
`),
)
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 5b145c6..bb98944 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -51,6 +51,10 @@
type platformCompatConfigProperties struct {
Src *string `android:"path"`
+
+ // If true, we include it in the "merged" XML (merged_compat_config.xml).
+ // Default is true.
+ Include_in_merged_xml *bool
}
type platformCompatConfig struct {
@@ -60,6 +64,7 @@
installDirPath android.InstallPath
configFile android.OutputPath
metadataFile android.OutputPath
+ doMerge bool
installConfigFile android.InstallPath
}
@@ -68,6 +73,10 @@
return p.metadataFile
}
+func (p *platformCompatConfig) includeInMergedXml() bool {
+ return p.doMerge
+}
+
func (p *platformCompatConfig) CompatConfig() android.OutputPath {
return p.configFile
}
@@ -78,6 +87,9 @@
type platformCompatConfigMetadataProvider interface {
compatConfigMetadata() android.Path
+
+ // Whether to include it in the "merged" XML (merged_compat_config.xml) or not.
+ includeInMergedXml() bool
}
type PlatformCompatConfigIntf interface {
@@ -98,6 +110,7 @@
metadataFileName := p.Name() + "_meta.xml"
p.configFile = android.PathForModuleOut(ctx, configFileName).OutputPath
p.metadataFile = android.PathForModuleOut(ctx, metadataFileName).OutputPath
+ p.doMerge = proptools.BoolDefault(p.properties.Include_in_merged_xml, true)
path := android.PathForModuleSrc(ctx, String(p.properties.Src))
rule.Command().
@@ -201,6 +214,10 @@
return module.metadataFile
}
+func (module *prebuiltCompatConfigModule) includeInMergedXml() bool {
+ return true // Always include in merged.xml
+}
+
func (module *prebuiltCompatConfigModule) BaseModuleName() string {
return proptools.StringDefault(module.properties.Source_module_name, module.ModuleBase.Name())
}
@@ -237,6 +254,9 @@
if !android.IsModulePreferred(module) {
return
}
+ if !c.includeInMergedXml() {
+ return
+ }
metadata := c.compatConfigMetadata()
compatConfigMetadata = append(compatConfigMetadata, metadata)
}
diff --git a/java/platform_compat_config_test.go b/java/platform_compat_config_test.go
index 80d991c..f7529a7 100644
--- a/java/platform_compat_config_test.go
+++ b/java/platform_compat_config_test.go
@@ -26,6 +26,7 @@
android.FixtureWithRootAndroidBp(`
platform_compat_config {
name: "myconfig2",
+ include_in_merged_xml: false,
}
platform_compat_config {
name: "myconfig1",
@@ -38,7 +39,6 @@
CheckMergedCompatConfigInputs(t, result, "myconfig",
"out/soong/.intermediates/myconfig1/myconfig1_meta.xml",
- "out/soong/.intermediates/myconfig2/myconfig2_meta.xml",
"out/soong/.intermediates/myconfig3/myconfig3_meta.xml",
)
}
diff --git a/ui/build/build.go b/ui/build/build.go
index 1dc6dbd..26f5969 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -107,8 +107,11 @@
{{end -}}
pool highmem_pool
depth = {{.HighmemParallel}}
-{{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
+{{if and (not .SkipKatiNinja) .HasKatiSuffix}}
+subninja {{.KatiBuildNinjaFile}}
subninja {{.KatiPackageNinjaFile}}
+{{else}}
+subninja {{.KatiSoongOnlyPackageNinjaFile}}
{{end -}}
subninja {{.SoongNinjaFile}}
`))
@@ -346,25 +349,31 @@
return
}
+ // Still generate the kati suffix in soong-only builds because soong-only still uses kati for
+ // the packaging step. Also, the kati suffix is used for the combined ninja file.
+ genKatiSuffix(ctx, config)
+
if what&RunSoong != 0 {
runSoong(ctx, config)
}
if what&RunKati != 0 {
- genKatiSuffix(ctx, config)
runKatiCleanSpec(ctx, config)
runKatiBuild(ctx, config)
- runKatiPackage(ctx, config)
+ runKatiPackage(ctx, config, false)
- ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
} else if what&RunKatiNinja != 0 {
// Load last Kati Suffix if it exists
- if katiSuffix, err := ioutil.ReadFile(config.LastKatiSuffixFile()); err == nil {
+ if katiSuffix, err := os.ReadFile(config.LastKatiSuffixFile()); err == nil {
ctx.Verboseln("Loaded previous kati config:", string(katiSuffix))
config.SetKatiSuffix(string(katiSuffix))
}
+ } else if what&RunSoong != 0 {
+ runKatiPackage(ctx, config, true)
}
+ os.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0666) // a+rw
+
// Write combined ninja file
createCombinedBuildNinjaFile(ctx, config)
diff --git a/ui/build/config.go b/ui/build/config.go
index dc468c2..4f2d213 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -1592,6 +1592,10 @@
return filepath.Join(c.OutDir(), "build"+c.KatiSuffix()+katiPackageSuffix+".ninja")
}
+func (c *configImpl) KatiSoongOnlyPackageNinjaFile() string {
+ return filepath.Join(c.OutDir(), "build"+c.KatiSuffix()+katiSoongOnlyPackageSuffix+".ninja")
+}
+
func (c *configImpl) SoongVarsFile() string {
targetProduct, err := c.TargetProductOrErr()
if err != nil {
@@ -1647,7 +1651,7 @@
}
func (c *configImpl) KatiPackageMkDir() string {
- return filepath.Join(c.ProductOut(), "obj", "CONFIG", "kati_packaging")
+ return filepath.Join(c.SoongOutDir(), "kati_packaging"+c.KatiSuffix())
}
func (c *configImpl) hostOutRoot() string {
diff --git a/ui/build/kati.go b/ui/build/kati.go
index acd5254..6519573 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -31,6 +31,7 @@
const katiBuildSuffix = ""
const katiCleanspecSuffix = "-cleanspec"
const katiPackageSuffix = "-package"
+const katiSoongOnlyPackageSuffix = "-soong-only-package"
// genKatiSuffix creates a filename suffix for kati-generated files so that we
// can cache them based on their inputs. Such files include the generated Ninja
@@ -40,8 +41,12 @@
// Currently that includes the TARGET_PRODUCT and kati-processed command line
// arguments.
func genKatiSuffix(ctx Context, config Config) {
+ targetProduct := "unknown"
+ if p, err := config.TargetProductOrErr(); err == nil {
+ targetProduct = p
+ }
// Construct the base suffix.
- katiSuffix := "-" + config.TargetProduct() + config.CoverageSuffix()
+ katiSuffix := "-" + targetProduct + config.CoverageSuffix()
// Append kati arguments to the suffix.
if args := config.KatiArgs(); len(args) > 0 {
@@ -68,13 +73,13 @@
func writeValueIfChanged(ctx Context, config Config, dir string, filename string, value string) {
filePath := filepath.Join(dir, filename)
previousValue := ""
- rawPreviousValue, err := ioutil.ReadFile(filePath)
+ rawPreviousValue, err := os.ReadFile(filePath)
if err == nil {
previousValue = string(rawPreviousValue)
}
if previousValue != value {
- if err = ioutil.WriteFile(filePath, []byte(value), 0666); err != nil {
+ if err = os.WriteFile(filePath, []byte(value), 0666); err != nil {
ctx.Fatalf("Failed to write: %v", err)
}
}
@@ -334,10 +339,19 @@
// Generate the Ninja file containing the packaging command lines for the dist
// dir.
-func runKatiPackage(ctx Context, config Config) {
+func runKatiPackage(ctx Context, config Config, soongOnly bool) {
ctx.BeginTrace(metrics.RunKati, "kati package")
defer ctx.EndTrace()
+ entryPoint := "build/make/packaging/main.mk"
+ suffix := katiPackageSuffix
+ ninjaFile := config.KatiPackageNinjaFile()
+ if soongOnly {
+ entryPoint = "build/make/packaging/main_soong_only.mk"
+ suffix = katiSoongOnlyPackageSuffix
+ ninjaFile = config.KatiSoongOnlyPackageNinjaFile()
+ }
+
args := []string{
// Mark the dist dir as writable.
"--writable", config.DistDir() + "/",
@@ -346,14 +360,14 @@
// Fail when redefining / duplicating a target.
"--werror_overriding_commands",
// Entry point.
- "-f", "build/make/packaging/main.mk",
+ "-f", entryPoint,
// Directory containing .mk files for packaging purposes, such as
// the dist.mk file, containing dist-for-goals data.
"KATI_PACKAGE_MK_DIR=" + config.KatiPackageMkDir(),
}
// Run Kati against a restricted set of environment variables.
- runKati(ctx, config, katiPackageSuffix, args, func(env *Environment) {
+ runKati(ctx, config, suffix, args, func(env *Environment) {
env.Allow([]string{
// Some generic basics
"LANG",
@@ -381,7 +395,7 @@
})
// Compress and dist the packaging Ninja file.
- distGzipFile(ctx, config, config.KatiPackageNinjaFile())
+ distGzipFile(ctx, config, ninjaFile)
}
// Run Kati on the cleanspec files to clean the build.
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 82e5c96..58334a9 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -197,6 +197,8 @@
func (pb PrimaryBuilderFactory) primaryBuilderInvocation(config Config) bootstrap.PrimaryBuilderInvocation {
commonArgs := make([]string, 0, 0)
+ commonArgs = append(commonArgs, "--kati_suffix", config.KatiSuffix())
+
if !pb.config.skipSoongTests {
commonArgs = append(commonArgs, "-t")
}