Merge changes from topic "soong-cleanup" into main
* changes:
Remove bp2build and appurtenances.
Remove multiproduct_kati and build_test.bash
Remove cuj script.
diff --git a/Android.bp b/Android.bp
index bd4b40f..d0f97db 100644
--- a/Android.bp
+++ b/Android.bp
@@ -147,6 +147,16 @@
// Framework guests.
cc_defaults {
name: "cc_baremetal_defaults",
+ arch: {
+ arm64: {
+ cflags: [
+ // Prevent the compiler from optimizing code using SVE, as the
+ // baremetal environment might not have configured the hardware.
+ "-Xclang -target-feature",
+ "-Xclang -sve",
+ ],
+ },
+ },
defaults_visibility: ["//visibility:public"],
}
diff --git a/android/config.go b/android/config.go
index e2fc756..1e51840 100644
--- a/android/config.go
+++ b/android/config.go
@@ -318,6 +318,9 @@
AndroidCommonTarget Target // the Target for common modules for the Android device
AndroidFirstDeviceTarget Target // the first Target for modules for the Android device
+ // Flags for Partial Compile, derived from SOONG_PARTIAL_COMPILE.
+ partialCompileFlags partialCompileFlags
+
// multilibConflicts for an ArchType is true if there is earlier configured
// device architecture with the same multilib value.
multilibConflicts map[ArchType]bool
@@ -367,6 +370,16 @@
ensureAllowlistIntegrity bool
}
+type partialCompileFlags struct {
+ // Is partial compilation enabled at all?
+ enabled bool
+
+ // Whether to use d8 instead of r8
+ use_d8 bool
+
+ // Add others as needed.
+}
+
type deviceConfig struct {
config *config
OncePer
@@ -376,6 +389,88 @@
SetDefaultConfig()
}
+// Parse SOONG_PARTIAL_COMPILE.
+//
+// SOONG_PARTIAL_COMPILE determines which features are enabled or disabled in
+// rule generation. Changing this environment variable causes reanalysis.
+//
+// SOONG_USE_PARTIAL_COMPILE determines whether or not we **use** PARTIAL_COMPILE.
+// Rule generation must support both cases, since changing it does not cause
+// reanalysis.
+//
+// The user-facing documentation shows:
+//
+// - empty or not set: "The current default state"
+// - "true" or "on": enable all stable partial compile features.
+// - "false" or "off": disable partial compile completely.
+//
+// What we actually allow is a comma separated list of tokens, whose first
+// character may be "+" (enable) or "-" (disable). If neither is present, "+"
+// is assumed. For example, "on,+use_d8" will enable partial compilation, and
+// additionally set the use_d8 flag (regardless of whether it is opt-in or
+// opt-out).
+//
+// To add a new feature to the list, add the field in the struct
+// `partialCompileFlags` above, and then add the name of the field in the
+// switch statement below.
+func (c *config) parsePartialCompileFlags() (partialCompileFlags, error) {
+ defaultFlags := partialCompileFlags{
+ // Set any opt-out flags here. Opt-in flags are off by default.
+ enabled: false,
+ }
+ value := c.Getenv("SOONG_PARTIAL_COMPILE")
+
+ if value == "" {
+ return defaultFlags, nil
+ }
+
+ ret := defaultFlags
+ tokens := strings.Split(strings.ToLower(value), ",")
+ makeVal := func(state string, defaultValue bool) bool {
+ switch state {
+ case "":
+ return defaultValue
+ case "-":
+ return false
+ case "+":
+ return true
+ }
+ return false
+ }
+ for _, tok := range tokens {
+ var state string
+ if len(tok) == 0 {
+ continue
+ }
+ switch tok[0:1] {
+ case "":
+ // Ignore empty tokens.
+ continue
+ case "-", "+":
+ state = tok[0:1]
+ tok = tok[1:]
+ default:
+ // Treat `feature` as `+feature`.
+ state = "+"
+ }
+ switch tok {
+ case "true":
+ ret = defaultFlags
+ ret.enabled = true
+ case "false":
+ // Set everything to false.
+ ret = partialCompileFlags{}
+ case "enabled":
+ ret.enabled = makeVal(state, defaultFlags.enabled)
+ case "use_d8":
+ ret.use_d8 = makeVal(state, defaultFlags.use_d8)
+ default:
+ return partialCompileFlags{}, fmt.Errorf("Unknown SOONG_PARTIAL_COMPILE value: %v", value)
+ }
+ }
+ return ret, nil
+}
+
func loadConfig(config *config) error {
return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName))
}
@@ -562,6 +657,11 @@
return Config{}, err
}
+ config.partialCompileFlags, err = config.parsePartialCompileFlags()
+ if err != nil {
+ return Config{}, err
+ }
+
// Make the CommonOS OsType available for all products.
targets[CommonOS] = []Target{commonTargetMap[CommonOS.Name]}
@@ -992,6 +1092,10 @@
return ApiLevelOrPanic(ctx, codename)
}
+func (c *config) PartialCompileFlags() partialCompileFlags {
+ return c.partialCompileFlags
+}
+
func (c *config) AppsDefaultVersionName() string {
return String(c.productVariables.AppsDefaultVersionName)
}
@@ -1413,6 +1517,10 @@
return "vendor"
}
+func (c *deviceConfig) BuildingVendorImage() bool {
+ return proptools.Bool(c.config.productVariables.BuildingVendorImage)
+}
+
func (c *deviceConfig) CurrentApiLevelForVendorModules() string {
return StringDefault(c.config.productVariables.DeviceCurrentApiLevelForVendorModules, "current")
}
@@ -1443,6 +1551,10 @@
return "product"
}
+func (c *deviceConfig) BuildingProductImage() bool {
+ return proptools.Bool(c.config.productVariables.BuildingProductImage)
+}
+
func (c *deviceConfig) SystemExtPath() string {
if c.config.productVariables.SystemExtPath != nil {
return *c.config.productVariables.SystemExtPath
diff --git a/android/filegroup.go b/android/filegroup.go
index a8b4f00..67e5add1f 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -41,6 +41,14 @@
Exclude_srcs proptools.Configurable[[]string] `android:"path"`
+ // Sources the will be included in the filegroup, but any module dependencies will be added
+ // using the device os and the device's first architecture's variant.
+ Device_first_srcs proptools.Configurable[[]string] `android:"path_device_first"`
+
+ // Sources the will be included in the filegroup, but any module dependencies will be added
+ // using the device os and the common architecture's variant.
+ Device_common_srcs proptools.Configurable[[]string] `android:"path_device_common"`
+
// The base path to the files. May be used by other modules to determine which portion
// of the path to use. For example, when a filegroup is used as data in a cc_test rule,
// the base path is stripped off the path and the remaining path is used as the
@@ -90,11 +98,13 @@
}
func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
- fg.srcs = PathsForModuleSrcExcludes(ctx, fg.properties.Srcs.GetOrDefault(ctx, nil), fg.properties.Exclude_srcs.GetOrDefault(ctx, nil))
+ srcs := PathsForModuleSrcExcludes(ctx, fg.properties.Srcs.GetOrDefault(ctx, nil), fg.properties.Exclude_srcs.GetOrDefault(ctx, nil))
+ srcs = append(srcs, PathsForModuleSrc(ctx, fg.properties.Device_first_srcs.GetOrDefault(ctx, nil))...)
+ srcs = append(srcs, PathsForModuleSrc(ctx, fg.properties.Device_common_srcs.GetOrDefault(ctx, nil))...)
if fg.properties.Path != nil {
- fg.srcs = PathsWithModuleSrcSubDir(ctx, fg.srcs, String(fg.properties.Path))
+ srcs = PathsWithModuleSrcSubDir(ctx, srcs, String(fg.properties.Path))
}
- SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: fg.srcs.Strings()})
+ SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()})
var aconfigDeclarations []string
var intermediateCacheOutputPaths Paths
@@ -108,6 +118,8 @@
maps.Copy(modeInfos, dep.ModeInfos)
}
})
+
+ fg.srcs = srcs
SetProvider(ctx, CodegenInfoProvider, CodegenInfo{
AconfigDeclarations: aconfigDeclarations,
IntermediateCacheOutputPaths: intermediateCacheOutputPaths,
diff --git a/android/image.go b/android/image.go
index 6e5a551..012267a 100644
--- a/android/image.go
+++ b/android/image.go
@@ -14,44 +14,61 @@
package android
+type ImageInterfaceContext interface {
+ ArchModuleContext
+
+ Module() Module
+
+ ModuleErrorf(fmt string, args ...interface{})
+ PropertyErrorf(property, fmt string, args ...interface{})
+
+ DeviceSpecific() bool
+ SocSpecific() bool
+ ProductSpecific() bool
+ SystemExtSpecific() bool
+ Platform() bool
+
+ Config() Config
+}
+
// ImageInterface is implemented by modules that need to be split by the imageTransitionMutator.
type ImageInterface interface {
// ImageMutatorBegin is called before any other method in the ImageInterface.
- ImageMutatorBegin(ctx BaseModuleContext)
+ ImageMutatorBegin(ctx ImageInterfaceContext)
// VendorVariantNeeded should return true if the module needs a vendor variant (installed on the vendor image).
- VendorVariantNeeded(ctx BaseModuleContext) bool
+ VendorVariantNeeded(ctx ImageInterfaceContext) bool
// ProductVariantNeeded should return true if the module needs a product variant (installed on the product image).
- ProductVariantNeeded(ctx BaseModuleContext) bool
+ ProductVariantNeeded(ctx ImageInterfaceContext) bool
// CoreVariantNeeded should return true if the module needs a core variant (installed on the system image).
- CoreVariantNeeded(ctx BaseModuleContext) bool
+ CoreVariantNeeded(ctx ImageInterfaceContext) bool
// RamdiskVariantNeeded should return true if the module needs a ramdisk variant (installed on the
// ramdisk partition).
- RamdiskVariantNeeded(ctx BaseModuleContext) bool
+ RamdiskVariantNeeded(ctx ImageInterfaceContext) bool
// VendorRamdiskVariantNeeded should return true if the module needs a vendor ramdisk variant (installed on the
// vendor ramdisk partition).
- VendorRamdiskVariantNeeded(ctx BaseModuleContext) bool
+ VendorRamdiskVariantNeeded(ctx ImageInterfaceContext) bool
// DebugRamdiskVariantNeeded should return true if the module needs a debug ramdisk variant (installed on the
// debug ramdisk partition: $(PRODUCT_OUT)/debug_ramdisk).
- DebugRamdiskVariantNeeded(ctx BaseModuleContext) bool
+ DebugRamdiskVariantNeeded(ctx ImageInterfaceContext) bool
// RecoveryVariantNeeded should return true if the module needs a recovery variant (installed on the
// recovery partition).
- RecoveryVariantNeeded(ctx BaseModuleContext) bool
+ RecoveryVariantNeeded(ctx ImageInterfaceContext) bool
// ExtraImageVariations should return a list of the additional variations needed for the module. After the
// variants are created the SetImageVariation method will be called on each newly created variant with the
// its variation.
- ExtraImageVariations(ctx BaseModuleContext) []string
+ ExtraImageVariations(ctx ImageInterfaceContext) []string
// SetImageVariation is called for each newly created image variant. The receiver is the original
// module, "variation" is the name of the newly created variant. "variation" is set on the receiver.
- SetImageVariation(ctx BaseModuleContext, variation string)
+ SetImageVariation(ctx ImageInterfaceContext, variation string)
}
const (
diff --git a/android/neverallow.go b/android/neverallow.go
index 439fe2d..57373d5 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -62,6 +62,7 @@
AddNeverAllowRules(createLimitNdkExportRule()...)
AddNeverAllowRules(createLimitDirgroupRule()...)
AddNeverAllowRules(createFilesystemIsAutoGeneratedRule())
+ AddNeverAllowRules(createKotlinPluginRule()...)
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -302,6 +303,22 @@
Because("is_auto_generated property is only allowed for filesystem modules in build/soong/fsgen directory")
}
+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",
+ }
+
+ return []Rule{
+ NeverAllow().
+ NotIn(kotlinPluginProjectsAllowedList...).
+ ModuleType("kotlin_plugin").
+ Because("kotlin_plugin can only be used in allowed projects"),
+ }
+}
+
func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module)
if !ok {
diff --git a/android/packaging.go b/android/packaging.go
index d615871..b505964 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -377,7 +377,17 @@
if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) {
continue
}
- ctx.AddFarVariationDependencies(t.Variations(), depTag, dep)
+ targetVariation := t.Variations()
+ sharedVariation := blueprint.Variation{
+ Mutator: "link",
+ Variation: "shared",
+ }
+ // If a shared variation exists, use that. Static variants do not provide any standalone files
+ // for packaging.
+ if ctx.OtherModuleFarDependencyVariantExists([]blueprint.Variation{sharedVariation}, dep) {
+ targetVariation = append(targetVariation, sharedVariation)
+ }
+ ctx.AddFarVariationDependencies(targetVariation, depTag, dep)
}
}
}
diff --git a/android/packaging_test.go b/android/packaging_test.go
index f5b1020..9c6760c 100644
--- a/android/packaging_test.go
+++ b/android/packaging_test.go
@@ -64,7 +64,7 @@
ModuleBase
PackagingBase
properties struct {
- Install_deps []string `android:`
+ Install_deps []string
}
entries []string
}
diff --git a/android/path_properties.go b/android/path_properties.go
index d80a8ed..8ada133 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -18,6 +18,7 @@
"fmt"
"reflect"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -38,20 +39,32 @@
// squashed into the real modules.
return
}
+ if !ctx.Module().Enabled(ctx) {
+ return
+ }
props := ctx.Module().base().GetProperties()
addPathDepsForProps(ctx, props)
}
func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) {
// Iterate through each property struct of the module extracting the contents of all properties
- // tagged with `android:"path"`.
+ // tagged with `android:"path"` or one of the variant-specifying tags.
var pathProperties []string
+ var pathDeviceFirstProperties []string
+ var pathDeviceCommonProperties []string
+ var pathCommonOsProperties []string
for _, ps := range props {
- pathProperties = append(pathProperties, pathPropertiesForPropertyStruct(ctx, ps)...)
+ pathProperties = append(pathProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path")...)
+ pathDeviceFirstProperties = append(pathDeviceFirstProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first")...)
+ pathDeviceCommonProperties = append(pathDeviceCommonProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_common")...)
+ pathCommonOsProperties = append(pathCommonOsProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_common_os")...)
}
// Remove duplicates to avoid multiple dependencies.
pathProperties = FirstUniqueStrings(pathProperties)
+ pathDeviceFirstProperties = FirstUniqueStrings(pathDeviceFirstProperties)
+ pathDeviceCommonProperties = FirstUniqueStrings(pathDeviceCommonProperties)
+ pathCommonOsProperties = FirstUniqueStrings(pathCommonOsProperties)
// Add dependencies to anything that is a module reference.
for _, s := range pathProperties {
@@ -59,12 +72,35 @@
ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m)
}
}
+ // For properties tagged "path_device_first", use the first arch device variant when adding
+ // dependencies. This allows host modules to have some properties that add dependencies on
+ // device modules.
+ for _, s := range pathDeviceFirstProperties {
+ if m, t := SrcIsModuleWithTag(s); m != "" {
+ ctx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), sourceOrOutputDepTag(m, t), m)
+ }
+ }
+ // properties tagged "path_device_common" get the device common variant
+ for _, s := range pathDeviceCommonProperties {
+ if m, t := SrcIsModuleWithTag(s); m != "" {
+ ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), sourceOrOutputDepTag(m, t), m)
+ }
+ }
+ // properties tagged "path_device_common" get the device common variant
+ for _, s := range pathCommonOsProperties {
+ if m, t := SrcIsModuleWithTag(s); m != "" {
+ ctx.AddVariationDependencies([]blueprint.Variation{
+ {Mutator: "os", Variation: "common_os"},
+ {Mutator: "arch", Variation: ""},
+ }, sourceOrOutputDepTag(m, t), m)
+ }
+ }
}
-// pathPropertiesForPropertyStruct uses the indexes of properties that are tagged with
-// android:"path" to extract all their values from a property struct, returning them as a single
+// taggedPropertiesForPropertyStruct uses the indexes of properties that are tagged with
+// android:"tagValue" to extract all their values from a property struct, returning them as a single
// slice of strings.
-func pathPropertiesForPropertyStruct(ctx BottomUpMutatorContext, ps interface{}) []string {
+func taggedPropertiesForPropertyStruct(ctx BottomUpMutatorContext, ps interface{}, tagValue string) []string {
v := reflect.ValueOf(ps)
if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
panic(fmt.Errorf("type %s is not a pointer to a struct", v.Type()))
@@ -79,7 +115,7 @@
v = v.Elem()
// Get or create the list of indexes of properties that are tagged with `android:"path"`.
- pathPropertyIndexes := pathPropertyIndexesForPropertyStruct(ps)
+ pathPropertyIndexes := taggedPropertyIndexesForPropertyStruct(ps, tagValue)
var ret []string
@@ -172,12 +208,20 @@
var pathPropertyIndexesCache OncePer
-// pathPropertyIndexesForPropertyStruct returns a list of all of the indexes of properties in
-// property struct type that are tagged with `android:"path"`. Each index is a []int suitable for
-// passing to reflect.Value.FieldByIndex. The value is cached in a global cache by type.
-func pathPropertyIndexesForPropertyStruct(ps interface{}) [][]int {
- key := NewCustomOnceKey(reflect.TypeOf(ps))
+// taggedPropertyIndexesForPropertyStruct returns a list of all of the indexes of properties in
+// property struct type that are tagged with `android:"tagValue"`. Each index is a []int suitable
+// for passing to reflect.Value.FieldByIndex. The value is cached in a global cache by type and
+// tagValue.
+func taggedPropertyIndexesForPropertyStruct(ps interface{}, tagValue string) [][]int {
+ type pathPropertyIndexesOnceKey struct {
+ propStructType reflect.Type
+ tagValue string
+ }
+ key := NewCustomOnceKey(pathPropertyIndexesOnceKey{
+ propStructType: reflect.TypeOf(ps),
+ tagValue: tagValue,
+ })
return pathPropertyIndexesCache.Once(key, func() interface{} {
- return proptools.PropertyIndexesWithTag(ps, "android", "path")
+ return proptools.PropertyIndexesWithTag(ps, "android", tagValue)
}).([][]int)
}
diff --git a/android/variable.go b/android/variable.go
index 73c0d0e..13d5f05 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -337,10 +337,12 @@
HWASanIncludePaths []string `json:",omitempty"`
HWASanExcludePaths []string `json:",omitempty"`
- VendorPath *string `json:",omitempty"`
- OdmPath *string `json:",omitempty"`
- ProductPath *string `json:",omitempty"`
- SystemExtPath *string `json:",omitempty"`
+ VendorPath *string `json:",omitempty"`
+ BuildingVendorImage *bool `json:",omitempty"`
+ OdmPath *string `json:",omitempty"`
+ ProductPath *string `json:",omitempty"`
+ BuildingProductImage *bool `json:",omitempty"`
+ SystemExtPath *string `json:",omitempty"`
ClangTidy *bool `json:",omitempty"`
TidyChecks *string `json:",omitempty"`
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 68978b2..bf4158c 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -11342,7 +11342,7 @@
}
filegroup {
name: "qux-filegroup",
- srcs: [
+ device_common_srcs: [
":qux-lib{.generated_srcjars}",
],
}
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 8679821..3b7073e 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -109,41 +109,41 @@
var _ android.ImageInterface = (*bpf)(nil)
-func (bpf *bpf) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (bpf *bpf) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
-func (bpf *bpf) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
return proptools.Bool(bpf.properties.Vendor)
}
-func (bpf *bpf) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (bpf *bpf) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
return !proptools.Bool(bpf.properties.Vendor)
}
-func (bpf *bpf) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (bpf *bpf) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (bpf *bpf) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (bpf *bpf) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (bpf *bpf) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (bpf *bpf) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (bpf *bpf) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
return nil
}
-func (bpf *bpf) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (bpf *bpf) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
bpf.properties.VendorInternal = variation == "vendor"
}
diff --git a/bpf/libbpf/libbpf_prog.go b/bpf/libbpf/libbpf_prog.go
index ac61510..0ca7af1 100644
--- a/bpf/libbpf/libbpf_prog.go
+++ b/bpf/libbpf/libbpf_prog.go
@@ -104,41 +104,41 @@
var _ android.ImageInterface = (*libbpfProg)(nil)
-func (libbpf *libbpfProg) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (libbpf *libbpfProg) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
-func (libbpf *libbpfProg) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (libbpf *libbpfProg) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (libbpf *libbpfProg) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
return true
}
-func (libbpf *libbpfProg) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (libbpf *libbpfProg) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (libbpf *libbpfProg) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (libbpf *libbpfProg) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (libbpf *libbpfProg) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (libbpf *libbpfProg) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (libbpf *libbpfProg) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
return nil
}
-func (libbpf *libbpfProg) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (libbpf *libbpfProg) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
}
func (libbpf *libbpfProg) DepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/bpf/libbpf/libbpf_prog_test.go b/bpf/libbpf/libbpf_prog_test.go
index f4f5167..7f3653d 100644
--- a/bpf/libbpf/libbpf_prog_test.go
+++ b/bpf/libbpf/libbpf_prog_test.go
@@ -47,6 +47,7 @@
cc_test {
name: "vts_test_binary_bpf_module",
+ compile_multilib: "first",
srcs: ["BpfTest.cpp"],
data: [":bpf.o"],
gtest: false,
diff --git a/cc/cc.go b/cc/cc.go
index 9c514ee..52bf669 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -119,9 +119,10 @@
ObjFiles []string
- GeneratedSources []string
- GeneratedHeaders []string
- GeneratedDeps []string
+ GeneratedSources []string
+ GeneratedHeaders []string
+ DeviceFirstGeneratedHeaders []string
+ GeneratedDeps []string
ReexportGeneratedHeaders []string
@@ -2609,6 +2610,11 @@
actx.AddDependency(c, depTag, gen)
}
+ for _, gen := range deps.DeviceFirstGeneratedHeaders {
+ depTag := genHeaderDepTag
+ actx.AddVariationDependencies(ctx.Config().AndroidFirstDeviceTarget.Variations(), depTag, gen)
+ }
+
crtVariations := GetCrtVariations(ctx, c)
actx.AddVariationDependencies(crtVariations, objDepTag, deps.ObjFiles...)
for _, crt := range deps.CrtBegin {
diff --git a/cc/cc_test.go b/cc/cc_test.go
index a479cb3..90ec811 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -20,6 +20,7 @@
"reflect"
"regexp"
"runtime"
+ "slices"
"strings"
"testing"
@@ -2733,6 +2734,11 @@
func TestIncludeDirectoryOrdering(t *testing.T) {
t.Parallel()
+
+ expectedPlatformFlags := []string{
+ "-nostdlibinc",
+ }
+
baseExpectedFlags := []string{
"${config.ArmThumbCflags}",
"${config.ArmCflags}",
@@ -2742,10 +2748,18 @@
"${config.ArmToolchainCflags}",
"${config.ArmArmv7ANeonCflags}",
"${config.ArmGenericCflags}",
+ }
+
+ expectedTargetNDKFlags := []string{
"-target",
"armv7a-linux-androideabi21",
}
+ expectedTargetPlatformFlags := []string{
+ "-target",
+ "armv7a-linux-androideabi10000",
+ }
+
expectedIncludes := []string{
"external/foo/android_arm_export_include_dirs",
"external/foo/lib32_export_include_dirs",
@@ -2773,6 +2787,9 @@
"external/foo/libarm",
"external/foo/lib32",
"external/foo/libandroid_arm",
+ }
+
+ expectedNDKSTLIncludes := []string{
"defaults/cc/common/ndk_libc++_shared_include_dirs",
}
@@ -2783,38 +2800,92 @@
cstd := []string{"-std=gnu17", "-std=conly"}
cppstd := []string{"-std=gnu++20", "-std=cpp", "-fno-rtti"}
- lastIncludes := []string{
- "out/soong/ndk/sysroot/usr/include",
- "out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
+ lastNDKFlags := []string{
+ "--sysroot",
+ "out/soong/ndk/sysroot",
}
- combineSlices := func(slices ...[]string) []string {
- var ret []string
- for _, s := range slices {
- ret = append(ret, s...)
- }
- return ret
+ lastPlatformIncludes := []string{
+ "${config.CommonGlobalIncludes}",
}
testCases := []struct {
- name string
- src string
- expected []string
+ name string
+ src string
+ expectedNDK []string
+ expectedPlatform []string
}{
{
- name: "c",
- src: "foo.c",
- expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
+ name: "c",
+ src: "foo.c",
+ expectedNDK: slices.Concat(
+ baseExpectedFlags,
+ expectedTargetNDKFlags,
+ conly,
+ expectedIncludes,
+ expectedNDKSTLIncludes,
+ cflags,
+ cstd,
+ lastNDKFlags,
+ []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
+ ),
+ expectedPlatform: slices.Concat(
+ expectedPlatformFlags,
+ baseExpectedFlags,
+ expectedTargetPlatformFlags,
+ conly,
+ expectedIncludes,
+ cflags,
+ cstd,
+ lastPlatformIncludes,
+ []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
+ ),
},
{
- name: "cc",
- src: "foo.cc",
- expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
+ name: "cc",
+ src: "foo.cc",
+ expectedNDK: slices.Concat(
+ baseExpectedFlags,
+ expectedTargetNDKFlags,
+ cppOnly,
+ expectedIncludes,
+ expectedNDKSTLIncludes,
+ cflags,
+ cppstd,
+ lastNDKFlags,
+ []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
+ ),
+ expectedPlatform: slices.Concat(
+ expectedPlatformFlags,
+ baseExpectedFlags,
+ expectedTargetPlatformFlags,
+ cppOnly,
+ expectedIncludes,
+ cflags,
+ cppstd,
+ lastPlatformIncludes,
+ []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"},
+ ),
},
{
- name: "assemble",
- src: "foo.s",
- expected: combineSlices(baseExpectedFlags, []string{"${config.CommonGlobalAsflags}"}, expectedIncludes, lastIncludes),
+ name: "assemble",
+ src: "foo.s",
+ expectedNDK: slices.Concat(
+ baseExpectedFlags,
+ expectedTargetNDKFlags,
+ []string{"${config.CommonGlobalAsflags}"},
+ expectedIncludes,
+ expectedNDKSTLIncludes,
+ lastNDKFlags,
+ ),
+ expectedPlatform: slices.Concat(
+ expectedPlatformFlags,
+ baseExpectedFlags,
+ expectedTargetPlatformFlags,
+ []string{"${config.CommonGlobalAsflags}"},
+ expectedIncludes,
+ lastPlatformIncludes,
+ ),
},
}
@@ -2909,25 +2980,34 @@
`, lib, lib)
}
- ctx := android.GroupFixturePreparers(
- PrepareForIntegrationTestWithCc,
- android.FixtureAddTextFile("external/foo/Android.bp", bp),
- ).RunTest(t)
- cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
+ runTest := func(t *testing.T, variant string, expected []string) {
+ ctx := android.GroupFixturePreparers(
+ PrepareForIntegrationTestWithCc,
+ android.FixtureAddTextFile("external/foo/Android.bp", bp),
+ ).RunTest(t)
+ cflags := ctx.ModuleForTests("libfoo", variant).Output("obj/external/foo/foo.o").Args["cFlags"]
- var includes []string
- flags := strings.Split(cflags, " ")
- for _, flag := range flags {
- if strings.HasPrefix(flag, "-I") {
- includes = append(includes, strings.TrimPrefix(flag, "-I"))
- } else if flag == "-isystem" {
- // skip isystem, include next
- } else if len(flag) > 0 {
- includes = append(includes, flag)
+ var includes []string
+ flags := strings.Split(cflags, " ")
+ for _, flag := range flags {
+ if strings.HasPrefix(flag, "-I") {
+ includes = append(includes, strings.TrimPrefix(flag, "-I"))
+ } else if flag == "-isystem" {
+ // skip isystem, include next
+ } else if len(flag) > 0 {
+ includes = append(includes, flag)
+ }
}
+
+ android.AssertArrayString(t, "includes", expected, includes)
}
- android.AssertArrayString(t, "includes", tc.expected, includes)
+ t.Run("platform", func(t *testing.T) {
+ runTest(t, "android_arm_armv7-a-neon_static", tc.expectedPlatform)
+ })
+ t.Run("ndk", func(t *testing.T) {
+ runTest(t, "android_arm_armv7-a-neon_sdk_static", tc.expectedNDK)
+ })
})
}
diff --git a/cc/compiler.go b/cc/compiler.go
index 7bba962..f06287c 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -100,6 +100,11 @@
// of genrule modules.
Generated_headers proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
+ // Same as generated_headers, but the dependencies will be added based on the first supported
+ // arch variant and the device os variant. This can be useful for creating a host tool that
+ // embeds a copy of a device tool, that it then extracts and pushes to a device at runtime.
+ Device_first_generated_headers proptools.Configurable[[]string] `android:"arch_variant,variant_prepend"`
+
// pass -frtti instead of -fno-rtti
Rtti *bool `android:"arch_variant"`
@@ -294,6 +299,7 @@
deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
deps.GeneratedSources = removeListFromList(deps.GeneratedSources, compiler.Properties.Exclude_generated_sources)
deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers.GetOrDefault(ctx, nil)...)
+ deps.DeviceFirstGeneratedHeaders = append(deps.DeviceFirstGeneratedHeaders, compiler.Properties.Device_first_generated_headers.GetOrDefault(ctx, nil)...)
deps.AidlLibs = append(deps.AidlLibs, compiler.Properties.Aidl.Libs...)
android.ProtoDeps(ctx, &compiler.Proto)
@@ -430,14 +436,14 @@
}
if ctx.useSdk() {
- // TODO: Switch to --sysroot.
// The NDK headers are installed to a common sysroot. While a more
// typical Soong approach would be to only make the headers for the
// library you're using available, we're trying to emulate the NDK
// behavior here, and the NDK always has all the NDK headers available.
flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
- "-isystem "+getCurrentIncludePath(ctx).String(),
- "-isystem "+getCurrentIncludePath(ctx).Join(ctx, config.NDKTriple(tc)).String())
+ "--sysroot "+getNdkSysrootBase(ctx).String())
+ } else if ctx.Device() {
+ flags.Global.CommonFlags = append(flags.Global.CFlags, "-nostdlibinc")
}
if ctx.InVendorOrProduct() {
diff --git a/cc/config/global.go b/cc/config/global.go
index 9d3de6d..d63f86d 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -172,7 +172,6 @@
"-Werror=address",
"-Werror=sequence-point",
"-Werror=format-security",
- "-nostdlibinc",
}
commonGlobalLldflags = []string{
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 0aa9d4b..cbe139f 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -182,9 +182,13 @@
}
func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
- subdir := "lib"
- if ctx.inVendor() {
+ var subdir string
+ if ctx.isForPlatform() {
+ subdir = "lib"
+ } else if ctx.inVendor() {
subdir = "lib/vendor"
+ } else {
+ ctx.ModuleErrorf("Fuzzer must be system or vendor variant")
}
flags = fuzz.binaryDecorator.linkerFlags(ctx, flags)
@@ -347,6 +351,7 @@
func PackageFuzzModule(ctx android.ModuleContext, fuzzPackagedModule fuzz.FuzzPackagedModule, pctx android.PackageContext) fuzz.FuzzPackagedModule {
fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Corpus)
+ fuzzPackagedModule.Corpus = append(fuzzPackagedModule.Corpus, android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Device_common_corpus)...)
fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzzPackagedModule.FuzzProperties.Data)
diff --git a/cc/genrule.go b/cc/genrule.go
index fe3b127..bd6c5f1 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -77,41 +77,41 @@
var _ android.ImageInterface = (*GenruleExtraProperties)(nil)
-func (g *GenruleExtraProperties) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (g *GenruleExtraProperties) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
-func (g *GenruleExtraProperties) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
return Bool(g.Vendor_available) || Bool(g.Odm_available) || ctx.SocSpecific() || ctx.DeviceSpecific()
}
-func (g *GenruleExtraProperties) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
return Bool(g.Product_available) || ctx.ProductSpecific()
}
-func (g *GenruleExtraProperties) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
return !(ctx.SocSpecific() || ctx.DeviceSpecific() || ctx.ProductSpecific())
}
-func (g *GenruleExtraProperties) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return Bool(g.Ramdisk_available)
}
-func (g *GenruleExtraProperties) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return Bool(g.Vendor_ramdisk_available)
}
-func (g *GenruleExtraProperties) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (g *GenruleExtraProperties) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (g *GenruleExtraProperties) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
// If the build is using a snapshot, the recovery variant under AOSP directories
// is not needed.
return Bool(g.Recovery_available)
}
-func (g *GenruleExtraProperties) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (g *GenruleExtraProperties) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
return nil
}
-func (g *GenruleExtraProperties) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (g *GenruleExtraProperties) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
}
diff --git a/cc/image.go b/cc/image.go
index 7594a08..ee40483 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -177,7 +177,7 @@
IsSnapshotPrebuilt() bool
// SnapshotVersion returns the snapshot version for this module.
- SnapshotVersion(mctx android.BaseModuleContext) string
+ SnapshotVersion(mctx android.ImageInterfaceContext) string
// SdkVersion returns the SDK version for this module.
SdkVersion() string
@@ -209,7 +209,7 @@
var _ ImageMutatableModule = (*Module)(nil)
-func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
+func (m *Module) ImageMutatorBegin(mctx android.ImageInterfaceContext) {
MutateImage(mctx, m)
}
@@ -273,7 +273,7 @@
m.Properties.VendorVariantNeeded = b
}
-func (m *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
+func (m *Module) SnapshotVersion(mctx android.ImageInterfaceContext) string {
if snapshot, ok := m.linker.(SnapshotInterface); ok {
return snapshot.Version()
} else {
@@ -291,7 +291,7 @@
}
// MutateImage handles common image mutations for ImageMutatableModule interfaces.
-func MutateImage(mctx android.BaseModuleContext, m ImageMutatableModule) {
+func MutateImage(mctx android.ImageInterfaceContext, m ImageMutatableModule) {
// Validation check
vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
productSpecific := mctx.ProductSpecific()
@@ -431,35 +431,35 @@
}
}
-func (c *Module) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
return c.Properties.VendorVariantNeeded
}
-func (c *Module) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
return c.Properties.ProductVariantNeeded
}
-func (c *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
return c.Properties.CoreVariantNeeded
}
-func (c *Module) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return c.Properties.RamdiskVariantNeeded
}
-func (c *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return c.Properties.VendorRamdiskVariantNeeded
}
-func (c *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (c *Module) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (c *Module) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
return c.Properties.RecoveryVariantNeeded
}
-func (c *Module) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (c *Module) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
return c.Properties.ExtraVersionedImageVariations
}
@@ -513,7 +513,7 @@
}
}
-func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string) {
+func (c *Module) SetImageVariation(ctx android.ImageInterfaceContext, variant string) {
if variant == android.RamdiskVariation {
c.MakeAsPlatform()
squashRamdiskSrcs(c)
diff --git a/cc/test.go b/cc/test.go
index f5bb761..ae73886 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -15,10 +15,11 @@
package cc
import (
- "github.com/google/blueprint/proptools"
"path/filepath"
"strconv"
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
"android/soong/tradefed"
)
@@ -82,6 +83,16 @@
// the test
Data []string `android:"path,arch_variant"`
+ // Same as data, but adds depedencies on modules using the device's os variant, and common
+ // architecture's variant. Can be useful to add device-built apps to the data of a host
+ // test.
+ Device_common_data []string `android:"path_device_common"`
+
+ // Same as data, but adds depedencies on modules using the device's os variant, and the device's
+ // first architecture's variant. Can be useful to add device-built apps to the data of a host
+ // test.
+ Device_first_data []string `android:"path_device_first"`
+
// list of shared library modules that should be installed alongside the test
Data_libs []string `android:"arch_variant"`
@@ -324,6 +335,8 @@
func (test *testBinary) install(ctx ModuleContext, file android.Path) {
dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
+ dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_common_data)...)
+ dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_first_data)...)
for _, dataSrcPath := range dataSrcPaths {
test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath})
diff --git a/etc/otacerts_zip.go b/etc/otacerts_zip.go
index b6f175a..d12bdac 100644
--- a/etc/otacerts_zip.go
+++ b/etc/otacerts_zip.go
@@ -61,41 +61,41 @@
var _ android.ImageInterface = (*otacertsZipModule)(nil)
-func (m *otacertsZipModule) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (m *otacertsZipModule) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
-func (m *otacertsZipModule) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (m *otacertsZipModule) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (m *otacertsZipModule) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
return !m.ModuleBase.InstallInRecovery()
}
-func (m *otacertsZipModule) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (m *otacertsZipModule) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (m *otacertsZipModule) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (m *otacertsZipModule) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (m *otacertsZipModule) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
return proptools.Bool(m.properties.Recovery_available) || m.ModuleBase.InstallInRecovery()
}
-func (m *otacertsZipModule) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (m *otacertsZipModule) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
return nil
}
-func (m *otacertsZipModule) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (m *otacertsZipModule) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
}
func (m *otacertsZipModule) InRecovery() bool {
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index fbe24d1..59712c0 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -236,30 +236,30 @@
var _ android.ImageInterface = (*PrebuiltEtc)(nil)
-func (p *PrebuiltEtc) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (p *PrebuiltEtc) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
-func (p *PrebuiltEtc) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (p *PrebuiltEtc) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
return !p.ModuleBase.InstallInRecovery() && !p.ModuleBase.InstallInRamdisk() &&
!p.ModuleBase.InstallInVendorRamdisk() && !p.ModuleBase.InstallInDebugRamdisk()
}
-func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return proptools.Bool(p.properties.Ramdisk_available) || p.ModuleBase.InstallInRamdisk()
}
-func (p *PrebuiltEtc) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return proptools.Bool(p.properties.Vendor_ramdisk_available) || p.ModuleBase.InstallInVendorRamdisk()
}
-func (p *PrebuiltEtc) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return proptools.Bool(p.properties.Debug_ramdisk_available) || p.ModuleBase.InstallInDebugRamdisk()
}
@@ -267,15 +267,15 @@
return proptools.Bool(p.rootProperties.Install_in_root)
}
-func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
return proptools.Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery()
}
-func (p *PrebuiltEtc) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (p *PrebuiltEtc) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
return nil
}
-func (p *PrebuiltEtc) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (p *PrebuiltEtc) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
}
func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path {
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index e796ab9..9d93925 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -75,7 +75,7 @@
// Path to the private key that avbtool will use to sign this filesystem image.
// TODO(jiyong): allow apex_key to be specified here
- Avb_private_key *string `android:"path"`
+ Avb_private_key *string `android:"path_device_first"`
// Hash and signing algorithm for avbtool. Default is SHA256_RSA4096.
Avb_algorithm *string
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 4bdd0a4..ca0a7f7 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -264,6 +264,9 @@
func (f *filesystem) filterInstallablePackagingSpec(ps android.PackagingSpec) bool {
// Filesystem module respects the installation semantic. A PackagingSpec from a module with
// IsSkipInstall() is skipped.
+ if proptools.Bool(f.properties.Is_auto_generated) { // TODO (spandandas): Remove this.
+ return !ps.SkipInstall() && (ps.Partition() == f.PartitionType())
+ }
return !ps.SkipInstall()
}
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 057dcaa..ab63550 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -584,3 +584,48 @@
android.AssertStringDoesContain(t, "erofs fs type compress hint", buildImageConfig, "erofs_default_compress_hints=compress_hints.txt")
android.AssertStringDoesContain(t, "erofs fs type sparse", buildImageConfig, "erofs_sparse_flag=-s")
}
+
+// If a system_ext/ module depends on system/ module, the dependency should *not*
+// be installed in system_ext/
+func TestDoNotPackageCrossPartitionDependencies(t *testing.T) {
+ t.Skip() // TODO (spandandas): Re-enable this
+ result := fixture.RunTestWithBp(t, `
+ android_filesystem {
+ name: "myfilesystem",
+ deps: ["binfoo"],
+ partition_type: "system_ext",
+ }
+
+ cc_binary {
+ name: "binfoo",
+ shared_libs: ["libfoo"],
+ system_ext_specific: true,
+ }
+ cc_library_shared {
+ name: "libfoo", // installed in system/
+ }
+ `)
+
+ partition := result.ModuleForTests("myfilesystem", "android_common")
+ fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList"))
+ android.AssertDeepEquals(t, "filesystem with dependencies on different partition", "bin/binfoo\n", fileList)
+}
+
+// If a cc_library is listed in `deps`, and it has a shared and static variant, then the shared variant
+// should be installed.
+func TestUseSharedVariationOfNativeLib(t *testing.T) {
+ result := fixture.RunTestWithBp(t, `
+ android_filesystem {
+ name: "myfilesystem",
+ deps: ["libfoo"],
+ }
+ // cc_library will create a static and shared variant.
+ cc_library {
+ name: "libfoo",
+ }
+ `)
+
+ partition := result.ModuleForTests("myfilesystem", "android_common")
+ fileList := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("fileList"))
+ android.AssertDeepEquals(t, "cc_library listed in deps", "lib64/libc++.so\nlib64/libc.so\nlib64/libdl.so\nlib64/libfoo.so\nlib64/libm.so\n", fileList)
+}
diff --git a/filesystem/fsverity_metadata.go b/filesystem/fsverity_metadata.go
index d7bb654..199c845 100644
--- a/filesystem/fsverity_metadata.go
+++ b/filesystem/fsverity_metadata.go
@@ -15,6 +15,7 @@
package filesystem
import (
+ "fmt"
"path/filepath"
"strings"
@@ -121,8 +122,13 @@
// STEP 2-2: generate BuildManifest.apk (unsigned)
aapt2Path := ctx.Config().HostToolPath(ctx, "aapt2")
- apkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", "BuildManifest.apk")
- idsigPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", "BuildManifest.apk.idsig")
+ apkNameSuffix := ""
+ if f.PartitionType() == "system_ext" {
+ //https://source.corp.google.com/h/googleplex-android/platform/build/+/e392d2b486c2d4187b20a72b1c67cc737ecbcca5:core/Makefile;l=3410;drc=ea8f34bc1d6e63656b4ec32f2391e9d54b3ebb6b;bpv=1;bpt=0
+ apkNameSuffix = "SystemExt"
+ }
+ apkPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk", apkNameSuffix))
+ idsigPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk.idsig", apkNameSuffix))
manifestTemplatePath := android.PathForSource(ctx, "system/security/fsverity/AndroidManifest.xml")
libs := android.PathsForModuleSrc(ctx, f.properties.Fsverity.Libs)
cmd.Implicit(aapt2Path)
diff --git a/filesystem/system_image.go b/filesystem/system_image.go
index 57239ae..7dbf986 100644
--- a/filesystem/system_image.go
+++ b/filesystem/system_image.go
@@ -103,6 +103,6 @@
// partition. Note that "apex" module installs its contents to "apex"(fake partition) as well
// for symbol lookup by imitating "activated" paths.
func (s *systemImage) filterPackagingSpec(ps android.PackagingSpec) bool {
- return s.filesystem.filterInstallablePackagingSpec(ps) &&
+ return !ps.SkipInstall() &&
(ps.Partition() == "system" || ps.Partition() == "root")
}
diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go
index 1d64796..51ba7c9 100644
--- a/filesystem/vbmeta.go
+++ b/filesystem/vbmeta.go
@@ -98,7 +98,7 @@
func vbmetaFactory() android.Module {
module := &vbmeta{}
module.AddProperties(&module.properties)
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
return module
}
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index 89db166..fde344b 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -101,6 +101,12 @@
if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
generatedPartitions = append(generatedPartitions, "system_ext")
}
+ if ctx.DeviceConfig().BuildingVendorImage() && ctx.DeviceConfig().VendorPath() == "vendor" {
+ generatedPartitions = append(generatedPartitions, "vendor")
+ }
+ if ctx.DeviceConfig().BuildingProductImage() && ctx.DeviceConfig().ProductPath() == "product" {
+ generatedPartitions = append(generatedPartitions, "product")
+ }
return &FsGenState{
depCandidates: candidates,
@@ -124,10 +130,19 @@
"public.libraries.android.txt": defaultDepCandidateProps(ctx.Config()),
"update_engine_sideload": defaultDepCandidateProps(ctx.Config()),
},
- "vendor": newMultilibDeps(),
- "odm": newMultilibDeps(),
- "product": newMultilibDeps(),
- "system_ext": newMultilibDeps(),
+ "vendor": newMultilibDeps(),
+ "odm": newMultilibDeps(),
+ "product": newMultilibDeps(),
+ "system_ext": &map[string]*depCandidateProps{
+ // VNDK apexes are automatically included.
+ // This hardcoded list will need to be updated if `PRODUCT_EXTRA_VNDK_VERSIONS` is updated.
+ // https://cs.android.com/android/_/android/platform/build/+/adba533072b00c53ac0f198c550a3cbd7a00e4cd:core/main.mk;l=984;bpv=1;bpt=0;drc=174db7b179592cf07cbfd2adb0119486fda911e7
+ "com.android.vndk.v30": defaultDepCandidateProps(ctx.Config()),
+ "com.android.vndk.v31": defaultDepCandidateProps(ctx.Config()),
+ "com.android.vndk.v32": defaultDepCandidateProps(ctx.Config()),
+ "com.android.vndk.v33": defaultDepCandidateProps(ctx.Config()),
+ "com.android.vndk.v34": defaultDepCandidateProps(ctx.Config()),
+ },
},
soongGeneratedPartitions: generatedPartitions,
fsDepsMutex: sync.Mutex{},
@@ -164,7 +179,7 @@
fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
m := mctx.Module()
- if slices.Contains(fsGenState.depCandidates, m.Name()) {
+ if m.Target().Os.Class == android.Device && slices.Contains(fsGenState.depCandidates, m.Name()) {
installPartition := m.PartitionTag(mctx.DeviceConfig())
fsGenState.fsDepsMutex.Lock()
// Only add the module as dependency when:
@@ -201,14 +216,6 @@
return fmt.Sprintf("//%s:%s", namespace, moduleName)
}
-// Returns the sorted unique list of module names with namespace, if the module specifies one.
-func fullyQualifiedModuleNames(modules multilibDeps) (ret []string) {
- for moduleName, moduleProp := range *modules {
- ret = append(ret, fullyQualifiedModuleName(moduleName, moduleProp.Namespace))
- }
- return android.SortedUniqueStrings(ret)
-}
-
func getBitness(archTypes []android.ArchType) (ret []string) {
for _, archType := range archTypes {
if archType.Multilib == "" {
@@ -226,43 +233,55 @@
soongGeneratedPartitionMap := getAllSoongGeneratedPartitionNames(mctx.Config(), fsGenState.soongGeneratedPartitions)
m := mctx.Module()
if partition, ok := soongGeneratedPartitionMap[m.Name()]; ok {
- depsStruct := packagingPropsStruct{}
- for depName, depProps := range *fsDeps[partition] {
- bitness := getBitness(depProps.Arch)
- fullyQualifiedDepName := fullyQualifiedModuleName(depName, depProps.Namespace)
- if android.InList("32", bitness) && android.InList("64", bitness) {
- // If both 32 and 64 bit variants are enabled for this module
- switch depProps.Multilib {
- case string(android.MultilibBoth):
- depsStruct.Multilib.Both.Deps = append(depsStruct.Multilib.Both.Deps, fullyQualifiedDepName)
- case string(android.MultilibCommon), string(android.MultilibFirst):
- depsStruct.Deps = append(depsStruct.Deps, fullyQualifiedDepName)
- case "32":
- depsStruct.Multilib.Lib32.Deps = append(depsStruct.Multilib.Lib32.Deps, fullyQualifiedDepName)
- case "64", "darwin_universal":
- depsStruct.Multilib.Lib64.Deps = append(depsStruct.Multilib.Lib64.Deps, fullyQualifiedDepName)
- case "prefer32", "first_prefer32":
- depsStruct.Multilib.Prefer32.Deps = append(depsStruct.Multilib.Prefer32.Deps, fullyQualifiedDepName)
- default:
- depsStruct.Multilib.Both.Deps = append(depsStruct.Multilib.Both.Deps, fullyQualifiedDepName)
- }
- } else if android.InList("64", bitness) {
- // If only 64 bit variant is enabled
- depsStruct.Multilib.Lib64.Deps = append(depsStruct.Multilib.Lib64.Deps, fullyQualifiedDepName)
- } else if android.InList("32", bitness) {
- // If only 32 bit variant is enabled
- depsStruct.Multilib.Lib32.Deps = append(depsStruct.Multilib.Lib32.Deps, fullyQualifiedDepName)
- } else {
- // If only common variant is enabled
- depsStruct.Multilib.Common.Deps = append(depsStruct.Multilib.Common.Deps, fullyQualifiedDepName)
- }
- }
- if err := proptools.AppendMatchingProperties(m.GetProperties(), &depsStruct, nil); err != nil {
+ depsStruct := generateDepStruct(*fsDeps[partition])
+ if err := proptools.AppendMatchingProperties(m.GetProperties(), depsStruct, nil); err != nil {
mctx.ModuleErrorf(err.Error())
}
}
}
+func generateDepStruct(deps map[string]*depCandidateProps) *packagingPropsStruct {
+ depsStruct := packagingPropsStruct{}
+ for depName, depProps := range deps {
+ bitness := getBitness(depProps.Arch)
+ fullyQualifiedDepName := fullyQualifiedModuleName(depName, depProps.Namespace)
+ if android.InList("32", bitness) && android.InList("64", bitness) {
+ // If both 32 and 64 bit variants are enabled for this module
+ switch depProps.Multilib {
+ case string(android.MultilibBoth):
+ depsStruct.Multilib.Both.Deps = append(depsStruct.Multilib.Both.Deps, fullyQualifiedDepName)
+ case string(android.MultilibCommon), string(android.MultilibFirst):
+ depsStruct.Deps = append(depsStruct.Deps, fullyQualifiedDepName)
+ case "32":
+ depsStruct.Multilib.Lib32.Deps = append(depsStruct.Multilib.Lib32.Deps, fullyQualifiedDepName)
+ case "64", "darwin_universal":
+ depsStruct.Multilib.Lib64.Deps = append(depsStruct.Multilib.Lib64.Deps, fullyQualifiedDepName)
+ case "prefer32", "first_prefer32":
+ depsStruct.Multilib.Prefer32.Deps = append(depsStruct.Multilib.Prefer32.Deps, fullyQualifiedDepName)
+ default:
+ depsStruct.Multilib.Both.Deps = append(depsStruct.Multilib.Both.Deps, fullyQualifiedDepName)
+ }
+ } else if android.InList("64", bitness) {
+ // If only 64 bit variant is enabled
+ depsStruct.Multilib.Lib64.Deps = append(depsStruct.Multilib.Lib64.Deps, fullyQualifiedDepName)
+ } else if android.InList("32", bitness) {
+ // If only 32 bit variant is enabled
+ depsStruct.Multilib.Lib32.Deps = append(depsStruct.Multilib.Lib32.Deps, fullyQualifiedDepName)
+ } else {
+ // If only common variant is enabled
+ depsStruct.Multilib.Common.Deps = append(depsStruct.Multilib.Common.Deps, fullyQualifiedDepName)
+ }
+ }
+ depsStruct.Deps = android.SortedUniqueStrings(depsStruct.Deps)
+ depsStruct.Multilib.Lib32.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Lib32.Deps)
+ depsStruct.Multilib.Lib64.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Lib64.Deps)
+ depsStruct.Multilib.Prefer32.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Prefer32.Deps)
+ depsStruct.Multilib.Both.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Both.Deps)
+ depsStruct.Multilib.Common.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Common.Deps)
+
+ return &depsStruct
+}
+
type filesystemCreatorProps struct {
Generated_partition_types []string `blueprint:"mutated"`
Unsupported_partition_types []string `blueprint:"mutated"`
@@ -327,35 +346,84 @@
if android.InList("system_ext", f.properties.Generated_partition_types) {
partitionProps.System_ext_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
}
+ if android.InList("vendor", f.properties.Generated_partition_types) {
+ partitionProps.Vendor_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor"))
+ }
+ if android.InList("product", f.properties.Generated_partition_types) {
+ partitionProps.Product_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "product"))
+ }
ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps)
}
-var (
- // https://source.corp.google.com/h/googleplex-android/platform/build/+/639d79f5012a6542ab1f733b0697db45761ab0f3:core/packaging/flags.mk;l=21;drc=5ba8a8b77507f93aa48cc61c5ba3f31a4d0cbf37;bpv=1;bpt=0
- partitionsWithAconfig = []string{"system", "product", "vendor"}
-)
+func partitionSpecificFsProps(fsProps *filesystem.FilesystemProperties, 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)
+ case "product":
+ fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
+ case "vendor":
+ fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
+ }
+}
// Creates a soong module to build the given partition. Returns false if we can't support building
// it.
func (f *filesystemCreator) createPartition(ctx android.LoadHookContext, partitionType string) bool {
- baseProps := &struct {
- Name *string
- Compile_multilib *string
- }{
- Name: proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)),
- Compile_multilib: proptools.StringPtr("both"),
+ baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)))
+
+ fsProps, supported := generateFsProps(ctx, partitionType)
+ if !supported {
+ return false
}
+ var module android.Module
+ if partitionType == "system" {
+ module = ctx.CreateModule(filesystem.SystemImageFactory, baseProps, fsProps)
+ } else {
+ // Explicitly set the partition.
+ fsProps.Partition_type = proptools.StringPtr(partitionType)
+ module = ctx.CreateModule(filesystem.FilesystemFactory, baseProps, fsProps)
+ }
+ module.HideFromMake()
+ return true
+}
+
+type filesystemBaseProperty struct {
+ Name *string
+ Compile_multilib *string
+}
+
+func generateBaseProps(namePtr *string) *filesystemBaseProperty {
+ return &filesystemBaseProperty{
+ Name: namePtr,
+ Compile_multilib: proptools.StringPtr("both"),
+ }
+}
+
+func generateFsProps(ctx android.EarlyModuleContext, partitionType string) (*filesystem.FilesystemProperties, bool) {
fsProps := &filesystem.FilesystemProperties{}
+ partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
+ specificPartitionVars := partitionVars.PartitionQualifiedVariables[partitionType]
+
+ // BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE
+ fsType := specificPartitionVars.BoardFileSystemType
+ if fsType == "" {
+ fsType = "ext4" //default
+ }
+ fsProps.Type = proptools.StringPtr(fsType)
+ if filesystem.GetFsTypeFromString(ctx, *fsProps.Type).IsUnknown() {
+ // Currently the android_filesystem module type only supports a handful of FS types like ext4, erofs
+ return nil, false
+ }
+
// Don't build this module on checkbuilds, the soong-built partitions are still in-progress
// and sometimes don't build.
fsProps.Unchecked_module = proptools.BoolPtr(true)
- partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
- specificPartitionVars := partitionVars.PartitionQualifiedVariables[partitionType]
-
// BOARD_AVB_ENABLE
fsProps.Use_avb = proptools.BoolPtr(partitionVars.BoardAvbEnable)
// BOARD_AVB_KEY_PATH
@@ -368,21 +436,9 @@
}
fsProps.Partition_name = proptools.StringPtr(partitionType)
- // BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE
- fsType := specificPartitionVars.BoardFileSystemType
- if fsType == "" {
- fsType = "ext4" //default
- }
- fsProps.Type = proptools.StringPtr(fsType)
- if filesystem.GetFsTypeFromString(ctx, *fsProps.Type).IsUnknown() {
- // Currently the android_filesystem module type only supports a handful of FS types like ext4, erofs
- return false
- }
fsProps.Base_dir = proptools.StringPtr(partitionType)
- fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(android.InList(partitionType, partitionsWithAconfig))
-
fsProps.Is_auto_generated = proptools.BoolPtr(true)
// Identical to that of the generic_system_image
@@ -395,6 +451,9 @@
"framework/*/*", // framework/{arch}
"framework/oat/*/*", // framework/oat/{arch}
}
+ fsProps.Fsverity.Libs = []string{":framework-res{.export-package.apk}"}
+
+ partitionSpecificFsProps(fsProps, partitionType)
// system_image properties that are not set:
// - filesystemProperties.Avb_hash_algorithm
@@ -406,18 +465,9 @@
// - filesystemProperties.Mount_point
// - filesystemProperties.Include_make_built_files
// - filesystemProperties.Build_logtags
- // - filesystemProperties.Fsverity.Libs
// - systemImageProperties.Linker_config_src
- var module android.Module
- if partitionType == "system" {
- module = ctx.CreateModule(filesystem.SystemImageFactory, baseProps, fsProps)
- } else {
- // Explicitly set the partition.
- fsProps.Partition_type = proptools.StringPtr(partitionType)
- module = ctx.CreateModule(filesystem.FilesystemFactory, baseProps, fsProps)
- }
- module.HideFromMake()
- return true
+
+ return fsProps, true
}
func (f *filesystemCreator) createDiffTest(ctx android.ModuleContext, partitionType string) android.Path {
@@ -475,9 +525,14 @@
}
f.HideFromMake()
- content := generateBpContent(ctx, "system")
- generatedBp := android.PathForOutput(ctx, "soong_generated_product_config.bp")
- android.WriteFileRule(ctx, generatedBp, content)
+ var content strings.Builder
+ generatedBp := android.PathForModuleOut(ctx, "soong_generated_product_config.bp")
+ for _, partition := range ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions {
+ content.WriteString(generateBpContent(ctx, partition))
+ content.WriteString("\n")
+ }
+ android.WriteFileRule(ctx, generatedBp, content.String())
+
ctx.Phony("product_config_to_bp", generatedBp)
var diffTestFiles []android.Path
@@ -494,27 +549,30 @@
ctx.Phony("soong_generated_filesystem_tests", diffTestFiles...)
}
-// TODO: assemble baseProps and fsProps here
func generateBpContent(ctx android.EarlyModuleContext, partitionType string) string {
- // Currently only system partition is supported
- if partitionType != "system" {
+ fsProps, fsTypeSupported := generateFsProps(ctx, partitionType)
+ if !fsTypeSupported {
return ""
}
- deps := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps
- depProps := &android.PackagingProperties{
- Deps: android.NewSimpleConfigurable(fullyQualifiedModuleNames(deps[partitionType])),
- }
+ baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)))
+ deps := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps[partitionType]
+ depProps := generateDepStruct(*deps)
- result, err := proptools.RepackProperties([]interface{}{depProps})
+ result, err := proptools.RepackProperties([]interface{}{baseProps, fsProps, depProps})
if err != nil {
ctx.ModuleErrorf(err.Error())
}
+ moduleType := "android_filesystem"
+ if partitionType == "system" {
+ moduleType = "android_system_image"
+ }
+
file := &parser.File{
Defs: []parser.Definition{
&parser.Module{
- Type: "module",
+ Type: moduleType,
Map: *result,
},
},
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index 42fd228..aa393a2 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -411,6 +411,11 @@
// Optional list of seed files to be installed to the fuzz target's output
// directory.
Corpus []string `android:"path"`
+
+ // Same as corpus, but adds dependencies on module references using the device's os variant
+ // and the common arch variant.
+ Device_common_corpus []string `android:"path_device_common"`
+
// Optional list of data files to be installed to the fuzz target's output
// directory. Directory structure relative to the module is preserved.
Data []string `android:"path"`
diff --git a/genrule/genrule.go b/genrule/genrule.go
index f2a761c..1ab1378 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -147,6 +147,18 @@
// list of input files
Srcs proptools.Configurable[[]string] `android:"path,arch_variant"`
+ // Same as srcs, but will add dependencies on modules via a device os variation and the device's
+ // first supported arch's variation. Can be used to add a dependency from a host genrule to
+ // a device module.
+ Device_first_srcs proptools.Configurable[[]string] `android:"path_device_first"`
+
+ // Same as srcs, but will add dependencies on modules via a device os variation and the common
+ // arch variation. Can be used to add a dependency from a host genrule to a device module.
+ Device_common_srcs proptools.Configurable[[]string] `android:"path_device_common"`
+
+ // Same as srcs, but will add dependencies on modules via a common_os os variation.
+ Common_os_srcs proptools.Configurable[[]string] `android:"path_common_os"`
+
// input files to exclude
Exclude_srcs []string `android:"path,arch_variant"`
@@ -289,7 +301,15 @@
// approach zero; there should be no genrule action registration done directly
// by Soong logic in the mixed-build case.
func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) {
- g.subName = ctx.ModuleSubDir()
+ // Add the variant as a suffix to the make modules to create, so that the make modules
+ // don't conflict because make doesn't know about variants. However, this causes issues with
+ // tracking required dependencies as the required property in soong is passed straight to make
+ // without accounting for these suffixes. To make it a little easier to work with, don't use
+ // a suffix for android_common variants so that java_genrules look like regular 1-variant
+ // genrules to make.
+ if ctx.ModuleSubDir() != "android_common" {
+ g.subName = ctx.ModuleSubDir()
+ }
if len(g.properties.Export_include_dirs) > 0 {
for _, dir := range g.properties.Export_include_dirs {
@@ -431,6 +451,9 @@
}
srcs := g.properties.Srcs.GetOrDefault(ctx, nil)
srcFiles := addLabelsForInputs("srcs", srcs, g.properties.Exclude_srcs)
+ srcFiles = append(srcFiles, addLabelsForInputs("device_first_srcs", g.properties.Device_first_srcs.GetOrDefault(ctx, nil), nil)...)
+ srcFiles = append(srcFiles, addLabelsForInputs("device_common_srcs", g.properties.Device_common_srcs.GetOrDefault(ctx, nil), nil)...)
+ srcFiles = append(srcFiles, addLabelsForInputs("common_os_srcs", g.properties.Common_os_srcs.GetOrDefault(ctx, nil), nil)...)
android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcFiles.Strings()})
var copyFrom android.Paths
@@ -723,16 +746,22 @@
type noopImageInterface struct{}
-func (x noopImageInterface) ImageMutatorBegin(android.BaseModuleContext) {}
-func (x noopImageInterface) VendorVariantNeeded(android.BaseModuleContext) bool { return false }
-func (x noopImageInterface) ProductVariantNeeded(android.BaseModuleContext) bool { return false }
-func (x noopImageInterface) CoreVariantNeeded(android.BaseModuleContext) bool { return false }
-func (x noopImageInterface) RamdiskVariantNeeded(android.BaseModuleContext) bool { return false }
-func (x noopImageInterface) VendorRamdiskVariantNeeded(android.BaseModuleContext) bool { return false }
-func (x noopImageInterface) DebugRamdiskVariantNeeded(android.BaseModuleContext) bool { return false }
-func (x noopImageInterface) RecoveryVariantNeeded(android.BaseModuleContext) bool { return false }
-func (x noopImageInterface) ExtraImageVariations(ctx android.BaseModuleContext) []string { return nil }
-func (x noopImageInterface) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (x noopImageInterface) ImageMutatorBegin(android.ImageInterfaceContext) {}
+func (x noopImageInterface) VendorVariantNeeded(android.ImageInterfaceContext) bool { return false }
+func (x noopImageInterface) ProductVariantNeeded(android.ImageInterfaceContext) bool { return false }
+func (x noopImageInterface) CoreVariantNeeded(android.ImageInterfaceContext) bool { return false }
+func (x noopImageInterface) RamdiskVariantNeeded(android.ImageInterfaceContext) bool { return false }
+func (x noopImageInterface) VendorRamdiskVariantNeeded(android.ImageInterfaceContext) bool {
+ return false
+}
+func (x noopImageInterface) DebugRamdiskVariantNeeded(android.ImageInterfaceContext) bool {
+ return false
+}
+func (x noopImageInterface) RecoveryVariantNeeded(android.ImageInterfaceContext) bool { return false }
+func (x noopImageInterface) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
+ return nil
+}
+func (x noopImageInterface) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
}
func NewGenSrcs() *Module {
diff --git a/java/aapt2.go b/java/aapt2.go
index 61cf373..bae4d1e 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -15,7 +15,9 @@
package java
import (
+ "fmt"
"path/filepath"
+ "regexp"
"sort"
"strconv"
"strings"
@@ -31,19 +33,35 @@
return strings.HasPrefix(lastDir, "values")
}
+func isFlagsPath(subDir string) bool {
+ re := regexp.MustCompile(`flag\(!?([a-zA-Z_-]+\.)*[a-zA-Z0-9_-]+\)`)
+ lastDir := filepath.Base(subDir)
+ return re.MatchString(lastDir)
+}
+
// Convert input resource file path to output file path.
// values-[config]/<file>.xml -> values-[config]_<file>.arsc.flat;
+// flag(fully.qualified.flag_name)/values-[config]/<file>.xml -> /values-[config]_<file>.(fully.qualified.flag_name).arsc.flat;
// For other resource file, just replace the last "/" with "_" and add .flat extension.
func pathToAapt2Path(ctx android.ModuleContext, res android.Path) android.WritablePath {
- name := res.Base()
+ extension := filepath.Ext(res.Base())
+ name := strings.TrimSuffix(res.Base(), extension)
if isPathValueResource(res) {
- name = strings.TrimSuffix(name, ".xml") + ".arsc"
+ extension = ".arsc"
}
subDir := filepath.Dir(res.String())
subDir, lastDir := filepath.Split(subDir)
- name = lastDir + "_" + name + ".flat"
- return android.PathForModuleOut(ctx, "aapt2", subDir, name)
+ if isFlagsPath(subDir) {
+ var flag string
+ subDir, flag = filepath.Split(filepath.Dir(subDir))
+ flag = strings.TrimPrefix(flag, "flag")
+ name = fmt.Sprintf("%s_%s.%s%s.flat", lastDir, name, flag, extension)
+ } else {
+ name = fmt.Sprintf("%s_%s%s.flat", lastDir, name, extension)
+ }
+ out := android.PathForModuleOut(ctx, "aapt2", subDir, name)
+ return out
}
// pathsToAapt2Paths Calls pathToAapt2Path on each entry of the given Paths, i.e. []Path.
diff --git a/java/app.go b/java/app.go
index e112e93..56fcfbb 100644
--- a/java/app.go
+++ b/java/app.go
@@ -678,7 +678,7 @@
a.dexProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
}
a.dexpreopter.uncompressedDex = *a.dexProperties.Uncompress_dex
- a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
+ a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
a.dexpreopter.classLoaderContexts = a.classLoaderContexts
a.dexpreopter.manifestFile = a.mergedManifestFile
a.dexpreopter.preventInstall = a.appProperties.PreventInstall
@@ -907,10 +907,10 @@
// Process all building blocks, from AAPT to certificates.
a.aaptBuildActions(ctx)
// The decision to enforce <uses-library> checks is made before adding implicit SDK libraries.
- a.usesLibrary.freezeEnforceUsesLibraries()
+ a.usesLibrary.freezeEnforceUsesLibraries(ctx)
// Check that the <uses-library> list is coherent with the manifest.
- if a.usesLibrary.enforceUsesLibraries() {
+ if a.usesLibrary.enforceUsesLibraries(ctx) {
manifestCheckFile := a.usesLibrary.verifyUsesLibrariesManifest(
ctx, a.mergedManifestFile, &a.classLoaderContexts)
apkDeps = append(apkDeps, manifestCheckFile)
@@ -1340,12 +1340,14 @@
Aaptflags []string
Manifest *string
Resource_dirs []string
+ Flags_packages []string
}{
Name: proptools.StringPtr(rroPackageName),
Filter_product: proptools.StringPtr(characteristics),
Aaptflags: []string{"--auto-add-overlay"},
Manifest: proptools.StringPtr(":" + rroManifestName),
Resource_dirs: a.aaptProperties.Resource_dirs,
+ Flags_packages: a.aaptProperties.Flags_packages,
}
if !Bool(a.aaptProperties.Aapt_include_all_resources) {
for _, aaptConfig := range ctx.Config().ProductAAPTConfig() {
@@ -1438,6 +1440,8 @@
a.testConfig = a.FixTestConfig(ctx, testConfig)
a.extraTestConfigs = android.PathsForModuleSrc(ctx, a.testProperties.Test_options.Extra_test_configs)
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
+ a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_common_data)...)
+ a.data = append(a.data, android.PathsForModuleSrc(ctx, a.testProperties.Device_first_data)...)
android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
android.SetProvider(ctx, tradefed.BaseTestProviderKey, tradefed.BaseTestProviderData{
InstalledFiles: a.data,
@@ -1686,11 +1690,11 @@
type UsesLibraryProperties struct {
// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file.
- Uses_libs []string
+ Uses_libs proptools.Configurable[[]string]
// A list of shared library modules that will be listed in uses-library tags in the AndroidManifest.xml file with
// required=false.
- Optional_uses_libs []string
+ Optional_uses_libs proptools.Configurable[[]string]
// If true, the list of uses_libs and optional_uses_libs modules must match the AndroidManifest.xml file. Defaults
// to true if either uses_libs or optional_uses_libs is set. Will unconditionally default to true in the future.
@@ -1738,7 +1742,7 @@
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps bool) {
if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
- ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
+ ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
presentOptionalUsesLibs := u.presentOptionalUsesLibs(ctx)
ctx.AddVariationDependencies(nil, usesLibOptTag, presentOptionalUsesLibs...)
// Only add these extra dependencies if the module is an app that depends on framework
@@ -1751,17 +1755,17 @@
ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
}
- _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs, presentOptionalUsesLibs)
+ _, diff, _ := android.ListSetDifference(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), presentOptionalUsesLibs)
u.usesLibraryProperties.Missing_optional_uses_libs = diff
} else {
- ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...)
+ ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)...)
ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...)
}
}
// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree.
func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string {
- optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs, func(s string) bool {
+ optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil), func(s string) bool {
exists := ctx.OtherModuleExists(s)
if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) {
fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s)
@@ -1827,15 +1831,15 @@
// enforceUsesLibraries returns true of <uses-library> tags should be checked against uses_libs and optional_uses_libs
// properties. Defaults to true if either of uses_libs or optional_uses_libs is specified. Will default to true
// unconditionally in the future.
-func (u *usesLibrary) enforceUsesLibraries() bool {
- defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs) > 0 ||
- len(u.usesLibraryProperties.Optional_uses_libs) > 0
+func (u *usesLibrary) enforceUsesLibraries(ctx android.ModuleContext) bool {
+ defaultEnforceUsesLibs := len(u.usesLibraryProperties.Uses_libs.GetOrDefault(ctx, nil)) > 0 ||
+ len(u.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) > 0
return BoolDefault(u.usesLibraryProperties.Enforce_uses_libs, u.enforce || defaultEnforceUsesLibs)
}
// Freeze the value of `enforce_uses_libs` based on the current values of `uses_libs` and `optional_uses_libs`.
-func (u *usesLibrary) freezeEnforceUsesLibraries() {
- enforce := u.enforceUsesLibraries()
+func (u *usesLibrary) freezeEnforceUsesLibraries(ctx android.ModuleContext) {
+ enforce := u.enforceUsesLibraries(ctx)
u.usesLibraryProperties.Enforce_uses_libs = &enforce
}
diff --git a/java/app_import.go b/java/app_import.go
index f5d9f3e..6b88f1c 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -364,13 +364,13 @@
a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned)
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
- a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
+ a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries(ctx)
a.dexpreopter.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
if a.usesLibrary.shouldDisableDexpreopt {
a.dexpreopter.disableDexpreopt()
}
- if a.usesLibrary.enforceUsesLibraries() {
+ if a.usesLibrary.enforceUsesLibraries(ctx) {
a.usesLibrary.verifyUsesLibrariesAPK(ctx, srcApk, &a.dexpreopter.classLoaderContexts)
}
diff --git a/java/app_test.go b/java/app_test.go
index dd672a0..3d83ea1 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -4679,3 +4679,51 @@
"--override-placeholder-version",
)
}
+
+func TestResourcesWithFlagDirectories(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.FixtureMergeMockFs(android.MockFS{
+ "res/flag(test.package.flag1)/values/bools.xml": nil,
+ "res/flag(!test.package.flag2)/values/bools.xml": nil,
+ "res/flag(test.package.flag1)/values-config/strings_google_services.xml": nil,
+ "res/flags(test.package.flag1)/values/strings.xml": nil,
+ }),
+ ).RunTestWithBp(t, `
+ android_library {
+ name: "foo",
+ srcs: ["a.java"],
+ use_resource_processor: true,
+ resource_dirs: [
+ "res",
+ ],
+ }
+ `)
+ fooModule := result.ModuleForTests("foo", "android_common")
+ compileOutputPaths := fooModule.Rule("aapt2Compile").Outputs.Strings()
+
+ android.AssertStringListContains(
+ t,
+ "Expected to generate flag path",
+ compileOutputPaths,
+ "out/soong/.intermediates/foo/android_common/aapt2/res/values_bools.(test.package.flag1).arsc.flat",
+ )
+ android.AssertStringListContains(
+ t,
+ "Expected to generate flag path with ! prefix in name",
+ compileOutputPaths,
+ "out/soong/.intermediates/foo/android_common/aapt2/res/values_bools.(!test.package.flag2).arsc.flat",
+ )
+ android.AssertStringListContains(
+ t,
+ "Expected to generate flag path with configs",
+ compileOutputPaths,
+ "out/soong/.intermediates/foo/android_common/aapt2/res/values-config_strings_google_services.(test.package.flag1).arsc.flat",
+ )
+ android.AssertStringListDoesNotContain(
+ t,
+ "Expected to not generate flag path with non-flag(flag_name) pattern",
+ compileOutputPaths,
+ "out/soong/.intermediates/foo/android_common/aapt2/res/values_strings.(test.package.flag1).arsc.flat",
+ )
+}
diff --git a/java/base.go b/java/base.go
index a9399cb..3927c61 100644
--- a/java/base.go
+++ b/java/base.go
@@ -71,6 +71,15 @@
// list of files that should be excluded from java_resources and java_resource_dirs
Exclude_java_resources []string `android:"path,arch_variant"`
+ // Same as java_resources, but modules added here will use the device variant. Can be useful
+ // for making a host test that tests the contents of a device built app.
+ Device_common_java_resources []string `android:"path_device_common"`
+
+ // Same as java_resources, but modules added here will use the device's os variant and the
+ // device's first architecture variant. Can be useful for making a host test that tests the
+ // contents of a native device built app.
+ Device_first_java_resources []string `android:"path_device_first"`
+
// list of module-specific flags that will be used for javac compiles
Javacflags []string `android:"arch_variant"`
@@ -113,6 +122,9 @@
// List of modules to use as annotation processors
Plugins []string
+ // List of modules to use as kotlin plugin
+ Kotlin_plugins []string
+
// List of modules to export to libraries that directly depend on this library as annotation
// processors. Note that if the plugins set generates_api: true this will disable the turbine
// optimization on modules that depend on this module, which will reduce parallelism and cause
@@ -862,7 +874,7 @@
// explicitly listed in the optional_uses_libs property.
tag := usesLibReqTag
if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) ||
- android.InList(*lib, j.usesLibrary.usesLibraryProperties.Optional_uses_libs) {
+ android.InList(*lib, j.usesLibrary.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) {
tag = usesLibOptTag
}
ctx.AddVariationDependencies(nil, tag, *lib)
@@ -872,6 +884,7 @@
}
ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
+ ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag, j.properties.Kotlin_plugins...)
ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), errorpronePluginTag, j.properties.Errorprone.Extra_check_modules...)
ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...)
@@ -904,7 +917,7 @@
if j.useCompose(ctx) {
ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag,
- "androidx.compose.compiler_compiler-hosted")
+ "androidx.compose.compiler_compiler-hosted-plugin")
}
}
@@ -1482,6 +1495,10 @@
dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs,
j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources)
fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources)
+ fileArgs2, fileDeps2 := ResourceFilesToJarArgs(ctx, j.properties.Device_common_java_resources, nil)
+ fileArgs3, fileDeps3 := ResourceFilesToJarArgs(ctx, j.properties.Device_first_java_resources, nil)
+ fileArgs = slices.Concat(fileArgs, fileArgs2, fileArgs3)
+ fileDeps = slices.Concat(fileDeps, fileDeps2, fileDeps3)
extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources
var resArgs []string
@@ -2499,7 +2516,11 @@
ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName)
}
case kotlinPluginTag:
- deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...)
+ if _, ok := module.(*KotlinPlugin); ok {
+ deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...)
+ } else {
+ ctx.PropertyErrorf("kotlin_plugins", "%q is not a kotlin_plugin module", otherName)
+ }
case syspropPublicStubDepTag:
// This is a sysprop implementation library, forward the JavaInfoProvider from
// the corresponding sysprop public stub library as SyspropPublicStubInfoProvider.
diff --git a/java/dex.go b/java/dex.go
index a3f699b..f4b53f0 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -404,6 +404,10 @@
r8Flags = append(r8Flags, "--resource-output", d.resourcesOutput.Path().String())
if d.dexProperties.optimizedResourceShrinkingEnabled(ctx) {
r8Flags = append(r8Flags, "--optimized-resource-shrinking")
+ if Bool(d.dexProperties.Optimize.Optimized_shrink_resources) {
+ // Explicitly opted into optimized shrinking, no need for keeping R$id entries
+ r8Flags = append(r8Flags, "--force-optimized-resource-shrinking")
+ }
}
}
diff --git a/java/fuzz.go b/java/fuzz.go
index e5f1f04..90f09a8 100644
--- a/java/fuzz.go
+++ b/java/fuzz.go
@@ -110,6 +110,9 @@
if j.fuzzPackagedModule.FuzzProperties.Corpus != nil {
j.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Corpus)
}
+ if j.fuzzPackagedModule.FuzzProperties.Device_common_corpus != nil {
+ j.fuzzPackagedModule.Corpus = append(j.fuzzPackagedModule.Corpus, android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Device_common_corpus)...)
+ }
if j.fuzzPackagedModule.FuzzProperties.Data != nil {
j.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, j.fuzzPackagedModule.FuzzProperties.Data)
}
diff --git a/java/java.go b/java/java.go
index 288042b..5bb3636 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1291,6 +1291,16 @@
// the test
Data []string `android:"path"`
+ // Same as data, but will add dependencies on modules using the device's os variation and
+ // the common arch variation. Useful for a host test that wants to embed a module built for
+ // device.
+ Device_common_data []string `android:"path_device_common"`
+
+ // same as data, but adds dependencies using the device's os variation and the device's first
+ // architecture's variation. Can be used to add a module built for device to the data of a
+ // host test.
+ Device_first_data []string `android:"path_device_first"`
+
// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
// doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
// explicitly.
@@ -1581,6 +1591,8 @@
})
j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
+ j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_common_data)...)
+ j.data = append(j.data, android.PathsForModuleSrc(ctx, j.testProperties.Device_first_data)...)
j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs)
@@ -3343,7 +3355,7 @@
if sdkLib != nil {
optional := false
if module, ok := ctx.Module().(ModuleWithUsesLibrary); ok {
- if android.InList(*sdkLib, module.UsesLibrary().usesLibraryProperties.Optional_uses_libs) {
+ if android.InList(*sdkLib, module.UsesLibrary().usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) {
optional = true
}
}
diff --git a/java/java_resources.go b/java/java_resources.go
index b0dc5a1..c525233 100644
--- a/java/java_resources.go
+++ b/java/java_resources.go
@@ -17,6 +17,7 @@
import (
"fmt"
"path/filepath"
+ "slices"
"strings"
"github.com/google/blueprint/pathtools"
@@ -99,10 +100,7 @@
// that should not be treated as resources (including *.java).
func ResourceFilesToJarArgs(ctx android.ModuleContext,
res, exclude []string) (args []string, deps android.Paths) {
-
- exclude = append([]string(nil), exclude...)
- exclude = append(exclude, resourceExcludes...)
- return resourceFilesToJarArgs(ctx, res, exclude)
+ return resourceFilesToJarArgs(ctx, res, slices.Concat(exclude, resourceExcludes))
}
func resourceFilesToJarArgs(ctx android.ModuleContext,
diff --git a/java/java_test.go b/java/java_test.go
index 51cfdab..54eb3e1 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1173,7 +1173,7 @@
filegroup {
name: "core-jar",
- srcs: [":core{.jar}"],
+ device_common_srcs: [":core{.jar}"],
}
`),
})
@@ -1189,7 +1189,7 @@
filegroup {
name: "core-jar",
- srcs: [":core{.jar}"],
+ device_common_srcs: [":core{.jar}"],
}
`),
})
diff --git a/java/kotlin_test.go b/java/kotlin_test.go
index f6e7fca..45eac01 100644
--- a/java/kotlin_test.go
+++ b/java/kotlin_test.go
@@ -500,8 +500,8 @@
name: "androidx.compose.runtime_runtime",
}
- java_library_host {
- name: "androidx.compose.compiler_compiler-hosted",
+ kotlin_plugin {
+ name: "androidx.compose.compiler_compiler-hosted-plugin",
}
java_library {
@@ -523,7 +523,7 @@
buildOS := result.Config.BuildOS.String()
- composeCompiler := result.ModuleForTests("androidx.compose.compiler_compiler-hosted", buildOS+"_common").Rule("combineJar").Output
+ composeCompiler := result.ModuleForTests("androidx.compose.compiler_compiler-hosted-plugin", buildOS+"_common").Rule("combineJar").Output
withCompose := result.ModuleForTests("withcompose", "android_common")
noCompose := result.ModuleForTests("nocompose", "android_common")
@@ -542,3 +542,50 @@
android.AssertStringDoesNotContain(t, "unexpected compose compiler plugin",
noCompose.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+composeCompiler.String())
}
+
+func TestKotlinPlugin(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, `
+ kotlin_plugin {
+ name: "kotlin_plugin",
+ }
+
+ java_library {
+ name: "with_kotlin_plugin",
+ srcs: ["a.kt"],
+ plugins: ["plugin"],
+ kotlin_plugins: ["kotlin_plugin"],
+ }
+
+ java_library {
+ name: "no_kotlin_plugin",
+ srcs: ["a.kt"],
+ }
+
+ java_plugin {
+ name: "plugin",
+ }
+ `)
+
+ buildOS := result.Config.BuildOS.String()
+
+ kotlinPlugin := result.ModuleForTests("kotlin_plugin", buildOS+"_common").Rule("combineJar").Output
+ withKotlinPlugin := result.ModuleForTests("with_kotlin_plugin", "android_common")
+ noKotlinPlugin := result.ModuleForTests("no_kotlin_plugin", "android_common")
+
+ android.AssertStringListContains(t, "missing plugin compiler dependency",
+ withKotlinPlugin.Rule("kotlinc").Implicits.Strings(), kotlinPlugin.String())
+
+ android.AssertStringDoesContain(t, "missing kotlin plugin",
+ withKotlinPlugin.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+kotlinPlugin.String())
+
+ android.AssertStringListContains(t, "missing kapt kotlin plugin dependency",
+ withKotlinPlugin.Rule("kapt").Implicits.Strings(), kotlinPlugin.String())
+
+ android.AssertStringListDoesNotContain(t, "unexpected kotlin plugin dependency",
+ noKotlinPlugin.Rule("kotlinc").Implicits.Strings(), kotlinPlugin.String())
+
+ android.AssertStringDoesNotContain(t, "unexpected kotlin plugin",
+ noKotlinPlugin.VariablesForTestsRelativeToTop()["kotlincFlags"], "-Xplugin="+kotlinPlugin.String())
+}
diff --git a/java/plugin.go b/java/plugin.go
index 9c4774a..610c9fd 100644
--- a/java/plugin.go
+++ b/java/plugin.go
@@ -24,6 +24,7 @@
func registerJavaPluginBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("java_plugin", PluginFactory)
+ ctx.RegisterModuleType("kotlin_plugin", KotlinPluginFactory)
}
func PluginFactory() android.Module {
@@ -37,6 +38,16 @@
return module
}
+func KotlinPluginFactory() android.Module {
+ module := &KotlinPlugin{}
+
+ module.addHostProperties()
+
+ InitJavaModule(module, android.HostSupported)
+
+ return module
+}
+
// Plugin describes a java_plugin module, a host java library that will be used by javac as an annotation processor.
type Plugin struct {
Library
@@ -53,3 +64,8 @@
// parallelism and cause more recompilation for modules that depend on modules that use this plugin.
Generates_api *bool
}
+
+// Plugin describes a kotlin_plugin module, a host java/kotlin library that will be used by kotlinc as a compiler plugin.
+type KotlinPlugin struct {
+ Library
+}
diff --git a/java/robolectric.go b/java/robolectric.go
index 30c7203..fb820ef 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -149,6 +149,8 @@
HostTemplate: "${RobolectricTestConfigTemplate}",
})
r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data)
+ r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_common_data)...)
+ r.data = append(r.data, android.PathsForModuleSrc(ctx, r.testProperties.Device_first_data)...)
var ok bool
var instrumentedApp *AndroidApp
@@ -208,6 +210,11 @@
installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
var installDeps android.InstallPaths
+ for _, data := range r.data {
+ installedData := ctx.InstallFile(installPath, data.Rel(), data)
+ installDeps = append(installDeps, installedData)
+ }
+
if manifest != nil {
r.data = append(r.data, manifest)
installedManifest := ctx.InstallFile(installPath, ctx.ModuleName()+"-AndroidManifest.xml", manifest)
@@ -228,11 +235,6 @@
installedConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
installDeps = append(installDeps, installedConfig)
- for _, data := range android.PathsForModuleSrc(ctx, r.testProperties.Data) {
- installedData := ctx.InstallFile(installPath, data.Rel(), data)
- installDeps = append(installDeps, installedData)
- }
-
soInstallPath := installPath.Join(ctx, getLibPath(r.forceArchType))
for _, jniLib := range collectTransitiveJniDeps(ctx) {
installJni := ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
diff --git a/java/sdk_library_internal.go b/java/sdk_library_internal.go
index ca088cf..768e57a 100644
--- a/java/sdk_library_internal.go
+++ b/java/sdk_library_internal.go
@@ -566,7 +566,7 @@
Min_device_sdk *string
Max_device_sdk *string
Sdk_library_min_api_level *string
- Uses_libs_dependencies []string
+ Uses_libs_dependencies proptools.Configurable[[]string]
}{
Name: proptools.StringPtr(module.xmlPermissionsModuleName()),
Enabled: module.EnabledProperty(),
@@ -577,7 +577,7 @@
Min_device_sdk: module.commonSdkLibraryProperties.Min_device_sdk,
Max_device_sdk: module.commonSdkLibraryProperties.Max_device_sdk,
Sdk_library_min_api_level: &moduleMinApiLevelStr,
- Uses_libs_dependencies: module.usesLibraryProperties.Uses_libs,
+ Uses_libs_dependencies: module.usesLibraryProperties.Uses_libs.Clone(),
}
mctx.CreateModule(sdkLibraryXmlFactory, &props)
@@ -742,7 +742,7 @@
// Uses-libs dependencies that the shared library requires to work correctly.
//
// This will add dependency="foo:bar" to the <library> section.
- Uses_libs_dependencies []string
+ Uses_libs_dependencies proptools.Configurable[[]string]
}
// java_sdk_library_xml builds the permission xml file for a java_sdk_library.
@@ -864,7 +864,7 @@
implicitUntilAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-before", module.properties.On_bootclasspath_before)
minSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "min-device-sdk", module.properties.Min_device_sdk)
maxSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "max-device-sdk", module.properties.Max_device_sdk)
- dependenciesAttr := formattedDependenciesAttribute(module.properties.Uses_libs_dependencies)
+ dependenciesAttr := formattedDependenciesAttribute(module.properties.Uses_libs_dependencies.GetOrDefault(ctx, nil))
// <library> is understood in all android versions whereas <apex-library> is only understood from API T (and ignored before that).
// similarly, min_device_sdk is only understood from T. So if a library is using that, we need to use the apex-library to make sure this library is not loaded before T
var libraryTag string
diff --git a/python/python.go b/python/python.go
index 01ac86c..d3e5743 100644
--- a/python/python.go
+++ b/python/python.go
@@ -90,6 +90,11 @@
// the test. the file extension can be arbitrary except for (.py).
Data []string `android:"path,arch_variant"`
+ // Same as data, but will add dependencies on modules using the device's os variation and
+ // the common arch variation. Useful for a host test that wants to embed a module built for
+ // device.
+ Device_common_data []string `android:"path_device_common"`
+
// list of java modules that provide data that should be installed alongside the test.
Java_data []string
@@ -451,6 +456,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)...)
// Emulate the data property for java_data dependencies.
for _, javaData := range ctx.GetDirectDepsWithTag(javaDataTag) {
diff --git a/rust/bindgen.go b/rust/bindgen.go
index abb5181..3944495 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -186,7 +186,7 @@
// Default clang flags
cflags = append(cflags, "${cc_config.CommonGlobalCflags}")
if ctx.Device() {
- cflags = append(cflags, "${cc_config.DeviceGlobalCflags}")
+ cflags = append(cflags, "${cc_config.DeviceGlobalCflags}", "-nostdlibinc")
}
// Toolchain clang flags
diff --git a/rust/image.go b/rust/image.go
index 26929b1..51b8289 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -85,7 +85,7 @@
mod.Properties.VendorVariantNeeded = b
}
-func (mod *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
+func (mod *Module) SnapshotVersion(mctx android.ImageInterfaceContext) string {
if snapshot, ok := mod.compiler.(cc.SnapshotInterface); ok {
return snapshot.Version()
} else {
@@ -94,35 +94,35 @@
}
}
-func (mod *Module) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
return mod.Properties.VendorVariantNeeded
}
-func (mod *Module) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
return mod.Properties.ProductVariantNeeded
}
-func (mod *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return mod.Properties.VendorRamdiskVariantNeeded
}
-func (mod *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
return mod.Properties.CoreVariantNeeded
}
-func (mod *Module) RamdiskVariantNeeded(android.BaseModuleContext) bool {
+func (mod *Module) RamdiskVariantNeeded(android.ImageInterfaceContext) bool {
return mod.Properties.RamdiskVariantNeeded
}
-func (mod *Module) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (mod *Module) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (mod *Module) RecoveryVariantNeeded(android.BaseModuleContext) bool {
+func (mod *Module) RecoveryVariantNeeded(android.ImageInterfaceContext) bool {
return mod.Properties.RecoveryVariantNeeded
}
-func (mod *Module) ExtraImageVariations(android.BaseModuleContext) []string {
+func (mod *Module) ExtraImageVariations(android.ImageInterfaceContext) []string {
return mod.Properties.ExtraVariants
}
@@ -213,7 +213,7 @@
return mod.InVendor() || mod.InProduct()
}
-func (mod *Module) SetImageVariation(ctx android.BaseModuleContext, variant string) {
+func (mod *Module) SetImageVariation(ctx android.ImageInterfaceContext, variant string) {
if variant == android.VendorRamdiskVariation {
mod.MakeAsPlatform()
} else if variant == android.RecoveryVariation {
@@ -231,7 +231,7 @@
}
}
-func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
+func (mod *Module) ImageMutatorBegin(mctx android.ImageInterfaceContext) {
if Bool(mod.VendorProperties.Double_loadable) {
mctx.PropertyErrorf("double_loadable",
"Rust modules do not yet support double loading")
diff --git a/rust/test.go b/rust/test.go
index b7ddd06..20ccfb3 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -46,6 +46,9 @@
// the test
Data []string `android:"path,arch_variant"`
+ // Same as data, but will add dependencies on the device's
+ Device_common_data []string `android:"path_device_common"`
+
// list of shared library modules that should be installed alongside the test
Data_libs []string `android:"arch_variant"`
@@ -143,6 +146,7 @@
})
dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
+ dataSrcPaths = append(dataSrcPaths, android.PathsForModuleSrc(ctx, test.Properties.Device_common_data)...)
ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
diff --git a/scripts/hiddenapi/Android.bp b/scripts/hiddenapi/Android.bp
index 43edf44..061af19 100644
--- a/scripts/hiddenapi/Android.bp
+++ b/scripts/hiddenapi/Android.bp
@@ -27,6 +27,12 @@
libs: [
"signature_trie",
],
+ target: {
+ windows: {
+ // go modules (bpmodify) don't support windows
+ enabled: false,
+ },
+ },
}
python_test_host {
@@ -44,6 +50,12 @@
test_options: {
unit_test: true,
},
+ target: {
+ windows: {
+ // go modules (bpmodify) don't support windows
+ enabled: false,
+ },
+ },
}
python_binary_host {
diff --git a/sdk/genrule_test.go b/sdk/genrule_test.go
index 6e52a3d..bf67795 100644
--- a/sdk/genrule_test.go
+++ b/sdk/genrule_test.go
@@ -23,21 +23,14 @@
)
func TestSdkGenrule(t *testing.T) {
- // Test that an sdk_genrule can depend on an sdk, and that a genrule can depend on an sdk_genrule
+ // Test that a genrule can depend on an sdk if using common_os_srcs
bp := `
sdk {
name: "my_sdk",
}
- sdk_genrule {
- name: "my_sdk_genrule",
- tool_files: ["tool"],
- cmd: "$(location tool) $(in) $(out)",
- srcs: [":my_sdk"],
- out: ["out"],
- }
genrule {
name: "my_regular_genrule",
- srcs: [":my_sdk_genrule"],
+ common_os_srcs: [":my_sdk"],
out: ["out"],
cmd: "cp $(in) $(out)",
}
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 15e13db..4db163c 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -1724,7 +1724,7 @@
filegroup {
name: "mygroup",
- srcs: [":myjavalib{.doctags}"],
+ device_common_srcs: [":myjavalib{.doctags}"],
}
`)
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 2e48d83..3991449 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -120,6 +120,16 @@
// the test.
Data []string `android:"path,arch_variant"`
+ // same as data, but adds dependencies using the device's os variation and the common
+ // architecture's variation. Can be used to add a module built for device to the data of a
+ // host test.
+ Device_common_data []string `android:"path_device_common"`
+
+ // same as data, but adds dependencies using the device's os variation and the device's first
+ // architecture's variation. Can be used to add a module built for device to the data of a
+ // host test.
+ Device_first_data []string `android:"path_device_first"`
+
// Add RootTargetPreparer to auto generated test config. This guarantees the test to run
// with root permission.
Require_root *bool
@@ -210,41 +220,41 @@
var _ android.ImageInterface = (*ShBinary)(nil)
-func (s *ShBinary) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (s *ShBinary) ImageMutatorBegin(ctx android.ImageInterfaceContext) {}
-func (s *ShBinary) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) VendorVariantNeeded(ctx android.ImageInterfaceContext) bool {
return s.InstallInVendor()
}
-func (s *ShBinary) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) ProductVariantNeeded(ctx android.ImageInterfaceContext) bool {
return s.InstallInProduct()
}
-func (s *ShBinary) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) CoreVariantNeeded(ctx android.ImageInterfaceContext) bool {
return !s.InstallInRecovery() && !s.InstallInRamdisk() && !s.InstallInVendorRamdisk() && !s.ModuleBase.InstallInVendor()
}
-func (s *ShBinary) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) RamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return proptools.Bool(s.properties.Ramdisk_available) || s.InstallInRamdisk()
}
-func (s *ShBinary) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) VendorRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return proptools.Bool(s.properties.Vendor_ramdisk_available) || s.InstallInVendorRamdisk()
}
-func (s *ShBinary) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) DebugRamdiskVariantNeeded(ctx android.ImageInterfaceContext) bool {
return false
}
-func (s *ShBinary) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
+func (s *ShBinary) RecoveryVariantNeeded(ctx android.ImageInterfaceContext) bool {
return proptools.Bool(s.properties.Recovery_available) || s.InstallInRecovery()
}
-func (s *ShBinary) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+func (s *ShBinary) ExtraImageVariations(ctx android.ImageInterfaceContext) []string {
return nil
}
-func (s *ShBinary) SetImageVariation(ctx android.BaseModuleContext, variation string) {
+func (s *ShBinary) SetImageVariation(ctx android.ImageInterfaceContext, variation string) {
s.properties.ImageVariation = variation
}
@@ -407,6 +417,8 @@
s.ShBinary.generateAndroidBuildActions(ctx)
expandedData := android.PathsForModuleSrc(ctx, s.testProperties.Data)
+ expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_common_data)...)
+ expandedData = append(expandedData, android.PathsForModuleSrc(ctx, s.testProperties.Device_first_data)...)
// Emulate the data property for java_data dependencies.
for _, javaData := range ctx.GetDirectDepsWithTag(shTestJavaDataTag) {
expandedData = append(expandedData, android.OutputFilesForModule(ctx, javaData, "")...)
diff --git a/tradefed_modules/test_module_config_test.go b/tradefed_modules/test_module_config_test.go
index f76a152..cf6c7d1 100644
--- a/tradefed_modules/test_module_config_test.go
+++ b/tradefed_modules/test_module_config_test.go
@@ -123,24 +123,24 @@
// Ensure we error for a base we don't support.
func TestModuleConfigWithHostBaseShouldFailWithExplicitMessage(t *testing.T) {
badBp := `
- java_test_host {
- name: "base",
- srcs: ["a.java"],
+ java_test {
+ name: "base",
+ srcs: ["a.java"],
}
- test_module_config {
- name: "derived_test",
- base: "base",
- exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
- include_annotations: ["android.platform.test.annotations.LargeTest"],
- test_suites: ["general-tests"],
- }`
+ test_module_config {
+ name: "derived_test",
+ base: "base",
+ exclude_filters: ["android.test.example.devcodelab.DevCodelabTest#testHelloFail"],
+ include_annotations: ["android.platform.test.annotations.LargeTest"],
+ test_suites: ["general-tests"],
+ }`
android.GroupFixturePreparers(
java.PrepareForTestWithJavaDefaultModules,
android.FixtureRegisterWithContext(RegisterTestModuleConfigBuildComponents),
).ExtendWithErrorHandler(
- android.FixtureExpectsAtLeastOneErrorMatchingPattern("'java_test_host' module used as base, but 'android_test' expected")).
+ android.FixtureExpectsAtLeastOneErrorMatchingPattern("'base' module used as base but it is not a 'android_test' module.")).
RunTestWithBp(t, badBp)
}
diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index fcf29c5..1f842f5 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -35,7 +35,6 @@
"blueprint",
"blueprint-bootstrap",
"blueprint-microfactory",
- "soong-android",
"soong-elf",
"soong-finder",
"soong-remoteexec",
diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go
index a8044df..c54d55f 100644
--- a/ui/build/androidmk_denylist.go
+++ b/ui/build/androidmk_denylist.go
@@ -16,8 +16,6 @@
import (
"strings"
-
- "android/soong/android"
)
var androidmk_denylist []string = []string{
@@ -82,13 +80,21 @@
"external/webp/",
}
-func ignoreNdkAndroidMks(androidMks []string) []string {
- return android.FilterListPred(androidMks, func(s string) bool {
+func ignoreNdkAndroidMks(androidMks []string) (filtered []string) {
+ filter := func(s string) bool {
for _, d := range external_ndk_androidmks {
if strings.HasPrefix(s, d) {
return false
}
}
return true
- })
+ }
+
+ for _, l := range androidMks {
+ if filter(l) {
+ filtered = append(filtered, l)
+ }
+ }
+
+ return
}
diff --git a/ui/build/config.go b/ui/build/config.go
index 7095f3a..f925a0c 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -96,7 +96,6 @@
buildFromSourceStub bool
incrementalBuildActions bool
ensureAllowlistIntegrity bool // For CI builds - make sure modules are mixed-built
- partialCompileFlags partialCompileFlags
// From the product config
katiArgs []string
@@ -136,16 +135,6 @@
ninjaCommand ninjaCommandType
}
-type partialCompileFlags struct {
- // Is partial compilation enabled at all?
- enabled bool
-
- // Whether to use d8 instead of r8
- use_d8 bool
-
- // Add others as needed.
-}
-
type NinjaWeightListSource uint
const (
@@ -302,12 +291,24 @@
ret.sandboxConfig.SetSrcDirIsRO(srcDirIsWritable == "false")
}
- ret.partialCompileFlags = parsePartialCompileFlags(ctx)
-
if os.Getenv("GENERATE_SOONG_DEBUG") == "true" {
ret.moduleDebugFile, _ = filepath.Abs(shared.JoinPath(ret.SoongOutDir(), "soong-debug-info.json"))
}
+ // If SOONG_USE_PARTIAL_COMPILE is set, make it one of "true" or the empty string.
+ // This simplifies the generated Ninja rules, so that they only need to check for the empty string.
+ if value, ok := os.LookupEnv("SOONG_USE_PARTIAL_COMPILE"); ok {
+ if value == "true" || value == "1" || value == "y" || value == "yes" {
+ value = "true"
+ } else {
+ value = ""
+ }
+ err = os.Setenv("SOONG_USE_PARTIAL_COMPILE", value)
+ if err != nil {
+ ctx.Fatalln("Failed to set SOONG_USE_PARTIAL_COMPILE: %v", err)
+ }
+ }
+
ret.ninjaCommand = NINJA_NINJA
switch os.Getenv("SOONG_NINJA") {
case "n2":
@@ -380,7 +381,6 @@
// Use config.ninjaCommand instead.
"SOONG_NINJA",
"SOONG_USE_N2",
- "SOONG_PARTIAL_COMPILE",
)
if ret.UseGoma() || ret.ForceUseGoma() {
@@ -499,78 +499,6 @@
return c
}
-// Parse SOONG_PARTIAL_COMPILE.
-//
-// The user-facing documentation shows:
-//
-// - empty or not set: "The current default state"
-// - "true" or "on": enable all stable partial compile features.
-// - "false" or "off": disable partial compile completely.
-//
-// What we actually allow is a comma separated list of tokens, whose first
-// character may be "+" (enable) or "-" (disable). If neither is present, "+"
-// is assumed. For example, "on,+use_d8" will enable partial compilation, and
-// additionally set the use_d8 flag (regardless of whether it is opt-in or
-// opt-out).
-//
-// To add a new feature to the list, add the field in the struct
-// `partialCompileFlags` above, and then add the name of the field in the
-// switch statement below.
-func parsePartialCompileFlags(ctx Context) partialCompileFlags {
- defaultFlags := partialCompileFlags{
- // Set any opt-out flags here. Opt-in flags are off by default.
- enabled: false,
- }
- value, ok := os.LookupEnv("SOONG_PARTIAL_COMPILE")
-
- if !ok {
- return defaultFlags
- }
-
- ret := defaultFlags
- tokens := strings.Split(strings.ToLower(value), ",")
- makeVal := func(state string, defaultValue bool) bool {
- switch state {
- case "":
- return defaultValue
- case "-":
- return false
- case "+":
- return true
- }
- return false
- }
- for _, tok := range tokens {
- var state string
- switch tok[0:1] {
- case "":
- // Ignore empty tokens.
- continue
- case "-", "+":
- state = tok[0:1]
- tok = tok[1:]
- default:
- // Treat `feature` as `+feature`.
- state = "+"
- }
- switch tok {
- case "true", "on", "yes":
- ret = defaultFlags
- ret.enabled = true
- case "false", "off", "no":
- // Set everything to false.
- ret = partialCompileFlags{}
- case "enabled":
- ret.enabled = makeVal(state, defaultFlags.enabled)
- case "use_d8":
- ret.use_d8 = makeVal(state, defaultFlags.use_d8)
- default:
- ctx.Fatalln("Unknown SOONG_PARTIAL_COMPILE value:", value)
- }
- }
- return ret
-}
-
// NewBuildActionConfig returns a build configuration based on the build action. The arguments are
// processed based on the build action and extracts any arguments that belongs to the build action.
func NewBuildActionConfig(action BuildAction, dir string, ctx Context, args ...string) Config {
@@ -1843,10 +1771,6 @@
return c.ensureAllowlistIntegrity
}
-func (c *configImpl) PartialCompileFlags() partialCompileFlags {
- return c.partialCompileFlags
-}
-
// Returns a Time object if one was passed via a command-line flag.
// Otherwise returns the passed default.
func (c *configImpl) BuildStartedTimeOrDefault(defaultTime time.Time) time.Time {
diff --git a/ui/build/kati.go b/ui/build/kati.go
index 5743ff7..4dfb710 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -183,6 +183,23 @@
username = usernameFromEnv
}
+ // SOONG_USE_PARTIAL_COMPILE may be used in makefiles, but both cases must be supported.
+ //
+ // In general, the partial compile features will be implemented in Soong-based rules. We
+ // also allow them to be used in makefiles. Clear the environment variable when calling
+ // kati so that we avoid reanalysis when the user changes it. We will pass it to Ninja.
+ // As a result, rules where we want to allow the developer to toggle the feature ("use
+ // the partial compile feature" vs "legacy, aka full compile behavior") need to use this
+ // in the rule, since changing it will not cause reanalysis.
+ //
+ // Shell syntax in the rule might look something like this:
+ // if [[ -n ${SOONG_USE_PARTIAL_COMPILE} ]]; then
+ // # partial compile behavior
+ // else
+ // # legacy behavior
+ // fi
+ cmd.Environment.Unset("SOONG_USE_PARTIAL_COMPILE")
+
hostname, ok := cmd.Environment.Get("BUILD_HOSTNAME")
// Unset BUILD_HOSTNAME during kati run to avoid kati rerun, kati will use BUILD_HOSTNAME from a file.
cmd.Environment.Unset("BUILD_HOSTNAME")
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index def0783..f5f637f 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -241,6 +241,9 @@
"SOONG_USE_N2",
"RUST_BACKTRACE",
"RUST_LOG",
+
+ // SOONG_USE_PARTIAL_COMPILE only determines which half of the rule we execute.
+ "SOONG_USE_PARTIAL_COMPILE",
}, config.BuildBrokenNinjaUsesEnvVars()...)...)
}