diff --git a/apex/apex.go b/apex/apex.go index 5891df0fc..158afb0f3 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -50,7 +50,7 @@ func registerApexBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("apex_vndk", vndkApexBundleFactory) ctx.RegisterModuleType("apex_defaults", defaultsFactory) ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory) - ctx.RegisterModuleType("override_apex", overrideApexFactory) + ctx.RegisterModuleType("override_apex", OverrideApexFactory) ctx.RegisterModuleType("apex_set", apexSetFactory) ctx.PreArchMutators(registerPreArchMutators) @@ -2451,6 +2451,7 @@ func DefaultsFactory(props ...interface{}) android.Module { type OverrideApex struct { android.ModuleBase android.OverrideModuleBase + android.BazelModuleBase } func (o *OverrideApex) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -2459,16 +2460,64 @@ func (o *OverrideApex) GenerateAndroidBuildActions(ctx android.ModuleContext) { // override_apex is used to create an apex module based on another apex module by overriding some of // its properties. -func overrideApexFactory() android.Module { +func OverrideApexFactory() android.Module { m := &OverrideApex{} m.AddProperties(&overridableProperties{}) android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibCommon) android.InitOverrideModule(m) + android.InitBazelModule(m) return m } +func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + if ctx.ModuleType() != "override_apex" { + return + } + + baseApexModuleName := o.OverrideModuleBase.GetOverriddenModuleName() + baseModule, baseApexExists := ctx.ModuleFromName(baseApexModuleName) + if !baseApexExists { + panic(fmt.Errorf("Base apex module doesn't exist: %s", baseApexModuleName)) + } + + a, baseModuleIsApex := baseModule.(*apexBundle) + if !baseModuleIsApex { + panic(fmt.Errorf("Base module is not apex module: %s", baseApexModuleName)) + } + attrs, props := convertWithBp2build(a, ctx) + + for _, p := range o.GetProperties() { + overridableProperties, ok := p.(*overridableProperties) + if !ok { + continue + } + // Key + if overridableProperties.Key != nil { + attrs.Key = bazel.LabelAttribute{} + attrs.Key.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Key)) + } + + // Certificate + if overridableProperties.Certificate != nil { + attrs.Certificate = bazel.LabelAttribute{} + attrs.Certificate.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Certificate)) + } + + // Prebuilts + prebuiltsLabelList := android.BazelLabelForModuleDeps(ctx, overridableProperties.Prebuilts) + attrs.Prebuilts = bazel.MakeLabelListAttribute(prebuiltsLabelList) + + // Compressible + if overridableProperties.Compressible != nil { + attrs.Compressible = bazel.BoolAttribute{Value: overridableProperties.Compressible} + } + } + + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: o.Name()}, &attrs) +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // Vality check routines // @@ -3154,6 +3203,11 @@ func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) { return } + attrs, props := convertWithBp2build(a, ctx) + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, &attrs) +} + +func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties) { var manifestLabelAttribute bazel.LabelAttribute if a.properties.Manifest != nil { manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.Manifest)) @@ -3165,8 +3219,15 @@ func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) { } var fileContextsLabelAttribute bazel.LabelAttribute - if a.properties.File_contexts != nil { + if a.properties.File_contexts == nil { + // See buildFileContexts(), if file_contexts is not specified the default one is used, which is //system/sepolicy/apex:-file_contexts + fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, a.Name()+"-file_contexts")) + } else if strings.HasPrefix(*a.properties.File_contexts, ":") { + // File_contexts is a module fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts)) + } else { + // File_contexts is a file + fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.File_contexts)) } // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but @@ -3224,7 +3285,7 @@ func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) { compressibleAttribute.Value = a.overridableProperties.Compressible } - attrs := &bazelApexBundleAttributes{ + attrs := bazelApexBundleAttributes{ Manifest: manifestLabelAttribute, Android_manifest: androidManifestLabelAttribute, File_contexts: fileContextsLabelAttribute, @@ -3245,7 +3306,7 @@ func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) { Bzl_load_location: "//build/bazel/rules/apex:apex.bzl", } - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: a.Name()}, attrs) + return attrs, props } // The following conversions are based on this table where the rows are the compile_multilib diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go index 90571893c..3ed21dba0 100644 --- a/bp2build/apex_conversion_test.go +++ b/bp2build/apex_conversion_test.go @@ -41,9 +41,27 @@ func registerApexModuleTypes(ctx android.RegistrationContext) { ctx.RegisterModuleType("filegroup", android.FileGroupFactory) } +func runOverrideApexTestCase(t *testing.T, tc bp2buildTestCase) { + t.Helper() + runBp2BuildTestCase(t, registerOverrideApexModuleTypes, tc) +} + +func registerOverrideApexModuleTypes(ctx android.RegistrationContext) { + // CC module types needed as they can be APEX dependencies + cc.RegisterCCBuildComponents(ctx) + + ctx.RegisterModuleType("sh_binary", sh.ShBinaryFactory) + ctx.RegisterModuleType("cc_binary", cc.BinaryFactory) + ctx.RegisterModuleType("cc_library", cc.LibraryFactory) + ctx.RegisterModuleType("apex_key", apex.ApexKeyFactory) + ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory) + ctx.RegisterModuleType("filegroup", android.FileGroupFactory) + ctx.RegisterModuleType("apex", apex.BundleFactory) +} + func TestApexBundleSimple(t *testing.T) { runApexTestCase(t, bp2buildTestCase{ - description: "apex - example with all props", + description: "apex - example with all props, file_context is a module in same Android.bp", moduleTypeUnderTest: "apex", moduleTypeUnderTestFactory: apex.BundleFactory, filesystem: map[string]string{}, @@ -71,13 +89,11 @@ cc_library { bazel_module: { bp2build_available: false }, } -// TODO(b/194878861): Add bp2build support for prebuilt_etc cc_library { name: "pretend_prebuilt_1", bazel_module: { bp2build_available: false }, } -// TODO(b/194878861): Add bp2build support for prebuilt_etc cc_library { name: "pretend_prebuilt_2", bazel_module: { bp2build_available: false }, @@ -86,7 +102,7 @@ cc_library { filegroup { name: "com.android.apogee-file_contexts", srcs: [ - "com.android.apogee-file_contexts", + "com.android.apogee-file_contexts", ], bazel_module: { bp2build_available: false }, } @@ -98,7 +114,7 @@ apex { name: "com.android.apogee", manifest: "apogee_manifest.json", androidManifest: "ApogeeAndroidManifest.xml", - file_contexts: "com.android.apogee-file_contexts", + file_contexts: ":com.android.apogee-file_contexts", min_sdk_version: "29", key: "com.android.apogee.key", certificate: "com.android.apogee.certificate", @@ -157,13 +173,97 @@ apex { }}) } +func TestApexBundleSimple_fileContextsInAnotherAndroidBp(t *testing.T) { + runApexTestCase(t, bp2buildTestCase{ + description: "apex - file contexts is a module in another Android.bp", + moduleTypeUnderTest: "apex", + moduleTypeUnderTestFactory: apex.BundleFactory, + filesystem: map[string]string{ + "a/b/Android.bp": ` +filegroup { + name: "com.android.apogee-file_contexts", + srcs: [ + "com.android.apogee-file_contexts", + ], + bazel_module: { bp2build_available: false }, +} +`, + }, + blueprint: ` +apex { + name: "com.android.apogee", + file_contexts: ":com.android.apogee-file_contexts", +} +`, + expectedBazelTargets: []string{ + makeBazelTarget("apex", "com.android.apogee", attrNameToString{ + "file_contexts": `"//a/b:com.android.apogee-file_contexts"`, + }), + }}) +} + +func TestApexBundleSimple_fileContextsIsFile(t *testing.T) { + runApexTestCase(t, bp2buildTestCase{ + description: "apex - file contexts is a file", + moduleTypeUnderTest: "apex", + moduleTypeUnderTestFactory: apex.BundleFactory, + filesystem: map[string]string{}, + blueprint: ` +apex { + name: "com.android.apogee", + file_contexts: "file_contexts_file", +} +`, + expectedBazelTargets: []string{ + makeBazelTarget("apex", "com.android.apogee", attrNameToString{ + "file_contexts": `"file_contexts_file"`, + }), + }}) +} + +func TestApexBundleSimple_fileContextsIsNotSpecified(t *testing.T) { + runApexTestCase(t, bp2buildTestCase{ + description: "apex - file contexts is not specified", + moduleTypeUnderTest: "apex", + moduleTypeUnderTestFactory: apex.BundleFactory, + filesystem: map[string]string{ + "system/sepolicy/apex/Android.bp": ` +filegroup { + name: "com.android.apogee-file_contexts", + srcs: [ + "com.android.apogee-file_contexts", + ], + bazel_module: { bp2build_available: false }, +} +`, + }, + blueprint: ` +apex { + name: "com.android.apogee", +} +`, + expectedBazelTargets: []string{ + makeBazelTarget("apex", "com.android.apogee", attrNameToString{ + "file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`, + }), + }}) +} + func TestApexBundleCompileMultilibBoth(t *testing.T) { runApexTestCase(t, bp2buildTestCase{ description: "apex - example with compile_multilib=both", moduleTypeUnderTest: "apex", moduleTypeUnderTestFactory: apex.BundleFactory, - filesystem: map[string]string{}, - blueprint: createMultilibBlueprint("both"), + filesystem: map[string]string{ + "system/sepolicy/apex/Android.bp": ` +filegroup { + name: "com.android.apogee-file_contexts", + srcs: [ "apogee-file_contexts", ], + bazel_module: { bp2build_available: false }, +} +`, + }, + blueprint: createMultilibBlueprint("both"), expectedBazelTargets: []string{ makeBazelTarget("apex", "com.android.apogee", attrNameToString{ "native_shared_libs_32": `[ @@ -187,6 +287,7 @@ func TestApexBundleCompileMultilibBoth(t *testing.T) { ], "//conditions:default": [], })`, + "file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`, }), }}) } @@ -196,8 +297,16 @@ func TestApexBundleCompileMultilibFirst(t *testing.T) { description: "apex - example with compile_multilib=first", moduleTypeUnderTest: "apex", moduleTypeUnderTestFactory: apex.BundleFactory, - filesystem: map[string]string{}, - blueprint: createMultilibBlueprint("first"), + filesystem: map[string]string{ + "system/sepolicy/apex/Android.bp": ` +filegroup { + name: "com.android.apogee-file_contexts", + srcs: [ "apogee-file_contexts", ], + bazel_module: { bp2build_available: false }, +} +`, + }, + blueprint: createMultilibBlueprint("first"), expectedBazelTargets: []string{ makeBazelTarget("apex", "com.android.apogee", attrNameToString{ "native_shared_libs_32": `select({ @@ -226,6 +335,7 @@ func TestApexBundleCompileMultilibFirst(t *testing.T) { ], "//conditions:default": [], })`, + "file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`, }), }}) } @@ -235,8 +345,16 @@ func TestApexBundleCompileMultilib32(t *testing.T) { description: "apex - example with compile_multilib=32", moduleTypeUnderTest: "apex", moduleTypeUnderTestFactory: apex.BundleFactory, - filesystem: map[string]string{}, - blueprint: createMultilibBlueprint("32"), + filesystem: map[string]string{ + "system/sepolicy/apex/Android.bp": ` +filegroup { + name: "com.android.apogee-file_contexts", + srcs: [ "apogee-file_contexts", ], + bazel_module: { bp2build_available: false }, +} +`, + }, + blueprint: createMultilibBlueprint("32"), expectedBazelTargets: []string{ makeBazelTarget("apex", "com.android.apogee", attrNameToString{ "native_shared_libs_32": `[ @@ -247,6 +365,7 @@ func TestApexBundleCompileMultilib32(t *testing.T) { "//build/bazel/platforms/arch:x86": [":native_shared_lib_2"], "//conditions:default": [], })`, + "file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`, }), }}) } @@ -256,8 +375,16 @@ func TestApexBundleCompileMultilib64(t *testing.T) { description: "apex - example with compile_multilib=64", moduleTypeUnderTest: "apex", moduleTypeUnderTestFactory: apex.BundleFactory, - filesystem: map[string]string{}, - blueprint: createMultilibBlueprint("64"), + filesystem: map[string]string{ + "system/sepolicy/apex/Android.bp": ` +filegroup { + name: "com.android.apogee-file_contexts", + srcs: [ "apogee-file_contexts", ], + bazel_module: { bp2build_available: false }, +} +`, + }, + blueprint: createMultilibBlueprint("64"), expectedBazelTargets: []string{ makeBazelTarget("apex", "com.android.apogee", attrNameToString{ "native_shared_libs_64": `select({ @@ -273,6 +400,7 @@ func TestApexBundleCompileMultilib64(t *testing.T) { ], "//conditions:default": [], })`, + "file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`, }), }}) } @@ -282,7 +410,15 @@ func TestApexBundleDefaultPropertyValues(t *testing.T) { description: "apex - default property values", moduleTypeUnderTest: "apex", moduleTypeUnderTestFactory: apex.BundleFactory, - filesystem: map[string]string{}, + filesystem: map[string]string{ + "system/sepolicy/apex/Android.bp": ` +filegroup { + name: "com.android.apogee-file_contexts", + srcs: [ "apogee-file_contexts", ], + bazel_module: { bp2build_available: false }, +} +`, + }, blueprint: ` apex { name: "com.android.apogee", @@ -290,7 +426,8 @@ apex { } `, expectedBazelTargets: []string{makeBazelTarget("apex", "com.android.apogee", attrNameToString{ - "manifest": `"apogee_manifest.json"`, + "manifest": `"apogee_manifest.json"`, + "file_contexts": `"//system/sepolicy/apex:com.android.apogee-file_contexts"`, }), }}) } @@ -300,7 +437,15 @@ func TestApexBundleHasBazelModuleProps(t *testing.T) { description: "apex - has bazel module props", moduleTypeUnderTest: "apex", moduleTypeUnderTestFactory: apex.BundleFactory, - filesystem: map[string]string{}, + filesystem: map[string]string{ + "system/sepolicy/apex/Android.bp": ` +filegroup { + name: "apogee-file_contexts", + srcs: [ "apogee-file_contexts", ], + bazel_module: { bp2build_available: false }, +} +`, + }, blueprint: ` apex { name: "apogee", @@ -309,7 +454,8 @@ apex { } `, expectedBazelTargets: []string{makeBazelTarget("apex", "apogee", attrNameToString{ - "manifest": `"manifest.json"`, + "manifest": `"manifest.json"`, + "file_contexts": `"//system/sepolicy/apex:apogee-file_contexts"`, }), }}) } @@ -363,3 +509,137 @@ apex { }, }` } + +func TestBp2BuildOverrideApex(t *testing.T) { + runOverrideApexTestCase(t, bp2buildTestCase{ + description: "override_apex", + moduleTypeUnderTest: "override_apex", + moduleTypeUnderTestFactory: apex.OverrideApexFactory, + filesystem: map[string]string{}, + blueprint: ` +apex_key { + name: "com.android.apogee.key", + public_key: "com.android.apogee.avbpubkey", + private_key: "com.android.apogee.pem", + bazel_module: { bp2build_available: false }, +} + +android_app_certificate { + name: "com.android.apogee.certificate", + certificate: "com.android.apogee", + bazel_module: { bp2build_available: false }, +} + +cc_library { + name: "native_shared_lib_1", + bazel_module: { bp2build_available: false }, +} + +cc_library { + name: "native_shared_lib_2", + bazel_module: { bp2build_available: false }, +} + +cc_library { + name: "pretend_prebuilt_1", + bazel_module: { bp2build_available: false }, +} + +cc_library { + name: "pretend_prebuilt_2", + bazel_module: { bp2build_available: false }, +} + +filegroup { + name: "com.android.apogee-file_contexts", + srcs: [ + "com.android.apogee-file_contexts", + ], + bazel_module: { bp2build_available: false }, +} + +cc_binary { name: "cc_binary_1", bazel_module: { bp2build_available: false } } +sh_binary { name: "sh_binary_2", bazel_module: { bp2build_available: false } } + +apex { + name: "com.android.apogee", + manifest: "apogee_manifest.json", + androidManifest: "ApogeeAndroidManifest.xml", + file_contexts: ":com.android.apogee-file_contexts", + min_sdk_version: "29", + key: "com.android.apogee.key", + certificate: "com.android.apogee.certificate", + updatable: false, + installable: false, + compressible: false, + native_shared_libs: [ + "native_shared_lib_1", + "native_shared_lib_2", + ], + binaries: [ + "cc_binary_1", + "sh_binary_2", + ], + prebuilts: [ + "pretend_prebuilt_1", + "pretend_prebuilt_2", + ], + bazel_module: { bp2build_available: false }, +} + +apex_key { + name: "com.google.android.apogee.key", + public_key: "com.google.android.apogee.avbpubkey", + private_key: "com.google.android.apogee.pem", + bazel_module: { bp2build_available: false }, +} + +android_app_certificate { + name: "com.google.android.apogee.certificate", + certificate: "com.google.android.apogee", + bazel_module: { bp2build_available: false }, +} + +override_apex { + name: "com.google.android.apogee", + base: ":com.android.apogee", + key: "com.google.android.apogee.key", + certificate: "com.google.android.apogee.certificate", + prebuilts: [], + compressible: true, +} +`, + expectedBazelTargets: []string{ + makeBazelTarget("apex", "com.google.android.apogee", attrNameToString{ + "android_manifest": `"ApogeeAndroidManifest.xml"`, + "binaries": `[ + ":cc_binary_1", + ":sh_binary_2", + ]`, + "certificate": `":com.google.android.apogee.certificate"`, + "file_contexts": `":com.android.apogee-file_contexts"`, + "installable": "False", + "key": `":com.google.android.apogee.key"`, + "manifest": `"apogee_manifest.json"`, + "min_sdk_version": `"29"`, + "native_shared_libs_32": `[ + ":native_shared_lib_1", + ":native_shared_lib_2", + ]`, + "native_shared_libs_64": `select({ + "//build/bazel/platforms/arch:arm64": [ + ":native_shared_lib_1", + ":native_shared_lib_2", + ], + "//build/bazel/platforms/arch:x86_64": [ + ":native_shared_lib_1", + ":native_shared_lib_2", + ], + "//conditions:default": [], + })`, + "prebuilts": `[]`, + "updatable": "False", + "compressible": "True", + }), + }}) +}