2018-02-21 02:22:23 +01:00
|
|
|
// Copyright 2018 Google Inc. All rights reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package java
|
|
|
|
|
|
|
|
import (
|
2019-02-20 01:59:53 +01:00
|
|
|
"fmt"
|
2019-06-18 02:40:56 +02:00
|
|
|
"path/filepath"
|
2023-11-22 00:13:56 +01:00
|
|
|
"slices"
|
2020-11-10 21:27:45 +01:00
|
|
|
"strconv"
|
2018-03-28 23:58:31 +02:00
|
|
|
"strings"
|
2018-02-21 02:22:23 +01:00
|
|
|
|
2020-01-18 19:33:43 +01:00
|
|
|
"android/soong/android"
|
2020-08-14 18:32:16 +02:00
|
|
|
"android/soong/dexpreopt"
|
2018-02-21 02:22:23 +01:00
|
|
|
"github.com/google/blueprint"
|
2018-03-28 23:58:31 +02:00
|
|
|
"github.com/google/blueprint/proptools"
|
2018-02-21 02:22:23 +01:00
|
|
|
)
|
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
type AndroidLibraryDependency interface {
|
|
|
|
ExportPackage() android.Path
|
2023-07-14 19:23:41 +02:00
|
|
|
ResourcesNodeDepSet() *android.DepSet[*resourcesNode]
|
|
|
|
RRODirsDepSet() *android.DepSet[rroDir]
|
|
|
|
ManifestsDepSet() *android.DepSet[android.Path]
|
2020-10-07 03:56:10 +02:00
|
|
|
SetRROEnforcedForDependent(enforce bool)
|
|
|
|
IsRROEnforced(ctx android.BaseModuleContext) bool
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
2018-02-21 02:22:23 +01:00
|
|
|
func init() {
|
2019-12-18 20:51:55 +01:00
|
|
|
RegisterAARBuildComponents(android.InitRegistrationContext)
|
|
|
|
}
|
|
|
|
|
|
|
|
func RegisterAARBuildComponents(ctx android.RegistrationContext) {
|
|
|
|
ctx.RegisterModuleType("android_library_import", AARImportFactory)
|
|
|
|
ctx.RegisterModuleType("android_library", AndroidLibraryFactory)
|
2021-03-22 14:56:43 +01:00
|
|
|
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
|
|
|
|
ctx.TopDown("propagate_rro_enforcement", propagateRROEnforcementMutator).Parallel()
|
|
|
|
})
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// AAR (android library)
|
|
|
|
//
|
|
|
|
|
|
|
|
type androidLibraryProperties struct {
|
|
|
|
BuildAAR bool `blueprint:"mutated"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type aaptProperties struct {
|
|
|
|
// flags passed to aapt when creating the apk
|
|
|
|
Aaptflags []string
|
|
|
|
|
2018-10-25 05:24:57 +02:00
|
|
|
// include all resource configurations, not just the product-configured
|
|
|
|
// ones.
|
|
|
|
Aapt_include_all_resources *bool
|
|
|
|
|
2023-10-13 19:08:59 +02:00
|
|
|
// list of files to use as assets.
|
|
|
|
Assets []string `android:"path"`
|
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
// list of directories relative to the Blueprints file containing assets.
|
2019-02-08 00:30:01 +01:00
|
|
|
// Defaults to ["assets"] if a directory called assets exists. Set to []
|
|
|
|
// to disable the default.
|
2018-03-28 23:58:31 +02:00
|
|
|
Asset_dirs []string
|
|
|
|
|
|
|
|
// list of directories relative to the Blueprints file containing
|
2019-02-08 00:30:01 +01:00
|
|
|
// Android resources. Defaults to ["res"] if a directory called res exists.
|
|
|
|
// Set to [] to disable the default.
|
2018-03-28 23:58:31 +02:00
|
|
|
Resource_dirs []string
|
|
|
|
|
2019-02-20 01:59:53 +01:00
|
|
|
// list of zip files containing Android resources.
|
2019-03-05 07:35:41 +01:00
|
|
|
Resource_zips []string `android:"path"`
|
2019-02-20 01:59:53 +01:00
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
// path to AndroidManifest.xml. If unset, defaults to "AndroidManifest.xml".
|
2019-03-05 07:35:41 +01:00
|
|
|
Manifest *string `android:"path"`
|
2019-08-08 11:37:17 +02:00
|
|
|
|
|
|
|
// paths to additional manifest files to merge with main manifest.
|
|
|
|
Additional_manifests []string `android:"path"`
|
2019-10-28 23:50:06 +01:00
|
|
|
|
|
|
|
// do not include AndroidManifest from dependent libraries
|
|
|
|
Dont_merge_manifests *bool
|
2020-10-07 03:56:10 +02:00
|
|
|
|
2023-06-21 07:40:02 +02:00
|
|
|
// If use_resource_processor is set, use Bazel's resource processor instead of aapt2 to generate R.class files.
|
|
|
|
// The resource processor produces more optimal R.class files that only list resources in the package of the
|
|
|
|
// library that provided them, as opposed to aapt2 which produces R.java files for every package containing
|
|
|
|
// every resource. Using the resource processor can provide significant build time speedups, but requires
|
|
|
|
// fixing the module to use the correct package to reference each resource, and to avoid having any other
|
|
|
|
// libraries in the tree that use the same package name. Defaults to false, but will default to true in the
|
|
|
|
// future.
|
|
|
|
Use_resource_processor *bool
|
|
|
|
|
2020-10-07 03:56:10 +02:00
|
|
|
// true if RRO is enforced for any of the dependent modules
|
|
|
|
RROEnforcedForDependent bool `blueprint:"mutated"`
|
2023-11-07 05:37:14 +01:00
|
|
|
|
|
|
|
// Filter only specified product and ignore other products
|
|
|
|
Filter_product *string `blueprint:"mutated"`
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type aapt struct {
|
2023-11-22 00:13:56 +01:00
|
|
|
aaptSrcJar android.Path
|
|
|
|
transitiveAaptRJars android.Paths
|
|
|
|
transitiveAaptResourcePackagesFile android.Path
|
|
|
|
exportPackage android.Path
|
|
|
|
manifestPath android.Path
|
|
|
|
proguardOptionsFile android.Path
|
|
|
|
rTxt android.Path
|
|
|
|
rJar android.Path
|
|
|
|
extraAaptPackagesFile android.Path
|
|
|
|
mergedManifestFile android.Path
|
|
|
|
noticeFile android.OptionalPath
|
|
|
|
assetPackage android.OptionalPath
|
|
|
|
isLibrary bool
|
|
|
|
defaultManifestVersion string
|
|
|
|
useEmbeddedNativeLibs bool
|
|
|
|
useEmbeddedDex bool
|
|
|
|
usesNonSdkApis bool
|
|
|
|
hasNoCode bool
|
|
|
|
LoggingParent string
|
|
|
|
resourceFiles android.Paths
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2019-03-20 00:03:11 +01:00
|
|
|
splitNames []string
|
|
|
|
splits []split
|
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
aaptProperties aaptProperties
|
2023-07-14 19:23:41 +02:00
|
|
|
|
|
|
|
resourcesNodesDepSet *android.DepSet[*resourcesNode]
|
|
|
|
rroDirsDepSet *android.DepSet[rroDir]
|
|
|
|
manifestsDepSet *android.DepSet[android.Path]
|
2023-08-31 17:48:23 +02:00
|
|
|
|
|
|
|
manifestValues struct {
|
|
|
|
applicationId string
|
|
|
|
}
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
2019-03-20 00:03:11 +01:00
|
|
|
type split struct {
|
|
|
|
name string
|
|
|
|
suffix string
|
|
|
|
path android.Path
|
|
|
|
}
|
|
|
|
|
2020-10-07 03:56:10 +02:00
|
|
|
// Propagate RRO enforcement flag to static lib dependencies transitively.
|
|
|
|
func propagateRROEnforcementMutator(ctx android.TopDownMutatorContext) {
|
|
|
|
m := ctx.Module()
|
|
|
|
if d, ok := m.(AndroidLibraryDependency); ok && d.IsRROEnforced(ctx) {
|
|
|
|
ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) {
|
|
|
|
if a, ok := d.(AndroidLibraryDependency); ok {
|
|
|
|
a.SetRROEnforcedForDependent(true)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-21 07:40:02 +02:00
|
|
|
func (a *aapt) useResourceProcessorBusyBox() bool {
|
|
|
|
return BoolDefault(a.aaptProperties.Use_resource_processor, false)
|
|
|
|
}
|
|
|
|
|
2023-11-07 05:37:14 +01:00
|
|
|
func (a *aapt) filterProduct() string {
|
|
|
|
return String(a.aaptProperties.Filter_product)
|
|
|
|
}
|
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
func (a *aapt) ExportPackage() android.Path {
|
|
|
|
return a.exportPackage
|
|
|
|
}
|
2023-07-14 19:23:41 +02:00
|
|
|
func (a *aapt) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
|
|
|
|
return a.resourcesNodesDepSet
|
2019-01-31 20:42:41 +01:00
|
|
|
}
|
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
func (a *aapt) RRODirsDepSet() *android.DepSet[rroDir] {
|
|
|
|
return a.rroDirsDepSet
|
2019-01-31 20:42:41 +01:00
|
|
|
}
|
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
func (a *aapt) ManifestsDepSet() *android.DepSet[android.Path] {
|
|
|
|
return a.manifestsDepSet
|
2020-01-15 23:15:10 +01:00
|
|
|
}
|
|
|
|
|
2020-10-07 03:56:10 +02:00
|
|
|
func (a *aapt) SetRROEnforcedForDependent(enforce bool) {
|
|
|
|
a.aaptProperties.RROEnforcedForDependent = enforce
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *aapt) IsRROEnforced(ctx android.BaseModuleContext) bool {
|
|
|
|
// True if RRO is enforced for this module or...
|
|
|
|
return ctx.Config().EnforceRROForModule(ctx.ModuleName()) ||
|
2021-02-19 04:11:51 +01:00
|
|
|
// if RRO is enforced for any of its dependents.
|
|
|
|
a.aaptProperties.RROEnforcedForDependent
|
2020-10-07 03:56:10 +02:00
|
|
|
}
|
|
|
|
|
2021-03-29 13:11:58 +02:00
|
|
|
func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext android.SdkContext,
|
2019-06-22 21:59:27 +02:00
|
|
|
manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
|
|
|
|
resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2020-02-11 16:54:35 +01:00
|
|
|
hasVersionCode := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-code")
|
|
|
|
hasVersionName := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-name")
|
2018-03-28 23:58:31 +02:00
|
|
|
|
|
|
|
// Flags specified in Android.bp
|
|
|
|
linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
|
|
|
|
|
|
|
|
// Find implicit or explicit asset and resource dirs
|
2023-10-13 19:08:59 +02:00
|
|
|
assets := android.PathsRelativeToModuleSourceDir(android.SourceInput{
|
|
|
|
Context: ctx,
|
|
|
|
Paths: a.aaptProperties.Assets,
|
|
|
|
IncludeDirs: false,
|
|
|
|
})
|
2018-03-28 23:58:31 +02:00
|
|
|
assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
|
|
|
|
resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
|
2019-03-06 07:25:09 +01:00
|
|
|
resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
|
2018-03-28 23:58:31 +02:00
|
|
|
|
|
|
|
// Glob directories into lists of paths
|
|
|
|
for _, dir := range resourceDirs {
|
|
|
|
resDirs = append(resDirs, globbedResourceDir{
|
|
|
|
dir: dir,
|
|
|
|
files: androidResourceGlob(ctx, dir),
|
|
|
|
})
|
2020-10-07 03:56:10 +02:00
|
|
|
resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, a, dir)
|
2018-03-28 23:58:31 +02:00
|
|
|
overlayDirs = append(overlayDirs, resOverlayDirs...)
|
|
|
|
rroDirs = append(rroDirs, resRRODirs...)
|
|
|
|
}
|
|
|
|
|
2020-11-10 21:27:45 +01:00
|
|
|
var assetDeps android.Paths
|
|
|
|
for i, dir := range assetDirs {
|
|
|
|
// Add a dependency on every file in the asset directory. This ensures the aapt2
|
|
|
|
// rule will be rerun if one of the files in the asset directory is modified.
|
|
|
|
assetDeps = append(assetDeps, androidResourceGlob(ctx, dir)...)
|
|
|
|
|
|
|
|
// Add a dependency on a file that contains a list of all the files in the asset directory.
|
|
|
|
// This ensures the aapt2 rule will be run if a file is removed from the asset directory,
|
|
|
|
// or a file is added whose timestamp is older than the output of aapt2.
|
|
|
|
assetFileListFile := android.PathForModuleOut(ctx, "asset_dir_globs", strconv.Itoa(i)+".glob")
|
|
|
|
androidResourceGlobList(ctx, dir, assetFileListFile)
|
|
|
|
assetDeps = append(assetDeps, assetFileListFile)
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
2019-06-18 02:40:56 +02:00
|
|
|
assetDirStrings := assetDirs.Strings()
|
|
|
|
if a.noticeFile.Valid() {
|
|
|
|
assetDirStrings = append(assetDirStrings, filepath.Dir(a.noticeFile.Path().String()))
|
2020-11-10 21:27:45 +01:00
|
|
|
assetDeps = append(assetDeps, a.noticeFile.Path())
|
2019-06-18 02:40:56 +02:00
|
|
|
}
|
2023-10-13 19:08:59 +02:00
|
|
|
if len(assets) > 0 {
|
|
|
|
// aapt2 doesn't support adding individual asset files. Create a temp directory to hold asset
|
|
|
|
// files and pass it to aapt2.
|
|
|
|
tmpAssetDir := android.PathForModuleOut(ctx, "tmp_asset_dir")
|
|
|
|
|
|
|
|
rule := android.NewRuleBuilder(pctx, ctx)
|
|
|
|
rule.Command().
|
|
|
|
Text("rm -rf").Text(tmpAssetDir.String()).
|
|
|
|
Text("&&").
|
|
|
|
Text("mkdir -p").Text(tmpAssetDir.String())
|
|
|
|
|
|
|
|
for _, asset := range assets {
|
|
|
|
output := tmpAssetDir.Join(ctx, asset.Rel())
|
|
|
|
assetDeps = append(assetDeps, output)
|
|
|
|
rule.Command().Text("mkdir -p").Text(filepath.Dir(output.String()))
|
|
|
|
rule.Command().Text("cp").Input(asset).Output(output)
|
|
|
|
}
|
|
|
|
|
|
|
|
rule.Build("tmp_asset_dir", "tmp_asset_dir")
|
|
|
|
|
|
|
|
assetDirStrings = append(assetDirStrings, tmpAssetDir.String())
|
|
|
|
}
|
2019-06-18 02:40:56 +02:00
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
|
|
|
|
linkDeps = append(linkDeps, manifestPath)
|
|
|
|
|
2019-06-18 02:40:56 +02:00
|
|
|
linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirStrings, "-A "))
|
2020-11-10 21:27:45 +01:00
|
|
|
linkDeps = append(linkDeps, assetDeps...)
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2023-02-23 22:31:33 +01:00
|
|
|
// Returns the effective version for {min|target}_sdk_version
|
2023-03-03 22:20:36 +01:00
|
|
|
effectiveVersionString := func(sdkVersion android.SdkSpec, minSdkVersion android.ApiLevel) string {
|
2023-02-23 22:31:33 +01:00
|
|
|
// If {min|target}_sdk_version is current, use sdk_version to determine the effective level
|
|
|
|
// This is necessary for vendor modules.
|
|
|
|
// The effective version does not _only_ depend on {min|target}_sdk_version(level),
|
|
|
|
// but also on the sdk_version (kind+level)
|
2023-03-03 22:20:36 +01:00
|
|
|
if minSdkVersion.IsCurrent() {
|
2023-02-23 22:31:33 +01:00
|
|
|
ret, err := sdkVersion.EffectiveVersionString(ctx)
|
|
|
|
if err != nil {
|
|
|
|
ctx.ModuleErrorf("invalid sdk_version: %s", err)
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
|
|
|
ret, err := minSdkVersion.EffectiveVersionString(ctx)
|
|
|
|
if err != nil {
|
|
|
|
ctx.ModuleErrorf("invalid min_sdk_version: %s", err)
|
|
|
|
}
|
|
|
|
return ret
|
Abstract sdk_version string using sdkSpec type
The value format that sdk_version (and min_sdk_version, etc.) can have
has consistently evolved and is quite complicated. Furthermore, with the
Mainline module effort, we are expected to have more sdk_versions like
'module-app-current', 'module-lib-current', etc.
The goal of this change is to abstract the various sdk versions, which
are currently represented in string and is parsed in various places,
into a type called sdkSpec, so that adding new sdk veresions becomes
easier than before.
The sdk_version string is now parsed in only one place 'SdkSpecFrom', in
which it is converted into the sdkSpec struct. The struct type provides
several methods that again converts sdkSpec into context-specific
information such as the effective version number, etc.
Bug: 146757305
Bug: 147879031
Test: m
Change-Id: I252f3706544f00ea71c61c23460f07561dd28ab0
2020-01-20 18:03:43 +01:00
|
|
|
}
|
2023-02-23 22:31:33 +01:00
|
|
|
// SDK version flags
|
|
|
|
sdkVersion := sdkContext.SdkVersion(ctx)
|
|
|
|
minSdkVersion := effectiveVersionString(sdkVersion, sdkContext.MinSdkVersion(ctx))
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2018-06-26 00:48:06 +02:00
|
|
|
linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion)
|
2023-02-23 20:27:07 +01:00
|
|
|
// Use minSdkVersion for target-sdk-version, even if `target_sdk_version` is set
|
|
|
|
// This behavior has been copied from Make.
|
2018-06-26 00:48:06 +02:00
|
|
|
linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion)
|
2018-03-28 23:58:31 +02:00
|
|
|
|
|
|
|
// Version code
|
|
|
|
if !hasVersionCode {
|
2020-07-24 02:32:15 +02:00
|
|
|
linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion().String())
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if !hasVersionName {
|
2018-04-25 23:54:06 +02:00
|
|
|
var versionName string
|
|
|
|
if ctx.ModuleName() == "framework-res" {
|
|
|
|
// Some builds set AppsDefaultVersionName() to include the build number ("O-123456"). aapt2 copies the
|
|
|
|
// version name of framework-res into app manifests as compileSdkVersionCodename, which confuses things
|
2018-05-09 20:11:35 +02:00
|
|
|
// if it contains the build number. Use the PlatformVersionName instead.
|
|
|
|
versionName = ctx.Config().PlatformVersionName()
|
2018-04-25 23:54:06 +02:00
|
|
|
} else {
|
|
|
|
versionName = ctx.Config().AppsDefaultVersionName()
|
|
|
|
}
|
2019-02-28 20:00:01 +01:00
|
|
|
versionName = proptools.NinjaEscape(versionName)
|
2018-03-28 23:58:31 +02:00
|
|
|
linkFlags = append(linkFlags, "--version-name ", versionName)
|
|
|
|
}
|
|
|
|
|
2019-06-22 21:59:27 +02:00
|
|
|
linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
|
|
|
|
|
|
|
|
// Always set --pseudo-localize, it will be stripped out later for release
|
|
|
|
// builds that don't want it.
|
|
|
|
compileFlags = append(compileFlags, "--pseudo-localize")
|
|
|
|
|
|
|
|
return compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
2019-06-07 11:44:37 +02:00
|
|
|
func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) {
|
2018-11-15 06:44:17 +01:00
|
|
|
if sdkDep.frameworkResModule != "" {
|
|
|
|
ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
2018-02-21 02:22:23 +01:00
|
|
|
}
|
|
|
|
|
2020-01-15 23:15:10 +01:00
|
|
|
var extractAssetsRule = pctx.AndroidStaticRule("extractAssets",
|
|
|
|
blueprint.RuleParams{
|
|
|
|
Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`,
|
|
|
|
CommandDeps: []string{"${config.Zip2ZipCmd}"},
|
|
|
|
})
|
|
|
|
|
2023-09-27 18:47:56 +02:00
|
|
|
type aaptBuildActionOptions struct {
|
|
|
|
sdkContext android.SdkContext
|
|
|
|
classLoaderContexts dexpreopt.ClassLoaderContextMap
|
|
|
|
excludedLibs []string
|
|
|
|
enforceDefaultTargetSdkVersion bool
|
|
|
|
extraLinkFlags []string
|
2023-12-01 23:01:06 +01:00
|
|
|
aconfigTextFiles android.Paths
|
2023-09-27 18:47:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptions) {
|
2019-05-22 19:46:27 +02:00
|
|
|
|
2023-10-13 00:58:57 +02:00
|
|
|
staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedExportPackages, libFlags :=
|
2023-09-27 18:47:56 +02:00
|
|
|
aaptLibs(ctx, opts.sdkContext, opts.classLoaderContexts)
|
2020-08-14 18:32:16 +02:00
|
|
|
|
2022-02-03 18:54:15 +01:00
|
|
|
// Exclude any libraries from the supplied list.
|
2023-09-27 18:47:56 +02:00
|
|
|
opts.classLoaderContexts = opts.classLoaderContexts.ExcludeLibs(opts.excludedLibs)
|
2022-02-03 18:54:15 +01:00
|
|
|
|
2018-05-25 01:11:20 +02:00
|
|
|
// App manifest file
|
|
|
|
manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
|
|
|
|
manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2022-02-10 14:28:35 +01:00
|
|
|
manifestPath := ManifestFixer(ctx, manifestSrcPath, ManifestFixerParams{
|
2023-09-27 18:47:56 +02:00
|
|
|
SdkContext: opts.sdkContext,
|
|
|
|
ClassLoaderContexts: opts.classLoaderContexts,
|
2022-06-10 13:24:05 +02:00
|
|
|
IsLibrary: a.isLibrary,
|
|
|
|
DefaultManifestVersion: a.defaultManifestVersion,
|
|
|
|
UseEmbeddedNativeLibs: a.useEmbeddedNativeLibs,
|
|
|
|
UsesNonSdkApis: a.usesNonSdkApis,
|
|
|
|
UseEmbeddedDex: a.useEmbeddedDex,
|
|
|
|
HasNoCode: a.hasNoCode,
|
|
|
|
LoggingParent: a.LoggingParent,
|
2023-09-27 18:47:56 +02:00
|
|
|
EnforceDefaultTargetSdkVersion: opts.enforceDefaultTargetSdkVersion,
|
2022-01-24 18:44:05 +01:00
|
|
|
})
|
2019-04-20 01:22:57 +02:00
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
|
2023-10-13 00:58:57 +02:00
|
|
|
sharedDeps := transitiveAarDeps(sharedResourcesNodesDepSet.ToList())
|
2023-07-14 19:23:41 +02:00
|
|
|
|
2019-09-10 22:13:31 +02:00
|
|
|
// Add additional manifest files to transitive manifests.
|
|
|
|
additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
|
2023-07-14 19:23:41 +02:00
|
|
|
transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...)
|
|
|
|
// TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
|
|
|
|
// modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
|
|
|
|
// of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
|
|
|
|
// android_library_import modules. If this is fixed, staticManifestsDepSet can be dropped completely in favor of
|
|
|
|
// staticResourcesNodesDepSet.manifests()
|
|
|
|
transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...)
|
|
|
|
|
|
|
|
if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) {
|
2023-09-27 18:47:56 +02:00
|
|
|
manifestMergerParams := ManifestMergerParams{
|
|
|
|
staticLibManifests: transitiveManifestPaths[1:],
|
2023-08-31 17:48:23 +02:00
|
|
|
isLibrary: a.isLibrary,
|
|
|
|
packageName: a.manifestValues.applicationId,
|
|
|
|
}
|
2023-09-27 18:47:56 +02:00
|
|
|
a.mergedManifestFile = manifestMerger(ctx, transitiveManifestPaths[0], manifestMergerParams)
|
2019-04-20 01:22:57 +02:00
|
|
|
if !a.isLibrary {
|
|
|
|
// Only use the merged manifest for applications. For libraries, the transitive closure of manifests
|
|
|
|
// will be propagated to the final application and merged there. The merged manifest for libraries is
|
|
|
|
// only passed to Make, which can't handle transitive dependencies.
|
|
|
|
manifestPath = a.mergedManifestFile
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
a.mergedManifestFile = manifestPath
|
|
|
|
}
|
2018-05-25 01:11:20 +02:00
|
|
|
|
2023-09-27 18:47:56 +02:00
|
|
|
compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, opts.sdkContext, manifestPath)
|
2018-05-25 01:11:20 +02:00
|
|
|
|
|
|
|
linkFlags = append(linkFlags, libFlags...)
|
2023-10-13 00:58:57 +02:00
|
|
|
linkDeps = append(linkDeps, sharedExportPackages...)
|
2023-07-14 19:23:41 +02:00
|
|
|
linkDeps = append(linkDeps, staticDeps.resPackages()...)
|
2023-09-27 18:47:56 +02:00
|
|
|
linkFlags = append(linkFlags, opts.extraLinkFlags...)
|
2018-07-24 23:51:30 +02:00
|
|
|
if a.isLibrary {
|
|
|
|
linkFlags = append(linkFlags, "--static-lib")
|
|
|
|
}
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2023-06-21 07:40:02 +02:00
|
|
|
if a.isLibrary && a.useResourceProcessorBusyBox() {
|
|
|
|
// When building an android_library using ResourceProcessorBusyBox the resources are merged into
|
|
|
|
// package-res.apk with --merge-only, but --no-static-lib-packages is not used so that R.txt only
|
|
|
|
// contains resources from this library.
|
|
|
|
linkFlags = append(linkFlags, "--merge-only")
|
|
|
|
} else {
|
|
|
|
// When building and app or when building an android_library without ResourceProcessorBusyBox
|
|
|
|
// --no-static-lib-packages is used to put all the resources into the app. If ResourceProcessorBusyBox
|
|
|
|
// is used then the app's R.txt will be post-processed along with the R.txt files from dependencies to
|
|
|
|
// sort resources into the right packages in R.class.
|
|
|
|
linkFlags = append(linkFlags, "--no-static-lib-packages")
|
|
|
|
}
|
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
packageRes := android.PathForModuleOut(ctx, "package-res.apk")
|
|
|
|
proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
|
|
|
|
rTxt := android.PathForModuleOut(ctx, "R.txt")
|
2018-05-02 21:58:28 +02:00
|
|
|
// This file isn't used by Soong, but is generated for exporting
|
|
|
|
extraPackages := android.PathForModuleOut(ctx, "extra_packages")
|
2023-06-21 07:40:02 +02:00
|
|
|
var transitiveRJars android.Paths
|
2023-08-03 00:49:00 +02:00
|
|
|
var srcJar android.WritablePath
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2018-08-22 00:14:37 +02:00
|
|
|
var compiledResDirs []android.Paths
|
2018-03-28 23:58:31 +02:00
|
|
|
for _, dir := range resDirs {
|
2020-06-03 05:09:13 +02:00
|
|
|
a.resourceFiles = append(a.resourceFiles, dir.files...)
|
2023-11-07 05:37:14 +01:00
|
|
|
compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files, compileFlags, a.filterProduct()).Paths())
|
2018-08-22 00:14:37 +02:00
|
|
|
}
|
|
|
|
|
2019-02-20 01:59:53 +01:00
|
|
|
for i, zip := range resZips {
|
|
|
|
flata := android.PathForModuleOut(ctx, fmt.Sprintf("reszip.%d.flata", i))
|
2019-06-22 21:59:27 +02:00
|
|
|
aapt2CompileZip(ctx, flata, zip, "", compileFlags)
|
2019-02-20 01:59:53 +01:00
|
|
|
compiledResDirs = append(compiledResDirs, android.Paths{flata})
|
|
|
|
}
|
|
|
|
|
2018-08-22 00:14:37 +02:00
|
|
|
var compiledRes, compiledOverlay android.Paths
|
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
// AAPT2 overlays are in lowest to highest priority order, reverse the topological order
|
|
|
|
// of transitiveStaticLibs.
|
|
|
|
transitiveStaticLibs := android.ReversePaths(staticDeps.resPackages())
|
|
|
|
|
2023-06-21 07:40:02 +02:00
|
|
|
if a.isLibrary && a.useResourceProcessorBusyBox() {
|
|
|
|
// When building an android_library with ResourceProcessorBusyBox enabled treat static library dependencies
|
|
|
|
// as imports. The resources from dependencies will not be merged into this module's package-res.apk, and
|
|
|
|
// instead modules depending on this module will reference package-res.apk from all transitive static
|
|
|
|
// dependencies.
|
|
|
|
for _, staticDep := range staticDeps {
|
|
|
|
linkDeps = append(linkDeps, staticDep.resPackage)
|
|
|
|
linkFlags = append(linkFlags, "-I "+staticDep.resPackage.String())
|
|
|
|
if staticDep.usedResourceProcessor {
|
|
|
|
transitiveRJars = append(transitiveRJars, staticDep.rJar)
|
|
|
|
}
|
|
|
|
}
|
2023-10-13 00:58:57 +02:00
|
|
|
for _, sharedDep := range sharedDeps {
|
|
|
|
if sharedDep.usedResourceProcessor {
|
|
|
|
transitiveRJars = append(transitiveRJars, sharedDep.rJar)
|
|
|
|
}
|
|
|
|
}
|
2023-06-21 07:40:02 +02:00
|
|
|
} else {
|
|
|
|
// When building an app or building a library without ResourceProcessorBusyBox enabled all static
|
|
|
|
// dependencies are compiled into this module's package-res.apk as overlays.
|
|
|
|
compiledOverlay = append(compiledOverlay, transitiveStaticLibs...)
|
|
|
|
}
|
2018-08-22 00:14:37 +02:00
|
|
|
|
2019-02-13 22:15:46 +01:00
|
|
|
if len(transitiveStaticLibs) > 0 {
|
2018-08-22 00:14:37 +02:00
|
|
|
// If we are using static android libraries, every source file becomes an overlay.
|
|
|
|
// This is to emulate old AAPT behavior which simulated library support.
|
|
|
|
for _, compiledResDir := range compiledResDirs {
|
|
|
|
compiledOverlay = append(compiledOverlay, compiledResDir...)
|
|
|
|
}
|
2019-02-13 22:15:46 +01:00
|
|
|
} else if a.isLibrary {
|
|
|
|
// Otherwise, for a static library we treat all the resources equally with no overlay.
|
|
|
|
for _, compiledResDir := range compiledResDirs {
|
|
|
|
compiledRes = append(compiledRes, compiledResDir...)
|
|
|
|
}
|
2018-08-22 00:14:37 +02:00
|
|
|
} else if len(compiledResDirs) > 0 {
|
|
|
|
// Without static libraries, the first directory is our directory, which can then be
|
|
|
|
// overlaid by the rest.
|
|
|
|
compiledRes = append(compiledRes, compiledResDirs[0]...)
|
|
|
|
for _, compiledResDir := range compiledResDirs[1:] {
|
|
|
|
compiledOverlay = append(compiledOverlay, compiledResDir...)
|
|
|
|
}
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
2018-08-22 00:14:37 +02:00
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
for _, dir := range overlayDirs {
|
2023-11-07 05:37:14 +01:00
|
|
|
compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files, compileFlags, a.filterProduct()).Paths()...)
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
2019-03-20 00:03:11 +01:00
|
|
|
var splitPackages android.WritablePaths
|
|
|
|
var splits []split
|
|
|
|
|
|
|
|
for _, s := range a.splitNames {
|
|
|
|
suffix := strings.Replace(s, ",", "_", -1)
|
|
|
|
path := android.PathForModuleOut(ctx, "package_"+suffix+".apk")
|
|
|
|
linkFlags = append(linkFlags, "--split", path.String()+":"+s)
|
|
|
|
splitPackages = append(splitPackages, path)
|
|
|
|
splits = append(splits, split{
|
|
|
|
name: s,
|
|
|
|
suffix: suffix,
|
|
|
|
path: path,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-08-03 00:49:00 +02:00
|
|
|
if !a.useResourceProcessorBusyBox() {
|
|
|
|
// the subdir "android" is required to be filtered by package names
|
|
|
|
srcJar = android.PathForModuleGen(ctx, "android", "R.srcjar")
|
|
|
|
}
|
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
// No need to specify assets from dependencies to aapt2Link for libraries, all transitive assets will be
|
|
|
|
// provided to the final app aapt2Link step.
|
|
|
|
var transitiveAssets android.Paths
|
|
|
|
if !a.isLibrary {
|
|
|
|
transitiveAssets = android.ReverseSliceInPlace(staticDeps.assets())
|
|
|
|
}
|
2023-08-03 00:49:00 +02:00
|
|
|
aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt,
|
2023-12-01 23:01:06 +01:00
|
|
|
linkFlags, linkDeps, compiledRes, compiledOverlay, transitiveAssets, splitPackages,
|
|
|
|
opts.aconfigTextFiles)
|
2020-01-15 23:15:10 +01:00
|
|
|
// Extract assets from the resource package output so that they can be used later in aapt2link
|
|
|
|
// for modules that depend on this one.
|
2023-07-14 19:23:41 +02:00
|
|
|
if android.PrefixInList(linkFlags, "-A ") {
|
2020-01-15 23:15:10 +01:00
|
|
|
assets := android.PathForModuleOut(ctx, "assets.zip")
|
|
|
|
ctx.Build(pctx, android.BuildParams{
|
|
|
|
Rule: extractAssetsRule,
|
|
|
|
Input: packageRes,
|
|
|
|
Output: assets,
|
|
|
|
Description: "extract assets from built resource file",
|
|
|
|
})
|
|
|
|
a.assetPackage = android.OptionalPathForPath(assets)
|
|
|
|
}
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2023-06-21 07:40:02 +02:00
|
|
|
if a.useResourceProcessorBusyBox() {
|
|
|
|
rJar := android.PathForModuleOut(ctx, "busybox/R.jar")
|
|
|
|
resourceProcessorBusyBoxGenerateBinaryR(ctx, rTxt, a.mergedManifestFile, rJar, staticDeps, a.isLibrary)
|
2023-08-03 00:49:00 +02:00
|
|
|
aapt2ExtractExtraPackages(ctx, extraPackages, rJar)
|
2023-06-21 07:40:02 +02:00
|
|
|
transitiveRJars = append(transitiveRJars, rJar)
|
|
|
|
a.rJar = rJar
|
2023-08-03 00:49:00 +02:00
|
|
|
} else {
|
|
|
|
aapt2ExtractExtraPackages(ctx, extraPackages, srcJar)
|
2023-06-21 07:40:02 +02:00
|
|
|
}
|
|
|
|
|
2023-11-22 00:13:56 +01:00
|
|
|
transitiveAaptResourcePackages := staticDeps.resPackages().Strings()
|
|
|
|
transitiveAaptResourcePackages = slices.DeleteFunc(transitiveAaptResourcePackages, func(p string) bool {
|
|
|
|
return p == packageRes.String()
|
|
|
|
})
|
|
|
|
transitiveAaptResourcePackagesFile := android.PathForModuleOut(ctx, "transitive-res-packages")
|
|
|
|
android.WriteFileRule(ctx, transitiveAaptResourcePackagesFile, strings.Join(transitiveAaptResourcePackages, "\n"))
|
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
a.aaptSrcJar = srcJar
|
2023-06-21 07:40:02 +02:00
|
|
|
a.transitiveAaptRJars = transitiveRJars
|
2023-11-22 00:13:56 +01:00
|
|
|
a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
|
2018-03-28 23:58:31 +02:00
|
|
|
a.exportPackage = packageRes
|
|
|
|
a.manifestPath = manifestPath
|
|
|
|
a.proguardOptionsFile = proguardOptionsFile
|
2018-05-02 21:58:28 +02:00
|
|
|
a.extraAaptPackagesFile = extraPackages
|
2018-03-28 23:58:31 +02:00
|
|
|
a.rTxt = rTxt
|
2019-03-20 00:03:11 +01:00
|
|
|
a.splits = splits
|
2023-07-14 19:23:41 +02:00
|
|
|
a.resourcesNodesDepSet = android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL).
|
|
|
|
Direct(&resourcesNode{
|
|
|
|
resPackage: a.exportPackage,
|
|
|
|
manifest: a.manifestPath,
|
|
|
|
additionalManifests: additionalManifests,
|
2023-06-21 07:40:02 +02:00
|
|
|
rTxt: a.rTxt,
|
|
|
|
rJar: a.rJar,
|
2023-07-14 19:23:41 +02:00
|
|
|
assets: a.assetPackage,
|
2023-06-21 07:40:02 +02:00
|
|
|
|
|
|
|
usedResourceProcessor: a.useResourceProcessorBusyBox(),
|
2023-07-14 19:23:41 +02:00
|
|
|
}).
|
|
|
|
Transitive(staticResourcesNodesDepSet).Build()
|
|
|
|
a.rroDirsDepSet = android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL).
|
|
|
|
Direct(rroDirs...).
|
|
|
|
Transitive(staticRRODirsDepSet).Build()
|
|
|
|
a.manifestsDepSet = android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).
|
|
|
|
Direct(a.manifestPath).
|
|
|
|
DirectSlice(additionalManifests).
|
|
|
|
Transitive(staticManifestsDepSet).Build()
|
|
|
|
}
|
|
|
|
|
2023-06-21 07:40:02 +02:00
|
|
|
var resourceProcessorBusyBox = pctx.AndroidStaticRule("resourceProcessorBusyBox",
|
|
|
|
blueprint.RuleParams{
|
|
|
|
Command: "${config.JavaCmd} -cp ${config.ResourceProcessorBusyBox} " +
|
|
|
|
"com.google.devtools.build.android.ResourceProcessorBusyBox --tool=GENERATE_BINARY_R -- @${out}.args && " +
|
|
|
|
"if cmp -s ${out}.tmp ${out} ; then rm ${out}.tmp ; else mv ${out}.tmp ${out}; fi",
|
|
|
|
CommandDeps: []string{"${config.ResourceProcessorBusyBox}"},
|
|
|
|
Rspfile: "${out}.args",
|
|
|
|
RspfileContent: "--primaryRTxt ${rTxt} --primaryManifest ${manifest} --classJarOutput ${out}.tmp ${args}",
|
|
|
|
Restat: true,
|
|
|
|
}, "rTxt", "manifest", "args")
|
|
|
|
|
|
|
|
// resourceProcessorBusyBoxGenerateBinaryR converts the R.txt file produced by aapt2 into R.class files
|
|
|
|
// using Bazel's ResourceProcessorBusyBox tool, which is faster than compiling the R.java files and
|
|
|
|
// supports producing classes for static dependencies that only include resources from that dependency.
|
|
|
|
func resourceProcessorBusyBoxGenerateBinaryR(ctx android.ModuleContext, rTxt, manifest android.Path,
|
|
|
|
rJar android.WritablePath, transitiveDeps transitiveAarDeps, isLibrary bool) {
|
|
|
|
|
|
|
|
var args []string
|
|
|
|
var deps android.Paths
|
|
|
|
|
|
|
|
if !isLibrary {
|
|
|
|
// When compiling an app, pass all R.txt and AndroidManifest.xml from transitive static library dependencies
|
|
|
|
// to ResourceProcessorBusyBox so that it can regenerate R.class files with the final resource IDs for each
|
|
|
|
// package.
|
|
|
|
args, deps = transitiveDeps.resourceProcessorDeps()
|
|
|
|
} else {
|
|
|
|
// When compiling a library don't pass any dependencies as it only needs to generate an R.class file for this
|
|
|
|
// library. Pass --finalFields=false so that the R.class file contains non-final fields so they don't get
|
|
|
|
// inlined into the library before the final IDs are assigned during app compilation.
|
|
|
|
args = append(args, "--finalFields=false")
|
|
|
|
}
|
|
|
|
|
|
|
|
deps = append(deps, rTxt, manifest)
|
|
|
|
|
|
|
|
ctx.Build(pctx, android.BuildParams{
|
|
|
|
Rule: resourceProcessorBusyBox,
|
|
|
|
Output: rJar,
|
|
|
|
Implicits: deps,
|
|
|
|
Description: "ResourceProcessorBusyBox",
|
|
|
|
Args: map[string]string{
|
|
|
|
"rTxt": rTxt.String(),
|
|
|
|
"manifest": manifest.String(),
|
|
|
|
"args": strings.Join(args, " "),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
type resourcesNode struct {
|
|
|
|
resPackage android.Path
|
|
|
|
manifest android.Path
|
|
|
|
additionalManifests android.Paths
|
2023-06-21 07:40:02 +02:00
|
|
|
rTxt android.Path
|
|
|
|
rJar android.Path
|
2023-07-14 19:23:41 +02:00
|
|
|
assets android.OptionalPath
|
2023-06-21 07:40:02 +02:00
|
|
|
|
|
|
|
usedResourceProcessor bool
|
2023-07-14 19:23:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type transitiveAarDeps []*resourcesNode
|
|
|
|
|
|
|
|
func (t transitiveAarDeps) resPackages() android.Paths {
|
2023-06-21 07:40:02 +02:00
|
|
|
paths := make(android.Paths, 0, len(t))
|
2023-07-14 19:23:41 +02:00
|
|
|
for _, dep := range t {
|
|
|
|
paths = append(paths, dep.resPackage)
|
|
|
|
}
|
2023-06-21 07:40:02 +02:00
|
|
|
return paths
|
2023-07-14 19:23:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t transitiveAarDeps) manifests() android.Paths {
|
2023-06-21 07:40:02 +02:00
|
|
|
paths := make(android.Paths, 0, len(t))
|
2023-07-14 19:23:41 +02:00
|
|
|
for _, dep := range t {
|
|
|
|
paths = append(paths, dep.manifest)
|
|
|
|
paths = append(paths, dep.additionalManifests...)
|
|
|
|
}
|
2023-06-21 07:40:02 +02:00
|
|
|
return paths
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t transitiveAarDeps) resourceProcessorDeps() (args []string, deps android.Paths) {
|
|
|
|
for _, dep := range t {
|
|
|
|
args = append(args, "--library="+dep.rTxt.String()+","+dep.manifest.String())
|
|
|
|
deps = append(deps, dep.rTxt, dep.manifest)
|
|
|
|
}
|
|
|
|
return args, deps
|
2023-07-14 19:23:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t transitiveAarDeps) assets() android.Paths {
|
2023-06-21 07:40:02 +02:00
|
|
|
paths := make(android.Paths, 0, len(t))
|
2023-07-14 19:23:41 +02:00
|
|
|
for _, dep := range t {
|
|
|
|
if dep.assets.Valid() {
|
|
|
|
paths = append(paths, dep.assets.Path())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return paths
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
|
2021-03-29 13:11:58 +02:00
|
|
|
func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoaderContexts dexpreopt.ClassLoaderContextMap) (
|
2023-10-13 00:58:57 +02:00
|
|
|
staticResourcesNodes, sharedResourcesNodes *android.DepSet[*resourcesNode], staticRRODirs *android.DepSet[rroDir],
|
2023-07-14 19:23:41 +02:00
|
|
|
staticManifests *android.DepSet[android.Path], sharedLibs android.Paths, flags []string) {
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2020-10-08 13:53:58 +02:00
|
|
|
if classLoaderContexts == nil {
|
2020-11-03 16:55:11 +01:00
|
|
|
// Not all callers need to compute class loader context, those who don't just pass nil.
|
|
|
|
// Create a temporary class loader context here (it will be computed, but not used).
|
2020-10-08 13:53:58 +02:00
|
|
|
classLoaderContexts = make(dexpreopt.ClassLoaderContextMap)
|
2020-11-03 16:55:11 +01:00
|
|
|
}
|
|
|
|
|
2018-06-26 00:48:06 +02:00
|
|
|
sdkDep := decodeSdkDep(ctx, sdkContext)
|
2018-03-28 23:58:31 +02:00
|
|
|
if sdkDep.useFiles {
|
2018-05-29 23:44:55 +02:00
|
|
|
sharedLibs = append(sharedLibs, sdkDep.jars...)
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
2023-10-13 00:58:57 +02:00
|
|
|
var staticResourcesNodeDepSets []*android.DepSet[*resourcesNode]
|
|
|
|
var sharedResourcesNodeDepSets []*android.DepSet[*resourcesNode]
|
2023-07-14 19:23:41 +02:00
|
|
|
rroDirsDepSetBuilder := android.NewDepSetBuilder[rroDir](android.TOPOLOGICAL)
|
|
|
|
manifestsDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL)
|
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
ctx.VisitDirectDeps(func(module android.Module) {
|
2020-12-03 17:50:22 +01:00
|
|
|
depTag := ctx.OtherModuleDependencyTag(module)
|
2020-11-03 16:55:11 +01:00
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
var exportPackage android.Path
|
2018-05-02 21:58:28 +02:00
|
|
|
aarDep, _ := module.(AndroidLibraryDependency)
|
|
|
|
if aarDep != nil {
|
2018-03-28 23:58:31 +02:00
|
|
|
exportPackage = aarDep.ExportPackage()
|
|
|
|
}
|
|
|
|
|
2020-12-03 17:50:22 +01:00
|
|
|
switch depTag {
|
2018-10-16 01:18:06 +02:00
|
|
|
case instrumentationForTag:
|
|
|
|
// Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
|
2022-09-23 22:50:56 +02:00
|
|
|
case sdkLibTag, libTag:
|
2019-05-22 19:46:27 +02:00
|
|
|
if exportPackage != nil {
|
2023-10-13 00:58:57 +02:00
|
|
|
sharedResourcesNodeDepSets = append(sharedResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
|
2019-05-22 19:46:27 +02:00
|
|
|
sharedLibs = append(sharedLibs, exportPackage)
|
|
|
|
}
|
|
|
|
case frameworkResTag:
|
2018-03-28 23:58:31 +02:00
|
|
|
if exportPackage != nil {
|
|
|
|
sharedLibs = append(sharedLibs, exportPackage)
|
|
|
|
}
|
|
|
|
case staticLibTag:
|
|
|
|
if exportPackage != nil {
|
2023-10-13 00:58:57 +02:00
|
|
|
staticResourcesNodeDepSets = append(staticResourcesNodeDepSets, aarDep.ResourcesNodeDepSet())
|
2023-07-14 19:23:41 +02:00
|
|
|
rroDirsDepSetBuilder.Transitive(aarDep.RRODirsDepSet())
|
|
|
|
manifestsDepSetBuilder.Transitive(aarDep.ManifestsDepSet())
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
}
|
2020-11-03 16:55:11 +01:00
|
|
|
|
2020-12-16 17:16:11 +01:00
|
|
|
addCLCFromDep(ctx, module, classLoaderContexts)
|
2018-03-28 23:58:31 +02:00
|
|
|
})
|
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
// AAPT2 overlays are in lowest to highest priority order, the topological order will be reversed later.
|
|
|
|
// Reverse the dependency order now going into the depset so that it comes out in order after the second
|
|
|
|
// reverse later.
|
|
|
|
// NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in
|
|
|
|
// dependencies) the highest priority dependency is listed first, but for resources the highest priority
|
|
|
|
// dependency has to be listed last.
|
|
|
|
staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
|
2023-10-13 00:58:57 +02:00
|
|
|
android.ReverseSliceInPlace(staticResourcesNodeDepSets))
|
|
|
|
sharedResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil,
|
|
|
|
android.ReverseSliceInPlace(sharedResourcesNodeDepSets))
|
2023-06-14 01:44:58 +02:00
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
staticRRODirs = rroDirsDepSetBuilder.Build()
|
|
|
|
staticManifests = manifestsDepSetBuilder.Build()
|
|
|
|
|
|
|
|
if len(staticResourcesNodes.ToList()) > 0 {
|
2018-03-28 23:58:31 +02:00
|
|
|
flags = append(flags, "--auto-add-overlay")
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, sharedLib := range sharedLibs {
|
|
|
|
flags = append(flags, "-I "+sharedLib.String())
|
|
|
|
}
|
|
|
|
|
2023-10-13 00:58:57 +02:00
|
|
|
return staticResourcesNodes, sharedResourcesNodes, staticRRODirs, staticManifests, sharedLibs, flags
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type AndroidLibrary struct {
|
|
|
|
Library
|
|
|
|
aapt
|
|
|
|
|
|
|
|
androidLibraryProperties androidLibraryProperties
|
|
|
|
|
|
|
|
aarFile android.WritablePath
|
2018-05-01 00:55:11 +02:00
|
|
|
}
|
|
|
|
|
2021-09-14 20:40:19 +02:00
|
|
|
var _ android.OutputFileProducer = (*AndroidLibrary)(nil)
|
|
|
|
|
|
|
|
// For OutputFileProducer interface
|
|
|
|
func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) {
|
|
|
|
switch tag {
|
|
|
|
case ".aar":
|
|
|
|
return []android.Path{a.aarFile}, nil
|
|
|
|
default:
|
|
|
|
return a.Library.OutputFiles(tag)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
|
|
|
|
|
|
|
|
func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
|
|
a.Module.deps(ctx)
|
2021-03-29 13:11:58 +02:00
|
|
|
sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
|
2019-06-07 11:44:37 +02:00
|
|
|
if sdkDep.hasFrameworkLibs() {
|
|
|
|
a.aapt.deps(ctx, sdkDep)
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
2022-12-22 06:51:52 +01:00
|
|
|
a.usesLibrary.deps(ctx, false)
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
2019-02-06 06:55:21 +01:00
|
|
|
a.aapt.isLibrary = true
|
2021-08-17 17:20:29 +02:00
|
|
|
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
|
2023-09-27 18:47:56 +02:00
|
|
|
a.aapt.buildActions(ctx,
|
|
|
|
aaptBuildActionOptions{
|
|
|
|
sdkContext: android.SdkContext(a),
|
|
|
|
classLoaderContexts: a.classLoaderContexts,
|
|
|
|
enforceDefaultTargetSdkVersion: false,
|
|
|
|
},
|
|
|
|
)
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2023-12-14 00:54:49 +01:00
|
|
|
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
|
|
|
|
a.hideApexVariantFromMake = !apexInfo.IsForPlatform()
|
2020-09-16 03:30:11 +02:00
|
|
|
|
2023-07-01 02:13:47 +02:00
|
|
|
a.stem = proptools.StringDefault(a.overridableDeviceProperties.Stem, ctx.ModuleName())
|
|
|
|
|
2023-06-21 07:40:02 +02:00
|
|
|
ctx.CheckbuildFile(a.aapt.proguardOptionsFile)
|
|
|
|
ctx.CheckbuildFile(a.aapt.exportPackage)
|
|
|
|
if a.useResourceProcessorBusyBox() {
|
|
|
|
ctx.CheckbuildFile(a.aapt.rJar)
|
2023-08-03 00:49:00 +02:00
|
|
|
} else {
|
|
|
|
ctx.CheckbuildFile(a.aapt.aaptSrcJar)
|
2023-06-21 07:40:02 +02:00
|
|
|
}
|
2018-03-28 23:58:31 +02:00
|
|
|
|
|
|
|
// apps manifests are handled by aapt, don't let Module see them
|
|
|
|
a.properties.Manifest = nil
|
|
|
|
|
2020-06-03 05:09:13 +02:00
|
|
|
a.linter.mergedManifest = a.aapt.mergedManifestFile
|
|
|
|
a.linter.manifest = a.aapt.manifestPath
|
|
|
|
a.linter.resources = a.aapt.resourceFiles
|
|
|
|
|
2023-10-31 18:27:02 +01:00
|
|
|
proguardSpecInfo := a.collectProguardSpecInfo(ctx)
|
2023-12-14 00:19:49 +01:00
|
|
|
android.SetProvider(ctx, ProguardSpecInfoProvider, proguardSpecInfo)
|
2023-11-22 00:13:56 +01:00
|
|
|
exportedProguardFlagsFiles := proguardSpecInfo.ProguardFlagsFiles.ToList()
|
|
|
|
a.extraProguardFlagsFiles = append(a.extraProguardFlagsFiles, exportedProguardFlagsFiles...)
|
|
|
|
a.extraProguardFlagsFiles = append(a.extraProguardFlagsFiles, a.proguardOptionsFile)
|
|
|
|
|
|
|
|
combinedExportedProguardFlagFile := android.PathForModuleOut(ctx, "export_proguard_flags")
|
|
|
|
writeCombinedProguardFlagsFile(ctx, combinedExportedProguardFlagFile, exportedProguardFlagsFiles)
|
|
|
|
a.combinedExportedProguardFlagsFile = combinedExportedProguardFlagFile
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2023-06-21 07:40:02 +02:00
|
|
|
var extraSrcJars android.Paths
|
|
|
|
var extraCombinedJars android.Paths
|
|
|
|
var extraClasspathJars android.Paths
|
|
|
|
if a.useResourceProcessorBusyBox() {
|
|
|
|
// When building a library with ResourceProcessorBusyBox enabled ResourceProcessorBusyBox for this
|
|
|
|
// library and each of the transitive static android_library dependencies has already created an
|
|
|
|
// R.class file for the appropriate package. Add all of those R.class files to the classpath.
|
|
|
|
extraClasspathJars = a.transitiveAaptRJars
|
|
|
|
} else {
|
|
|
|
// When building a library without ResourceProcessorBusyBox the aapt2 rule creates R.srcjar containing
|
|
|
|
// R.java files for the library's package and the packages from all transitive static android_library
|
|
|
|
// dependencies. Compile the srcjar alongside the rest of the sources.
|
|
|
|
extraSrcJars = android.Paths{a.aapt.aaptSrcJar}
|
|
|
|
}
|
|
|
|
|
|
|
|
a.Module.compile(ctx, extraSrcJars, extraClasspathJars, extraCombinedJars)
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2019-01-25 22:20:38 +01:00
|
|
|
a.aarFile = android.PathForModuleOut(ctx, ctx.ModuleName()+".aar")
|
2018-03-28 23:58:31 +02:00
|
|
|
var res android.Paths
|
|
|
|
if a.androidLibraryProperties.BuildAAR {
|
|
|
|
BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
|
|
|
|
ctx.CheckbuildFile(a.aarFile)
|
|
|
|
}
|
2018-05-01 00:55:11 +02:00
|
|
|
|
2022-06-10 19:05:42 +02:00
|
|
|
prebuiltJniPackages := android.Paths{}
|
|
|
|
ctx.VisitDirectDeps(func(module android.Module) {
|
2023-12-13 22:47:44 +01:00
|
|
|
if info, ok := android.OtherModuleProvider(ctx, module, JniPackageProvider); ok {
|
2022-06-10 19:05:42 +02:00
|
|
|
prebuiltJniPackages = append(prebuiltJniPackages, info.JniPackages...)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
if len(prebuiltJniPackages) > 0 {
|
2023-12-14 00:19:49 +01:00
|
|
|
android.SetProvider(ctx, JniPackageProvider, JniPackageInfo{
|
2022-06-10 19:05:42 +02:00
|
|
|
JniPackages: prebuiltJniPackages,
|
|
|
|
})
|
|
|
|
}
|
2018-03-28 23:58:31 +02:00
|
|
|
}
|
|
|
|
|
2023-10-17 22:21:02 +02:00
|
|
|
func (a *AndroidLibrary) IDEInfo(dpInfo *android.IdeInfo) {
|
|
|
|
a.Library.IDEInfo(dpInfo)
|
|
|
|
a.aapt.IDEInfo(dpInfo)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *aapt) IDEInfo(dpInfo *android.IdeInfo) {
|
|
|
|
if a.useResourceProcessorBusyBox() {
|
|
|
|
dpInfo.Jars = append(dpInfo.Jars, a.rJar.String())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-12 23:41:32 +01:00
|
|
|
// android_library builds and links sources into a `.jar` file for the device along with Android resources.
|
|
|
|
//
|
|
|
|
// An android_library has a single variant that produces a `.jar` file containing `.class` files that were
|
2022-06-10 19:05:42 +02:00
|
|
|
// compiled against the device bootclasspath, along with a `package-res.apk` file containing Android resources compiled
|
2019-02-12 23:41:32 +01:00
|
|
|
// with aapt2. This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
|
|
|
|
// an android_app module.
|
2018-03-28 23:58:31 +02:00
|
|
|
func AndroidLibraryFactory() android.Module {
|
|
|
|
module := &AndroidLibrary{}
|
|
|
|
|
2020-06-16 01:09:53 +02:00
|
|
|
module.Module.addHostAndDeviceProperties()
|
2018-03-28 23:58:31 +02:00
|
|
|
module.AddProperties(
|
|
|
|
&module.aaptProperties,
|
|
|
|
&module.androidLibraryProperties)
|
|
|
|
|
|
|
|
module.androidLibraryProperties.BuildAAR = true
|
2020-06-03 05:09:13 +02:00
|
|
|
module.Module.linter.library = true
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2020-05-20 02:06:00 +02:00
|
|
|
android.InitApexModule(module)
|
2018-10-02 22:53:33 +02:00
|
|
|
InitJavaModule(module, android.DeviceSupported)
|
2018-03-28 23:58:31 +02:00
|
|
|
return module
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// AAR (android library) prebuilts
|
|
|
|
//
|
|
|
|
|
2022-04-13 03:30:44 +02:00
|
|
|
// Properties for android_library_import
|
2018-02-21 02:22:23 +01:00
|
|
|
type AARImportProperties struct {
|
2022-04-13 03:30:44 +02:00
|
|
|
// ARR (android library prebuilt) filepath. Exactly one ARR is required.
|
2019-03-05 07:35:41 +01:00
|
|
|
Aars []string `android:"path"`
|
2022-04-13 03:30:44 +02:00
|
|
|
// If not blank, set to the version of the sdk to compile against.
|
|
|
|
// Defaults to private.
|
|
|
|
// Values are of one of the following forms:
|
|
|
|
// 1) numerical API level, "current", "none", or "core_platform"
|
|
|
|
// 2) An SDK kind with an API level: "<sdk kind>_<API level>"
|
|
|
|
// See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
|
|
|
|
// If the SDK kind is empty, it will be set to public
|
|
|
|
Sdk_version *string
|
|
|
|
// If not blank, set the minimum version of the sdk that the compiled artifacts will run against.
|
|
|
|
// Defaults to sdk_version if not set. See sdk_version for possible values.
|
2018-07-10 22:39:30 +02:00
|
|
|
Min_sdk_version *string
|
2022-04-13 03:30:44 +02:00
|
|
|
// List of java static libraries that the included ARR (android library prebuilts) has dependencies to.
|
2018-03-28 23:58:31 +02:00
|
|
|
Static_libs []string
|
2022-04-13 03:30:44 +02:00
|
|
|
// List of java libraries that the included ARR (android library prebuilts) has dependencies to.
|
|
|
|
Libs []string
|
|
|
|
// If set to true, run Jetifier against .aar file. Defaults to false.
|
2019-03-22 06:21:39 +01:00
|
|
|
Jetifier *bool
|
2022-06-10 19:05:42 +02:00
|
|
|
// If true, extract JNI libs from AAR archive. These libs will be accessible to android_app modules and
|
|
|
|
// will be passed transitively through android_libraries to an android_app.
|
|
|
|
//TODO(b/241138093) evaluate whether we can have this flag default to true for Bazel conversion
|
|
|
|
Extract_jni *bool
|
2018-02-21 02:22:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
type AARImport struct {
|
|
|
|
android.ModuleBase
|
2018-10-02 22:53:33 +02:00
|
|
|
android.DefaultableModuleBase
|
2020-05-20 02:06:00 +02:00
|
|
|
android.ApexModuleBase
|
2018-02-21 02:22:23 +01:00
|
|
|
prebuilt android.Prebuilt
|
|
|
|
|
2020-05-20 02:06:00 +02:00
|
|
|
// Functionality common to Module and Import.
|
|
|
|
embeddableInModuleAndImport
|
|
|
|
|
2022-11-29 17:19:37 +01:00
|
|
|
providesTransitiveHeaderJars
|
|
|
|
|
2018-02-21 02:22:23 +01:00
|
|
|
properties AARImportProperties
|
|
|
|
|
2023-11-22 00:13:56 +01:00
|
|
|
classpathFile android.WritablePath
|
|
|
|
proguardFlags android.WritablePath
|
|
|
|
exportPackage android.WritablePath
|
|
|
|
transitiveAaptResourcePackagesFile android.Path
|
|
|
|
extraAaptPackagesFile android.WritablePath
|
|
|
|
manifest android.WritablePath
|
|
|
|
assetsPackage android.WritablePath
|
|
|
|
rTxt android.WritablePath
|
|
|
|
rJar android.WritablePath
|
2018-05-02 21:58:28 +02:00
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
resourcesNodesDepSet *android.DepSet[*resourcesNode]
|
|
|
|
manifestsDepSet *android.DepSet[android.Path]
|
2020-09-16 03:30:11 +02:00
|
|
|
|
|
|
|
hideApexVariantFromMake bool
|
2020-10-05 21:09:09 +02:00
|
|
|
|
2022-06-10 19:05:42 +02:00
|
|
|
aarPath android.Path
|
|
|
|
jniPackages android.Paths
|
2021-04-02 01:45:46 +02:00
|
|
|
|
|
|
|
sdkVersion android.SdkSpec
|
2023-03-03 22:20:36 +01:00
|
|
|
minSdkVersion android.ApiLevel
|
2020-10-05 21:09:09 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var _ android.OutputFileProducer = (*AARImport)(nil)
|
|
|
|
|
|
|
|
// For OutputFileProducer interface
|
|
|
|
func (a *AARImport) OutputFiles(tag string) (android.Paths, error) {
|
|
|
|
switch tag {
|
|
|
|
case ".aar":
|
|
|
|
return []android.Path{a.aarPath}, nil
|
|
|
|
case "":
|
|
|
|
return []android.Path{a.classpathFile}, nil
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
|
|
|
|
}
|
2018-02-21 02:22:23 +01:00
|
|
|
}
|
|
|
|
|
2021-04-02 01:45:46 +02:00
|
|
|
func (a *AARImport) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
|
|
|
|
return android.SdkSpecFrom(ctx, String(a.properties.Sdk_version))
|
2018-06-26 00:48:06 +02:00
|
|
|
}
|
|
|
|
|
2021-03-29 13:11:58 +02:00
|
|
|
func (a *AARImport) SystemModules() string {
|
2019-10-11 14:50:28 +02:00
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2023-03-03 22:20:36 +01:00
|
|
|
func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
|
2018-07-10 22:39:30 +02:00
|
|
|
if a.properties.Min_sdk_version != nil {
|
2023-03-03 22:20:36 +01:00
|
|
|
return android.ApiLevelFrom(ctx, *a.properties.Min_sdk_version)
|
2018-07-10 22:39:30 +02:00
|
|
|
}
|
2023-03-03 22:20:36 +01:00
|
|
|
return a.SdkVersion(ctx).ApiLevel
|
2018-06-26 00:48:06 +02:00
|
|
|
}
|
|
|
|
|
2023-03-02 01:56:06 +01:00
|
|
|
func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
|
|
|
|
return android.SdkSpecFrom(ctx, "").ApiLevel
|
2022-05-17 22:21:50 +02:00
|
|
|
}
|
|
|
|
|
2023-03-02 00:38:49 +01:00
|
|
|
func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
|
|
|
|
return a.SdkVersion(ctx).ApiLevel
|
2018-10-31 23:28:47 +01:00
|
|
|
}
|
2019-06-07 11:44:37 +02:00
|
|
|
|
2019-10-28 19:37:20 +01:00
|
|
|
func (a *AARImport) javaVersion() string {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2018-03-28 23:58:31 +02:00
|
|
|
var _ AndroidLibraryDependency = (*AARImport)(nil)
|
|
|
|
|
|
|
|
func (a *AARImport) ExportPackage() android.Path {
|
|
|
|
return a.exportPackage
|
|
|
|
}
|
2023-07-14 19:23:41 +02:00
|
|
|
func (a *AARImport) ResourcesNodeDepSet() *android.DepSet[*resourcesNode] {
|
|
|
|
return a.resourcesNodesDepSet
|
2018-05-02 21:58:28 +02:00
|
|
|
}
|
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
func (a *AARImport) RRODirsDepSet() *android.DepSet[rroDir] {
|
|
|
|
return android.NewDepSet[rroDir](android.TOPOLOGICAL, nil, nil)
|
2018-05-25 01:11:20 +02:00
|
|
|
}
|
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
func (a *AARImport) ManifestsDepSet() *android.DepSet[android.Path] {
|
|
|
|
return a.manifestsDepSet
|
2020-01-15 23:15:10 +01:00
|
|
|
}
|
|
|
|
|
2020-10-07 03:56:10 +02:00
|
|
|
// RRO enforcement is not available on aar_import since its RRO dirs are not
|
|
|
|
// exported.
|
|
|
|
func (a *AARImport) SetRROEnforcedForDependent(enforce bool) {
|
|
|
|
}
|
|
|
|
|
|
|
|
// RRO enforcement is not available on aar_import since its RRO dirs are not
|
|
|
|
// exported.
|
|
|
|
func (a *AARImport) IsRROEnforced(ctx android.BaseModuleContext) bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-02-21 02:22:23 +01:00
|
|
|
func (a *AARImport) Prebuilt() *android.Prebuilt {
|
|
|
|
return &a.prebuilt
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AARImport) Name() string {
|
|
|
|
return a.prebuilt.Name(a.ModuleBase.Name())
|
|
|
|
}
|
|
|
|
|
2020-01-08 05:35:43 +01:00
|
|
|
func (a *AARImport) JacocoReportClassesFile() android.Path {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-02-21 02:22:23 +01:00
|
|
|
func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
|
2020-07-07 18:09:23 +02:00
|
|
|
if !ctx.Config().AlwaysUsePrebuiltSdks() {
|
2021-03-29 13:11:58 +02:00
|
|
|
sdkDep := decodeSdkDep(ctx, android.SdkContext(a))
|
2018-03-28 23:58:31 +02:00
|
|
|
if sdkDep.useModule && sdkDep.frameworkResModule != "" {
|
2018-08-29 23:10:52 +02:00
|
|
|
ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
|
2018-02-21 02:22:23 +01:00
|
|
|
}
|
|
|
|
}
|
2018-03-28 23:58:31 +02:00
|
|
|
|
2018-08-29 23:10:52 +02:00
|
|
|
ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...)
|
|
|
|
ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs...)
|
2018-02-21 02:22:23 +01:00
|
|
|
}
|
|
|
|
|
2022-06-10 19:05:42 +02:00
|
|
|
type JniPackageInfo struct {
|
|
|
|
// List of zip files containing JNI libraries
|
|
|
|
// Zip files should have directory structure jni/<arch>/*.so
|
|
|
|
JniPackages android.Paths
|
|
|
|
}
|
|
|
|
|
2023-12-13 01:39:03 +01:00
|
|
|
var JniPackageProvider = blueprint.NewProvider[JniPackageInfo]()
|
2022-06-10 19:05:42 +02:00
|
|
|
|
|
|
|
// Unzip an AAR and extract the JNI libs for $archString.
|
|
|
|
var extractJNI = pctx.AndroidStaticRule("extractJNI",
|
|
|
|
blueprint.RuleParams{
|
|
|
|
Command: `rm -rf $out $outDir && touch $out && ` +
|
|
|
|
`unzip -qoDD -d $outDir $in "jni/${archString}/*" && ` +
|
|
|
|
`jni_files=$$(find $outDir/jni -type f) && ` +
|
|
|
|
// print error message if there are no JNI libs for this arch
|
|
|
|
`[ -n "$$jni_files" ] || (echo "ERROR: no JNI libs found for arch ${archString}" && exit 1) && ` +
|
2023-06-22 21:36:02 +02:00
|
|
|
`${config.SoongZipCmd} -o $out -L 0 -P 'lib/${archString}' ` +
|
2022-06-10 19:05:42 +02:00
|
|
|
`-C $outDir/jni/${archString} $$(echo $$jni_files | xargs -n1 printf " -f %s")`,
|
|
|
|
CommandDeps: []string{"${config.SoongZipCmd}"},
|
|
|
|
},
|
|
|
|
"outDir", "archString")
|
|
|
|
|
2018-02-21 02:22:23 +01:00
|
|
|
// Unzip an AAR into its constituent files and directories. Any files in Outputs that don't exist in the AAR will be
|
2019-05-28 23:49:06 +02:00
|
|
|
// touched to create an empty file. The res directory is not extracted, as it will be extracted in its own rule.
|
2018-02-21 02:22:23 +01:00
|
|
|
var unzipAAR = pctx.AndroidStaticRule("unzipAAR",
|
|
|
|
blueprint.RuleParams{
|
2019-05-28 23:49:06 +02:00
|
|
|
Command: `rm -rf $outDir && mkdir -p $outDir && ` +
|
2020-08-06 22:20:17 +02:00
|
|
|
`unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out && ` +
|
2021-12-03 22:25:10 +01:00
|
|
|
`${config.Zip2ZipCmd} -i $in -o $assetsPackage 'assets/**/*' && ` +
|
2020-08-06 22:20:17 +02:00
|
|
|
`${config.MergeZipsCmd} $combinedClassesJar $$(ls $outDir/classes.jar 2> /dev/null) $$(ls $outDir/libs/*.jar 2> /dev/null)`,
|
2021-12-03 22:25:10 +01:00
|
|
|
CommandDeps: []string{"${config.MergeZipsCmd}", "${config.Zip2ZipCmd}"},
|
2018-02-21 02:22:23 +01:00
|
|
|
},
|
2021-12-03 22:25:10 +01:00
|
|
|
"outDir", "combinedClassesJar", "assetsPackage")
|
2018-02-21 02:22:23 +01:00
|
|
|
|
|
|
|
func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
|
|
if len(a.properties.Aars) != 1 {
|
|
|
|
ctx.PropertyErrorf("aars", "exactly one aar is required")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-04-02 01:45:46 +02:00
|
|
|
a.sdkVersion = a.SdkVersion(ctx)
|
|
|
|
a.minSdkVersion = a.MinSdkVersion(ctx)
|
|
|
|
|
2023-12-14 00:54:49 +01:00
|
|
|
apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
|
|
|
|
a.hideApexVariantFromMake = !apexInfo.IsForPlatform()
|
2020-09-16 03:30:11 +02:00
|
|
|
|
2018-08-28 03:31:46 +02:00
|
|
|
aarName := ctx.ModuleName() + ".aar"
|
2020-10-05 21:09:09 +02:00
|
|
|
a.aarPath = android.PathForModuleSrc(ctx, a.properties.Aars[0])
|
|
|
|
|
2019-03-22 06:21:39 +01:00
|
|
|
if Bool(a.properties.Jetifier) {
|
2020-10-05 21:09:09 +02:00
|
|
|
inputFile := a.aarPath
|
|
|
|
a.aarPath = android.PathForModuleOut(ctx, "jetifier", aarName)
|
|
|
|
TransformJetifier(ctx, a.aarPath.(android.WritablePath), inputFile)
|
2018-08-28 03:31:46 +02:00
|
|
|
}
|
2018-02-21 02:22:23 +01:00
|
|
|
|
|
|
|
extractedAARDir := android.PathForModuleOut(ctx, "aar")
|
2020-08-06 22:20:17 +02:00
|
|
|
a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar")
|
2018-05-23 19:59:28 +02:00
|
|
|
a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml")
|
2023-06-21 07:40:02 +02:00
|
|
|
aarRTxt := extractedAARDir.Join(ctx, "R.txt")
|
2021-12-03 22:25:10 +01:00
|
|
|
a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip")
|
2023-08-03 00:00:35 +02:00
|
|
|
a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt")
|
2023-12-14 00:19:49 +01:00
|
|
|
android.SetProvider(ctx, ProguardSpecInfoProvider, ProguardSpecInfo{
|
2023-08-03 00:00:35 +02:00
|
|
|
ProguardFlagsFiles: android.NewDepSet[android.Path](
|
|
|
|
android.POSTORDER,
|
|
|
|
android.Paths{a.proguardFlags},
|
|
|
|
nil,
|
|
|
|
),
|
|
|
|
})
|
2018-02-21 02:22:23 +01:00
|
|
|
|
|
|
|
ctx.Build(pctx, android.BuildParams{
|
|
|
|
Rule: unzipAAR,
|
2020-10-05 21:09:09 +02:00
|
|
|
Input: a.aarPath,
|
2023-06-21 07:40:02 +02:00
|
|
|
Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, aarRTxt},
|
2018-02-21 02:22:23 +01:00
|
|
|
Description: "unzip AAR",
|
|
|
|
Args: map[string]string{
|
2020-08-06 22:20:17 +02:00
|
|
|
"outDir": extractedAARDir.String(),
|
|
|
|
"combinedClassesJar": a.classpathFile.String(),
|
2021-12-03 22:25:10 +01:00
|
|
|
"assetsPackage": a.assetsPackage.String(),
|
2018-02-21 02:22:23 +01:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
2019-06-22 21:59:27 +02:00
|
|
|
// Always set --pseudo-localize, it will be stripped out later for release
|
|
|
|
// builds that don't want it.
|
|
|
|
compileFlags := []string{"--pseudo-localize"}
|
2018-02-21 02:22:23 +01:00
|
|
|
compiledResDir := android.PathForModuleOut(ctx, "flat-res")
|
|
|
|
flata := compiledResDir.Join(ctx, "gen_res.flata")
|
2020-10-05 21:09:09 +02:00
|
|
|
aapt2CompileZip(ctx, flata, a.aarPath, "res", compileFlags)
|
2018-02-21 02:22:23 +01:00
|
|
|
|
|
|
|
a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
|
|
|
|
proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
|
2023-06-21 07:40:02 +02:00
|
|
|
a.rTxt = android.PathForModuleOut(ctx, "R.txt")
|
2018-05-02 21:58:28 +02:00
|
|
|
a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
|
2018-02-21 02:22:23 +01:00
|
|
|
|
|
|
|
var linkDeps android.Paths
|
|
|
|
|
|
|
|
linkFlags := []string{
|
|
|
|
"--static-lib",
|
2023-06-21 07:40:02 +02:00
|
|
|
"--merge-only",
|
2018-02-21 02:22:23 +01:00
|
|
|
"--auto-add-overlay",
|
|
|
|
}
|
|
|
|
|
2018-05-23 19:59:28 +02:00
|
|
|
linkFlags = append(linkFlags, "--manifest "+a.manifest.String())
|
|
|
|
linkDeps = append(linkDeps, a.manifest)
|
2018-02-21 02:22:23 +01:00
|
|
|
|
2023-10-13 00:58:57 +02:00
|
|
|
staticResourcesNodesDepSet, sharedResourcesNodesDepSet, staticRRODirsDepSet, staticManifestsDepSet, sharedLibs, libFlags :=
|
2021-03-29 13:11:58 +02:00
|
|
|
aaptLibs(ctx, android.SdkContext(a), nil)
|
2018-05-25 01:11:20 +02:00
|
|
|
|
2023-10-13 00:58:57 +02:00
|
|
|
_ = sharedResourcesNodesDepSet
|
2023-07-14 19:23:41 +02:00
|
|
|
_ = staticRRODirsDepSet
|
2023-10-13 00:58:57 +02:00
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
staticDeps := transitiveAarDeps(staticResourcesNodesDepSet.ToList())
|
|
|
|
|
|
|
|
linkDeps = append(linkDeps, sharedLibs...)
|
2023-06-21 07:40:02 +02:00
|
|
|
linkDeps = append(linkDeps, staticDeps.resPackages()...)
|
2018-03-28 23:58:31 +02:00
|
|
|
linkFlags = append(linkFlags, libFlags...)
|
2018-02-21 02:22:23 +01:00
|
|
|
|
2023-06-21 07:40:02 +02:00
|
|
|
overlayRes := android.Paths{flata}
|
|
|
|
|
|
|
|
// Treat static library dependencies of static libraries as imports.
|
|
|
|
transitiveStaticLibs := staticDeps.resPackages()
|
|
|
|
linkDeps = append(linkDeps, transitiveStaticLibs...)
|
|
|
|
for _, staticLib := range transitiveStaticLibs {
|
|
|
|
linkFlags = append(linkFlags, "-I "+staticLib.String())
|
|
|
|
}
|
2018-02-21 02:22:23 +01:00
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
transitiveAssets := android.ReverseSliceInPlace(staticDeps.assets())
|
2023-08-03 00:49:00 +02:00
|
|
|
aapt2Link(ctx, a.exportPackage, nil, proguardOptionsFile, a.rTxt,
|
2023-12-01 23:01:06 +01:00
|
|
|
linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil, nil)
|
2018-02-21 02:22:23 +01:00
|
|
|
|
2023-06-21 07:40:02 +02:00
|
|
|
a.rJar = android.PathForModuleOut(ctx, "busybox/R.jar")
|
|
|
|
resourceProcessorBusyBoxGenerateBinaryR(ctx, a.rTxt, a.manifest, a.rJar, nil, true)
|
|
|
|
|
2023-08-03 00:49:00 +02:00
|
|
|
aapt2ExtractExtraPackages(ctx, a.extraAaptPackagesFile, a.rJar)
|
|
|
|
|
2023-07-14 19:23:41 +02:00
|
|
|
resourcesNodesDepSetBuilder := android.NewDepSetBuilder[*resourcesNode](android.TOPOLOGICAL)
|
|
|
|
resourcesNodesDepSetBuilder.Direct(&resourcesNode{
|
|
|
|
resPackage: a.exportPackage,
|
|
|
|
manifest: a.manifest,
|
2023-06-21 07:40:02 +02:00
|
|
|
rTxt: a.rTxt,
|
|
|
|
rJar: a.rJar,
|
2023-07-14 19:23:41 +02:00
|
|
|
assets: android.OptionalPathForPath(a.assetsPackage),
|
2023-06-21 07:40:02 +02:00
|
|
|
|
|
|
|
usedResourceProcessor: true,
|
2023-07-14 19:23:41 +02:00
|
|
|
})
|
|
|
|
resourcesNodesDepSetBuilder.Transitive(staticResourcesNodesDepSet)
|
|
|
|
a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build()
|
|
|
|
|
|
|
|
manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest)
|
|
|
|
// TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import
|
|
|
|
// modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies
|
|
|
|
// of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of
|
|
|
|
// android_library_import modules. If this is fixed, AndroidLibraryDependency.ManifestsDepSet can be dropped
|
|
|
|
// completely in favor of AndroidLibraryDependency.ResourceNodesDepSet.manifest
|
|
|
|
//manifestDepSetBuilder.Transitive(transitiveStaticDeps.manifests)
|
|
|
|
_ = staticManifestsDepSet
|
|
|
|
a.manifestsDepSet = manifestDepSetBuilder.Build()
|
2021-12-03 22:25:10 +01:00
|
|
|
|
2023-11-22 00:13:56 +01:00
|
|
|
transitiveAaptResourcePackages := staticDeps.resPackages().Strings()
|
|
|
|
transitiveAaptResourcePackages = slices.DeleteFunc(transitiveAaptResourcePackages, func(p string) bool {
|
|
|
|
return p == a.exportPackage.String()
|
|
|
|
})
|
|
|
|
transitiveAaptResourcePackagesFile := android.PathForModuleOut(ctx, "transitive-res-packages")
|
|
|
|
android.WriteFileRule(ctx, transitiveAaptResourcePackagesFile, strings.Join(transitiveAaptResourcePackages, "\n"))
|
|
|
|
a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile
|
2023-06-21 07:40:02 +02:00
|
|
|
|
2022-11-29 17:19:37 +01:00
|
|
|
a.collectTransitiveHeaderJars(ctx)
|
2023-12-14 00:19:49 +01:00
|
|
|
android.SetProvider(ctx, JavaInfoProvider, JavaInfo{
|
2021-02-01 22:59:03 +01:00
|
|
|
HeaderJars: android.PathsIfNonNil(a.classpathFile),
|
2022-11-29 17:19:37 +01:00
|
|
|
TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars,
|
|
|
|
TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
|
2021-02-01 22:59:03 +01:00
|
|
|
ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
|
|
|
|
ImplementationJars: android.PathsIfNonNil(a.classpathFile),
|
2023-07-16 22:20:33 +02:00
|
|
|
// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
|
2021-02-01 22:59:03 +01:00
|
|
|
})
|
2022-06-10 19:05:42 +02:00
|
|
|
|
|
|
|
if proptools.Bool(a.properties.Extract_jni) {
|
|
|
|
for _, t := range ctx.MultiTargets() {
|
|
|
|
arch := t.Arch.Abi[0]
|
|
|
|
path := android.PathForModuleOut(ctx, arch+"_jni.zip")
|
|
|
|
a.jniPackages = append(a.jniPackages, path)
|
|
|
|
|
|
|
|
outDir := android.PathForModuleOut(ctx, "aarForJni")
|
|
|
|
aarPath := android.PathForModuleSrc(ctx, a.properties.Aars[0])
|
|
|
|
ctx.Build(pctx, android.BuildParams{
|
|
|
|
Rule: extractJNI,
|
|
|
|
Input: aarPath,
|
|
|
|
Outputs: android.WritablePaths{path},
|
|
|
|
Description: "extract JNI from AAR",
|
|
|
|
Args: map[string]string{
|
|
|
|
"outDir": outDir.String(),
|
|
|
|
"archString": arch,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2023-12-14 23:50:05 +01:00
|
|
|
|
2023-12-14 00:19:49 +01:00
|
|
|
android.SetProvider(ctx, JniPackageProvider, JniPackageInfo{
|
2023-12-14 23:50:05 +01:00
|
|
|
JniPackages: a.jniPackages,
|
|
|
|
})
|
2021-02-01 22:59:03 +01:00
|
|
|
}
|
2018-02-21 02:22:23 +01:00
|
|
|
|
|
|
|
func (a *AARImport) HeaderJars() android.Paths {
|
|
|
|
return android.Paths{a.classpathFile}
|
|
|
|
}
|
|
|
|
|
2018-08-16 05:40:52 +02:00
|
|
|
func (a *AARImport) ImplementationAndResourcesJars() android.Paths {
|
|
|
|
return android.Paths{a.classpathFile}
|
|
|
|
}
|
|
|
|
|
2020-06-04 16:08:17 +02:00
|
|
|
func (a *AARImport) DexJarBuildPath() android.Path {
|
2020-06-09 15:31:19 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *AARImport) DexJarInstallPath() android.Path {
|
2019-01-31 23:12:44 +01:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-10-08 13:53:58 +02:00
|
|
|
func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
|
2018-05-28 11:02:19 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-12-15 14:29:02 +01:00
|
|
|
var _ android.ApexModule = (*AARImport)(nil)
|
|
|
|
|
|
|
|
// Implements android.ApexModule
|
2020-05-20 02:06:00 +02:00
|
|
|
func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
|
|
|
|
return a.depIsInSameApex(ctx, dep)
|
|
|
|
}
|
|
|
|
|
2020-12-15 14:29:02 +01:00
|
|
|
// Implements android.ApexModule
|
2020-07-23 07:32:17 +02:00
|
|
|
func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
|
|
|
|
sdkVersion android.ApiLevel) error {
|
2020-04-15 04:03:39 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-07-25 21:39:32 +02:00
|
|
|
var _ android.PrebuiltInterface = (*AARImport)(nil)
|
2018-02-21 02:22:23 +01:00
|
|
|
|
2019-02-12 23:41:32 +01:00
|
|
|
// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
|
|
|
|
//
|
|
|
|
// This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
|
|
|
|
// an android_app module.
|
2018-02-21 02:22:23 +01:00
|
|
|
func AARImportFactory() android.Module {
|
|
|
|
module := &AARImport{}
|
|
|
|
|
|
|
|
module.AddProperties(&module.properties)
|
|
|
|
|
|
|
|
android.InitPrebuiltModule(module, &module.properties.Aars)
|
2020-05-20 02:06:00 +02:00
|
|
|
android.InitApexModule(module)
|
2022-06-10 19:05:42 +02:00
|
|
|
InitJavaModuleMultiTargets(module, android.DeviceSupported)
|
2018-02-21 02:22:23 +01:00
|
|
|
return module
|
|
|
|
}
|