Merge "Enable soong build tool to handle APEX compression" am: 5d2c54f1e2
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1511283 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I567fada250e030005c9c103b1c24228bf0b52988
This commit is contained in:
@@ -1272,6 +1272,10 @@ func (c *config) FlattenApex() bool {
|
|||||||
return Bool(c.productVariables.Flatten_apex)
|
return Bool(c.productVariables.Flatten_apex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *config) CompressedApex() bool {
|
||||||
|
return Bool(c.productVariables.CompressedApex)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *config) EnforceSystemCertificate() bool {
|
func (c *config) EnforceSystemCertificate() bool {
|
||||||
return Bool(c.productVariables.EnforceSystemCertificate)
|
return Bool(c.productVariables.EnforceSystemCertificate)
|
||||||
}
|
}
|
||||||
|
@@ -319,8 +319,9 @@ type productVariables struct {
|
|||||||
Ndk_abis *bool `json:",omitempty"`
|
Ndk_abis *bool `json:",omitempty"`
|
||||||
Exclude_draft_ndk_apis *bool `json:",omitempty"`
|
Exclude_draft_ndk_apis *bool `json:",omitempty"`
|
||||||
|
|
||||||
Flatten_apex *bool `json:",omitempty"`
|
Flatten_apex *bool `json:",omitempty"`
|
||||||
Aml_abis *bool `json:",omitempty"`
|
CompressedApex *bool `json:",omitempty"`
|
||||||
|
Aml_abis *bool `json:",omitempty"`
|
||||||
|
|
||||||
DexpreoptGlobalConfig *string `json:",omitempty"`
|
DexpreoptGlobalConfig *string `json:",omitempty"`
|
||||||
|
|
||||||
|
@@ -360,7 +360,11 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
|
|||||||
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.ToMakePath().String())
|
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.ToMakePath().String())
|
||||||
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", name+apexType.suffix())
|
stemSuffix := apexType.suffix()
|
||||||
|
if a.isCompressed {
|
||||||
|
stemSuffix = ".capex"
|
||||||
|
}
|
||||||
|
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", name+stemSuffix)
|
||||||
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !a.installable())
|
fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !a.installable())
|
||||||
|
|
||||||
// Because apex writes .mk with Custom(), we need to write manually some common properties
|
// Because apex writes .mk with Custom(), we need to write manually some common properties
|
||||||
|
@@ -120,6 +120,12 @@ type apexBundleProperties struct {
|
|||||||
// Default: true.
|
// Default: true.
|
||||||
Installable *bool
|
Installable *bool
|
||||||
|
|
||||||
|
// Whether this APEX can be compressed or not. Setting this property to false means this
|
||||||
|
// APEX will never be compressed. When set to true, APEX will be compressed if other
|
||||||
|
// conditions, e.g, target device needs to support APEX compression, are also fulfilled.
|
||||||
|
// Default: true.
|
||||||
|
Compressible *bool
|
||||||
|
|
||||||
// For native libraries and binaries, use the vendor variant instead of the core (platform)
|
// For native libraries and binaries, use the vendor variant instead of the core (platform)
|
||||||
// variant. Default is false. DO NOT use this for APEXes that are installed to the system or
|
// variant. Default is false. DO NOT use this for APEXes that are installed to the system or
|
||||||
// system_ext partition.
|
// system_ext partition.
|
||||||
@@ -354,6 +360,8 @@ type apexBundle struct {
|
|||||||
|
|
||||||
prebuiltFileToDelete string
|
prebuiltFileToDelete string
|
||||||
|
|
||||||
|
isCompressed bool
|
||||||
|
|
||||||
// Path of API coverage generate file
|
// Path of API coverage generate file
|
||||||
coverageOutputPath android.ModuleOutPath
|
coverageOutputPath android.ModuleOutPath
|
||||||
}
|
}
|
||||||
|
@@ -346,6 +346,13 @@ func ensureListEmpty(t *testing.T, result []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ensureListNotEmpty(t *testing.T, result []string) {
|
||||||
|
t.Helper()
|
||||||
|
if len(result) == 0 {
|
||||||
|
t.Errorf("%q is expected to be not empty", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Minimal test
|
// Minimal test
|
||||||
func TestBasicApex(t *testing.T) {
|
func TestBasicApex(t *testing.T) {
|
||||||
ctx, config := testApex(t, `
|
ctx, config := testApex(t, `
|
||||||
@@ -6186,6 +6193,40 @@ func TestNonPreferredPrebuiltDependency(t *testing.T) {
|
|||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCompressedApex(t *testing.T) {
|
||||||
|
ctx, config := testApex(t, `
|
||||||
|
apex {
|
||||||
|
name: "myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
compressible: true,
|
||||||
|
}
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
`, func(fs map[string][]byte, config android.Config) {
|
||||||
|
config.TestProductVariables.CompressedApex = proptools.BoolPtr(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
compressRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("compressRule")
|
||||||
|
ensureContains(t, compressRule.Output.String(), "myapex.capex.unsigned")
|
||||||
|
|
||||||
|
signApkRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Description("sign compressedApex")
|
||||||
|
ensureEquals(t, signApkRule.Input.String(), compressRule.Output.String())
|
||||||
|
|
||||||
|
// Make sure output of bundle is .capex
|
||||||
|
ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
|
||||||
|
ensureContains(t, ab.outputFile.String(), "myapex.capex")
|
||||||
|
|
||||||
|
// Verify android.mk rules
|
||||||
|
data := android.AndroidMkDataForTest(t, config, "", ab)
|
||||||
|
var builder strings.Builder
|
||||||
|
data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data)
|
||||||
|
androidMk := builder.String()
|
||||||
|
ensureContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.capex\n")
|
||||||
|
}
|
||||||
|
|
||||||
func TestPreferredPrebuiltSharedLibDep(t *testing.T) {
|
func TestPreferredPrebuiltSharedLibDep(t *testing.T) {
|
||||||
ctx, config := testApex(t, `
|
ctx, config := testApex(t, `
|
||||||
apex {
|
apex {
|
||||||
|
@@ -66,6 +66,7 @@ func init() {
|
|||||||
pctx.HostBinToolVariable("extract_apks", "extract_apks")
|
pctx.HostBinToolVariable("extract_apks", "extract_apks")
|
||||||
pctx.HostBinToolVariable("make_f2fs", "make_f2fs")
|
pctx.HostBinToolVariable("make_f2fs", "make_f2fs")
|
||||||
pctx.HostBinToolVariable("sload_f2fs", "sload_f2fs")
|
pctx.HostBinToolVariable("sload_f2fs", "sload_f2fs")
|
||||||
|
pctx.HostBinToolVariable("apex_compression_tool", "apex_compression_tool")
|
||||||
pctx.SourcePathVariable("genNdkUsedbyApexPath", "build/soong/scripts/gen_ndk_usedby_apex.sh")
|
pctx.SourcePathVariable("genNdkUsedbyApexPath", "build/soong/scripts/gen_ndk_usedby_apex.sh")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,7 +739,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Step 4: Sign the APEX using signapk
|
// Step 4: Sign the APEX using signapk
|
||||||
a.outputFile = android.PathForModuleOut(ctx, a.Name()+suffix)
|
signedOutputFile := android.PathForModuleOut(ctx, a.Name()+suffix)
|
||||||
|
|
||||||
pem, key := a.getCertificateAndPrivateKey(ctx)
|
pem, key := a.getCertificateAndPrivateKey(ctx)
|
||||||
rule := java.Signapk
|
rule := java.Signapk
|
||||||
@@ -750,16 +751,47 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_SIGNAPK") {
|
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_SIGNAPK") {
|
||||||
rule = java.SignapkRE
|
rule = java.SignapkRE
|
||||||
args["implicits"] = strings.Join(implicits.Strings(), ",")
|
args["implicits"] = strings.Join(implicits.Strings(), ",")
|
||||||
args["outCommaList"] = a.outputFile.String()
|
args["outCommaList"] = signedOutputFile.String()
|
||||||
}
|
}
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: rule,
|
Rule: rule,
|
||||||
Description: "signapk",
|
Description: "signapk",
|
||||||
Output: a.outputFile,
|
Output: signedOutputFile,
|
||||||
Input: unsignedOutputFile,
|
Input: unsignedOutputFile,
|
||||||
Implicits: implicits,
|
Implicits: implicits,
|
||||||
Args: args,
|
Args: args,
|
||||||
})
|
})
|
||||||
|
a.outputFile = signedOutputFile
|
||||||
|
|
||||||
|
// Process APEX compression if enabled
|
||||||
|
compressionEnabled := ctx.Config().CompressedApex() && proptools.BoolDefault(a.properties.Compressible, true)
|
||||||
|
if compressionEnabled && apexType == imageApex {
|
||||||
|
a.isCompressed = true
|
||||||
|
unsignedCompressedOutputFile := android.PathForModuleOut(ctx, a.Name()+".capex.unsigned")
|
||||||
|
|
||||||
|
compressRule := android.NewRuleBuilder(pctx, ctx)
|
||||||
|
compressRule.Command().
|
||||||
|
Text("rm").
|
||||||
|
FlagWithOutput("-f ", unsignedCompressedOutputFile)
|
||||||
|
compressRule.Command().
|
||||||
|
BuiltTool("apex_compression_tool").
|
||||||
|
Flag("compress").
|
||||||
|
FlagWithArg("--apex_compression_tool ", outHostBinDir+":"+prebuiltSdkToolsBinDir).
|
||||||
|
FlagWithInput("--input ", signedOutputFile).
|
||||||
|
FlagWithOutput("--output ", unsignedCompressedOutputFile)
|
||||||
|
compressRule.Build("compressRule", "Generate unsigned compressed APEX file")
|
||||||
|
|
||||||
|
signedCompressedOutputFile := android.PathForModuleOut(ctx, a.Name()+".capex")
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: rule,
|
||||||
|
Description: "sign compressedApex",
|
||||||
|
Output: signedCompressedOutputFile,
|
||||||
|
Input: unsignedCompressedOutputFile,
|
||||||
|
Implicits: implicits,
|
||||||
|
Args: args,
|
||||||
|
})
|
||||||
|
a.outputFile = signedCompressedOutputFile
|
||||||
|
}
|
||||||
|
|
||||||
// Install to $OUT/soong/{target,host}/.../apex
|
// Install to $OUT/soong/{target,host}/.../apex
|
||||||
if a.installable() {
|
if a.installable() {
|
||||||
|
Reference in New Issue
Block a user