Merge "Building android_device will build all the partitions" into main
diff --git a/aconfig/all_aconfig_declarations.go b/aconfig/all_aconfig_declarations.go
index 6ad54da..3262493 100644
--- a/aconfig/all_aconfig_declarations.go
+++ b/aconfig/all_aconfig_declarations.go
@@ -65,15 +65,16 @@
})
var numOffendingPkg = 0
+ offendingPkgsMessage := ""
for pkg, cnt := range packages {
if cnt > 1 {
- fmt.Printf("%d aconfig_declarations found for package %s\n", cnt, pkg)
+ offendingPkgsMessage += fmt.Sprintf("%d aconfig_declarations found for package %s\n", cnt, pkg)
numOffendingPkg++
}
}
if numOffendingPkg > 0 {
- panic(fmt.Errorf("Only one aconfig_declarations allowed for each package."))
+ panic("Only one aconfig_declarations allowed for each package.\n" + offendingPkgsMessage)
}
// Generate build action for aconfig (binary proto output)
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..70c5e4f 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] {
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/module_context.go b/android/module_context.go
index b59e33d..ba31cb2 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -688,7 +688,6 @@
Input: srcPath,
Implicits: implicitDeps,
OrderOnly: orderOnlyDeps,
- Default: !m.Config().KatiEnabled(),
Args: map[string]string{
"extraCmds": extraCmds,
},
@@ -735,7 +734,6 @@
Description: "install symlink " + fullInstallPath.Base(),
Output: fullInstallPath,
Input: srcPath,
- Default: !m.Config().KatiEnabled(),
Args: map[string]string{
"fromPath": relPath,
},
@@ -782,7 +780,6 @@
Rule: Symlink,
Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
Output: fullInstallPath,
- Default: !m.Config().KatiEnabled(),
Args: map[string]string{
"fromPath": absPath,
},
diff --git a/android/neverallow.go b/android/neverallow.go
index fdcbe1c..d211784 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -322,9 +322,6 @@
func createKotlinPluginRule() []Rule {
kotlinPluginProjectsAllowedList := []string{
- // TODO: Migrate compose plugin to the bundled compiler plugin
- // Actual path prebuilts/sdk/current/androidx/m2repository/androidx/compose/compiler/compiler-hosted
- "prebuilts/sdk/current/androidx",
"external/kotlinc",
}
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/android/util.go b/android/util.go
index 3fc4608..30d8ec6 100644
--- a/android/util.go
+++ b/android/util.go
@@ -308,6 +308,20 @@
return
}
+// FilterListByPrefixes performs the same splitting as FilterList does, but treats the passed
+// filters as prefixes
+func FilterListByPrefix(list []string, filter []string) (remainder []string, filtered []string) {
+ for _, l := range list {
+ if HasAnyPrefix(l, filter) {
+ filtered = append(filtered, l)
+ } else {
+ remainder = append(remainder, l)
+ }
+ }
+
+ return
+}
+
// FilterListPred returns the elements of the given list for which the predicate
// returns true. Order is kept.
func FilterListPred(list []string, pred func(s string) bool) (filtered []string) {
diff --git a/android/variable.go b/android/variable.go
index ec84274..6e46e9d 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -162,6 +162,7 @@
Optimize struct {
Enabled *bool
}
+ Aaptflags []string
}
Uml struct {
diff --git a/apex/builder.go b/apex/builder.go
index c85d0a0..b74f4de 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -211,10 +211,10 @@
apexSepolicyTestsRule = pctx.StaticRule("apexSepolicyTestsRule", blueprint.RuleParams{
Command: `${deapexer} --debugfs_path ${debugfs_static} list -Z ${in} > ${out}.fc` +
- ` && ${apex_sepolicy_tests} -f ${out}.fc && touch ${out}`,
+ ` && ${apex_sepolicy_tests} -f ${out}.fc --partition ${partition_tag} && touch ${out}`,
CommandDeps: []string{"${apex_sepolicy_tests}", "${deapexer}", "${debugfs_static}"},
Description: "run apex_sepolicy_tests",
- })
+ }, "partition_tag")
apexLinkerconfigValidationRule = pctx.StaticRule("apexLinkerconfigValidationRule", blueprint.RuleParams{
Command: `${conv_linker_config} validate --type apex ${image_dir} && touch ${out}`,
@@ -920,7 +920,7 @@
validations = append(validations, runApexLinkerconfigValidation(ctx, unsignedOutputFile, imageDir))
// TODO(b/279688635) deapexer supports [ext4]
if !a.skipValidation(apexSepolicyTests) && suffix == imageApexSuffix && ext4 == a.payloadFsType {
- validations = append(validations, runApexSepolicyTests(ctx, unsignedOutputFile))
+ validations = append(validations, runApexSepolicyTests(ctx, a, unsignedOutputFile))
}
if !a.testApex && len(a.properties.Unwanted_transitive_deps) > 0 {
validations = append(validations,
@@ -1206,12 +1206,15 @@
//
// $ deapexer list -Z {apex_file} > {file_contexts}
// $ apex_sepolicy_tests -f {file_contexts}
-func runApexSepolicyTests(ctx android.ModuleContext, apexFile android.Path) android.Path {
+func runApexSepolicyTests(ctx android.ModuleContext, a *apexBundle, apexFile android.Path) android.Path {
timestamp := android.PathForModuleOut(ctx, "apex_sepolicy_tests.timestamp")
ctx.Build(pctx, android.BuildParams{
Rule: apexSepolicyTestsRule,
Input: apexFile,
Output: timestamp,
+ Args: map[string]string{
+ "partition_tag": a.PartitionTag(ctx.DeviceConfig()),
+ },
})
return timestamp
}
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 758c79e..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"
@@ -44,6 +46,12 @@
Vbmeta_partitions []string
// Name of the userdata partition filesystem module
Userdata_partition_name *string
+ // Name of the system_dlkm partition filesystem module
+ System_dlkm_partition_name *string
+ // Name of the vendor_dlkm partition filesystem module
+ Vendor_dlkm_partition_name *string
+ // Name of the odm_dlkm partition filesystem module
+ Odm_dlkm_partition_name *string
}
type androidDevice struct {
@@ -55,7 +63,7 @@
func AndroidDeviceFactory() android.Module {
module := &androidDevice{}
module.AddProperties(&module.partitionProps)
- android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibFirst)
return module
}
@@ -68,17 +76,23 @@
func (a *androidDevice) DepsMutator(ctx android.BottomUpMutatorContext) {
addDependencyIfDefined := func(dep *string) {
if dep != nil {
- ctx.AddFarVariationDependencies(nil, filesystemDepTag, proptools.String(dep))
+ ctx.AddDependency(ctx.Module(), filesystemDepTag, proptools.String(dep))
}
}
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)
addDependencyIfDefined(a.partitionProps.Vendor_partition_name)
addDependencyIfDefined(a.partitionProps.Odm_partition_name)
addDependencyIfDefined(a.partitionProps.Userdata_partition_name)
+ 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)
}
@@ -107,6 +121,11 @@
ctx.CheckbuildFile(out)
}
+type targetFilesZipCopy struct {
+ srcModule *string
+ destSubdir string
+}
+
func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) {
targetFilesDir := android.PathForModuleOut(ctx, "target_files_dir")
targetFilesZip := android.PathForModuleOut(ctx, "target_files.zip")
@@ -114,14 +133,55 @@
builder := android.NewRuleBuilder(pctx, ctx)
builder.Command().Textf("rm -rf %s", targetFilesDir.String())
builder.Command().Textf("mkdir -p %s", targetFilesDir.String())
- if a.partitionProps.Vendor_partition_name != nil {
- fsInfo := a.getFilesystemInfo(ctx, *a.partitionProps.Vendor_partition_name)
- builder.Command().Textf("mkdir -p %s/VENDOR", targetFilesDir.String())
+ 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"},
+ }
+ // 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, *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/VENDOR", fsInfo.RootDir, targetFilesDir).
+ 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/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index 560c201..41faf94 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -214,6 +214,15 @@
if android.InList("recovery", f.properties.Generated_partition_types) {
partitionProps.Recovery_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "recovery"))
}
+ if android.InList("system_dlkm", f.properties.Generated_partition_types) {
+ partitionProps.System_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_dlkm"))
+ }
+ if android.InList("vendor_dlkm", f.properties.Generated_partition_types) {
+ partitionProps.Vendor_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_dlkm"))
+ }
+ if android.InList("odm_dlkm", f.properties.Generated_partition_types) {
+ partitionProps.Odm_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm_dlkm"))
+ }
if f.properties.Boot_image != "" {
partitionProps.Boot_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "boot"))
}
@@ -580,7 +589,7 @@
}{
Name: proptools.StringPtr(generatedModuleName(ctx.Config(), "android_info.prop")),
Board_info_files: partitionVars.BoardInfoFiles,
- Stem: proptools.StringPtr("android_info.txt"),
+ Stem: proptools.StringPtr("android-info.txt"),
}
if len(androidInfoProps.Board_info_files) == 0 {
androidInfoProps.Bootloader_board_name = proptools.StringPtr(partitionVars.BootLoaderBoardName)
diff --git a/java/aar.go b/java/aar.go
index 3c62441..ed2fb7a 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -391,8 +391,9 @@
versionName = proptools.NinjaEscape(versionName)
linkFlags = append(linkFlags, "--version-name ", versionName)
}
-
- linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
+ // Split the flags by prefix, as --png-compression-level has the "=value" suffix.
+ linkFlags, compileFlags = android.FilterListByPrefix(linkFlags,
+ []string{"--legacy", "--png-compression-level"})
// Always set --pseudo-localize, it will be stripped out later for release
// builds that don't want it.
diff --git a/java/app.go b/java/app.go
index d56ea5f..a4e84e0 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1738,6 +1738,8 @@
// TODO(b/192032291): Disable by default after auditing downstream usage.
module.Module.dexProperties.Optimize.EnabledByDefault = true
+ module.Module.dexProperties.Optimize.Ignore_library_extends_program = proptools.BoolPtr(true)
+ module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
module.Module.properties.Installable = proptools.BoolPtr(true)
module.appProperties.Use_embedded_native_libs = proptools.BoolPtr(true)
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/builder.go b/java/builder.go
index 8d4d6af..30de61d 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -226,6 +226,12 @@
},
"jarArgs")
+ extractR8Rules = pctx.AndroidStaticRule("extractR8Rules",
+ blueprint.RuleParams{
+ Command: `${config.ExtractR8RulesCmd} --rules-output $out --include-origin-comments $in`,
+ CommandDeps: []string{"${config.ExtractR8RulesCmd}"},
+ })
+
jarjar = pctx.AndroidStaticRule("jarjar",
blueprint.RuleParams{
Command: "" +
@@ -739,6 +745,16 @@
})
}
+func TransformJarToR8Rules(ctx android.ModuleContext, outputFile android.WritablePath,
+ jar android.Path) {
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: extractR8Rules,
+ Output: outputFile,
+ Input: jar,
+ })
+}
+
func convertImplementationJarToHeaderJar(ctx android.ModuleContext, implementationJarFile android.Path,
headerJarFile android.WritablePath) {
ctx.Build(pctx, android.BuildParams{
diff --git a/java/config/config.go b/java/config/config.go
index 7c29722..71025de 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -171,6 +171,7 @@
pctx.HostBinToolVariable("ApiCheckCmd", "apicheck")
pctx.HostBinToolVariable("D8Cmd", "d8")
pctx.HostBinToolVariable("R8Cmd", "r8")
+ pctx.HostBinToolVariable("ExtractR8RulesCmd", "extract-r8-rules")
pctx.HostBinToolVariable("ResourceShrinkerCmd", "resourceshrinker")
pctx.HostBinToolVariable("HiddenAPICmd", "hiddenapi")
pctx.HostBinToolVariable("ExtractApksCmd", "extract_apks")
diff --git a/java/dex.go b/java/dex.go
index 168a231..7b99549 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -42,11 +42,15 @@
// True if the module containing this has it set by default.
EnabledByDefault bool `blueprint:"mutated"`
+ // Whether to allow that library classes inherit from program classes.
+ // Defaults to false.
+ Ignore_library_extends_program *bool
+
// Whether to continue building even if warnings are emitted. Defaults to true.
Ignore_warnings *bool
// If true, runs R8 in Proguard compatibility mode, otherwise runs R8 in full mode.
- // Defaults to false for apps, true for libraries and tests.
+ // Defaults to false for apps and tests, true for libraries.
Proguard_compatibility *bool
// If true, optimize for size by removing unused code. Defaults to true for apps,
@@ -356,6 +360,10 @@
r8Flags = append(r8Flags, opt.Proguard_flags...)
+ if BoolDefault(opt.Ignore_library_extends_program, false) {
+ r8Flags = append(r8Flags, "--ignore-library-extends-program")
+ }
+
if BoolDefault(opt.Proguard_compatibility, true) {
r8Flags = append(r8Flags, "--force-proguard-compatibility")
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index e955949..fa1fb86 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -629,8 +629,8 @@
cmd.Implicit(dep)
} else if filename != "android.jar" && depBase == "android.jar" {
// Metalava implicitly searches these patterns:
- // prebuilts/tools/common/api-versions/android-%/android.jar
- // prebuilts/sdk/%/public/android.jar
+ // prebuilts/tools/common/api-versions/android-{version:level}/android.jar
+ // prebuilts/sdk/{version:level}/public/android.jar
// Add android.jar files from the api_levels_annotations_dirs directories to try
// to satisfy these patterns. If Metalava can't find a match for an API level
// between 1 and 28 in at least one pattern it will fail.
@@ -646,11 +646,11 @@
})
// Generate the list of --android-jar-pattern options. The order matters so the first one which
- // matches will be the one that is used for a specific api level..
+ // matches will be the one that is used for a specific api level.
for _, sdkDir := range sdkDirs {
for _, dir := range dirs {
addPattern := func(jarFilename string) {
- cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/%%/%s/%s", dir, sdkDir, jarFilename))
+ cmd.FlagWithArg("--android-jar-pattern ", fmt.Sprintf("%s/{version:level}/%s/%s", dir, sdkDir, jarFilename))
}
if sdkDir == "module-lib" || sdkDir == "system-server" {
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 1e8362c..37740ae 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -88,7 +88,7 @@
cmdline := String(sboxProto.Commands[0].Command)
android.AssertStringContainsEquals(t, "api-versions generation flag", cmdline, "--generate-api-levels", c.generate_xml)
if c.expectedJarFilename != "" {
- expected := "--android-jar-pattern ./%/public/" + c.expectedJarFilename
+ expected := "--android-jar-pattern ./{version:level}/public/" + c.expectedJarFilename
if !strings.Contains(cmdline, expected) {
t.Errorf("For %q, expected metalava argument %q, but was not found %q", c.moduleName, expected, cmdline)
}
@@ -142,8 +142,8 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "public")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:level}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
}, patterns)
}
@@ -151,10 +151,10 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "system")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/system/android.jar",
- "--android-jar-pattern someotherdir/%/system/android.jar",
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:level}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
+ "--android-jar-pattern somedir/{version:level}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
}, patterns)
}
@@ -162,12 +162,12 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "module-lib")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/module-lib/android.jar",
- "--android-jar-pattern someotherdir/%/module-lib/android.jar",
- "--android-jar-pattern somedir/%/system/android.jar",
- "--android-jar-pattern someotherdir/%/system/android.jar",
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:level}/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar",
+ "--android-jar-pattern somedir/{version:level}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
+ "--android-jar-pattern somedir/{version:level}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
}, patterns)
}
@@ -175,14 +175,14 @@
patterns := getAndroidJarPatternsForDroidstubs(t, "system-server")
android.AssertArrayString(t, "order of patterns", []string{
- "--android-jar-pattern somedir/%/system-server/android.jar",
- "--android-jar-pattern someotherdir/%/system-server/android.jar",
- "--android-jar-pattern somedir/%/module-lib/android.jar",
- "--android-jar-pattern someotherdir/%/module-lib/android.jar",
- "--android-jar-pattern somedir/%/system/android.jar",
- "--android-jar-pattern someotherdir/%/system/android.jar",
- "--android-jar-pattern somedir/%/public/android.jar",
- "--android-jar-pattern someotherdir/%/public/android.jar",
+ "--android-jar-pattern somedir/{version:level}/system-server/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/system-server/android.jar",
+ "--android-jar-pattern somedir/{version:level}/module-lib/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/module-lib/android.jar",
+ "--android-jar-pattern somedir/{version:level}/system/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/system/android.jar",
+ "--android-jar-pattern somedir/{version:level}/public/android.jar",
+ "--android-jar-pattern someotherdir/{version:level}/public/android.jar",
}, patterns)
}
diff --git a/java/java.go b/java/java.go
index a975ca6..0ab3440 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2827,6 +2827,23 @@
outputFile = combinedJar
}
+ proguardFlags := android.PathForModuleOut(ctx, "proguard_flags")
+ TransformJarToR8Rules(ctx, proguardFlags, outputFile)
+
+ transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx)
+ android.SetProvider(ctx, ProguardSpecInfoProvider, ProguardSpecInfo{
+ ProguardFlagsFiles: depset.New[android.Path](
+ depset.POSTORDER,
+ android.Paths{proguardFlags},
+ transitiveProguardFlags,
+ ),
+ UnconditionallyExportedProguardFlags: depset.New[android.Path](
+ depset.POSTORDER,
+ nil,
+ transitiveUnconditionalExportedFlags,
+ ),
+ })
+
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource.
// Also strip the relative path from the header output file so that the reuseImplementationJarAsHeaderJar check
// in a module that depends on this module considers them equal.
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/python/python.go b/python/python.go
index be9411b..914b77e 100644
--- a/python/python.go
+++ b/python/python.go
@@ -95,6 +95,11 @@
// device.
Device_common_data []string `android:"path_device_common"`
+ // Same as data, but will add dependencies on modules via a device os variation and the
+ // device's first supported arch's variation. Useful for a host test that wants to embed a
+ // module built for device.
+ Device_first_data []string `android:"path_device_first"`
+
// list of java modules that provide data that should be installed alongside the test.
Java_data []string
@@ -456,6 +461,7 @@
// expand data files from "data" property.
expandedData := android.PathsForModuleSrc(ctx, p.properties.Data)
expandedData = append(expandedData, android.PathsForModuleSrc(ctx, p.properties.Device_common_data)...)
+ expandedData = append(expandedData, android.PathsForModuleSrc(ctx, p.properties.Device_first_data)...)
// Emulate the data property for java_data dependencies.
for _, javaData := range ctx.GetDirectDepsWithTag(javaDataTag) {
diff --git a/python/test.go b/python/test.go
index 9f57bea..37947dd 100644
--- a/python/test.go
+++ b/python/test.go
@@ -68,6 +68,11 @@
// device.
Device_common_data []string `android:"path_device_common"`
+ // Same as data, but will add dependencies on modules via a device os variation and the
+ // device's first supported arch's variation. Useful for a host test that wants to embed a
+ // module built for device.
+ Device_first_data []string `android:"path_device_first"`
+
// list of java modules that provide data that should be installed alongside the test.
Java_data []string
@@ -189,6 +194,9 @@
for _, dataSrcPath := range android.PathsForModuleSrc(ctx, p.testProperties.Device_common_data) {
p.data = append(p.data, android.DataPath{SrcPath: dataSrcPath})
}
+ for _, dataSrcPath := range android.PathsForModuleSrc(ctx, p.testProperties.Device_first_data) {
+ p.data = append(p.data, android.DataPath{SrcPath: dataSrcPath})
+ }
if p.isTestHost() && len(p.testProperties.Data_device_bins_both) > 0 {
ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) {
diff --git a/rust/builder.go b/rust/builder.go
index e5434ef..8a869aa 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -264,7 +264,7 @@
libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
}
for _, lib := range deps.DyLibs {
- libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
+ libFlags = append(libFlags, "--extern force:"+lib.CrateName+"="+lib.Path.String())
}
for _, proc_macro := range deps.ProcMacros {
libFlags = append(libFlags, "--extern "+proc_macro.CrateName+"="+proc_macro.Path.String())
diff --git a/rust/config/global.go b/rust/config/global.go
index 66ffc0b..0a4b314 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -42,6 +42,8 @@
}
GlobalRustFlags = []string{
+ // Allow `--extern force:foo` for dylib support
+ "-Z unstable-options",
"-Z stack-protector=strong",
"-Z remap-cwd-prefix=.",
"-C debuginfo=2",
diff --git a/rust/library.go b/rust/library.go
index 14a2b65..2d62dcf 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -457,13 +457,6 @@
cfgs := library.baseCompiler.Properties.Cfgs.GetOrDefault(ctx, nil)
- if library.dylib() {
- // We need to add a dependency on std in order to link crates as dylibs.
- // The hack to add this dependency is guarded by the following cfg so
- // that we don't force a dependency when it isn't needed.
- cfgs = append(cfgs, "android_dylib")
- }
-
cfgFlags := cfgsToFlags(cfgs)
flags.RustFlags = append(flags.RustFlags, cfgFlags...)
diff --git a/rust/library_test.go b/rust/library_test.go
index 256cb35..e5fd5e0 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -89,22 +89,6 @@
}
}
-// Check that we are passing the android_dylib config flag
-func TestAndroidDylib(t *testing.T) {
- ctx := testRust(t, `
- rust_library_host_dylib {
- name: "libfoo",
- srcs: ["foo.rs"],
- crate_name: "foo",
- }`)
-
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
-
- if !strings.Contains(libfooDylib.Args["rustcFlags"], "--cfg 'android_dylib'") {
- t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
- }
-}
-
func TestValidateLibraryStem(t *testing.T) {
testRustError(t, "crate_name must be defined.", `
rust_library_host {
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 90c1f61..9f65dec 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -424,11 +424,11 @@
}`)
fooRustc := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
- if !strings.Contains(fooRustc.Args["libFlags"], "--extern bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so") {
- t.Errorf("--extern bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
+ if !strings.Contains(fooRustc.Args["libFlags"], "--extern force:bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so") {
+ t.Errorf("--extern force:bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
}
- if !strings.Contains(fooRustc.Args["libFlags"], "--extern baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so") {
- t.Errorf("--extern baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
+ if !strings.Contains(fooRustc.Args["libFlags"], "--extern force:baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so") {
+ t.Errorf("--extern force:baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
}
}
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")
}
diff --git a/ui/metrics/proc/status_linux_test.go b/ui/metrics/proc/status_linux_test.go
index 6709850..0edc400 100644
--- a/ui/metrics/proc/status_linux_test.go
+++ b/ui/metrics/proc/status_linux_test.go
@@ -1,7 +1,6 @@
package proc
import (
- "fmt"
"path/filepath"
"reflect"
"strconv"
@@ -29,7 +28,6 @@
t.Fatalf("got %v, want nil for error", err)
}
- fmt.Printf("%d %d\b", status.VmPeak, expectedStatus.VmPeak)
if !reflect.DeepEqual(status, expectedStatus) {
t.Errorf("got %v, expecting %v for ProcStatus", status, expectedStatus)
}