apex: Remove 'zip' apex support
zip apex is no longer supported. Bug: 279835185 Test: m Change-Id: I651b0dc4e0efe766f61e97b1e5dd263e0ab74102
This commit is contained in:
parent
15aed3b882
commit
06a8a1c384
6 changed files with 255 additions and 495 deletions
|
@ -67,7 +67,7 @@ func (a *apexBundle) fullModuleName(apexBundleName string, linkToSystemLib bool,
|
||||||
if linkToSystemLib {
|
if linkToSystemLib {
|
||||||
return fi.androidMkModuleName
|
return fi.androidMkModuleName
|
||||||
}
|
}
|
||||||
return fi.androidMkModuleName + "." + apexBundleName + a.suffix
|
return fi.androidMkModuleName + "." + apexBundleName
|
||||||
}
|
}
|
||||||
|
|
||||||
// androidMkForFiles generates Make definitions for the contents of an
|
// androidMkForFiles generates Make definitions for the contents of an
|
||||||
|
@ -85,11 +85,6 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st
|
||||||
// conflicts between two apexes with the same apexName.
|
// conflicts between two apexes with the same apexName.
|
||||||
|
|
||||||
moduleNames := []string{}
|
moduleNames := []string{}
|
||||||
// To avoid creating duplicate build rules, run this function only when primaryApexType is true
|
|
||||||
// to install symbol files in $(PRODUCT_OUT}/apex.
|
|
||||||
if !a.primaryApexType {
|
|
||||||
return moduleNames
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, fi := range a.filesInfo {
|
for _, fi := range a.filesInfo {
|
||||||
linkToSystemLib := a.linkToSystemLib && fi.transitiveDep && fi.availableToPlatform()
|
linkToSystemLib := a.linkToSystemLib && fi.transitiveDep && fi.availableToPlatform()
|
||||||
|
@ -237,7 +232,7 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st
|
||||||
}
|
}
|
||||||
|
|
||||||
// m <module_name> will build <module_name>.<apex_name> as well.
|
// m <module_name> will build <module_name>.<apex_name> as well.
|
||||||
if fi.androidMkModuleName != moduleName && a.primaryApexType {
|
if fi.androidMkModuleName != moduleName {
|
||||||
fmt.Fprintf(w, ".PHONY: %s\n", fi.androidMkModuleName)
|
fmt.Fprintf(w, ".PHONY: %s\n", fi.androidMkModuleName)
|
||||||
fmt.Fprintf(w, "%s: %s\n", fi.androidMkModuleName, moduleName)
|
fmt.Fprintf(w, "%s: %s\n", fi.androidMkModuleName, moduleName)
|
||||||
}
|
}
|
||||||
|
@ -266,19 +261,18 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
|
||||||
return android.AndroidMkData{
|
return android.AndroidMkData{
|
||||||
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
|
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
|
||||||
moduleNames := []string{}
|
moduleNames := []string{}
|
||||||
apexType := a.properties.ApexType
|
|
||||||
if a.installable() {
|
if a.installable() {
|
||||||
moduleNames = a.androidMkForFiles(w, name, moduleDir, data)
|
moduleNames = a.androidMkForFiles(w, name, moduleDir, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintln(w, "\ninclude $(CLEAR_VARS) # apex.apexBundle")
|
fmt.Fprintln(w, "\ninclude $(CLEAR_VARS) # apex.apexBundle")
|
||||||
fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
|
fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
|
||||||
fmt.Fprintln(w, "LOCAL_MODULE :=", name+a.suffix)
|
fmt.Fprintln(w, "LOCAL_MODULE :=", name)
|
||||||
data.Entries.WriteLicenseVariables(w)
|
data.Entries.WriteLicenseVariables(w)
|
||||||
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") // do we need a new class?
|
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") // do we need a new class?
|
||||||
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", a.outputFile.String())
|
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", a.outputFile.String())
|
||||||
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.String())
|
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.String())
|
||||||
stemSuffix := apexType.suffix()
|
stemSuffix := imageApexSuffix
|
||||||
if a.isCompressed {
|
if a.isCompressed {
|
||||||
stemSuffix = imageCapexSuffix
|
stemSuffix = imageCapexSuffix
|
||||||
}
|
}
|
||||||
|
@ -306,10 +300,7 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
|
||||||
a.writeRequiredModules(w, moduleNames)
|
a.writeRequiredModules(w, moduleNames)
|
||||||
|
|
||||||
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
|
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
|
||||||
|
fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())
|
||||||
if apexType == imageApex {
|
|
||||||
fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())
|
|
||||||
}
|
|
||||||
android.AndroidMkEmitAssignList(w, "ALL_MODULES.$(my_register_name).LINT_REPORTS", a.lintReports.Strings())
|
android.AndroidMkEmitAssignList(w, "ALL_MODULES.$(my_register_name).LINT_REPORTS", a.lintReports.Strings())
|
||||||
|
|
||||||
if a.installedFilesFile != nil {
|
if a.installedFilesFile != nil {
|
||||||
|
|
149
apex/apex.go
149
apex/apex.go
|
@ -166,15 +166,7 @@ type apexBundleProperties struct {
|
||||||
// Should be only used in non-system apexes (e.g. vendor: true). Default is false.
|
// Should be only used in non-system apexes (e.g. vendor: true). Default is false.
|
||||||
Use_vndk_as_stable *bool
|
Use_vndk_as_stable *bool
|
||||||
|
|
||||||
// The type of APEX to build. Controls what the APEX payload is. Either 'image', 'zip' or
|
// The type of filesystem to use. Either 'ext4', 'f2fs' or 'erofs'. Default 'ext4'.
|
||||||
// 'both'. When set to image, contents are stored in a filesystem image inside a zip
|
|
||||||
// container. When set to zip, contents are stored in a zip container directly. This type is
|
|
||||||
// mostly for host-side debugging. When set to both, the two types are both built. Default
|
|
||||||
// is 'image'.
|
|
||||||
Payload_type *string
|
|
||||||
|
|
||||||
// The type of filesystem to use when the payload_type is 'image'. Either 'ext4', 'f2fs'
|
|
||||||
// or 'erofs'. Default 'ext4'.
|
|
||||||
Payload_fs_type *string
|
Payload_fs_type *string
|
||||||
|
|
||||||
// For telling the APEX to ignore special handling for system libraries such as bionic.
|
// For telling the APEX to ignore special handling for system libraries such as bionic.
|
||||||
|
@ -216,9 +208,6 @@ type apexBundleProperties struct {
|
||||||
|
|
||||||
HideFromMake bool `blueprint:"mutated"`
|
HideFromMake bool `blueprint:"mutated"`
|
||||||
|
|
||||||
// Internal package method for this APEX.
|
|
||||||
ApexType apexPackaging `blueprint:"mutated"`
|
|
||||||
|
|
||||||
// Name that dependencies can specify in their apex_available properties to refer to this module.
|
// Name that dependencies can specify in their apex_available properties to refer to this module.
|
||||||
// If not specified, this defaults to Soong module name. This must be the name of a Soong module.
|
// If not specified, this defaults to Soong module name. This must be the name of a Soong module.
|
||||||
Apex_available_name *string
|
Apex_available_name *string
|
||||||
|
@ -421,13 +410,6 @@ type apexBundle struct {
|
||||||
testApex bool
|
testApex bool
|
||||||
vndkApex bool
|
vndkApex bool
|
||||||
|
|
||||||
// Tells whether this variant of the APEX bundle is the primary one or not. Only the primary
|
|
||||||
// one gets installed to the device.
|
|
||||||
primaryApexType bool
|
|
||||||
|
|
||||||
// Suffix of module name in Android.mk ".apex", ".zipapex", or ""
|
|
||||||
suffix string
|
|
||||||
|
|
||||||
// File system type of apex_payload.img
|
// File system type of apex_payload.img
|
||||||
payloadFsType fsType
|
payloadFsType fsType
|
||||||
|
|
||||||
|
@ -1353,88 +1335,26 @@ func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// apexPackaging represents a specific packaging method for an APEX.
|
|
||||||
type apexPackaging int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// imageApex is a packaging method where contents are included in a filesystem image which
|
|
||||||
// is then included in a zip container. This is the most typical way of packaging.
|
|
||||||
imageApex apexPackaging = iota
|
|
||||||
|
|
||||||
// zipApex is a packaging method where contents are directly included in the zip container.
|
|
||||||
// This is used for host-side testing - because the contents are easily accessible by
|
|
||||||
// unzipping the container.
|
|
||||||
// TODO(b/279835185) deprecate zipApex
|
|
||||||
zipApex
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// File extensions of an APEX for different packaging methods
|
// File extensions of an APEX for different packaging methods
|
||||||
imageApexSuffix = ".apex"
|
imageApexSuffix = ".apex"
|
||||||
imageCapexSuffix = ".capex"
|
imageCapexSuffix = ".capex"
|
||||||
zipApexSuffix = ".zipapex"
|
|
||||||
|
|
||||||
// variant names each of which is for a packaging method
|
// variant names each of which is for a packaging method
|
||||||
imageApexType = "image"
|
imageApexType = "image"
|
||||||
zipApexType = "zip"
|
|
||||||
|
|
||||||
ext4FsType = "ext4"
|
ext4FsType = "ext4"
|
||||||
f2fsFsType = "f2fs"
|
f2fsFsType = "f2fs"
|
||||||
erofsFsType = "erofs"
|
erofsFsType = "erofs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The suffix for the output "file", not the module
|
|
||||||
func (a apexPackaging) suffix() string {
|
|
||||||
switch a {
|
|
||||||
case imageApex:
|
|
||||||
return imageApexSuffix
|
|
||||||
case zipApex:
|
|
||||||
return zipApexSuffix
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("unknown APEX type %d", a))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a apexPackaging) name() string {
|
|
||||||
switch a {
|
|
||||||
case imageApex:
|
|
||||||
return imageApexType
|
|
||||||
case zipApex:
|
|
||||||
return zipApexType
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("unknown APEX type %d", a))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// apexPackagingMutator creates one or more variations each of which is for a packaging method.
|
// apexPackagingMutator creates one or more variations each of which is for a packaging method.
|
||||||
func apexPackagingMutator(mctx android.BottomUpMutatorContext) {
|
func apexPackagingMutator(mctx android.BottomUpMutatorContext) {
|
||||||
if !mctx.Module().Enabled() {
|
if !mctx.Module().Enabled() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ab, ok := mctx.Module().(*apexBundle); ok {
|
if _, ok := mctx.Module().(*apexBundle); ok {
|
||||||
var variants []string
|
mctx.CreateLocalVariations(imageApexType)
|
||||||
switch proptools.StringDefault(ab.properties.Payload_type, "image") {
|
|
||||||
case "image":
|
|
||||||
variants = append(variants, imageApexType)
|
|
||||||
case "zip":
|
|
||||||
variants = append(variants, zipApexType)
|
|
||||||
case "both":
|
|
||||||
variants = append(variants, imageApexType, zipApexType)
|
|
||||||
default:
|
|
||||||
mctx.PropertyErrorf("payload_type", "%q is not one of \"image\", \"zip\", or \"both\".", *ab.properties.Payload_type)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
modules := mctx.CreateLocalVariations(variants...)
|
|
||||||
|
|
||||||
for i, v := range variants {
|
|
||||||
switch v {
|
|
||||||
case imageApexType:
|
|
||||||
modules[i].(*apexBundle).properties.ApexType = imageApex
|
|
||||||
case zipApexType:
|
|
||||||
modules[i].(*apexBundle).properties.ApexType = zipApex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if _, ok := mctx.Module().(*OverrideApex); ok {
|
} else if _, ok := mctx.Module().(*OverrideApex); ok {
|
||||||
// payload_type is forcibly overridden to "image"
|
// payload_type is forcibly overridden to "image"
|
||||||
// TODO(jiyong): is this the right decision?
|
// TODO(jiyong): is this the right decision?
|
||||||
|
@ -1945,7 +1865,7 @@ func (f fsType) string() string {
|
||||||
var _ android.MixedBuildBuildable = (*apexBundle)(nil)
|
var _ android.MixedBuildBuildable = (*apexBundle)(nil)
|
||||||
|
|
||||||
func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
|
func (a *apexBundle) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
|
||||||
return a.properties.ApexType == imageApex
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
|
func (a *apexBundle) QueueBazelCall(ctx android.BaseModuleContext) {
|
||||||
|
@ -1966,13 +1886,9 @@ func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a.setApexTypeAndSuffix(ctx)
|
|
||||||
a.setPayloadFsType(ctx)
|
a.setPayloadFsType(ctx)
|
||||||
a.setSystemLibLink(ctx)
|
a.setSystemLibLink(ctx)
|
||||||
|
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
|
||||||
if a.properties.ApexType != zipApex {
|
|
||||||
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
|
|
||||||
}
|
|
||||||
|
|
||||||
bazelCtx := ctx.Config().BazelContext
|
bazelCtx := ctx.Config().BazelContext
|
||||||
outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
|
outputs, err := bazelCtx.GetApexInfo(a.GetBazelLabel(ctx, a), android.GetConfigKey(ctx))
|
||||||
|
@ -2007,24 +1923,18 @@ func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
|
||||||
// part of a bundled build.
|
// part of a bundled build.
|
||||||
a.makeModulesToInstall = append(a.makeModulesToInstall, outputs.MakeModulesToInstall...)
|
a.makeModulesToInstall = append(a.makeModulesToInstall, outputs.MakeModulesToInstall...)
|
||||||
|
|
||||||
apexType := a.properties.ApexType
|
a.bundleModuleFile = android.PathForBazelOut(ctx, outputs.BundleFile)
|
||||||
switch apexType {
|
a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.SymbolsUsedByApex))
|
||||||
case imageApex:
|
a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.BackingLibs))
|
||||||
a.bundleModuleFile = android.PathForBazelOut(ctx, outputs.BundleFile)
|
// TODO(b/239084755): Generate the java api using.xml file from Bazel.
|
||||||
a.nativeApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.SymbolsUsedByApex))
|
a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.JavaSymbolsUsedByApex))
|
||||||
a.nativeApisBackedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.BackingLibs))
|
a.installedFilesFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.InstalledFiles))
|
||||||
// TODO(b/239084755): Generate the java api using.xml file from Bazel.
|
installSuffix := imageApexSuffix
|
||||||
a.javaApisUsedByModuleFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.JavaSymbolsUsedByApex))
|
if a.isCompressed {
|
||||||
a.installedFilesFile = android.ModuleOutPath(android.PathForBazelOut(ctx, outputs.InstalledFiles))
|
installSuffix = imageCapexSuffix
|
||||||
installSuffix := imageApexSuffix
|
|
||||||
if a.isCompressed {
|
|
||||||
installSuffix = imageCapexSuffix
|
|
||||||
}
|
|
||||||
a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
|
|
||||||
a.compatSymlinks.Paths()...)
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("internal error: unexpected apex_type for the ProcessBazelQueryResponse: %v", a.properties.ApexType))
|
|
||||||
}
|
}
|
||||||
|
a.installedFile = ctx.InstallFile(a.installDir, a.Name()+installSuffix, a.outputFile,
|
||||||
|
a.compatSymlinks.Paths()...)
|
||||||
|
|
||||||
// filesInfo in mixed mode must retrieve all information about the apex's
|
// filesInfo in mixed mode must retrieve all information about the apex's
|
||||||
// contents completely from the Starlark providers. It should never rely on
|
// contents completely from the Starlark providers. It should never rely on
|
||||||
|
@ -2065,9 +1975,7 @@ func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apexBundle) setCompression(ctx android.ModuleContext) {
|
func (a *apexBundle) setCompression(ctx android.ModuleContext) {
|
||||||
if a.properties.ApexType != imageApex {
|
if a.testOnlyShouldForceCompression() {
|
||||||
a.isCompressed = false
|
|
||||||
} else if a.testOnlyShouldForceCompression() {
|
|
||||||
a.isCompressed = true
|
a.isCompressed = true
|
||||||
} else {
|
} else {
|
||||||
a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
|
a.isCompressed = ctx.Config().ApexCompressionEnabled() && a.isCompressable()
|
||||||
|
@ -2093,7 +2001,7 @@ func (a *apexBundle) setSystemLibLink(ctx android.ModuleContext) {
|
||||||
|
|
||||||
// We don't need the optimization for updatable APEXes, as it might give false signal
|
// We don't need the optimization for updatable APEXes, as it might give false signal
|
||||||
// to the system health when the APEXes are still bundled (b/149805758).
|
// to the system health when the APEXes are still bundled (b/149805758).
|
||||||
if !forced && updatable && a.properties.ApexType == imageApex {
|
if !forced && updatable {
|
||||||
a.linkToSystemLib = false
|
a.linkToSystemLib = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2116,22 +2024,6 @@ func (a *apexBundle) setPayloadFsType(ctx android.ModuleContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apexBundle) setApexTypeAndSuffix(ctx android.ModuleContext) {
|
|
||||||
// Set suffix and primaryApexType depending on the ApexType
|
|
||||||
switch a.properties.ApexType {
|
|
||||||
case imageApex:
|
|
||||||
a.suffix = ""
|
|
||||||
a.primaryApexType = true
|
|
||||||
case zipApex:
|
|
||||||
if proptools.String(a.properties.Payload_type) == "zip" {
|
|
||||||
a.suffix = ""
|
|
||||||
a.primaryApexType = true
|
|
||||||
} else {
|
|
||||||
a.suffix = zipApexSuffix
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apexBundle) isCompressable() bool {
|
func (a *apexBundle) isCompressable() bool {
|
||||||
return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
|
return proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex
|
||||||
}
|
}
|
||||||
|
@ -2621,12 +2513,9 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
a.installDir = android.PathForModuleInstall(ctx, "apex")
|
a.installDir = android.PathForModuleInstall(ctx, "apex")
|
||||||
a.filesInfo = vctx.filesInfo
|
a.filesInfo = vctx.filesInfo
|
||||||
|
|
||||||
a.setApexTypeAndSuffix(ctx)
|
|
||||||
a.setPayloadFsType(ctx)
|
a.setPayloadFsType(ctx)
|
||||||
a.setSystemLibLink(ctx)
|
a.setSystemLibLink(ctx)
|
||||||
if a.properties.ApexType != zipApex {
|
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
|
||||||
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, a.primaryApexType)
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// 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.
|
||||||
|
|
|
@ -819,57 +819,6 @@ func TestFileContexts(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBasicZipApex(t *testing.T) {
|
|
||||||
ctx := testApex(t, `
|
|
||||||
apex {
|
|
||||||
name: "myapex",
|
|
||||||
key: "myapex.key",
|
|
||||||
payload_type: "zip",
|
|
||||||
native_shared_libs: ["mylib"],
|
|
||||||
updatable: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
apex_key {
|
|
||||||
name: "myapex.key",
|
|
||||||
public_key: "testkey.avbpubkey",
|
|
||||||
private_key: "testkey.pem",
|
|
||||||
}
|
|
||||||
|
|
||||||
cc_library {
|
|
||||||
name: "mylib",
|
|
||||||
srcs: ["mylib.cpp"],
|
|
||||||
shared_libs: ["mylib2"],
|
|
||||||
system_shared_libs: [],
|
|
||||||
stl: "none",
|
|
||||||
apex_available: [ "myapex" ],
|
|
||||||
}
|
|
||||||
|
|
||||||
cc_library {
|
|
||||||
name: "mylib2",
|
|
||||||
srcs: ["mylib.cpp"],
|
|
||||||
system_shared_libs: [],
|
|
||||||
stl: "none",
|
|
||||||
apex_available: [ "myapex" ],
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
zipApexRule := ctx.ModuleForTests("myapex", "android_common_myapex_zip").Rule("zipApexRule")
|
|
||||||
copyCmds := zipApexRule.Args["copy_commands"]
|
|
||||||
|
|
||||||
// Ensure that main rule creates an output
|
|
||||||
ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned")
|
|
||||||
|
|
||||||
// Ensure that APEX variant is created for the direct dep
|
|
||||||
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
|
|
||||||
|
|
||||||
// Ensure that APEX variant is created for the indirect dep
|
|
||||||
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000")
|
|
||||||
|
|
||||||
// Ensure that both direct and indirect deps are copied into apex
|
|
||||||
ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so")
|
|
||||||
ensureContains(t, copyCmds, "image.zipapex/lib64/mylib2.so")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApexWithStubs(t *testing.T) {
|
func TestApexWithStubs(t *testing.T) {
|
||||||
ctx := testApex(t, `
|
ctx := testApex(t, `
|
||||||
apex {
|
apex {
|
||||||
|
@ -3657,10 +3606,6 @@ func getFiles(t *testing.T, ctx *android.TestContext, moduleName, variant string
|
||||||
module := ctx.ModuleForTests(moduleName, variant)
|
module := ctx.ModuleForTests(moduleName, variant)
|
||||||
apexRule := module.MaybeRule("apexRule")
|
apexRule := module.MaybeRule("apexRule")
|
||||||
apexDir := "/image.apex/"
|
apexDir := "/image.apex/"
|
||||||
if apexRule.Rule == nil {
|
|
||||||
apexRule = module.Rule("zipApexRule")
|
|
||||||
apexDir = "/image.zipapex/"
|
|
||||||
}
|
|
||||||
copyCmds := apexRule.Args["copy_commands"]
|
copyCmds := apexRule.Args["copy_commands"]
|
||||||
var ret []fileInApex
|
var ret []fileInApex
|
||||||
for _, cmd := range strings.Split(copyCmds, "&&") {
|
for _, cmd := range strings.Split(copyCmds, "&&") {
|
||||||
|
@ -9554,28 +9499,6 @@ func TestPrebuiltStubLibDep(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHostApexInHostOnlyBuild(t *testing.T) {
|
|
||||||
testApex(t, `
|
|
||||||
apex {
|
|
||||||
name: "myapex",
|
|
||||||
host_supported: true,
|
|
||||||
key: "myapex.key",
|
|
||||||
updatable: false,
|
|
||||||
payload_type: "zip",
|
|
||||||
}
|
|
||||||
apex_key {
|
|
||||||
name: "myapex.key",
|
|
||||||
public_key: "testkey.avbpubkey",
|
|
||||||
private_key: "testkey.pem",
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
android.FixtureModifyConfig(func(config android.Config) {
|
|
||||||
// We may not have device targets in all builds, e.g. in
|
|
||||||
// prebuilts/build-tools/build-prebuilts.sh
|
|
||||||
config.Targets[android.Android] = []android.Target{}
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestApexJavaCoverage(t *testing.T) {
|
func TestApexJavaCoverage(t *testing.T) {
|
||||||
bp := `
|
bp := `
|
||||||
apex {
|
apex {
|
||||||
|
|
489
apex/builder.go
489
apex/builder.go
|
@ -179,19 +179,6 @@ var (
|
||||||
}, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key",
|
}, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key",
|
||||||
"opt_flags", "manifest", "libs_to_trim")
|
"opt_flags", "manifest", "libs_to_trim")
|
||||||
|
|
||||||
zipApexRule = pctx.StaticRule("zipApexRule", blueprint.RuleParams{
|
|
||||||
Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` +
|
|
||||||
`(. ${out}.copy_commands) && ` +
|
|
||||||
`APEXER_TOOL_PATH=${tool_path} ` +
|
|
||||||
`${apexer} --force --manifest ${manifest} ` +
|
|
||||||
`--payload_type zip ` +
|
|
||||||
`${image_dir} ${out} `,
|
|
||||||
CommandDeps: []string{"${apexer}", "${merge_zips}", "${soong_zip}", "${zipalign}", "${aapt2}"},
|
|
||||||
Rspfile: "${out}.copy_commands",
|
|
||||||
RspfileContent: "${copy_commands}",
|
|
||||||
Description: "ZipAPEX ${image_dir} => ${out}",
|
|
||||||
}, "tool_path", "image_dir", "copy_commands", "manifest")
|
|
||||||
|
|
||||||
apexProtoConvertRule = pctx.AndroidStaticRule("apexProtoConvertRule",
|
apexProtoConvertRule = pctx.AndroidStaticRule("apexProtoConvertRule",
|
||||||
blueprint.RuleParams{
|
blueprint.RuleParams{
|
||||||
Command: `${aapt2} convert --output-format proto $in -o $out`,
|
Command: `${aapt2} convert --output-format proto $in -o $out`,
|
||||||
|
@ -369,21 +356,16 @@ func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) android.Output
|
||||||
// even though VNDK APEX is supposed to be installed on /system. (See com.android.vndk.current.on_vendor)
|
// even though VNDK APEX is supposed to be installed on /system. (See com.android.vndk.current.on_vendor)
|
||||||
forceLabel = "u:object_r:vendor_apex_metadata_file:s0"
|
forceLabel = "u:object_r:vendor_apex_metadata_file:s0"
|
||||||
}
|
}
|
||||||
switch a.properties.ApexType {
|
// remove old file
|
||||||
case imageApex:
|
rule.Command().Text("rm").FlagWithOutput("-f ", output)
|
||||||
// remove old file
|
// copy file_contexts
|
||||||
rule.Command().Text("rm").FlagWithOutput("-f ", output)
|
rule.Command().Text("cat").Input(fileContexts).Text(">>").Output(output)
|
||||||
// copy file_contexts
|
// new line
|
||||||
rule.Command().Text("cat").Input(fileContexts).Text(">>").Output(output)
|
rule.Command().Text("echo").Text(">>").Output(output)
|
||||||
// new line
|
if !useFileContextsAsIs {
|
||||||
rule.Command().Text("echo").Text(">>").Output(output)
|
// force-label /apex_manifest.pb and /
|
||||||
if !useFileContextsAsIs {
|
rule.Command().Text("echo").Text("/apex_manifest\\\\.pb").Text(forceLabel).Text(">>").Output(output)
|
||||||
// force-label /apex_manifest.pb and /
|
rule.Command().Text("echo").Text("/").Text(forceLabel).Text(">>").Output(output)
|
||||||
rule.Command().Text("echo").Text("/apex_manifest\\\\.pb").Text(forceLabel).Text(">>").Output(output)
|
|
||||||
rule.Command().Text("echo").Text("/").Text(forceLabel).Text(">>").Output(output)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("unsupported type %v", a.properties.ApexType))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rule.Build("file_contexts."+a.Name(), "Generate file_contexts")
|
rule.Build("file_contexts."+a.Name(), "Generate file_contexts")
|
||||||
|
@ -464,8 +446,7 @@ func markManifestTestOnly(ctx android.ModuleContext, androidManifestFile android
|
||||||
|
|
||||||
// buildApex creates build rules to build an APEX using apexer.
|
// buildApex creates build rules to build an APEX using apexer.
|
||||||
func (a *apexBundle) buildApex(ctx android.ModuleContext) {
|
func (a *apexBundle) buildApex(ctx android.ModuleContext) {
|
||||||
apexType := a.properties.ApexType
|
suffix := imageApexSuffix
|
||||||
suffix := apexType.suffix()
|
|
||||||
apexName := a.BaseModuleName()
|
apexName := a.BaseModuleName()
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -604,263 +585,247 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
|
||||||
outHostBinDir := ctx.Config().HostToolPath(ctx, "").String()
|
outHostBinDir := ctx.Config().HostToolPath(ctx, "").String()
|
||||||
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
|
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
|
||||||
|
|
||||||
if apexType == imageApex {
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Step 2: create canned_fs_config which encodes filemode,uid,gid of each files
|
||||||
|
// in this APEX. The file will be used by apexer in later steps.
|
||||||
|
cannedFsConfig := a.buildCannedFsConfig(ctx)
|
||||||
|
implicitInputs = append(implicitInputs, cannedFsConfig)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Step 2: create canned_fs_config which encodes filemode,uid,gid of each files
|
// Step 3: Prepare option flags for apexer and invoke it to create an unsigned APEX.
|
||||||
// in this APEX. The file will be used by apexer in later steps.
|
// TODO(jiyong): use the RuleBuilder
|
||||||
cannedFsConfig := a.buildCannedFsConfig(ctx)
|
optFlags := []string{}
|
||||||
implicitInputs = append(implicitInputs, cannedFsConfig)
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
fileContexts := a.buildFileContexts(ctx)
|
||||||
// Step 3: Prepare option flags for apexer and invoke it to create an unsigned APEX.
|
implicitInputs = append(implicitInputs, fileContexts)
|
||||||
// TODO(jiyong): use the RuleBuilder
|
|
||||||
optFlags := []string{}
|
|
||||||
|
|
||||||
fileContexts := a.buildFileContexts(ctx)
|
implicitInputs = append(implicitInputs, a.privateKeyFile, a.publicKeyFile)
|
||||||
implicitInputs = append(implicitInputs, fileContexts)
|
optFlags = append(optFlags, "--pubkey "+a.publicKeyFile.String())
|
||||||
|
|
||||||
implicitInputs = append(implicitInputs, a.privateKeyFile, a.publicKeyFile)
|
manifestPackageName := a.getOverrideManifestPackageName(ctx)
|
||||||
optFlags = append(optFlags, "--pubkey "+a.publicKeyFile.String())
|
if manifestPackageName != "" {
|
||||||
|
optFlags = append(optFlags, "--override_apk_package_name "+manifestPackageName)
|
||||||
|
}
|
||||||
|
|
||||||
manifestPackageName := a.getOverrideManifestPackageName(ctx)
|
if a.properties.AndroidManifest != nil {
|
||||||
if manifestPackageName != "" {
|
androidManifestFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.AndroidManifest))
|
||||||
optFlags = append(optFlags, "--override_apk_package_name "+manifestPackageName)
|
|
||||||
|
if a.testApex {
|
||||||
|
androidManifestFile = markManifestTestOnly(ctx, androidManifestFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.properties.AndroidManifest != nil {
|
implicitInputs = append(implicitInputs, androidManifestFile)
|
||||||
androidManifestFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.AndroidManifest))
|
optFlags = append(optFlags, "--android_manifest "+androidManifestFile.String())
|
||||||
|
} else if a.testApex {
|
||||||
|
optFlags = append(optFlags, "--test_only")
|
||||||
|
}
|
||||||
|
|
||||||
if a.testApex {
|
// Determine target/min sdk version from the context
|
||||||
androidManifestFile = markManifestTestOnly(ctx, androidManifestFile)
|
// TODO(jiyong): make this as a function
|
||||||
}
|
moduleMinSdkVersion := a.minSdkVersion(ctx)
|
||||||
|
minSdkVersion := moduleMinSdkVersion.String()
|
||||||
|
|
||||||
implicitInputs = append(implicitInputs, androidManifestFile)
|
// bundletool doesn't understand what "current" is. We need to transform it to
|
||||||
optFlags = append(optFlags, "--android_manifest "+androidManifestFile.String())
|
// codename
|
||||||
} else if a.testApex {
|
if moduleMinSdkVersion.IsCurrent() || moduleMinSdkVersion.IsNone() {
|
||||||
optFlags = append(optFlags, "--test_only")
|
minSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String()
|
||||||
}
|
|
||||||
|
|
||||||
// Determine target/min sdk version from the context
|
|
||||||
// TODO(jiyong): make this as a function
|
|
||||||
moduleMinSdkVersion := a.minSdkVersion(ctx)
|
|
||||||
minSdkVersion := moduleMinSdkVersion.String()
|
|
||||||
|
|
||||||
// bundletool doesn't understand what "current" is. We need to transform it to
|
|
||||||
// codename
|
|
||||||
if moduleMinSdkVersion.IsCurrent() || moduleMinSdkVersion.IsNone() {
|
|
||||||
minSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String()
|
|
||||||
|
|
||||||
if java.UseApiFingerprint(ctx) {
|
|
||||||
minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
|
|
||||||
implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// apex module doesn't have a concept of target_sdk_version, hence for the time
|
|
||||||
// being targetSdkVersion == default targetSdkVersion of the branch.
|
|
||||||
targetSdkVersion := strconv.Itoa(ctx.Config().DefaultAppTargetSdk(ctx).FinalOrFutureInt())
|
|
||||||
|
|
||||||
if java.UseApiFingerprint(ctx) {
|
if java.UseApiFingerprint(ctx) {
|
||||||
targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
|
minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
|
||||||
implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
|
implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
|
||||||
}
|
}
|
||||||
optFlags = append(optFlags, "--target_sdk_version "+targetSdkVersion)
|
}
|
||||||
optFlags = append(optFlags, "--min_sdk_version "+minSdkVersion)
|
// apex module doesn't have a concept of target_sdk_version, hence for the time
|
||||||
|
// being targetSdkVersion == default targetSdkVersion of the branch.
|
||||||
|
targetSdkVersion := strconv.Itoa(ctx.Config().DefaultAppTargetSdk(ctx).FinalOrFutureInt())
|
||||||
|
|
||||||
if a.overridableProperties.Logging_parent != "" {
|
if java.UseApiFingerprint(ctx) {
|
||||||
optFlags = append(optFlags, "--logging_parent ", a.overridableProperties.Logging_parent)
|
targetSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
|
||||||
}
|
implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
|
||||||
|
}
|
||||||
|
optFlags = append(optFlags, "--target_sdk_version "+targetSdkVersion)
|
||||||
|
optFlags = append(optFlags, "--min_sdk_version "+minSdkVersion)
|
||||||
|
|
||||||
// Create a NOTICE file, and embed it as an asset file in the APEX.
|
if a.overridableProperties.Logging_parent != "" {
|
||||||
htmlGzNotice := android.PathForModuleOut(ctx, "NOTICE.html.gz")
|
optFlags = append(optFlags, "--logging_parent ", a.overridableProperties.Logging_parent)
|
||||||
android.BuildNoticeHtmlOutputFromLicenseMetadata(
|
}
|
||||||
ctx, htmlGzNotice, "", "",
|
|
||||||
[]string{
|
|
||||||
android.PathForModuleInstall(ctx).String() + "/",
|
|
||||||
android.PathForModuleInPartitionInstall(ctx, "apex").String() + "/",
|
|
||||||
})
|
|
||||||
noticeAssetPath := android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
|
|
||||||
builder := android.NewRuleBuilder(pctx, ctx)
|
|
||||||
builder.Command().Text("cp").
|
|
||||||
Input(htmlGzNotice).
|
|
||||||
Output(noticeAssetPath)
|
|
||||||
builder.Build("notice_dir", "Building notice dir")
|
|
||||||
implicitInputs = append(implicitInputs, noticeAssetPath)
|
|
||||||
optFlags = append(optFlags, "--assets_dir "+filepath.Dir(noticeAssetPath.String()))
|
|
||||||
|
|
||||||
// Apexes which are supposed to be installed in builtin dirs(/system, etc)
|
// Create a NOTICE file, and embed it as an asset file in the APEX.
|
||||||
// don't need hashtree for activation. Therefore, by removing hashtree from
|
htmlGzNotice := android.PathForModuleOut(ctx, "NOTICE.html.gz")
|
||||||
// apex bundle (filesystem image in it, to be specific), we can save storage.
|
android.BuildNoticeHtmlOutputFromLicenseMetadata(
|
||||||
needHashTree := moduleMinSdkVersion.LessThanOrEqualTo(android.SdkVersion_Android10) ||
|
ctx, htmlGzNotice, "", "",
|
||||||
a.shouldGenerateHashtree()
|
[]string{
|
||||||
if ctx.Config().ApexCompressionEnabled() && a.isCompressable() {
|
android.PathForModuleInstall(ctx).String() + "/",
|
||||||
needHashTree = true
|
android.PathForModuleInPartitionInstall(ctx, "apex").String() + "/",
|
||||||
}
|
|
||||||
if !needHashTree {
|
|
||||||
optFlags = append(optFlags, "--no_hashtree")
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.testOnlyShouldSkipPayloadSign() {
|
|
||||||
optFlags = append(optFlags, "--unsigned_payload")
|
|
||||||
}
|
|
||||||
|
|
||||||
if moduleMinSdkVersion == android.SdkVersion_Android10 {
|
|
||||||
implicitInputs = append(implicitInputs, a.manifestJsonOut)
|
|
||||||
optFlags = append(optFlags, "--manifest_json "+a.manifestJsonOut.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
optFlags = append(optFlags, "--payload_fs_type "+a.payloadFsType.string())
|
|
||||||
|
|
||||||
if a.dynamic_common_lib_apex() {
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
|
||||||
Rule: DCLAApexRule,
|
|
||||||
Implicits: implicitInputs,
|
|
||||||
Output: unsignedOutputFile,
|
|
||||||
Description: "apex (" + apexType.name() + ")",
|
|
||||||
Args: map[string]string{
|
|
||||||
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
|
||||||
"image_dir": imageDir.String(),
|
|
||||||
"copy_commands": strings.Join(copyCommands, " && "),
|
|
||||||
"manifest": a.manifestPbOut.String(),
|
|
||||||
"file_contexts": fileContexts.String(),
|
|
||||||
"canned_fs_config": cannedFsConfig.String(),
|
|
||||||
"key": a.privateKeyFile.String(),
|
|
||||||
"opt_flags": strings.Join(optFlags, " "),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} else if ctx.Config().ApexTrimEnabled() && len(a.libs_to_trim(ctx)) > 0 {
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
|
||||||
Rule: TrimmedApexRule,
|
|
||||||
Implicits: implicitInputs,
|
|
||||||
Output: unsignedOutputFile,
|
|
||||||
Description: "apex (" + apexType.name() + ")",
|
|
||||||
Args: map[string]string{
|
|
||||||
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
|
||||||
"image_dir": imageDir.String(),
|
|
||||||
"copy_commands": strings.Join(copyCommands, " && "),
|
|
||||||
"manifest": a.manifestPbOut.String(),
|
|
||||||
"file_contexts": fileContexts.String(),
|
|
||||||
"canned_fs_config": cannedFsConfig.String(),
|
|
||||||
"key": a.privateKeyFile.String(),
|
|
||||||
"opt_flags": strings.Join(optFlags, " "),
|
|
||||||
"libs_to_trim": strings.Join(a.libs_to_trim(ctx), ","),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
|
||||||
Rule: apexRule,
|
|
||||||
Implicits: implicitInputs,
|
|
||||||
Output: unsignedOutputFile,
|
|
||||||
Description: "apex (" + apexType.name() + ")",
|
|
||||||
Args: map[string]string{
|
|
||||||
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
|
||||||
"image_dir": imageDir.String(),
|
|
||||||
"copy_commands": strings.Join(copyCommands, " && "),
|
|
||||||
"manifest": a.manifestPbOut.String(),
|
|
||||||
"file_contexts": fileContexts.String(),
|
|
||||||
"canned_fs_config": cannedFsConfig.String(),
|
|
||||||
"key": a.privateKeyFile.String(),
|
|
||||||
"opt_flags": strings.Join(optFlags, " "),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(jiyong): make the two rules below as separate functions
|
|
||||||
apexProtoFile := android.PathForModuleOut(ctx, a.Name()+".pb"+suffix)
|
|
||||||
bundleModuleFile := android.PathForModuleOut(ctx, a.Name()+suffix+"-base.zip")
|
|
||||||
a.bundleModuleFile = bundleModuleFile
|
|
||||||
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
|
||||||
Rule: apexProtoConvertRule,
|
|
||||||
Input: unsignedOutputFile,
|
|
||||||
Output: apexProtoFile,
|
|
||||||
Description: "apex proto convert",
|
|
||||||
})
|
})
|
||||||
|
noticeAssetPath := android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz")
|
||||||
|
builder := android.NewRuleBuilder(pctx, ctx)
|
||||||
|
builder.Command().Text("cp").
|
||||||
|
Input(htmlGzNotice).
|
||||||
|
Output(noticeAssetPath)
|
||||||
|
builder.Build("notice_dir", "Building notice dir")
|
||||||
|
implicitInputs = append(implicitInputs, noticeAssetPath)
|
||||||
|
optFlags = append(optFlags, "--assets_dir "+filepath.Dir(noticeAssetPath.String()))
|
||||||
|
|
||||||
implicitInputs = append(implicitInputs, unsignedOutputFile)
|
// Apexes which are supposed to be installed in builtin dirs(/system, etc)
|
||||||
|
// don't need hashtree for activation. Therefore, by removing hashtree from
|
||||||
|
// apex bundle (filesystem image in it, to be specific), we can save storage.
|
||||||
|
needHashTree := moduleMinSdkVersion.LessThanOrEqualTo(android.SdkVersion_Android10) ||
|
||||||
|
a.shouldGenerateHashtree()
|
||||||
|
if ctx.Config().ApexCompressionEnabled() && a.isCompressable() {
|
||||||
|
needHashTree = true
|
||||||
|
}
|
||||||
|
if !needHashTree {
|
||||||
|
optFlags = append(optFlags, "--no_hashtree")
|
||||||
|
}
|
||||||
|
|
||||||
// Run coverage analysis
|
if a.testOnlyShouldSkipPayloadSign() {
|
||||||
apisUsedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_using.txt")
|
optFlags = append(optFlags, "--unsigned_payload")
|
||||||
|
}
|
||||||
|
|
||||||
|
if moduleMinSdkVersion == android.SdkVersion_Android10 {
|
||||||
|
implicitInputs = append(implicitInputs, a.manifestJsonOut)
|
||||||
|
optFlags = append(optFlags, "--manifest_json "+a.manifestJsonOut.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
optFlags = append(optFlags, "--payload_fs_type "+a.payloadFsType.string())
|
||||||
|
|
||||||
|
if a.dynamic_common_lib_apex() {
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: generateAPIsUsedbyApexRule,
|
Rule: DCLAApexRule,
|
||||||
Implicits: implicitInputs,
|
|
||||||
Description: "coverage",
|
|
||||||
Output: apisUsedbyOutputFile,
|
|
||||||
Args: map[string]string{
|
|
||||||
"image_dir": imageDir.String(),
|
|
||||||
"readelf": "${config.ClangBin}/llvm-readelf",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
a.nativeApisUsedByModuleFile = apisUsedbyOutputFile
|
|
||||||
|
|
||||||
var nativeLibNames []string
|
|
||||||
for _, f := range a.filesInfo {
|
|
||||||
if f.class == nativeSharedLib {
|
|
||||||
nativeLibNames = append(nativeLibNames, f.stem())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
apisBackedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_backing.txt")
|
|
||||||
rule := android.NewRuleBuilder(pctx, ctx)
|
|
||||||
rule.Command().
|
|
||||||
Tool(android.PathForSource(ctx, "build/soong/scripts/gen_ndk_backedby_apex.sh")).
|
|
||||||
Output(apisBackedbyOutputFile).
|
|
||||||
Flags(nativeLibNames)
|
|
||||||
rule.Build("ndk_backedby_list", "Generate API libraries backed by Apex")
|
|
||||||
a.nativeApisBackedByModuleFile = apisBackedbyOutputFile
|
|
||||||
|
|
||||||
var javaLibOrApkPath []android.Path
|
|
||||||
for _, f := range a.filesInfo {
|
|
||||||
if f.class == javaSharedLib || f.class == app {
|
|
||||||
javaLibOrApkPath = append(javaLibOrApkPath, f.builtFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
javaApiUsedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_using.xml")
|
|
||||||
javaUsedByRule := android.NewRuleBuilder(pctx, ctx)
|
|
||||||
javaUsedByRule.Command().
|
|
||||||
Tool(android.PathForSource(ctx, "build/soong/scripts/gen_java_usedby_apex.sh")).
|
|
||||||
BuiltTool("dexdeps").
|
|
||||||
Output(javaApiUsedbyOutputFile).
|
|
||||||
Inputs(javaLibOrApkPath)
|
|
||||||
javaUsedByRule.Build("java_usedby_list", "Generate Java APIs used by Apex")
|
|
||||||
a.javaApisUsedByModuleFile = javaApiUsedbyOutputFile
|
|
||||||
|
|
||||||
bundleConfig := a.buildBundleConfig(ctx)
|
|
||||||
|
|
||||||
var abis []string
|
|
||||||
for _, target := range ctx.MultiTargets() {
|
|
||||||
if len(target.Arch.Abi) > 0 {
|
|
||||||
abis = append(abis, target.Arch.Abi[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abis = android.FirstUniqueStrings(abis)
|
|
||||||
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
|
||||||
Rule: apexBundleRule,
|
|
||||||
Input: apexProtoFile,
|
|
||||||
Implicit: bundleConfig,
|
|
||||||
Output: a.bundleModuleFile,
|
|
||||||
Description: "apex bundle module",
|
|
||||||
Args: map[string]string{
|
|
||||||
"abi": strings.Join(abis, "."),
|
|
||||||
"config": bundleConfig.String(),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} else { // zipApex
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
|
||||||
Rule: zipApexRule,
|
|
||||||
Implicits: implicitInputs,
|
Implicits: implicitInputs,
|
||||||
Output: unsignedOutputFile,
|
Output: unsignedOutputFile,
|
||||||
Description: "apex (" + apexType.name() + ")",
|
Description: "apex",
|
||||||
Args: map[string]string{
|
Args: map[string]string{
|
||||||
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
||||||
"image_dir": imageDir.String(),
|
"image_dir": imageDir.String(),
|
||||||
"copy_commands": strings.Join(copyCommands, " && "),
|
"copy_commands": strings.Join(copyCommands, " && "),
|
||||||
"manifest": a.manifestPbOut.String(),
|
"manifest": a.manifestPbOut.String(),
|
||||||
|
"file_contexts": fileContexts.String(),
|
||||||
|
"canned_fs_config": cannedFsConfig.String(),
|
||||||
|
"key": a.privateKeyFile.String(),
|
||||||
|
"opt_flags": strings.Join(optFlags, " "),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else if ctx.Config().ApexTrimEnabled() && len(a.libs_to_trim(ctx)) > 0 {
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: TrimmedApexRule,
|
||||||
|
Implicits: implicitInputs,
|
||||||
|
Output: unsignedOutputFile,
|
||||||
|
Description: "apex",
|
||||||
|
Args: map[string]string{
|
||||||
|
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
||||||
|
"image_dir": imageDir.String(),
|
||||||
|
"copy_commands": strings.Join(copyCommands, " && "),
|
||||||
|
"manifest": a.manifestPbOut.String(),
|
||||||
|
"file_contexts": fileContexts.String(),
|
||||||
|
"canned_fs_config": cannedFsConfig.String(),
|
||||||
|
"key": a.privateKeyFile.String(),
|
||||||
|
"opt_flags": strings.Join(optFlags, " "),
|
||||||
|
"libs_to_trim": strings.Join(a.libs_to_trim(ctx), ","),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: apexRule,
|
||||||
|
Implicits: implicitInputs,
|
||||||
|
Output: unsignedOutputFile,
|
||||||
|
Description: "apex",
|
||||||
|
Args: map[string]string{
|
||||||
|
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
||||||
|
"image_dir": imageDir.String(),
|
||||||
|
"copy_commands": strings.Join(copyCommands, " && "),
|
||||||
|
"manifest": a.manifestPbOut.String(),
|
||||||
|
"file_contexts": fileContexts.String(),
|
||||||
|
"canned_fs_config": cannedFsConfig.String(),
|
||||||
|
"key": a.privateKeyFile.String(),
|
||||||
|
"opt_flags": strings.Join(optFlags, " "),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(jiyong): make the two rules below as separate functions
|
||||||
|
apexProtoFile := android.PathForModuleOut(ctx, a.Name()+".pb"+suffix)
|
||||||
|
bundleModuleFile := android.PathForModuleOut(ctx, a.Name()+suffix+"-base.zip")
|
||||||
|
a.bundleModuleFile = bundleModuleFile
|
||||||
|
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: apexProtoConvertRule,
|
||||||
|
Input: unsignedOutputFile,
|
||||||
|
Output: apexProtoFile,
|
||||||
|
Description: "apex proto convert",
|
||||||
|
})
|
||||||
|
|
||||||
|
implicitInputs = append(implicitInputs, unsignedOutputFile)
|
||||||
|
|
||||||
|
// Run coverage analysis
|
||||||
|
apisUsedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_using.txt")
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: generateAPIsUsedbyApexRule,
|
||||||
|
Implicits: implicitInputs,
|
||||||
|
Description: "coverage",
|
||||||
|
Output: apisUsedbyOutputFile,
|
||||||
|
Args: map[string]string{
|
||||||
|
"image_dir": imageDir.String(),
|
||||||
|
"readelf": "${config.ClangBin}/llvm-readelf",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
a.nativeApisUsedByModuleFile = apisUsedbyOutputFile
|
||||||
|
|
||||||
|
var nativeLibNames []string
|
||||||
|
for _, f := range a.filesInfo {
|
||||||
|
if f.class == nativeSharedLib {
|
||||||
|
nativeLibNames = append(nativeLibNames, f.stem())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apisBackedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_backing.txt")
|
||||||
|
rb := android.NewRuleBuilder(pctx, ctx)
|
||||||
|
rb.Command().
|
||||||
|
Tool(android.PathForSource(ctx, "build/soong/scripts/gen_ndk_backedby_apex.sh")).
|
||||||
|
Output(apisBackedbyOutputFile).
|
||||||
|
Flags(nativeLibNames)
|
||||||
|
rb.Build("ndk_backedby_list", "Generate API libraries backed by Apex")
|
||||||
|
a.nativeApisBackedByModuleFile = apisBackedbyOutputFile
|
||||||
|
|
||||||
|
var javaLibOrApkPath []android.Path
|
||||||
|
for _, f := range a.filesInfo {
|
||||||
|
if f.class == javaSharedLib || f.class == app {
|
||||||
|
javaLibOrApkPath = append(javaLibOrApkPath, f.builtFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
javaApiUsedbyOutputFile := android.PathForModuleOut(ctx, a.Name()+"_using.xml")
|
||||||
|
javaUsedByRule := android.NewRuleBuilder(pctx, ctx)
|
||||||
|
javaUsedByRule.Command().
|
||||||
|
Tool(android.PathForSource(ctx, "build/soong/scripts/gen_java_usedby_apex.sh")).
|
||||||
|
BuiltTool("dexdeps").
|
||||||
|
Output(javaApiUsedbyOutputFile).
|
||||||
|
Inputs(javaLibOrApkPath)
|
||||||
|
javaUsedByRule.Build("java_usedby_list", "Generate Java APIs used by Apex")
|
||||||
|
a.javaApisUsedByModuleFile = javaApiUsedbyOutputFile
|
||||||
|
|
||||||
|
bundleConfig := a.buildBundleConfig(ctx)
|
||||||
|
|
||||||
|
var abis []string
|
||||||
|
for _, target := range ctx.MultiTargets() {
|
||||||
|
if len(target.Arch.Abi) > 0 {
|
||||||
|
abis = append(abis, target.Arch.Abi[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abis = android.FirstUniqueStrings(abis)
|
||||||
|
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: apexBundleRule,
|
||||||
|
Input: apexProtoFile,
|
||||||
|
Implicit: bundleConfig,
|
||||||
|
Output: a.bundleModuleFile,
|
||||||
|
Description: "apex bundle module",
|
||||||
|
Args: map[string]string{
|
||||||
|
"abi": strings.Join(abis, "."),
|
||||||
|
"config": bundleConfig.String(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Step 4: Sign the APEX using signapk
|
// Step 4: Sign the APEX using signapk
|
||||||
signedOutputFile := android.PathForModuleOut(ctx, a.Name()+suffix)
|
signedOutputFile := android.PathForModuleOut(ctx, a.Name()+suffix)
|
||||||
|
@ -987,10 +952,6 @@ func (a *apexBundle) getOverrideManifestPackageName(ctx android.ModuleContext) s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) {
|
func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) {
|
||||||
if !a.primaryApexType {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.properties.IsCoverageVariant {
|
if a.properties.IsCoverageVariant {
|
||||||
// Otherwise, we will have duplicated rules for coverage and
|
// Otherwise, we will have duplicated rules for coverage and
|
||||||
// non-coverage variants of the same APEX
|
// non-coverage variants of the same APEX
|
||||||
|
|
|
@ -781,10 +781,10 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
p.initApexFilesForAndroidMk(ctx)
|
p.initApexFilesForAndroidMk(ctx)
|
||||||
|
|
||||||
// in case that prebuilt_apex replaces source apex (using prefer: prop)
|
// in case that prebuilt_apex replaces source apex (using prefer: prop)
|
||||||
p.compatSymlinks = makeCompatSymlinks(p.BaseModuleName(), ctx, true)
|
p.compatSymlinks = makeCompatSymlinks(p.BaseModuleName(), ctx)
|
||||||
// or that prebuilt_apex overrides other apexes (using overrides: prop)
|
// or that prebuilt_apex overrides other apexes (using overrides: prop)
|
||||||
for _, overridden := range p.prebuiltCommonProperties.Overrides {
|
for _, overridden := range p.prebuiltCommonProperties.Overrides {
|
||||||
p.compatSymlinks = append(p.compatSymlinks, makeCompatSymlinks(overridden, ctx, true)...)
|
p.compatSymlinks = append(p.compatSymlinks, makeCompatSymlinks(overridden, ctx)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.installable() {
|
if p.installable() {
|
||||||
|
@ -1006,10 +1006,10 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// in case that apex_set replaces source apex (using prefer: prop)
|
// in case that apex_set replaces source apex (using prefer: prop)
|
||||||
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx, true)
|
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
|
||||||
// or that apex_set overrides other apexes (using overrides: prop)
|
// or that apex_set overrides other apexes (using overrides: prop)
|
||||||
for _, overridden := range a.prebuiltCommonProperties.Overrides {
|
for _, overridden := range a.prebuiltCommonProperties.Overrides {
|
||||||
a.compatSymlinks = append(a.compatSymlinks, makeCompatSymlinks(overridden, ctx, true)...)
|
a.compatSymlinks = append(a.compatSymlinks, makeCompatSymlinks(overridden, ctx)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,14 +112,10 @@ func apexVndkDepsMutator(mctx android.BottomUpMutatorContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// name is module.BaseModuleName() which is used as LOCAL_MODULE_NAME and also LOCAL_OVERRIDES_*
|
// name is module.BaseModuleName() which is used as LOCAL_MODULE_NAME and also LOCAL_OVERRIDES_*
|
||||||
func makeCompatSymlinks(name string, ctx android.ModuleContext, primaryApex bool) (symlinks android.InstallPaths) {
|
func makeCompatSymlinks(name string, ctx android.ModuleContext) (symlinks android.InstallPaths) {
|
||||||
// small helper to add symlink commands
|
// small helper to add symlink commands
|
||||||
addSymlink := func(target string, dir android.InstallPath, linkName string) {
|
addSymlink := func(target string, dir android.InstallPath, linkName string) {
|
||||||
if primaryApex {
|
symlinks = append(symlinks, ctx.InstallAbsoluteSymlink(dir, linkName, target))
|
||||||
symlinks = append(symlinks, ctx.InstallAbsoluteSymlink(dir, linkName, target))
|
|
||||||
} else {
|
|
||||||
symlinks = append(symlinks, dir.Join(ctx, linkName))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/142911355): [VNDK APEX] Fix hard-coded references to /system/lib/vndk
|
// TODO(b/142911355): [VNDK APEX] Fix hard-coded references to /system/lib/vndk
|
||||||
|
|
Loading…
Reference in a new issue