diff options
Diffstat (limited to 'apex/apex.go')
-rw-r--r-- | apex/apex.go | 263 |
1 files changed, 185 insertions, 78 deletions
diff --git a/apex/apex.go b/apex/apex.go index 7b6707ce6..e9b08150f 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -17,6 +17,7 @@ package apex import ( + "android/soong/bazel/cquery" "fmt" "path/filepath" "regexp" @@ -639,7 +640,7 @@ var ( fsTag = &dependencyTag{name: "filesystem", payload: true} bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType} sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType} - compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true} + compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType} javaLibTag = &dependencyTag{name: "javaLib", payload: true} jniLibTag = &dependencyTag{name: "jniLib", payload: true} keyTag = &dependencyTag{name: "key"} @@ -1803,6 +1804,184 @@ func (f fsType) string() string { } } +var _ android.MixedBuildBuildable = (*apexBundle)(nil) + +func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool { + return ctx.ModuleType() == "apex" && a.properties.ApexType == imageApex +} + +func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) { + bazelCtx := ctx.Config().BazelContext + bazelCtx.QueueBazelRequest(a.GetBazelLabel(ctx, a), cquery.GetApexInfo, android.GetConfigKey(ctx)) +} + +func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) { + if !a.commonBuildActions(ctx) { + return + } + + a.setApexTypeAndSuffix(ctx) + a.setPayloadFsType(ctx) + a.setSystemLibLink(ctx) + + if a.properties.ApexType != zipApex { + a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType) + } + + bazelCtx := ctx.Config().BazelContext + outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx)) + if err != nil { + ctx.ModuleErrorf(err.Error()) + return + } + a.installDir = android.PathForModuleInstall(ctx, "apex") + a.outputApexFile = android.PathForBazelOut(ctx, outputs.SignedOutput) + a.outputFile = a.outputApexFile + a.setCompression(ctx) + + a.publicKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyPair[0]) + a.privateKeyFile = android.PathForBazelOut(ctx, outputs.BundleKeyPair[1]) + a.containerCertificateFile = android.PathForBazelOut(ctx, outputs.ContainerKeyPair[0]) + a.containerPrivateKeyFile = android.PathForBazelOut(ctx, outputs.ContainerKeyPair[1]) + apexType := a.properties.ApexType + switch apexType { + case imageApex: + // TODO(asmundak): Bazel does not create these files yet. + // b/190817312 + a.htmlGzNotice = android.PathForBazelOut(ctx, "NOTICE.html.gz") + // b/239081457 + a.bundleModuleFile = android.PathForBazelOut(ctx, a.Name()+apexType.suffix()+"-base.zip") + // b/239081455 + a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.txt")) + // b/239081456 + a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_backing.txt")) + // b/239084755 + a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, a.Name()+"_using.xml")) + installSuffix := imageApexSuffix + if a.isCompressed { + installSuffix = imageCapexSuffix + } + a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile, + a.compatSymlinks.Paths()...) + default: + panic(fmt.Errorf("unexpected apex_type for the ProcessBazelQuery: %v", a.properties.ApexType)) + } + + /* + TODO(asmundak): compared to building an APEX with Soong, building it with Bazel does not + return filesInfo and requiredDeps fields (in the Soong build the latter is updated). + Fix this, as these fields are subsequently used in apex/androidmk.go and in apex/builder/go + To find out what Soong build puts there, run: + vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)} + ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { + return a.depVisitor(&vctx, ctx, child, parent) + }) + vctx.normalizeFileInfo() + */ + +} + +func (a *apexBundle) setCompression(ctx android.ModuleContext) { + if a.properties.ApexType != imageApex { + a.isCompressed = false + } else if a.testOnlyShouldForceCompression() { + a.isCompressed = true + } else { + a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable() + } +} + +func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) { + // Optimization. If we are building bundled APEX, for the files that are gathered due to the + // transitive dependencies, don't place them inside the APEX, but place a symlink pointing + // the same library in the system partition, thus effectively sharing the same libraries + // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed + // in the APEX. + a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable() + + // APEXes targeting other than system/system_ext partitions use vendor/product variants. + // So we can't link them to /system/lib libs which are core variants. + if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) { + a.linkToSystemLib = false + } + + forced := ctx.Config().ForceApexSymlinkOptimization() + updatable := a.Updatable() || a.FutureUpdatable() + + // We don't need the optimization for updatable APEXes, as it might give false signal + // to the system health when the APEXes are still bundled (b/149805758). + if !forced && updatable && a.properties.ApexType == imageApex { + a.linkToSystemLib = false + } + + // We also don't want the optimization for host APEXes, because it doesn't make sense. + if ctx.Host() { + a.linkToSystemLib = false + } +} + +func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) { + switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) { + case ext4FsType: + a.payloadFsType = ext4 + case f2fsFsType: + a.payloadFsType = f2fs + case erofsFsType: + a.payloadFsType = erofs + default: + ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type) + } +} + +func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) { + // Set suffix and primaryApexType depending on the ApexType + buildFlattenedAsDefault := ctx.Config().FlattenApex() + switch a.properties.ApexType { + case imageApex: + if buildFlattenedAsDefault { + a.suffix = imageApexSuffix + } else { + a.suffix = "" + a.primaryApexType = true + + if ctx.Config().InstallExtraFlattenedApexes() { + a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix) + } + } + case zipApex: + if proptools.String(a.properties.Payload_type) == "zip" { + a.suffix = "" + a.primaryApexType = true + } else { + a.suffix = zipApexSuffix + } + case flattenedApex: + if buildFlattenedAsDefault { + a.suffix = "" + a.primaryApexType = true + } else { + a.suffix = flattenedSuffix + } + } +} + +func (a apexBundle) isCompressable() bool { + return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex +} + +func (a *apexBundle) commonBuildActions(ctx android.ModuleContext) bool { + a.checkApexAvailability(ctx) + a.checkUpdatable(ctx) + a.CheckMinSdkVersion(ctx) + a.checkStaticLinkingToStubLibraries(ctx) + a.checkStaticExecutables(ctx) + if len(a.properties.Tests) > 0 && !a.testApex { + ctx.PropertyErrorf("tests", "property allowed only in apex_test module type") + return false + } + return true +} + type visitorContext struct { // all the files that will be included in this APEX filesInfo []apexFile @@ -2188,16 +2367,9 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { //////////////////////////////////////////////////////////////////////////////////////////// // 1) do some validity checks such as apex_available, min_sdk_version, etc. - a.checkApexAvailability(ctx) - a.checkUpdatable(ctx) - a.CheckMinSdkVersion(ctx) - a.checkStaticLinkingToStubLibraries(ctx) - a.checkStaticExecutables(ctx) - if len(a.properties.Tests) > 0 && !a.testApex { - ctx.PropertyErrorf("tests", "property allowed only in apex_test module type") + if !a.commonBuildActions(ctx) { return } - //////////////////////////////////////////////////////////////////////////////////////////// // 2) traverse the dependency tree to collect apexFile structs from them. @@ -2219,74 +2391,9 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.installDir = android.PathForModuleInstall(ctx, "apex") a.filesInfo = vctx.filesInfo - // Set suffix and primaryApexType depending on the ApexType - buildFlattenedAsDefault := ctx.Config().FlattenApex() - switch a.properties.ApexType { - case imageApex: - if buildFlattenedAsDefault { - a.suffix = imageApexSuffix - } else { - a.suffix = "" - a.primaryApexType = true - - if ctx.Config().InstallExtraFlattenedApexes() { - a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix) - } - } - case zipApex: - if proptools.String(a.properties.Payload_type) == "zip" { - a.suffix = "" - a.primaryApexType = true - } else { - a.suffix = zipApexSuffix - } - case flattenedApex: - if buildFlattenedAsDefault { - a.suffix = "" - a.primaryApexType = true - } else { - a.suffix = flattenedSuffix - } - } - - switch proptools.StringDefault(a.properties.Payload_fs_type, ext4FsType) { - case ext4FsType: - a.payloadFsType = ext4 - case f2fsFsType: - a.payloadFsType = f2fs - case erofsFsType: - a.payloadFsType = erofs - default: - ctx.PropertyErrorf("payload_fs_type", "%q is not a valid filesystem for apex [ext4, f2fs, erofs]", *a.properties.Payload_fs_type) - } - - // Optimization. If we are building bundled APEX, for the files that are gathered due to the - // transitive dependencies, don't place them inside the APEX, but place a symlink pointing - // the same library in the system partition, thus effectively sharing the same libraries - // across the APEX boundary. For unbundled APEX, all the gathered files are actually placed - // in the APEX. - a.linkToSystemLib = !ctx.Config().UnbundledBuild() && a.installable() - - // APEXes targeting other than system/system_ext partitions use vendor/product variants. - // So we can't link them to /system/lib libs which are core variants. - if a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) { - a.linkToSystemLib = false - } - - forced := ctx.Config().ForceApexSymlinkOptimization() - updatable := a.Updatable() || a.FutureUpdatable() - - // We don't need the optimization for updatable APEXes, as it might give false signal - // to the system health when the APEXes are still bundled (b/149805758). - if !forced && updatable && a.properties.ApexType == imageApex { - a.linkToSystemLib = false - } - - // We also don't want the optimization for host APEXes, because it doesn't make sense. - if ctx.Host() { - a.linkToSystemLib = false - } - + a.setApexTypeAndSuffix(ctx) + a.setPayloadFsType(ctx) + a.setSystemLibLink(ctx) if a.properties.ApexType != zipApex { a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType) } @@ -2594,7 +2701,7 @@ func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) { var _ android.ModuleWithMinSdkVersionCheck = (*apexBundle)(nil) -// Entures that min_sdk_version of the included modules are equal or less than the min_sdk_version +// Ensures that min_sdk_version of the included modules are equal or less than the min_sdk_version // of this apexBundle. func (a *apexBundle) CheckMinSdkVersion(ctx android.ModuleContext) { if a.testApex || a.vndkApex { |