Merge changes I8081fb3e,I235fa688 into main
* changes:
Remove ApexContents
Remove DirectlyInAnyApex
diff --git a/android/config.go b/android/config.go
index 27d3b87..dff3ea5 100644
--- a/android/config.go
+++ b/android/config.go
@@ -285,6 +285,10 @@
return c.config.productVariables.GetBuildFlagBool("RELEASE_CREATE_ACONFIG_STORAGE_FILE")
}
+func (c Config) ReleaseUseSystemFeatureBuildFlags() bool {
+ return c.config.productVariables.GetBuildFlagBool("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS")
+}
+
// A DeviceConfig object represents the configuration for a particular device
// being built. For now there will only be one of these, but in the future there
// may be multiple devices being built.
@@ -1834,6 +1838,10 @@
return Bool(c.productVariables.CompressedApex) && !c.UnbundledBuildApps()
}
+func (c *config) DefaultApexPayloadType() string {
+ return StringDefault(c.productVariables.DefaultApexPayloadType, "ext4")
+}
+
func (c *config) UseSoongSystemImage() bool {
return Bool(c.productVariables.UseSoongSystemImage)
}
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 403c184..a157386 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -611,6 +611,7 @@
nsjailCmd.WriteString(" -m none:/tmp:tmpfs:size=1073741824") // 1GB, should be enough
nsjailCmd.WriteString(" -D nsjail_build_sandbox")
nsjailCmd.WriteString(" --disable_rlimits")
+ nsjailCmd.WriteString(" --skip_setsid") // ABFS relies on process-groups to track file operations
nsjailCmd.WriteString(" -q")
nsjailCmd.WriteString(" -- ")
nsjailCmd.WriteString("/bin/bash -c ")
diff --git a/android/sbom.go b/android/sbom.go
index 2a5499e..f2b9c0f 100644
--- a/android/sbom.go
+++ b/android/sbom.go
@@ -15,9 +15,7 @@
package android
import (
- "io"
"path/filepath"
- "strings"
"github.com/google/blueprint"
)
@@ -55,21 +53,7 @@
if !ctx.Config().HasDeviceProduct() {
return
}
- // Get all METADATA files and add them as implicit input
- metadataFileListFile := PathForArbitraryOutput(ctx, ".module_paths", "METADATA.list")
- f, err := ctx.Config().fs.Open(metadataFileListFile.String())
- if err != nil {
- panic(err)
- }
- b, err := io.ReadAll(f)
- if err != nil {
- panic(err)
- }
- allMetadataFiles := strings.Split(string(b), "\n")
- implicits := []Path{metadataFileListFile}
- for _, path := range allMetadataFiles {
- implicits = append(implicits, PathForSource(ctx, path))
- }
+ implicits := []Path{}
prodVars := ctx.Config().productVariables
buildFingerprintFile := PathForArbitraryOutput(ctx, "target", "product", String(prodVars.DeviceName), "build_fingerprint.txt")
implicits = append(implicits, buildFingerprintFile)
diff --git a/android/variable.go b/android/variable.go
index 88cf5a5..7ae9a43 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -408,9 +408,10 @@
Ndk_abis *bool `json:",omitempty"`
- ForceApexSymlinkOptimization *bool `json:",omitempty"`
- CompressedApex *bool `json:",omitempty"`
- Aml_abis *bool `json:",omitempty"`
+ ForceApexSymlinkOptimization *bool `json:",omitempty"`
+ CompressedApex *bool `json:",omitempty"`
+ DefaultApexPayloadType *string `json:",omitempty"`
+ Aml_abis *bool `json:",omitempty"`
DexpreoptGlobalConfig *string `json:",omitempty"`
@@ -612,6 +613,7 @@
// Boot image stuff
BuildingRamdiskImage bool `json:",omitempty"`
ProductBuildBootImage bool `json:",omitempty"`
+ ProductBuildVendorBootImage string `json:",omitempty"`
ProductBuildInitBootImage bool `json:",omitempty"`
BoardUsesRecoveryAsBoot bool `json:",omitempty"`
BoardPrebuiltBootimage string `json:",omitempty"`
@@ -620,6 +622,7 @@
BoardInitBootimagePartitionSize string `json:",omitempty"`
BoardBootHeaderVersion string `json:",omitempty"`
TargetKernelPath string `json:",omitempty"`
+ BoardUsesGenericKernelImage bool `json:",omitempty"`
// Avb (android verified boot) stuff
BoardAvbEnable bool `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 7f259a8..ed9e58a 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1724,7 +1724,8 @@
}
func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
- switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) {
+ defaultFsType := ctx.Config().DefaultApexPayloadType()
+ switch proptools.StringDefault(a.properties.Payload_fs_type, defaultFsType) {
case ext4FsType:
a.payloadFsType = ext4
case f2fsFsType:
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 226d95c..2249506 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -36,6 +36,8 @@
output android.Path
installDir android.InstallPath
+
+ bootImageType bootImageType
}
type BootimgProperties struct {
@@ -56,9 +58,13 @@
// https://source.android.com/devices/bootloader/boot-image-header
Header_version *string
- // Determines if this image is for the vendor_boot partition. Default is false. Refer to
- // https://source.android.com/devices/bootloader/partitions/vendor-boot-partitions
- Vendor_boot *bool
+ // Determines the specific type of boot image this module is building. Can be boot,
+ // vendor_boot or init_boot. Defaults to boot.
+ // Refer to https://source.android.com/devices/bootloader/partitions/vendor-boot-partitions
+ // for vendor_boot.
+ // Refer to https://source.android.com/docs/core/architecture/partitions/generic-boot for
+ // init_boot.
+ Boot_image_type *string
// Optional kernel commandline arguments
Cmdline []string `android:"arch_variant"`
@@ -67,6 +73,10 @@
// and `header_version` is greater than or equal to 4.
Bootconfig *string `android:"arch_variant,path"`
+ // The size of the partition on the device. It will be a build error if this built partition
+ // image exceeds this size.
+ Partition_size *int64
+
// When set to true, sign the image with avbtool. Default is false.
Use_avb *bool
@@ -81,6 +91,41 @@
Avb_algorithm *string
}
+type bootImageType int
+
+const (
+ unsupported bootImageType = iota
+ boot
+ vendorBoot
+ initBoot
+)
+
+func toBootImageType(ctx android.ModuleContext, bootImageType string) bootImageType {
+ switch bootImageType {
+ case "boot":
+ return boot
+ case "vendor_boot":
+ return vendorBoot
+ case "init_boot":
+ return initBoot
+ default:
+ ctx.ModuleErrorf("Unknown boot_image_type %s. Must be one of \"boot\", \"vendor_boot\", or \"init_boot\"", bootImageType)
+ }
+ return unsupported
+}
+
+func (b bootImageType) isBoot() bool {
+ return b == boot
+}
+
+func (b bootImageType) isVendorBoot() bool {
+ return b == vendorBoot
+}
+
+func (b bootImageType) isInitBoot() bool {
+ return b == initBoot
+}
+
// bootimg is the image for the boot partition. It consists of header, kernel, ramdisk, and dtb.
func BootimgFactory() android.Module {
module := &bootimg{}
@@ -112,8 +157,8 @@
}
func (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- vendor := proptools.Bool(b.properties.Vendor_boot)
- unsignedOutput := b.buildBootImage(ctx, vendor)
+ b.bootImageType = toBootImageType(ctx, proptools.StringDefault(b.properties.Boot_image_type, "boot"))
+ unsignedOutput := b.buildBootImage(ctx)
output := unsignedOutput
if proptools.Bool(b.properties.Use_avb) {
@@ -127,18 +172,19 @@
b.output = output
}
-func (b *bootimg) buildBootImage(ctx android.ModuleContext, vendor bool) android.Path {
+func (b *bootimg) buildBootImage(ctx android.ModuleContext) android.Path {
output := android.PathForModuleOut(ctx, "unsigned", b.installFileName())
builder := android.NewRuleBuilder(pctx, ctx)
cmd := builder.Command().BuiltTool("mkbootimg")
kernel := proptools.String(b.properties.Kernel_prebuilt)
- if vendor && kernel != "" {
+ if b.bootImageType.isVendorBoot() && kernel != "" {
ctx.PropertyErrorf("kernel_prebuilt", "vendor_boot partition can't have kernel")
return output
}
- if !vendor && kernel == "" {
+
+ if b.bootImageType.isBoot() && kernel == "" {
ctx.PropertyErrorf("kernel_prebuilt", "boot partition must have kernel")
return output
}
@@ -146,6 +192,12 @@
cmd.FlagWithInput("--kernel ", android.PathForModuleSrc(ctx, kernel))
}
+ // These arguments are passed for boot.img and init_boot.img generation
+ if b.bootImageType.isBoot() || b.bootImageType.isInitBoot() {
+ cmd.FlagWithArg("--os_version ", ctx.Config().PlatformVersionLastStable())
+ cmd.FlagWithArg("--os_patch_level ", ctx.Config().PlatformSecurityPatch())
+ }
+
dtbName := proptools.String(b.properties.Dtb_prebuilt)
if dtbName != "" {
dtb := android.PathForModuleSrc(ctx, dtbName)
@@ -155,7 +207,7 @@
cmdline := strings.Join(b.properties.Cmdline, " ")
if cmdline != "" {
flag := "--cmdline "
- if vendor {
+ if b.bootImageType.isVendorBoot() {
flag = "--vendor_cmdline "
}
cmd.FlagWithArg(flag, proptools.ShellEscapeIncludingSpaces(cmdline))
@@ -182,7 +234,7 @@
ramdisk := ctx.GetDirectDepWithTag(ramdiskName, bootimgRamdiskDep)
if filesystem, ok := ramdisk.(*filesystem); ok {
flag := "--ramdisk "
- if vendor {
+ if b.bootImageType.isVendorBoot() {
flag = "--vendor_ramdisk "
}
cmd.FlagWithInput(flag, filesystem.OutputPath())
@@ -194,7 +246,7 @@
bootconfig := proptools.String(b.properties.Bootconfig)
if bootconfig != "" {
- if !vendor {
+ if !b.bootImageType.isVendorBoot() {
ctx.PropertyErrorf("bootconfig", "requires vendor_boot: true")
return output
}
@@ -205,12 +257,17 @@
cmd.FlagWithInput("--vendor_bootconfig ", android.PathForModuleSrc(ctx, bootconfig))
}
+ // Output flag for boot.img and init_boot.img
flag := "--output "
- if vendor {
+ if b.bootImageType.isVendorBoot() {
flag = "--vendor_boot "
}
cmd.FlagWithOutput(flag, output)
+ if b.properties.Partition_size != nil {
+ assertMaxImageSize(builder, output, *b.properties.Partition_size, proptools.Bool(b.properties.Use_avb))
+ }
+
builder.Build("build_bootimg", fmt.Sprintf("Creating %s", b.BaseModuleName()))
return output
}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index c346770..dadacae 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -162,6 +162,10 @@
// Determines if the module is auto-generated from Soong or not. If the module is
// auto-generated, its deps are exempted from visibility enforcement.
Is_auto_generated *bool
+
+ // Path to the dev nodes description file. This is only needed for building the ramdisk
+ // partition and should not be explicitly specified.
+ Dev_nodes_description_file *string `android:"path" blueprint:"mutated"`
}
// Additional properties required to generate erofs FS partitions.
@@ -210,6 +214,10 @@
filesystemModule.PackagingBase.AllowHighPriorityDeps = true
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
+
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ filesystemModule.setDevNodesDescriptionProp()
+ })
}
type depTag struct {
@@ -229,6 +237,16 @@
var dependencyTagWithVisibilityEnforcementBypass = depTagWithVisibilityEnforcementBypass{}
+// ramdiskDevNodesDescription is the name of the filegroup module that provides the file that
+// contains the description of dev nodes added to the CPIO archive for the ramdisk partition.
+const ramdiskDevNodesDescription = "ramdisk_node_list"
+
+func (f *filesystem) setDevNodesDescriptionProp() {
+ if proptools.String(f.properties.Partition_name) == "ramdisk" {
+ f.properties.Dev_nodes_description_file = proptools.StringPtr(":" + ramdiskDevNodesDescription)
+ }
+}
+
func (f *filesystem) DepsMutator(ctx android.BottomUpMutatorContext) {
if proptools.Bool(f.properties.Is_auto_generated) {
f.AddDeps(ctx, dependencyTagWithVisibilityEnforcementBypass)
@@ -659,6 +677,9 @@
cmd := builder.Command().
BuiltTool("mkbootfs").
Text(rootDir.String()) // input directory
+ if nodeList := f.properties.Dev_nodes_description_file; nodeList != nil {
+ cmd.FlagWithInput("-n ", android.PathForModuleSrc(ctx, proptools.String(nodeList)))
+ }
if compressed {
cmd.Text("|").
BuiltTool("lz4").
@@ -689,6 +710,7 @@
"odm_dlkm",
"system_dlkm",
"ramdisk",
+ "vendor_ramdisk",
}
func (f *filesystem) addMakeBuiltFiles(ctx android.ModuleContext, builder *android.RuleBuilder, rootDir android.Path) {
@@ -904,3 +926,26 @@
return provideModules, requireModules
}
+
+// Checks that the given file doesn't exceed the given size, and will also print a warning
+// if it's nearing the maximum size. Equivalent to assert-max-image-size in make:
+// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/definitions.mk;l=3455;drc=993c4de29a02a6accd60ceaaee153307e1a18d10
+func assertMaxImageSize(builder *android.RuleBuilder, image android.Path, maxSize int64, addAvbLater bool) {
+ if addAvbLater {
+ // The value 69632 is derived from MAX_VBMETA_SIZE + MAX_FOOTER_SIZE in avbtool.
+ // Logic copied from make:
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=228;drc=a6a0007ef24e16c0b79f439beac4a118416717e6
+ maxSize -= 69632
+ }
+ cmd := builder.Command()
+ cmd.Textf(`file="%s"; maxsize="%d";`+
+ `total=$(stat -c "%%s" "$file" | tr -d '\n');`+
+ `if [ "$total" -gt "$maxsize" ]; then `+
+ ` echo "error: $file too large ($total > $maxsize)";`+
+ ` false;`+
+ `elif [ "$total" -gt $((maxsize - 32768)) ]; then `+
+ ` echo "WARNING: $file approaching size limit ($total now; limit $maxsize)";`+
+ `fi`,
+ image, maxSize)
+ cmd.Implicit(image)
+}
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 7c342cc..746e4de 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -758,3 +758,28 @@
fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList"))
android.AssertStringEquals(t, "filesystem with override app", "app/myoverrideapp/myoverrideapp.apk\n", fileList)
}
+
+func TestRamdiskPartitionSetsDevNodes(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ fixture,
+ android.FixtureMergeMockFs(android.MockFS{
+ "ramdisk_node_list": nil,
+ }),
+ ).RunTestWithBp(t, `
+ android_filesystem {
+ name: "ramdisk_filesystem",
+ partition_name: "ramdisk",
+ }
+ filegroup {
+ name: "ramdisk_node_list",
+ srcs: ["ramdisk_node_list"],
+ }
+ `)
+
+ android.AssertBoolEquals(
+ t,
+ "Generated ramdisk image expected to depend on \"ramdisk_node_list\" module",
+ true,
+ java.CheckModuleHasDependency(t, result.TestContext, "ramdisk_filesystem", "android_common", "ramdisk_node_list"),
+ )
+}
diff --git a/fsgen/boot_imgs.go b/fsgen/boot_imgs.go
index 66d9107..630aaff 100644
--- a/fsgen/boot_imgs.go
+++ b/fsgen/boot_imgs.go
@@ -3,7 +3,9 @@
import (
"android/soong/android"
"android/soong/filesystem"
+ "fmt"
"path/filepath"
+ "strconv"
"github.com/google/blueprint/proptools"
)
@@ -34,12 +36,63 @@
},
)
+ var partitionSize *int64
+ if partitionVariables.BoardBootimagePartitionSize != "" {
+ parsed, err := strconv.ParseInt(partitionVariables.BoardBootimagePartitionSize, 10, 64)
+ if err != nil {
+ panic(fmt.Sprintf("BOARD_BOOTIMAGE_PARTITION_SIZE must be an int, got %s", partitionVariables.BoardBootimagePartitionSize))
+ }
+ partitionSize = &parsed
+ }
+
bootImageName := generatedModuleNameForPartition(ctx.Config(), "boot")
ctx.CreateModule(
filesystem.BootimgFactory,
&filesystem.BootimgProperties{
Kernel_prebuilt: proptools.StringPtr(":" + kernelFilegroupName),
+ Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
+ Partition_size: partitionSize,
+ },
+ &struct {
+ Name *string
+ }{
+ Name: proptools.StringPtr(bootImageName),
+ },
+ )
+ return true
+}
+
+func createVendorBootImage(ctx android.LoadHookContext) bool {
+ partitionVariables := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
+
+ bootImageName := generatedModuleNameForPartition(ctx.Config(), "vendor_boot")
+
+ ctx.CreateModule(
+ filesystem.BootimgFactory,
+ &filesystem.BootimgProperties{
+ Boot_image_type: proptools.StringPtr("vendor_boot"),
+ Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_ramdisk")),
+ Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
+ },
+ &struct {
+ Name *string
+ }{
+ Name: proptools.StringPtr(bootImageName),
+ },
+ )
+ return true
+}
+
+func createInitBootImage(ctx android.LoadHookContext) bool {
+ partitionVariables := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
+
+ bootImageName := generatedModuleNameForPartition(ctx.Config(), "init_boot")
+
+ ctx.CreateModule(
+ filesystem.BootimgFactory,
+ &filesystem.BootimgProperties{
+ Boot_image_type: proptools.StringPtr("init_boot"),
Ramdisk_module: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "ramdisk")),
Header_version: proptools.StringPtr(partitionVariables.BoardBootHeaderVersion),
},
@@ -76,3 +129,44 @@
return false
}
+
+// Returns the equivalent of the BUILDING_VENDOR_BOOT_IMAGE variable in make. Derived from this logic:
+// https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/board_config.mk;l=518;drc=5b55f926830963c02ab1d2d91e46442f04ba3af0
+func buildingVendorBootImage(partitionVars android.PartitionVariables) bool {
+ if v, exists := boardBootHeaderVersion(partitionVars); exists && v >= 3 {
+ x := partitionVars.ProductBuildVendorBootImage
+ if x == "" || x == "true" {
+ return true
+ }
+ }
+
+ return false
+}
+
+// Derived from: https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/board_config.mk;l=480;drc=5b55f926830963c02ab1d2d91e46442f04ba3af0
+func buildingInitBootImage(partitionVars android.PartitionVariables) bool {
+ if !partitionVars.ProductBuildInitBootImage {
+ if partitionVars.BoardUsesRecoveryAsBoot || len(partitionVars.BoardPrebuiltInitBootimage) > 0 {
+ return false
+ } else if len(partitionVars.BoardInitBootimagePartitionSize) > 0 {
+ return true
+ }
+ } else {
+ if partitionVars.BoardUsesRecoveryAsBoot {
+ panic("PRODUCT_BUILD_INIT_BOOT_IMAGE is true, but so is BOARD_USES_RECOVERY_AS_BOOT. Use only one option.")
+ }
+ return true
+ }
+ return false
+}
+
+func boardBootHeaderVersion(partitionVars android.PartitionVariables) (int, bool) {
+ if len(partitionVars.BoardBootHeaderVersion) == 0 {
+ return 0, false
+ }
+ v, err := strconv.ParseInt(partitionVars.BoardBootHeaderVersion, 10, 32)
+ if err != nil {
+ panic(fmt.Sprintf("BOARD_BOOT_HEADER_VERSION must be an int, got: %q", partitionVars.BoardBootHeaderVersion))
+ }
+ return int(v), true
+}
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index 7daefcb..6bfb097 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -48,7 +48,9 @@
Vbmeta_module_names []string `blueprint:"mutated"`
Vbmeta_partition_names []string `blueprint:"mutated"`
- Boot_image string `blueprint:"mutated" android:"path_device_first"`
+ Boot_image string `blueprint:"mutated" android:"path_device_first"`
+ Vendor_boot_image string `blueprint:"mutated" android:"path_device_first"`
+ Init_boot_image string `blueprint:"mutated" android:"path_device_first"`
}
type filesystemCreator struct {
@@ -74,6 +76,7 @@
}
func generatedPartitions(ctx android.LoadHookContext) []string {
+ partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
generatedPartitions := []string{"system"}
if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
generatedPartitions = append(generatedPartitions, "system_ext")
@@ -90,18 +93,21 @@
if ctx.DeviceConfig().BuildingUserdataImage() && ctx.DeviceConfig().UserdataPath() == "data" {
generatedPartitions = append(generatedPartitions, "userdata")
}
- if ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BuildingSystemDlkmImage {
+ if partitionVars.BuildingSystemDlkmImage {
generatedPartitions = append(generatedPartitions, "system_dlkm")
}
- if ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BuildingVendorDlkmImage {
+ if partitionVars.BuildingVendorDlkmImage {
generatedPartitions = append(generatedPartitions, "vendor_dlkm")
}
- if ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BuildingOdmDlkmImage {
+ if partitionVars.BuildingOdmDlkmImage {
generatedPartitions = append(generatedPartitions, "odm_dlkm")
}
- if ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.BuildingRamdiskImage {
+ if partitionVars.BuildingRamdiskImage {
generatedPartitions = append(generatedPartitions, "ramdisk")
}
+ if buildingVendorBootImage(partitionVars) {
+ generatedPartitions = append(generatedPartitions, "vendor_ramdisk")
+ }
return generatedPartitions
}
@@ -117,13 +123,28 @@
}
}
- if buildingBootImage(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse) {
+ partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
+ if buildingBootImage(partitionVars) {
if createBootImage(ctx) {
f.properties.Boot_image = ":" + generatedModuleNameForPartition(ctx.Config(), "boot")
} else {
f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, "boot")
}
}
+ if buildingVendorBootImage(partitionVars) {
+ if createVendorBootImage(ctx) {
+ f.properties.Vendor_boot_image = ":" + generatedModuleNameForPartition(ctx.Config(), "vendor_boot")
+ } else {
+ f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, "vendor_boot")
+ }
+ }
+ if buildingInitBootImage(partitionVars) {
+ if createInitBootImage(ctx) {
+ f.properties.Init_boot_image = ":" + generatedModuleNameForPartition(ctx.Config(), "init_boot")
+ } else {
+ f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, "init_boot")
+ }
+ }
for _, x := range createVbmetaPartitions(ctx, finalSoongGeneratedPartitions) {
f.properties.Vbmeta_module_names = append(f.properties.Vbmeta_module_names, x.moduleName)
@@ -182,13 +203,13 @@
ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps)
}
-func partitionSpecificFsProps(fsProps *filesystem.FilesystemProperties, partitionType string) {
+func partitionSpecificFsProps(fsProps *filesystem.FilesystemProperties, partitionVars android.PartitionVariables, partitionType string) {
switch partitionType {
case "system":
fsProps.Build_logtags = proptools.BoolPtr(true)
// https://source.corp.google.com/h/googleplex-android/platform/build//639d79f5012a6542ab1f733b0697db45761ab0f3:core/packaging/flags.mk;l=21;drc=5ba8a8b77507f93aa48cc61c5ba3f31a4d0cbf37;bpv=1;bpt=0
fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
- // Identical to that of the generic_system_image
+ // Identical to that of the aosp_shared_system_image
fsProps.Fsverity.Inputs = []string{
"etc/boot-image.prof",
"etc/dirty-image-objects",
@@ -248,7 +269,28 @@
}
case "userdata":
fsProps.Base_dir = proptools.StringPtr("data")
-
+ case "ramdisk":
+ // Following the logic in https://cs.android.com/android/platform/superproject/main/+/c3c5063df32748a8806ce5da5dd0db158eab9ad9:build/make/core/Makefile;l=1307
+ fsProps.Dirs = android.NewSimpleConfigurable([]string{
+ "debug_ramdisk",
+ "dev",
+ "metadata",
+ "mnt",
+ "proc",
+ "second_stage_resources",
+ "sys",
+ })
+ if partitionVars.BoardUsesGenericKernelImage {
+ fsProps.Dirs.AppendSimpleValue([]string{
+ "first_stage_ramdisk/debug_ramdisk",
+ "first_stage_ramdisk/dev",
+ "first_stage_ramdisk/metadata",
+ "first_stage_ramdisk/mnt",
+ "first_stage_ramdisk/proc",
+ "first_stage_ramdisk/second_stage_resources",
+ "first_stage_ramdisk/sys",
+ })
+ }
}
}
@@ -359,7 +401,7 @@
}
switch partitionType {
case "system_dlkm":
- props.Srcs = ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.SystemKernelModules
+ props.Srcs = android.ExistentPathsForSources(ctx, ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.SystemKernelModules).Strings()
props.System_dlkm_specific = proptools.BoolPtr(true)
if len(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.SystemKernelLoadModules) == 0 {
// Create empty modules.load file for system
@@ -370,7 +412,7 @@
props.Blocklist_file = proptools.StringPtr(blocklistFile)
}
case "vendor_dlkm":
- props.Srcs = ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.VendorKernelModules
+ props.Srcs = android.ExistentPathsForSources(ctx, ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.VendorKernelModules).Strings()
if len(ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.SystemKernelModules) > 0 {
props.System_deps = []string{":" + generatedModuleName(ctx.Config(), "system_dlkm-kernel-modules") + "{.modules}"}
}
@@ -379,7 +421,7 @@
props.Blocklist_file = proptools.StringPtr(blocklistFile)
}
case "odm_dlkm":
- props.Srcs = ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.OdmKernelModules
+ props.Srcs = android.ExistentPathsForSources(ctx, ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.OdmKernelModules).Strings()
props.Odm_dlkm_specific = proptools.BoolPtr(true)
if blocklistFile := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.OdmKernelBlocklistFile; blocklistFile != "" {
props.Blocklist_file = proptools.StringPtr(blocklistFile)
@@ -564,11 +606,13 @@
fsProps.Partition_name = proptools.StringPtr(partitionType)
- fsProps.Base_dir = proptools.StringPtr(partitionType)
+ if !strings.Contains(partitionType, "ramdisk") {
+ fsProps.Base_dir = proptools.StringPtr(partitionType)
+ }
fsProps.Is_auto_generated = proptools.BoolPtr(true)
- partitionSpecificFsProps(fsProps, partitionType)
+ partitionSpecificFsProps(fsProps, partitionVars, partitionType)
// system_image properties that are not set:
// - filesystemProperties.Avb_hash_algorithm
@@ -699,6 +743,22 @@
diffTestFiles = append(diffTestFiles, diffTestFile)
ctx.Phony("soong_generated_boot_filesystem_test", diffTestFile)
}
+ if f.properties.Vendor_boot_image != "" {
+ diffTestFile := android.PathForModuleOut(ctx, "vendor_boot_diff_test.txt")
+ soongBootImg := android.PathForModuleSrc(ctx, f.properties.Vendor_boot_image)
+ makeBootImage := android.PathForArbitraryOutput(ctx, fmt.Sprintf("target/product/%s/vendor_boot.img", ctx.Config().DeviceName()))
+ createDiffTest(ctx, diffTestFile, soongBootImg, makeBootImage)
+ diffTestFiles = append(diffTestFiles, diffTestFile)
+ ctx.Phony("soong_generated_vendor_boot_filesystem_test", diffTestFile)
+ }
+ if f.properties.Init_boot_image != "" {
+ diffTestFile := android.PathForModuleOut(ctx, "init_boot_diff_test.txt")
+ soongBootImg := android.PathForModuleSrc(ctx, f.properties.Init_boot_image)
+ makeBootImage := android.PathForArbitraryOutput(ctx, fmt.Sprintf("target/product/%s/init_boot.img", ctx.Config().DeviceName()))
+ createDiffTest(ctx, diffTestFile, soongBootImg, makeBootImage)
+ diffTestFiles = append(diffTestFiles, diffTestFile)
+ ctx.Phony("soong_generated_init_boot_filesystem_test", diffTestFile)
+ }
ctx.Phony("soong_generated_filesystem_tests", diffTestFiles...)
}
diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go
index 0d18660..12f9956 100644
--- a/fsgen/fsgen_mutators.go
+++ b/fsgen/fsgen_mutators.go
@@ -146,7 +146,8 @@
"fs_config_files_odm_dlkm": defaultDepCandidateProps(ctx.Config()),
"odm_dlkm-build.prop": defaultDepCandidateProps(ctx.Config()),
},
- "ramdisk": {},
+ "ramdisk": {},
+ "vendor_ramdisk": {},
},
fsDepsMutex: sync.Mutex{},
moduleToInstallationProps: map[string]installationProperties{},
diff --git a/java/app.go b/java/app.go
index 8bb73cb..7f80160 100644
--- a/java/app.go
+++ b/java/app.go
@@ -164,7 +164,7 @@
type overridableAppProperties struct {
// The name of a certificate in the default certificate directory, blank to use the default product certificate,
// or an android_app_certificate module name in the form ":module".
- Certificate *string
+ Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
// Name of the signing certificate lineage file or filegroup module.
Lineage *string `android:"path"`
@@ -1252,7 +1252,7 @@
if overridden {
return ":" + certificate
}
- return String(a.overridableAppProperties.Certificate)
+ return a.overridableAppProperties.Certificate.GetOrDefault(ctx, "")
}
func (a *AndroidApp) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
diff --git a/java/app_import.go b/java/app_import.go
index f044c68..8951c7d 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -97,7 +97,7 @@
// The name of a certificate in the default certificate directory or an android_app_certificate
// module name in the form ":module". Should be empty if presigned or default_dev_cert is set.
- Certificate *string
+ Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
// Names of extra android_app_certificate modules to sign the apk with in the form ":module".
Additional_certificates []string
@@ -240,7 +240,7 @@
}
func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
- cert := android.SrcIsModule(String(a.properties.Certificate))
+ cert := android.SrcIsModule(a.properties.Certificate.GetOrDefault(ctx, ""))
if cert != "" {
ctx.AddDependency(ctx.Module(), certificateTag, cert)
}
@@ -323,7 +323,7 @@
}
numCertPropsSet := 0
- if String(a.properties.Certificate) != "" {
+ if a.properties.Certificate.GetOrDefault(ctx, "") != "" {
numCertPropsSet++
}
if Bool(a.properties.Presigned) {
@@ -406,7 +406,7 @@
// If the certificate property is empty at this point, default_dev_cert must be set to true.
// Which makes processMainCert's behavior for the empty cert string WAI.
_, _, certificates := collectAppDeps(ctx, a, false, false)
- a.certificate, certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
+ a.certificate, certificates = processMainCert(a.ModuleBase, a.properties.Certificate.GetOrDefault(ctx, ""), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", apkFilename)
var lineageFile android.Path
if lineage := String(a.properties.Lineage); lineage != "" {
diff --git a/java/rro.go b/java/rro.go
index 8bb9be2..f225e1f 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -50,7 +50,7 @@
type RuntimeResourceOverlayProperties struct {
// the name of a certificate in the default certificate directory or an android_app_certificate
// module name in the form ":module".
- Certificate *string
+ Certificate proptools.Configurable[string] `android:"replace_instead_of_append"`
// Name of the signing certificate lineage file.
Lineage *string
@@ -119,7 +119,7 @@
r.aapt.deps(ctx, sdkDep)
}
- cert := android.SrcIsModule(String(r.properties.Certificate))
+ cert := android.SrcIsModule(r.properties.Certificate.GetOrDefault(ctx, ""))
if cert != "" {
ctx.AddDependency(ctx.Module(), certificateTag, cert)
}
@@ -166,7 +166,7 @@
// Sign the built package
_, _, certificates := collectAppDeps(ctx, r, false, false)
- r.certificate, certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
+ r.certificate, certificates = processMainCert(r.ModuleBase, r.properties.Certificate.GetOrDefault(ctx, ""), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
var lineageFile android.Path
if lineage := String(r.properties.Lineage); lineage != "" {
diff --git a/systemfeatures/Android.bp b/systemfeatures/Android.bp
new file mode 100644
index 0000000..a65a6b6
--- /dev/null
+++ b/systemfeatures/Android.bp
@@ -0,0 +1,18 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-systemfeatures",
+ pkgPath: "android/soong/systemfeatures",
+ deps: [
+ "blueprint",
+ "blueprint-proptools",
+ "soong",
+ "soong-android",
+ "soong-java",
+ ],
+ srcs: ["system_features.go"],
+ testSrcs: ["system_features_test.go"],
+ pluginFor: ["soong_build"],
+}
diff --git a/systemfeatures/OWNERS b/systemfeatures/OWNERS
new file mode 100644
index 0000000..3e44806
--- /dev/null
+++ b/systemfeatures/OWNERS
@@ -0,0 +1,2 @@
+jdduke@google.com
+shayba@google.com
diff --git a/systemfeatures/system_features.go b/systemfeatures/system_features.go
new file mode 100644
index 0000000..0c1a566
--- /dev/null
+++ b/systemfeatures/system_features.go
@@ -0,0 +1,102 @@
+// Copyright 2024 Google Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package systemfeatures
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+
+ "android/soong/android"
+ "android/soong/genrule"
+)
+
+var (
+ pctx = android.NewPackageContext("android/soong/systemfeatures")
+)
+
+func init() {
+ registerSystemFeaturesComponents(android.InitRegistrationContext)
+}
+
+func registerSystemFeaturesComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("java_system_features_srcs", JavaSystemFeaturesSrcsFactory)
+}
+
+type javaSystemFeaturesSrcs struct {
+ android.ModuleBase
+ properties struct {
+ // The fully qualified class name for the generated code, e.g., com.android.Foo
+ Full_class_name string
+ }
+ outputFiles android.WritablePaths
+}
+
+var _ genrule.SourceFileGenerator = (*javaSystemFeaturesSrcs)(nil)
+var _ android.SourceFileProducer = (*javaSystemFeaturesSrcs)(nil)
+
+func (m *javaSystemFeaturesSrcs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // Create a file name appropriate for the given fully qualified (w/ package) class name.
+ classNameParts := strings.Split(m.properties.Full_class_name, ".")
+ outputDir := android.PathForModuleGen(ctx)
+ outputFileName := classNameParts[len(classNameParts)-1] + ".java"
+ outputFile := android.PathForModuleGen(ctx, outputFileName).OutputPath
+
+ // Collect all RELEASE_SYSTEM_FEATURE_$K:$V build flags into a list of "$K:$V" pairs.
+ var features []string
+ for k, v := range ctx.Config().ProductVariables().BuildFlags {
+ if strings.HasPrefix(k, "RELEASE_SYSTEM_FEATURE_") {
+ shortFeatureName := strings.TrimPrefix(k, "RELEASE_SYSTEM_FEATURE_")
+ features = append(features, fmt.Sprintf("%s:%s", shortFeatureName, v))
+ }
+ }
+ // Ensure sorted outputs for consistency of flag ordering in ninja outputs.
+ sort.Strings(features)
+
+ rule := android.NewRuleBuilder(pctx, ctx)
+ rule.Command().Text("rm -rf").Text(outputDir.String())
+ rule.Command().Text("mkdir -p").Text(outputDir.String())
+ rule.Command().
+ BuiltTool("systemfeatures-gen-tool").
+ Flag(m.properties.Full_class_name).
+ FlagForEachArg("--feature=", features).
+ FlagWithArg("--readonly=", fmt.Sprint(ctx.Config().ReleaseUseSystemFeatureBuildFlags())).
+ FlagWithOutput(" > ", outputFile)
+ rule.Build(ctx.ModuleName(), "Generating systemfeatures srcs filegroup")
+
+ m.outputFiles = append(m.outputFiles, outputFile)
+}
+
+func (m *javaSystemFeaturesSrcs) Srcs() android.Paths {
+ return m.outputFiles.Paths()
+}
+
+func (m *javaSystemFeaturesSrcs) GeneratedSourceFiles() android.Paths {
+ return m.outputFiles.Paths()
+}
+
+func (m *javaSystemFeaturesSrcs) GeneratedDeps() android.Paths {
+ return m.outputFiles.Paths()
+}
+
+func (m *javaSystemFeaturesSrcs) GeneratedHeaderDirs() android.Paths {
+ return nil
+}
+
+func JavaSystemFeaturesSrcsFactory() android.Module {
+ module := &javaSystemFeaturesSrcs{}
+ module.AddProperties(&module.properties)
+ android.InitAndroidModule(module)
+ return module
+}
diff --git a/systemfeatures/system_features_test.go b/systemfeatures/system_features_test.go
new file mode 100644
index 0000000..558bb95
--- /dev/null
+++ b/systemfeatures/system_features_test.go
@@ -0,0 +1,51 @@
+// Copyright 2024 Google Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package systemfeatures
+
+import (
+ "android/soong/android"
+
+ "testing"
+)
+
+func TestJavaSystemFeaturesSrcs(t *testing.T) {
+ bp := `
+java_system_features_srcs {
+ name: "system-features-srcs",
+ full_class_name: "com.android.test.RoSystemFeatures",
+}
+`
+
+ res := android.GroupFixturePreparers(
+ android.FixtureRegisterWithContext(registerSystemFeaturesComponents),
+ android.PrepareForTestWithBuildFlag("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS", "true"),
+ android.PrepareForTestWithBuildFlag("RELEASE_SYSTEM_FEATURE_AUTOMOTIVE", "0"),
+ android.PrepareForTestWithBuildFlag("RELEASE_SYSTEM_FEATURE_TELEVISION", "UNAVAILABLE"),
+ android.PrepareForTestWithBuildFlag("RELEASE_SYSTEM_FEATURE_WATCH", ""),
+ android.PrepareForTestWithBuildFlag("RELEASE_NOT_SYSTEM_FEATURE_FOO", "BAR"),
+ ).RunTestWithBp(t, bp)
+
+ module := res.ModuleForTests("system-features-srcs", "")
+ cmd := module.Rule("system-features-srcs").RuleParams.Command
+ android.AssertStringDoesContain(t, "Expected fully class name", cmd, " com.android.test.RoSystemFeatures ")
+ android.AssertStringDoesContain(t, "Expected readonly flag", cmd, "--readonly=true")
+ android.AssertStringDoesContain(t, "Expected AUTOMOTIVE feature flag", cmd, "--feature=AUTOMOTIVE:0 ")
+ android.AssertStringDoesContain(t, "Expected TELEVISION feature flag", cmd, "--feature=TELEVISION:UNAVAILABLE ")
+ android.AssertStringDoesContain(t, "Expected WATCH feature flag", cmd, "--feature=WATCH: ")
+ android.AssertStringDoesNotContain(t, "Unexpected FOO arg from non-system feature flag", cmd, "FOO")
+
+ systemFeaturesModule := module.Module().(*javaSystemFeaturesSrcs)
+ expectedOutputPath := "out/soong/.intermediates/system-features-srcs/gen/RoSystemFeatures.java"
+ android.AssertPathsRelativeToTopEquals(t, "Expected output file", []string{expectedOutputPath}, systemFeaturesModule.Srcs())
+}