Merge "Refactor apexBundle code." am: 114ad30d76
am: 7028b50308
am: a416730bf1
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/2138053 Change-Id: Ic9fd2b9318f6f7cf57a7a6149cb527302a5fdbfe Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
755
apex/apex.go
755
apex/apex.go
@@ -1338,7 +1338,7 @@ func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
|
|||||||
var _ android.DepIsInSameApex = (*apexBundle)(nil)
|
var _ android.DepIsInSameApex = (*apexBundle)(nil)
|
||||||
|
|
||||||
// Implements android.DepInInSameApex
|
// Implements android.DepInInSameApex
|
||||||
func (a *apexBundle) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
|
func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
|
||||||
// direct deps of an APEX bundle are all part of the APEX bundle
|
// direct deps of an APEX bundle are all part of the APEX bundle
|
||||||
// TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
|
// TODO(jiyong): shouldn't we look into the payload field of the dependencyTag?
|
||||||
return true
|
return true
|
||||||
@@ -1474,7 +1474,7 @@ func (a *apexBundle) IsSanitizerEnabled(config android.Config, sanitizerName str
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Then follow the global setting
|
// Then follow the global setting
|
||||||
globalSanitizerNames := []string{}
|
var globalSanitizerNames []string
|
||||||
if a.Host() {
|
if a.Host() {
|
||||||
globalSanitizerNames = config.SanitizeHost()
|
globalSanitizerNames = config.SanitizeHost()
|
||||||
} else {
|
} else {
|
||||||
@@ -1790,6 +1790,382 @@ func (f fsType) string() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type visitorContext struct {
|
||||||
|
// all the files that will be included in this APEX
|
||||||
|
filesInfo []apexFile
|
||||||
|
|
||||||
|
// native lib dependencies
|
||||||
|
provideNativeLibs []string
|
||||||
|
requireNativeLibs []string
|
||||||
|
|
||||||
|
handleSpecialLibs bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vctx *visitorContext) normalizeFileInfo() {
|
||||||
|
encountered := make(map[string]apexFile)
|
||||||
|
for _, f := range vctx.filesInfo {
|
||||||
|
dest := filepath.Join(f.installDir, f.builtFile.Base())
|
||||||
|
if e, ok := encountered[dest]; !ok {
|
||||||
|
encountered[dest] = f
|
||||||
|
} else {
|
||||||
|
// If a module is directly included and also transitively depended on
|
||||||
|
// consider it as directly included.
|
||||||
|
e.transitiveDep = e.transitiveDep && f.transitiveDep
|
||||||
|
encountered[dest] = e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vctx.filesInfo = vctx.filesInfo[:0]
|
||||||
|
for _, v := range encountered {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, v)
|
||||||
|
}
|
||||||
|
sort.Slice(vctx.filesInfo, func(i, j int) bool {
|
||||||
|
// Sort by destination path so as to ensure consistent ordering even if the source of the files
|
||||||
|
// changes.
|
||||||
|
return vctx.filesInfo[i].path() < vctx.filesInfo[j].path()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, child, parent blueprint.Module) bool {
|
||||||
|
depTag := ctx.OtherModuleDependencyTag(child)
|
||||||
|
if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if mod, ok := child.(android.Module); ok && !mod.Enabled() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
depName := ctx.OtherModuleName(child)
|
||||||
|
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
|
||||||
|
switch depTag {
|
||||||
|
case sharedLibTag, jniLibTag:
|
||||||
|
isJniLib := depTag == jniLibTag
|
||||||
|
switch ch := child.(type) {
|
||||||
|
case *cc.Module:
|
||||||
|
fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
|
||||||
|
fi.isJniLib = isJniLib
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, fi)
|
||||||
|
// Collect the list of stub-providing libs except:
|
||||||
|
// - VNDK libs are only for vendors
|
||||||
|
// - bootstrap bionic libs are treated as provided by system
|
||||||
|
if ch.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(ch.BaseModuleName(), ctx.Config()) {
|
||||||
|
vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
|
||||||
|
}
|
||||||
|
return true // track transitive dependencies
|
||||||
|
case *rust.Module:
|
||||||
|
fi := apexFileForRustLibrary(ctx, ch)
|
||||||
|
fi.isJniLib = isJniLib
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, fi)
|
||||||
|
return true // track transitive dependencies
|
||||||
|
default:
|
||||||
|
propertyName := "native_shared_libs"
|
||||||
|
if isJniLib {
|
||||||
|
propertyName = "jni_libs"
|
||||||
|
}
|
||||||
|
ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
|
||||||
|
}
|
||||||
|
case executableTag:
|
||||||
|
switch ch := child.(type) {
|
||||||
|
case *cc.Module:
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
|
||||||
|
return true // track transitive dependencies
|
||||||
|
case *python.Module:
|
||||||
|
if ch.HostToolPath().Valid() {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch))
|
||||||
|
}
|
||||||
|
case bootstrap.GoBinaryTool:
|
||||||
|
if a.Host() {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForGoBinary(ctx, depName, ch))
|
||||||
|
}
|
||||||
|
case *rust.Module:
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
|
||||||
|
return true // track transitive dependencies
|
||||||
|
default:
|
||||||
|
ctx.PropertyErrorf("binaries",
|
||||||
|
"%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
|
||||||
|
}
|
||||||
|
case shBinaryTag:
|
||||||
|
if csh, ok := child.(*sh.ShBinary); ok {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForShBinary(ctx, csh))
|
||||||
|
} else {
|
||||||
|
ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
|
||||||
|
}
|
||||||
|
case bcpfTag:
|
||||||
|
bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
|
||||||
|
if !ok {
|
||||||
|
ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexBootclasspathFragmentFiles(ctx, child)...)
|
||||||
|
for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
|
||||||
|
a.requiredDeps = append(a.requiredDeps, makeModuleName)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
case sscpfTag:
|
||||||
|
if _, ok := child.(*java.SystemServerClasspathModule); !ok {
|
||||||
|
ctx.PropertyErrorf("systemserverclasspath_fragments",
|
||||||
|
"%q is not a systemserverclasspath_fragment module", depName)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, *af)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
case javaLibTag:
|
||||||
|
switch child.(type) {
|
||||||
|
case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
|
||||||
|
af := apexFileForJavaModule(ctx, child.(javaModule))
|
||||||
|
if !af.ok() {
|
||||||
|
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
return true // track transitive dependencies
|
||||||
|
default:
|
||||||
|
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
|
||||||
|
}
|
||||||
|
case androidAppTag:
|
||||||
|
switch ap := child.(type) {
|
||||||
|
case *java.AndroidApp:
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
|
||||||
|
return true // track transitive dependencies
|
||||||
|
case *java.AndroidAppImport:
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
|
||||||
|
case *java.AndroidTestHelperApp:
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForAndroidApp(ctx, ap))
|
||||||
|
case *java.AndroidAppSet:
|
||||||
|
appDir := "app"
|
||||||
|
if ap.Privileged() {
|
||||||
|
appDir = "priv-app"
|
||||||
|
}
|
||||||
|
// TODO(b/224589412, b/226559955): Ensure that the dirname is
|
||||||
|
// suffixed so that PackageManager correctly invalidates the
|
||||||
|
// existing installed apk in favour of the new APK-in-APEX.
|
||||||
|
// See bugs for more information.
|
||||||
|
appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
|
||||||
|
af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
|
||||||
|
af.certificate = java.PresignedCertificate
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
default:
|
||||||
|
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
|
||||||
|
}
|
||||||
|
case rroTag:
|
||||||
|
if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
|
||||||
|
} else {
|
||||||
|
ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
|
||||||
|
}
|
||||||
|
case bpfTag:
|
||||||
|
if bpfProgram, ok := child.(bpf.BpfModule); ok {
|
||||||
|
filesToCopy, _ := bpfProgram.OutputFiles("")
|
||||||
|
apex_sub_dir := bpfProgram.SubDir()
|
||||||
|
for _, bpfFile := range filesToCopy {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
|
||||||
|
}
|
||||||
|
case fsTag:
|
||||||
|
if fs, ok := child.(filesystem.Filesystem); ok {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
|
||||||
|
} else {
|
||||||
|
ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
|
||||||
|
}
|
||||||
|
case prebuiltTag:
|
||||||
|
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
|
||||||
|
} else {
|
||||||
|
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
|
||||||
|
}
|
||||||
|
case compatConfigTag:
|
||||||
|
if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
|
||||||
|
} else {
|
||||||
|
ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
|
||||||
|
}
|
||||||
|
case testTag:
|
||||||
|
if ccTest, ok := child.(*cc.Module); ok {
|
||||||
|
if ccTest.IsTestPerSrcAllTestsVariation() {
|
||||||
|
// Multiple-output test module (where `test_per_src: true`).
|
||||||
|
//
|
||||||
|
// `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
|
||||||
|
// We do not add this variation to `filesInfo`, as it has no output;
|
||||||
|
// however, we do add the other variations of this module as indirect
|
||||||
|
// dependencies (see below).
|
||||||
|
} else {
|
||||||
|
// Single-output test module (where `test_per_src: false`).
|
||||||
|
af := apexFileForExecutable(ctx, ccTest)
|
||||||
|
af.class = nativeTest
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
}
|
||||||
|
return true // track transitive dependencies
|
||||||
|
} else {
|
||||||
|
ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
|
||||||
|
}
|
||||||
|
case keyTag:
|
||||||
|
if key, ok := child.(*apexKey); ok {
|
||||||
|
a.privateKeyFile = key.privateKeyFile
|
||||||
|
a.publicKeyFile = key.publicKeyFile
|
||||||
|
} else {
|
||||||
|
ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
|
||||||
|
}
|
||||||
|
case certificateTag:
|
||||||
|
if dep, ok := child.(*java.AndroidAppCertificate); ok {
|
||||||
|
a.containerCertificateFile = dep.Certificate.Pem
|
||||||
|
a.containerPrivateKeyFile = dep.Certificate.Key
|
||||||
|
} else {
|
||||||
|
ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
|
||||||
|
}
|
||||||
|
case android.PrebuiltDepTag:
|
||||||
|
// If the prebuilt is force disabled, remember to delete the prebuilt file
|
||||||
|
// that might have been installed in the previous builds
|
||||||
|
if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
|
||||||
|
a.prebuiltFileToDelete = prebuilt.InstallFilename()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.vndkApex {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// indirect dependencies
|
||||||
|
am, ok := child.(android.ApexModule)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// We cannot use a switch statement on `depTag` here as the checked
|
||||||
|
// tags used below are private (e.g. `cc.sharedDepTag`).
|
||||||
|
if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
|
||||||
|
if ch, ok := child.(*cc.Module); ok {
|
||||||
|
if ch.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && ch.IsVndk() {
|
||||||
|
vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
|
||||||
|
af.transitiveDep = true
|
||||||
|
|
||||||
|
// Always track transitive dependencies for host.
|
||||||
|
if a.Host() {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
|
||||||
|
if !abInfo.Contents.DirectlyInApex(depName) && (ch.IsStubs() || ch.HasStubsVariants()) {
|
||||||
|
// If the dependency is a stubs lib, don't include it in this APEX,
|
||||||
|
// but make sure that the lib is installed on the device.
|
||||||
|
// In case no APEX is having the lib, the lib is installed to the system
|
||||||
|
// partition.
|
||||||
|
//
|
||||||
|
// Always include if we are a host-apex however since those won't have any
|
||||||
|
// system libraries.
|
||||||
|
if !am.DirectlyInAnyApex() {
|
||||||
|
// we need a module name for Make
|
||||||
|
name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
|
||||||
|
if !android.InList(name, a.requiredDeps) {
|
||||||
|
a.requiredDeps = append(a.requiredDeps, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vctx.requireNativeLibs = append(vctx.requireNativeLibs, af.stem())
|
||||||
|
// Don't track further
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the dep is not considered to be in the same
|
||||||
|
// apex, don't add it to filesInfo so that it is not
|
||||||
|
// included in this APEX.
|
||||||
|
// TODO(jiyong): move this to at the top of the
|
||||||
|
// else-if clause for the indirect dependencies.
|
||||||
|
// Currently, that's impossible because we would
|
||||||
|
// like to record requiredNativeLibs even when
|
||||||
|
// DepIsInSameAPex is false. We also shouldn't do
|
||||||
|
// this for host.
|
||||||
|
//
|
||||||
|
// TODO(jiyong): explain why the same module is passed in twice.
|
||||||
|
// Switching the first am to parent breaks lots of tests.
|
||||||
|
if !android.IsDepInSameApex(ctx, am, am) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
return true // track transitive dependencies
|
||||||
|
} else if rm, ok := child.(*rust.Module); ok {
|
||||||
|
af := apexFileForRustLibrary(ctx, rm)
|
||||||
|
af.transitiveDep = true
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
return true // track transitive dependencies
|
||||||
|
}
|
||||||
|
} else if cc.IsTestPerSrcDepTag(depTag) {
|
||||||
|
if ch, ok := child.(*cc.Module); ok {
|
||||||
|
af := apexFileForExecutable(ctx, ch)
|
||||||
|
// Handle modules created as `test_per_src` variations of a single test module:
|
||||||
|
// use the name of the generated test binary (`fileToCopy`) instead of the name
|
||||||
|
// of the original test module (`depName`, shared by all `test_per_src`
|
||||||
|
// variations of that module).
|
||||||
|
af.androidMkModuleName = filepath.Base(af.builtFile.String())
|
||||||
|
// these are not considered transitive dep
|
||||||
|
af.transitiveDep = false
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
return true // track transitive dependencies
|
||||||
|
}
|
||||||
|
} else if cc.IsHeaderDepTag(depTag) {
|
||||||
|
// nothing
|
||||||
|
} else if java.IsJniDepTag(depTag) {
|
||||||
|
// Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
|
||||||
|
} else if java.IsXmlPermissionsFileDepTag(depTag) {
|
||||||
|
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
|
||||||
|
}
|
||||||
|
} else if rust.IsDylibDepTag(depTag) {
|
||||||
|
if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
|
||||||
|
af := apexFileForRustLibrary(ctx, rustm)
|
||||||
|
af.transitiveDep = true
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
return true // track transitive dependencies
|
||||||
|
}
|
||||||
|
} else if rust.IsRlibDepTag(depTag) {
|
||||||
|
// Rlib is statically linked, but it might have shared lib
|
||||||
|
// dependencies. Track them.
|
||||||
|
return true
|
||||||
|
} else if java.IsBootclasspathFragmentContentDepTag(depTag) {
|
||||||
|
// Add the contents of the bootclasspath fragment to the apex.
|
||||||
|
switch child.(type) {
|
||||||
|
case *java.Library, *java.SdkLibrary:
|
||||||
|
javaModule := child.(javaModule)
|
||||||
|
af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
|
||||||
|
if !af.ok() {
|
||||||
|
ctx.PropertyErrorf("bootclasspath_fragments",
|
||||||
|
"bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
return true // track transitive dependencies
|
||||||
|
default:
|
||||||
|
ctx.PropertyErrorf("bootclasspath_fragments",
|
||||||
|
"bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
|
||||||
|
}
|
||||||
|
} else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
|
||||||
|
// Add the contents of the systemserverclasspath fragment to the apex.
|
||||||
|
switch child.(type) {
|
||||||
|
case *java.Library, *java.SdkLibrary:
|
||||||
|
af := apexFileForJavaModule(ctx, child.(javaModule))
|
||||||
|
vctx.filesInfo = append(vctx.filesInfo, af)
|
||||||
|
return true // track transitive dependencies
|
||||||
|
default:
|
||||||
|
ctx.PropertyErrorf("systemserverclasspath_fragments",
|
||||||
|
"systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
|
||||||
|
}
|
||||||
|
} else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
|
||||||
|
// nothing
|
||||||
|
} else if depTag == android.DarwinUniversalVariantTag {
|
||||||
|
// nothing
|
||||||
|
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
|
||||||
|
ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Creates build rules for an APEX. It consists of the following major steps:
|
// Creates build rules for an APEX. It consists of the following major steps:
|
||||||
//
|
//
|
||||||
// 1) do some validity checks such as apex_available, min_sdk_version, etc.
|
// 1) do some validity checks such as apex_available, min_sdk_version, etc.
|
||||||
@@ -1812,386 +2188,23 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// 2) traverse the dependency tree to collect apexFile structs from them.
|
// 2) traverse the dependency tree to collect apexFile structs from them.
|
||||||
|
|
||||||
// all the files that will be included in this APEX
|
|
||||||
var filesInfo []apexFile
|
|
||||||
|
|
||||||
// native lib dependencies
|
|
||||||
var provideNativeLibs []string
|
|
||||||
var requireNativeLibs []string
|
|
||||||
|
|
||||||
handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
|
|
||||||
|
|
||||||
// Collect the module directory for IDE info in java/jdeps.go.
|
// Collect the module directory for IDE info in java/jdeps.go.
|
||||||
a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
|
a.modulePaths = append(a.modulePaths, ctx.ModuleDir())
|
||||||
|
|
||||||
// TODO(jiyong): do this using WalkPayloadDeps
|
// TODO(jiyong): do this using WalkPayloadDeps
|
||||||
// TODO(jiyong): make this clean!!!
|
// TODO(jiyong): make this clean!!!
|
||||||
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
|
vctx := visitorContext{handleSpecialLibs: !android.Bool(a.properties.Ignore_system_library_special_case)}
|
||||||
depTag := ctx.OtherModuleDependencyTag(child)
|
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool { return a.depVisitor(&vctx, ctx, child, parent) })
|
||||||
if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
|
vctx.normalizeFileInfo()
|
||||||
return false
|
|
||||||
}
|
|
||||||
if mod, ok := child.(android.Module); ok && !mod.Enabled() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
depName := ctx.OtherModuleName(child)
|
|
||||||
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
|
|
||||||
switch depTag {
|
|
||||||
case sharedLibTag, jniLibTag:
|
|
||||||
isJniLib := depTag == jniLibTag
|
|
||||||
if c, ok := child.(*cc.Module); ok {
|
|
||||||
fi := apexFileForNativeLibrary(ctx, c, handleSpecialLibs)
|
|
||||||
fi.isJniLib = isJniLib
|
|
||||||
filesInfo = append(filesInfo, fi)
|
|
||||||
// Collect the list of stub-providing libs except:
|
|
||||||
// - VNDK libs are only for vendors
|
|
||||||
// - bootstrap bionic libs are treated as provided by system
|
|
||||||
if c.HasStubsVariants() && !a.vndkApex && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) {
|
|
||||||
provideNativeLibs = append(provideNativeLibs, fi.stem())
|
|
||||||
}
|
|
||||||
return true // track transitive dependencies
|
|
||||||
} else if r, ok := child.(*rust.Module); ok {
|
|
||||||
fi := apexFileForRustLibrary(ctx, r)
|
|
||||||
fi.isJniLib = isJniLib
|
|
||||||
filesInfo = append(filesInfo, fi)
|
|
||||||
return true // track transitive dependencies
|
|
||||||
} else {
|
|
||||||
propertyName := "native_shared_libs"
|
|
||||||
if isJniLib {
|
|
||||||
propertyName = "jni_libs"
|
|
||||||
}
|
|
||||||
ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
|
|
||||||
}
|
|
||||||
case executableTag:
|
|
||||||
if cc, ok := child.(*cc.Module); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForExecutable(ctx, cc))
|
|
||||||
return true // track transitive dependencies
|
|
||||||
} else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() {
|
|
||||||
filesInfo = append(filesInfo, apexFileForPyBinary(ctx, py))
|
|
||||||
} else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() {
|
|
||||||
filesInfo = append(filesInfo, apexFileForGoBinary(ctx, depName, gb))
|
|
||||||
} else if rust, ok := child.(*rust.Module); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForRustExecutable(ctx, rust))
|
|
||||||
return true // track transitive dependencies
|
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("binaries", "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, nor (host) bootstrap_go_binary", depName)
|
|
||||||
}
|
|
||||||
case shBinaryTag:
|
|
||||||
if sh, ok := child.(*sh.ShBinary); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForShBinary(ctx, sh))
|
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("sh_binaries", "%q is not a sh_binary module", depName)
|
|
||||||
}
|
|
||||||
case bcpfTag:
|
|
||||||
{
|
|
||||||
bcpfModule, ok := child.(*java.BootclasspathFragmentModule)
|
|
||||||
if !ok {
|
|
||||||
ctx.PropertyErrorf("bootclasspath_fragments", "%q is not a bootclasspath_fragment module", depName)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
filesToAdd := apexBootclasspathFragmentFiles(ctx, child)
|
|
||||||
filesInfo = append(filesInfo, filesToAdd...)
|
|
||||||
for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
|
|
||||||
a.requiredDeps = append(a.requiredDeps, makeModuleName)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case sscpfTag:
|
|
||||||
{
|
|
||||||
if _, ok := child.(*java.SystemServerClasspathModule); !ok {
|
|
||||||
ctx.PropertyErrorf("systemserverclasspath_fragments", "%q is not a systemserverclasspath_fragment module", depName)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if af := apexClasspathFragmentProtoFile(ctx, child); af != nil {
|
|
||||||
filesInfo = append(filesInfo, *af)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
case javaLibTag:
|
|
||||||
switch child.(type) {
|
|
||||||
case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
|
|
||||||
af := apexFileForJavaModule(ctx, child.(javaModule))
|
|
||||||
if !af.ok() {
|
|
||||||
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
filesInfo = append(filesInfo, af)
|
|
||||||
return true // track transitive dependencies
|
|
||||||
default:
|
|
||||||
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
|
|
||||||
}
|
|
||||||
case androidAppTag:
|
|
||||||
if ap, ok := child.(*java.AndroidApp); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
|
|
||||||
return true // track transitive dependencies
|
|
||||||
} else if ap, ok := child.(*java.AndroidAppImport); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
|
|
||||||
} else if ap, ok := child.(*java.AndroidTestHelperApp); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
|
|
||||||
} else if ap, ok := child.(*java.AndroidAppSet); ok {
|
|
||||||
appDir := "app"
|
|
||||||
if ap.Privileged() {
|
|
||||||
appDir = "priv-app"
|
|
||||||
}
|
|
||||||
// TODO(b/224589412, b/226559955): Ensure that the dirname is
|
|
||||||
// suffixed so that PackageManager correctly invalidates the
|
|
||||||
// existing installed apk in favour of the new APK-in-APEX.
|
|
||||||
// See bugs for more information.
|
|
||||||
appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+sanitizedBuildIdForPath(ctx))
|
|
||||||
af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
|
|
||||||
af.certificate = java.PresignedCertificate
|
|
||||||
filesInfo = append(filesInfo, af)
|
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
|
|
||||||
}
|
|
||||||
case rroTag:
|
|
||||||
if rro, ok := child.(java.RuntimeResourceOverlayModule); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForRuntimeResourceOverlay(ctx, rro))
|
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay module", depName)
|
|
||||||
}
|
|
||||||
case bpfTag:
|
|
||||||
if bpfProgram, ok := child.(bpf.BpfModule); ok {
|
|
||||||
filesToCopy, _ := bpfProgram.OutputFiles("")
|
|
||||||
apex_sub_dir := bpfProgram.SubDir()
|
|
||||||
for _, bpfFile := range filesToCopy {
|
|
||||||
filesInfo = append(filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName)
|
|
||||||
}
|
|
||||||
case fsTag:
|
|
||||||
if fs, ok := child.(filesystem.Filesystem); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForFilesystem(ctx, fs.OutputPath(), fs))
|
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("filesystems", "%q is not a filesystem module", depName)
|
|
||||||
}
|
|
||||||
case prebuiltTag:
|
|
||||||
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
|
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
|
|
||||||
}
|
|
||||||
case compatConfigTag:
|
|
||||||
if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName))
|
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("compat_configs", "%q is not a platform_compat_config module", depName)
|
|
||||||
}
|
|
||||||
case testTag:
|
|
||||||
if ccTest, ok := child.(*cc.Module); ok {
|
|
||||||
if ccTest.IsTestPerSrcAllTestsVariation() {
|
|
||||||
// Multiple-output test module (where `test_per_src: true`).
|
|
||||||
//
|
|
||||||
// `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
|
|
||||||
// We do not add this variation to `filesInfo`, as it has no output;
|
|
||||||
// however, we do add the other variations of this module as indirect
|
|
||||||
// dependencies (see below).
|
|
||||||
} else {
|
|
||||||
// Single-output test module (where `test_per_src: false`).
|
|
||||||
af := apexFileForExecutable(ctx, ccTest)
|
|
||||||
af.class = nativeTest
|
|
||||||
filesInfo = append(filesInfo, af)
|
|
||||||
}
|
|
||||||
return true // track transitive dependencies
|
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
|
|
||||||
}
|
|
||||||
case keyTag:
|
|
||||||
if key, ok := child.(*apexKey); ok {
|
|
||||||
a.privateKeyFile = key.privateKeyFile
|
|
||||||
a.publicKeyFile = key.publicKeyFile
|
|
||||||
} else {
|
|
||||||
ctx.PropertyErrorf("key", "%q is not an apex_key module", depName)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
case certificateTag:
|
|
||||||
if dep, ok := child.(*java.AndroidAppCertificate); ok {
|
|
||||||
a.containerCertificateFile = dep.Certificate.Pem
|
|
||||||
a.containerPrivateKeyFile = dep.Certificate.Key
|
|
||||||
} else {
|
|
||||||
ctx.ModuleErrorf("certificate dependency %q must be an android_app_certificate module", depName)
|
|
||||||
}
|
|
||||||
case android.PrebuiltDepTag:
|
|
||||||
// If the prebuilt is force disabled, remember to delete the prebuilt file
|
|
||||||
// that might have been installed in the previous builds
|
|
||||||
if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
|
|
||||||
a.prebuiltFileToDelete = prebuilt.InstallFilename()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if !a.vndkApex {
|
|
||||||
// indirect dependencies
|
|
||||||
if am, ok := child.(android.ApexModule); ok {
|
|
||||||
// We cannot use a switch statement on `depTag` here as the checked
|
|
||||||
// tags used below are private (e.g. `cc.sharedDepTag`).
|
|
||||||
if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
|
|
||||||
if cc, ok := child.(*cc.Module); ok {
|
|
||||||
if cc.UseVndk() && proptools.Bool(a.properties.Use_vndk_as_stable) && cc.IsVndk() {
|
|
||||||
requireNativeLibs = append(requireNativeLibs, ":vndk")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
|
|
||||||
af.transitiveDep = true
|
|
||||||
|
|
||||||
// Always track transitive dependencies for host.
|
|
||||||
if a.Host() {
|
|
||||||
filesInfo = append(filesInfo, af)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo)
|
|
||||||
if !abInfo.Contents.DirectlyInApex(depName) && (cc.IsStubs() || cc.HasStubsVariants()) {
|
|
||||||
// If the dependency is a stubs lib, don't include it in this APEX,
|
|
||||||
// but make sure that the lib is installed on the device.
|
|
||||||
// In case no APEX is having the lib, the lib is installed to the system
|
|
||||||
// partition.
|
|
||||||
//
|
|
||||||
// Always include if we are a host-apex however since those won't have any
|
|
||||||
// system libraries.
|
|
||||||
if !am.DirectlyInAnyApex() {
|
|
||||||
// we need a module name for Make
|
|
||||||
name := cc.ImplementationModuleNameForMake(ctx) + cc.Properties.SubName
|
|
||||||
if !android.InList(name, a.requiredDeps) {
|
|
||||||
a.requiredDeps = append(a.requiredDeps, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
requireNativeLibs = append(requireNativeLibs, af.stem())
|
|
||||||
// Don't track further
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the dep is not considered to be in the same
|
|
||||||
// apex, don't add it to filesInfo so that it is not
|
|
||||||
// included in this APEX.
|
|
||||||
// TODO(jiyong): move this to at the top of the
|
|
||||||
// else-if clause for the indirect dependencies.
|
|
||||||
// Currently, that's impossible because we would
|
|
||||||
// like to record requiredNativeLibs even when
|
|
||||||
// DepIsInSameAPex is false. We also shouldn't do
|
|
||||||
// this for host.
|
|
||||||
//
|
|
||||||
// TODO(jiyong): explain why the same module is passed in twice.
|
|
||||||
// Switching the first am to parent breaks lots of tests.
|
|
||||||
if !android.IsDepInSameApex(ctx, am, am) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
filesInfo = append(filesInfo, af)
|
|
||||||
return true // track transitive dependencies
|
|
||||||
} else if rm, ok := child.(*rust.Module); ok {
|
|
||||||
af := apexFileForRustLibrary(ctx, rm)
|
|
||||||
af.transitiveDep = true
|
|
||||||
filesInfo = append(filesInfo, af)
|
|
||||||
return true // track transitive dependencies
|
|
||||||
}
|
|
||||||
} else if cc.IsTestPerSrcDepTag(depTag) {
|
|
||||||
if cc, ok := child.(*cc.Module); ok {
|
|
||||||
af := apexFileForExecutable(ctx, cc)
|
|
||||||
// Handle modules created as `test_per_src` variations of a single test module:
|
|
||||||
// use the name of the generated test binary (`fileToCopy`) instead of the name
|
|
||||||
// of the original test module (`depName`, shared by all `test_per_src`
|
|
||||||
// variations of that module).
|
|
||||||
af.androidMkModuleName = filepath.Base(af.builtFile.String())
|
|
||||||
// these are not considered transitive dep
|
|
||||||
af.transitiveDep = false
|
|
||||||
filesInfo = append(filesInfo, af)
|
|
||||||
return true // track transitive dependencies
|
|
||||||
}
|
|
||||||
} else if cc.IsHeaderDepTag(depTag) {
|
|
||||||
// nothing
|
|
||||||
} else if java.IsJniDepTag(depTag) {
|
|
||||||
// Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
|
|
||||||
return false
|
|
||||||
} else if java.IsXmlPermissionsFileDepTag(depTag) {
|
|
||||||
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
|
|
||||||
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
|
|
||||||
}
|
|
||||||
} else if rust.IsDylibDepTag(depTag) {
|
|
||||||
if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
|
|
||||||
af := apexFileForRustLibrary(ctx, rustm)
|
|
||||||
af.transitiveDep = true
|
|
||||||
filesInfo = append(filesInfo, af)
|
|
||||||
return true // track transitive dependencies
|
|
||||||
}
|
|
||||||
} else if rust.IsRlibDepTag(depTag) {
|
|
||||||
// Rlib is statically linked, but it might have shared lib
|
|
||||||
// dependencies. Track them.
|
|
||||||
return true
|
|
||||||
} else if java.IsBootclasspathFragmentContentDepTag(depTag) {
|
|
||||||
// Add the contents of the bootclasspath fragment to the apex.
|
|
||||||
switch child.(type) {
|
|
||||||
case *java.Library, *java.SdkLibrary:
|
|
||||||
javaModule := child.(javaModule)
|
|
||||||
af := apexFileForBootclasspathFragmentContentModule(ctx, parent, javaModule)
|
|
||||||
if !af.ok() {
|
|
||||||
ctx.PropertyErrorf("bootclasspath_fragments", "bootclasspath_fragment content %q is not configured to be compiled into dex", depName)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
filesInfo = append(filesInfo, af)
|
|
||||||
return true // track transitive dependencies
|
|
||||||
default:
|
|
||||||
ctx.PropertyErrorf("bootclasspath_fragments", "bootclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
|
|
||||||
}
|
|
||||||
} else if java.IsSystemServerClasspathFragmentContentDepTag(depTag) {
|
|
||||||
// Add the contents of the systemserverclasspath fragment to the apex.
|
|
||||||
switch child.(type) {
|
|
||||||
case *java.Library, *java.SdkLibrary:
|
|
||||||
af := apexFileForJavaModule(ctx, child.(javaModule))
|
|
||||||
filesInfo = append(filesInfo, af)
|
|
||||||
return true // track transitive dependencies
|
|
||||||
default:
|
|
||||||
ctx.PropertyErrorf("systemserverclasspath_fragments", "systemserverclasspath_fragment content %q of type %q is not supported", depName, ctx.OtherModuleType(child))
|
|
||||||
}
|
|
||||||
} else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
|
|
||||||
// nothing
|
|
||||||
} else if depTag == android.DarwinUniversalVariantTag {
|
|
||||||
// nothing
|
|
||||||
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
|
|
||||||
ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
if a.privateKeyFile == nil {
|
if a.privateKeyFile == nil {
|
||||||
ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
|
ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.overridableProperties.Key))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove duplicates in filesInfo
|
|
||||||
removeDup := func(filesInfo []apexFile) []apexFile {
|
|
||||||
encountered := make(map[string]apexFile)
|
|
||||||
for _, f := range filesInfo {
|
|
||||||
dest := filepath.Join(f.installDir, f.builtFile.Base())
|
|
||||||
if e, ok := encountered[dest]; !ok {
|
|
||||||
encountered[dest] = f
|
|
||||||
} else {
|
|
||||||
// If a module is directly included and also transitively depended on
|
|
||||||
// consider it as directly included.
|
|
||||||
e.transitiveDep = e.transitiveDep && f.transitiveDep
|
|
||||||
encountered[dest] = e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var result []apexFile
|
|
||||||
for _, v := range encountered {
|
|
||||||
result = append(result, v)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
filesInfo = removeDup(filesInfo)
|
|
||||||
|
|
||||||
// Sort to have consistent build rules
|
|
||||||
sort.Slice(filesInfo, func(i, j int) bool {
|
|
||||||
// Sort by destination path so as to ensure consistent ordering even if the source of the files
|
|
||||||
// changes.
|
|
||||||
return filesInfo[i].path() < filesInfo[j].path()
|
|
||||||
})
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// 3) some fields in apexBundle struct are configured
|
// 3) some fields in apexBundle struct are configured
|
||||||
a.installDir = android.PathForModuleInstall(ctx, "apex")
|
a.installDir = android.PathForModuleInstall(ctx, "apex")
|
||||||
a.filesInfo = filesInfo
|
a.filesInfo = vctx.filesInfo
|
||||||
|
|
||||||
// Set suffix and primaryApexType depending on the ApexType
|
// Set suffix and primaryApexType depending on the ApexType
|
||||||
buildFlattenedAsDefault := ctx.Config().FlattenApex()
|
buildFlattenedAsDefault := ctx.Config().FlattenApex()
|
||||||
@@ -2267,7 +2280,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// 4) generate the build rules to create the APEX. This is done in builder.go.
|
// 4) generate the build rules to create the APEX. This is done in builder.go.
|
||||||
a.buildManifest(ctx, provideNativeLibs, requireNativeLibs)
|
a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
|
||||||
if a.properties.ApexType == flattenedApex {
|
if a.properties.ApexType == flattenedApex {
|
||||||
a.buildFlattenedApex(ctx)
|
a.buildFlattenedApex(ctx)
|
||||||
} else {
|
} else {
|
||||||
@@ -2458,7 +2471,7 @@ type OverrideApex struct {
|
|||||||
android.BazelModuleBase
|
android.BazelModuleBase
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OverrideApex) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
func (o *OverrideApex) GenerateAndroidBuildActions(_ android.ModuleContext) {
|
||||||
// All the overrides happen in the base module.
|
// All the overrides happen in the base module.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user