Merge "Documenting apex/builer.go" am: 9c4c534d25
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1509688 Change-Id: I5c65d5e0bbc591de5591f6d1c9228042f036675f
This commit is contained in:
22
apex/apex.go
22
apex/apex.go
@@ -1786,14 +1786,11 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
a.linkToSystemLib = false
|
a.linkToSystemLib = false
|
||||||
}
|
}
|
||||||
|
|
||||||
a.setCertificateAndPrivateKey(ctx)
|
|
||||||
|
|
||||||
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
|
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// 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, provideNativeLibs, requireNativeLibs)
|
||||||
a.buildFileContexts(ctx)
|
|
||||||
if a.properties.ApexType == flattenedApex {
|
if a.properties.ApexType == flattenedApex {
|
||||||
a.buildFlattenedApex(ctx)
|
a.buildFlattenedApex(ctx)
|
||||||
} else {
|
} else {
|
||||||
@@ -1802,6 +1799,25 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
a.buildApexDependencyInfo(ctx)
|
a.buildApexDependencyInfo(ctx)
|
||||||
a.buildLintReports(ctx)
|
a.buildLintReports(ctx)
|
||||||
a.distFiles = a.GenerateTaggedDistFiles(ctx)
|
a.distFiles = a.GenerateTaggedDistFiles(ctx)
|
||||||
|
|
||||||
|
// Append meta-files to the filesInfo list so that they are reflected in Android.mk as well.
|
||||||
|
if a.installable() {
|
||||||
|
// For flattened APEX, make sure that APEX manifest and apex_pubkey are also copied
|
||||||
|
// along with other ordinary files. (Note that this is done by apexer for
|
||||||
|
// non-flattened APEXes)
|
||||||
|
a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
|
||||||
|
|
||||||
|
// Place the public key as apex_pubkey. This is also done by apexer for
|
||||||
|
// non-flattened APEXes case.
|
||||||
|
// TODO(jiyong): Why do we need this CP rule?
|
||||||
|
copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: android.Cp,
|
||||||
|
Input: a.public_key_file,
|
||||||
|
Output: copiedPubkey,
|
||||||
|
})
|
||||||
|
a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
287
apex/builder.go
287
apex/builder.go
@@ -40,7 +40,7 @@ func init() {
|
|||||||
pctx.Import("android/soong/java")
|
pctx.Import("android/soong/java")
|
||||||
pctx.HostBinToolVariable("apexer", "apexer")
|
pctx.HostBinToolVariable("apexer", "apexer")
|
||||||
// ART minimal builds (using the master-art manifest) do not have the "frameworks/base"
|
// ART minimal builds (using the master-art manifest) do not have the "frameworks/base"
|
||||||
// projects, and hence cannot built 'aapt2'. Use the SDK prebuilt instead.
|
// projects, and hence cannot build 'aapt2'. Use the SDK prebuilt instead.
|
||||||
hostBinToolVariableWithPrebuilt := func(name, prebuiltDir, tool string) {
|
hostBinToolVariableWithPrebuilt := func(name, prebuiltDir, tool string) {
|
||||||
pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
|
pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
|
||||||
if !ctx.Config().FrameworksBaseDirExists(ctx) {
|
if !ctx.Config().FrameworksBaseDirExists(ctx) {
|
||||||
@@ -175,24 +175,29 @@ var (
|
|||||||
`exit 1); touch ${out}`,
|
`exit 1); touch ${out}`,
|
||||||
Description: "Diff ${image_content_file} and ${allowed_files_file}",
|
Description: "Diff ${image_content_file} and ${allowed_files_file}",
|
||||||
}, "image_content_file", "allowed_files_file", "apex_module_name")
|
}, "image_content_file", "allowed_files_file", "apex_module_name")
|
||||||
|
|
||||||
|
// Don't add more rules here. Consider using android.NewRuleBuilder instead.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// buildManifest creates buile rules to modify the input apex_manifest.json to add information
|
||||||
|
// gathered by the build system such as provided/required native libraries. Two output files having
|
||||||
|
// different formats are generated. a.manifestJsonOut is JSON format for Q devices, and
|
||||||
|
// a.manifest.PbOut is protobuf format for R+ devices.
|
||||||
|
// TODO(jiyong): make this to return paths instead of directly storing the paths to apexBundle
|
||||||
func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs, requireNativeLibs []string) {
|
func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs, requireNativeLibs []string) {
|
||||||
manifestSrc := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
|
src := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
|
||||||
|
|
||||||
manifestJsonFullOut := android.PathForModuleOut(ctx, "apex_manifest_full.json")
|
// Put dependency({provide|require}NativeLibs) in apex_manifest.json
|
||||||
|
|
||||||
// put dependency({provide|require}NativeLibs) in apex_manifest.json
|
|
||||||
provideNativeLibs = android.SortedUniqueStrings(provideNativeLibs)
|
provideNativeLibs = android.SortedUniqueStrings(provideNativeLibs)
|
||||||
requireNativeLibs = android.SortedUniqueStrings(android.RemoveListFromList(requireNativeLibs, provideNativeLibs))
|
requireNativeLibs = android.SortedUniqueStrings(android.RemoveListFromList(requireNativeLibs, provideNativeLibs))
|
||||||
|
|
||||||
// apex name can be overridden
|
// APEX name can be overridden
|
||||||
optCommands := []string{}
|
optCommands := []string{}
|
||||||
if a.properties.Apex_name != nil {
|
if a.properties.Apex_name != nil {
|
||||||
optCommands = append(optCommands, "-v name "+*a.properties.Apex_name)
|
optCommands = append(optCommands, "-v name "+*a.properties.Apex_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect jniLibs. Notice that a.filesInfo is already sorted
|
// Collect jniLibs. Notice that a.filesInfo is already sorted
|
||||||
var jniLibs []string
|
var jniLibs []string
|
||||||
for _, fi := range a.filesInfo {
|
for _, fi := range a.filesInfo {
|
||||||
if fi.isJniLib && !android.InList(fi.stem(), jniLibs) {
|
if fi.isJniLib && !android.InList(fi.stem(), jniLibs) {
|
||||||
@@ -203,9 +208,10 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs,
|
|||||||
optCommands = append(optCommands, "-a jniLibs "+strings.Join(jniLibs, " "))
|
optCommands = append(optCommands, "-a jniLibs "+strings.Join(jniLibs, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
manifestJsonFullOut := android.PathForModuleOut(ctx, "apex_manifest_full.json")
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: apexManifestRule,
|
Rule: apexManifestRule,
|
||||||
Input: manifestSrc,
|
Input: src,
|
||||||
Output: manifestJsonFullOut,
|
Output: manifestJsonFullOut,
|
||||||
Args: map[string]string{
|
Args: map[string]string{
|
||||||
"provideNativeLibs": strings.Join(provideNativeLibs, " "),
|
"provideNativeLibs": strings.Join(provideNativeLibs, " "),
|
||||||
@@ -214,10 +220,10 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs,
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// b/143654022 Q apexd can't understand newly added keys in apex_manifest.json prepare
|
||||||
|
// stripped-down version so that APEX modules built from R+ can be installed to Q
|
||||||
minSdkVersion := a.minSdkVersion(ctx)
|
minSdkVersion := a.minSdkVersion(ctx)
|
||||||
if minSdkVersion.EqualTo(android.SdkVersion_Android10) {
|
if minSdkVersion.EqualTo(android.SdkVersion_Android10) {
|
||||||
// b/143654022 Q apexd can't understand newly added keys in apex_manifest.json
|
|
||||||
// prepare stripped-down version so that APEX modules built from R+ can be installed to Q
|
|
||||||
a.manifestJsonOut = android.PathForModuleOut(ctx, "apex_manifest.json")
|
a.manifestJsonOut = android.PathForModuleOut(ctx, "apex_manifest.json")
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: stripApexManifestRule,
|
Rule: stripApexManifestRule,
|
||||||
@@ -226,7 +232,7 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// from R+, protobuf binary format (.pb) is the standard format for apex_manifest
|
// From R+, protobuf binary format (.pb) is the standard format for apex_manifest
|
||||||
a.manifestPbOut = android.PathForModuleOut(ctx, "apex_manifest.pb")
|
a.manifestPbOut = android.PathForModuleOut(ctx, "apex_manifest.pb")
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: pbApexManifestRule,
|
Rule: pbApexManifestRule,
|
||||||
@@ -235,10 +241,11 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) {
|
// buildFileContexts create build rules to append an entry for apex_manifest.pb to the file_contexts
|
||||||
if a.properties.ApexType == zipApex {
|
// file for this APEX which is either from /systme/sepolicy/apex/<apexname>-file_contexts or from
|
||||||
return
|
// the file_contexts property of this APEX. This is to make sure that the manifest file is correctly
|
||||||
}
|
// labeled as system_file.
|
||||||
|
func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) android.OutputPath {
|
||||||
var fileContexts android.Path
|
var fileContexts android.Path
|
||||||
if a.properties.File_contexts == nil {
|
if a.properties.File_contexts == nil {
|
||||||
fileContexts = android.PathForSource(ctx, "system/sepolicy/apex", ctx.ModuleName()+"-file_contexts")
|
fileContexts = android.PathForSource(ctx, "system/sepolicy/apex", ctx.ModuleName()+"-file_contexts")
|
||||||
@@ -248,18 +255,17 @@ func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) {
|
|||||||
if a.Platform() {
|
if a.Platform() {
|
||||||
if matched, err := path.Match("system/sepolicy/**/*", fileContexts.String()); err != nil || !matched {
|
if matched, err := path.Match("system/sepolicy/**/*", fileContexts.String()); err != nil || !matched {
|
||||||
ctx.PropertyErrorf("file_contexts", "should be under system/sepolicy, but %q", fileContexts)
|
ctx.PropertyErrorf("file_contexts", "should be under system/sepolicy, but %q", fileContexts)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !android.ExistentPathForSource(ctx, fileContexts.String()).Valid() {
|
if !android.ExistentPathForSource(ctx, fileContexts.String()).Valid() {
|
||||||
ctx.PropertyErrorf("file_contexts", "cannot find file_contexts file: %q", a.fileContexts)
|
ctx.PropertyErrorf("file_contexts", "cannot find file_contexts file: %q", fileContexts.String())
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
output := android.PathForModuleOut(ctx, "file_contexts")
|
output := android.PathForModuleOut(ctx, "file_contexts")
|
||||||
rule := android.NewRuleBuilder()
|
rule := android.NewRuleBuilder()
|
||||||
|
|
||||||
if a.properties.ApexType == imageApex {
|
switch a.properties.ApexType {
|
||||||
|
case imageApex:
|
||||||
// remove old file
|
// remove old file
|
||||||
rule.Command().Text("rm").FlagWithOutput("-f ", output)
|
rule.Command().Text("rm").FlagWithOutput("-f ", output)
|
||||||
// copy file_contexts
|
// copy file_contexts
|
||||||
@@ -269,7 +275,7 @@ func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) {
|
|||||||
// force-label /apex_manifest.pb and / as system_file so that apexd can read them
|
// force-label /apex_manifest.pb and / as system_file so that apexd can read them
|
||||||
rule.Command().Text("echo").Flag("/apex_manifest\\\\.pb u:object_r:system_file:s0").Text(">>").Output(output)
|
rule.Command().Text("echo").Flag("/apex_manifest\\\\.pb u:object_r:system_file:s0").Text(">>").Output(output)
|
||||||
rule.Command().Text("echo").Flag("/ u:object_r:system_file:s0").Text(">>").Output(output)
|
rule.Command().Text("echo").Flag("/ u:object_r:system_file:s0").Text(">>").Output(output)
|
||||||
} else {
|
case flattenedApex:
|
||||||
// For flattened apexes, install path should be prepended.
|
// For flattened apexes, install path should be prepended.
|
||||||
// File_contexts file should be emiited to make via LOCAL_FILE_CONTEXTS
|
// File_contexts file should be emiited to make via LOCAL_FILE_CONTEXTS
|
||||||
// so that it can be merged into file_contexts.bin
|
// so that it can be merged into file_contexts.bin
|
||||||
@@ -284,13 +290,16 @@ func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) {
|
|||||||
// force-label /apex_manifest.pb and / as system_file so that apexd can read them
|
// force-label /apex_manifest.pb and / as system_file so that apexd can read them
|
||||||
rule.Command().Text("echo").Flag(apexPath + `/apex_manifest\\.pb u:object_r:system_file:s0`).Text(">>").Output(output)
|
rule.Command().Text("echo").Flag(apexPath + `/apex_manifest\\.pb u:object_r:system_file:s0`).Text(">>").Output(output)
|
||||||
rule.Command().Text("echo").Flag(apexPath + "/ u:object_r:system_file:s0").Text(">>").Output(output)
|
rule.Command().Text("echo").Flag(apexPath + "/ u:object_r:system_file:s0").Text(">>").Output(output)
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("unsupported type %v", a.properties.ApexType))
|
||||||
}
|
}
|
||||||
|
|
||||||
rule.Build(pctx, ctx, "file_contexts."+a.Name(), "Generate file_contexts")
|
rule.Build(pctx, ctx, "file_contexts."+a.Name(), "Generate file_contexts")
|
||||||
|
return output.OutputPath
|
||||||
a.fileContexts = output.OutputPath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buildNoticeFiles creates a buile rule for aggregating notice files from the modules that
|
||||||
|
// contributes to this APEX. The notice files are merged into a big notice file.
|
||||||
func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName string) android.NoticeOutputs {
|
func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName string) android.NoticeOutputs {
|
||||||
var noticeFiles android.Paths
|
var noticeFiles android.Paths
|
||||||
|
|
||||||
@@ -299,13 +308,11 @@ func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName st
|
|||||||
// As soon as the dependency graph crosses the APEX boundary, don't go further.
|
// As soon as the dependency graph crosses the APEX boundary, don't go further.
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
noticeFiles = append(noticeFiles, to.NoticeFiles()...)
|
||||||
notices := to.NoticeFiles()
|
|
||||||
noticeFiles = append(noticeFiles, notices...)
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TODO(jiyong): why do we need this? WalkPayloadDeps should have already covered this.
|
||||||
for _, fi := range a.filesInfo {
|
for _, fi := range a.filesInfo {
|
||||||
noticeFiles = append(noticeFiles, fi.noticeFiles...)
|
noticeFiles = append(noticeFiles, fi.noticeFiles...)
|
||||||
}
|
}
|
||||||
@@ -317,6 +324,9 @@ func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName st
|
|||||||
return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.SortedUniquePaths(noticeFiles))
|
return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.SortedUniquePaths(noticeFiles))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buildInstalledFilesFile creates a build rule for the installed-files.txt file where the list of
|
||||||
|
// files included in this APEX is shown. The text file is dist'ed so that people can see what's
|
||||||
|
// included in the APEX without actually downloading and extracting it.
|
||||||
func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.OutputPath {
|
func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.OutputPath {
|
||||||
output := android.PathForModuleOut(ctx, "installed-files.txt")
|
output := android.PathForModuleOut(ctx, "installed-files.txt")
|
||||||
rule := android.NewRuleBuilder()
|
rule := android.NewRuleBuilder()
|
||||||
@@ -330,6 +340,8 @@ func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApe
|
|||||||
return output.OutputPath
|
return output.OutputPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buildBundleConfig creates a build rule for the bundle config file that will control the bundle
|
||||||
|
// creation process.
|
||||||
func (a *apexBundle) buildBundleConfig(ctx android.ModuleContext) android.OutputPath {
|
func (a *apexBundle) buildBundleConfig(ctx android.ModuleContext) android.OutputPath {
|
||||||
output := android.PathForModuleOut(ctx, "bundle_config.json")
|
output := android.PathForModuleOut(ctx, "bundle_config.json")
|
||||||
|
|
||||||
@@ -351,8 +363,8 @@ func (a *apexBundle) buildBundleConfig(ctx android.ModuleContext) android.Output
|
|||||||
"apex_manifest.*",
|
"apex_manifest.*",
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect the manifest names and paths of android apps
|
// Collect the manifest names and paths of android apps if their manifest names are
|
||||||
// if their manifest names are overridden
|
// overridden.
|
||||||
for _, fi := range a.filesInfo {
|
for _, fi := range a.filesInfo {
|
||||||
if fi.class != app && fi.class != appSet {
|
if fi.class != app && fi.class != appSet {
|
||||||
continue
|
continue
|
||||||
@@ -378,30 +390,31 @@ func (a *apexBundle) buildBundleConfig(ctx android.ModuleContext) android.Output
|
|||||||
return output.OutputPath
|
return output.OutputPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buildUnflattendApex creates build rules to build an APEX using apexer.
|
||||||
func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
||||||
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)
|
|
||||||
|
|
||||||
apexType := a.properties.ApexType
|
apexType := a.properties.ApexType
|
||||||
suffix := apexType.suffix()
|
suffix := apexType.suffix()
|
||||||
var implicitInputs []android.Path
|
|
||||||
unsignedOutputFile := android.PathForModuleOut(ctx, a.Name()+suffix+".unsigned")
|
|
||||||
|
|
||||||
// TODO(jiyong): construct the copy rules using RuleBuilder
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Step 1: copy built files to appropriate directories under the image directory
|
||||||
|
|
||||||
|
imageDir := android.PathForModuleOut(ctx, "image"+suffix)
|
||||||
|
|
||||||
|
// TODO(jiyong): use the RuleBuilder
|
||||||
var copyCommands []string
|
var copyCommands []string
|
||||||
|
var implicitInputs []android.Path
|
||||||
for _, fi := range a.filesInfo {
|
for _, fi := range a.filesInfo {
|
||||||
destPath := android.PathForModuleOut(ctx, "image"+suffix, fi.path()).String()
|
destPath := imageDir.Join(ctx, fi.path()).String()
|
||||||
|
|
||||||
|
// Prepare the destination path
|
||||||
destPathDir := filepath.Dir(destPath)
|
destPathDir := filepath.Dir(destPath)
|
||||||
if fi.class == appSet {
|
if fi.class == appSet {
|
||||||
copyCommands = append(copyCommands, "rm -rf "+destPathDir)
|
copyCommands = append(copyCommands, "rm -rf "+destPathDir)
|
||||||
}
|
}
|
||||||
copyCommands = append(copyCommands, "mkdir -p "+destPathDir)
|
copyCommands = append(copyCommands, "mkdir -p "+destPathDir)
|
||||||
|
|
||||||
|
// Copy the built file to the directory. But if the symlink optimization is turned
|
||||||
|
// on, place a symlink to the corresponding file in /system partition instead.
|
||||||
if a.linkToSystemLib && fi.transitiveDep && fi.availableToPlatform() {
|
if a.linkToSystemLib && fi.transitiveDep && fi.availableToPlatform() {
|
||||||
// TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
|
// TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
|
||||||
pathOnDevice := filepath.Join("/system", fi.path())
|
pathOnDevice := filepath.Join("/system", fi.path())
|
||||||
@@ -415,11 +428,15 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
implicitInputs = append(implicitInputs, fi.builtFile)
|
implicitInputs = append(implicitInputs, fi.builtFile)
|
||||||
}
|
}
|
||||||
// create additional symlinks pointing the file inside the APEX
|
|
||||||
|
// Create additional symlinks pointing the file inside the APEX (if any). Note that
|
||||||
|
// this is independent from the symlink optimization.
|
||||||
for _, symlinkPath := range fi.symlinkPaths() {
|
for _, symlinkPath := range fi.symlinkPaths() {
|
||||||
symlinkDest := android.PathForModuleOut(ctx, "image"+suffix, symlinkPath).String()
|
symlinkDest := imageDir.Join(ctx, symlinkPath).String()
|
||||||
copyCommands = append(copyCommands, "ln -sfn "+filepath.Base(destPath)+" "+symlinkDest)
|
copyCommands = append(copyCommands, "ln -sfn "+filepath.Base(destPath)+" "+symlinkDest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy the test files (if any)
|
||||||
for _, d := range fi.dataPaths {
|
for _, d := range fi.dataPaths {
|
||||||
// TODO(eakammer): This is now the third repetition of ~this logic for test paths, refactoring should be possible
|
// TODO(eakammer): This is now the third repetition of ~this logic for test paths, refactoring should be possible
|
||||||
relPath := d.SrcPath.Rel()
|
relPath := d.SrcPath.Rel()
|
||||||
@@ -428,28 +445,37 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
panic(fmt.Errorf("path %q does not end with %q", dataPath, relPath))
|
panic(fmt.Errorf("path %q does not end with %q", dataPath, relPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
dataDest := android.PathForModuleOut(ctx, "image"+suffix, fi.apexRelativePath(relPath), d.RelativeInstallPath).String()
|
dataDest := imageDir.Join(ctx, fi.apexRelativePath(relPath), d.RelativeInstallPath).String()
|
||||||
|
|
||||||
copyCommands = append(copyCommands, "cp -f "+d.SrcPath.String()+" "+dataDest)
|
copyCommands = append(copyCommands, "cp -f "+d.SrcPath.String()+" "+dataDest)
|
||||||
implicitInputs = append(implicitInputs, d.SrcPath)
|
implicitInputs = append(implicitInputs, d.SrcPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(jiyong): use RuleBuilder
|
|
||||||
var emitCommands []string
|
|
||||||
imageContentFile := android.PathForModuleOut(ctx, "content.txt")
|
|
||||||
emitCommands = append(emitCommands, "echo ./apex_manifest.pb >> "+imageContentFile.String())
|
|
||||||
minSdkVersion := a.minSdkVersion(ctx)
|
|
||||||
if minSdkVersion.EqualTo(android.SdkVersion_Android10) {
|
|
||||||
emitCommands = append(emitCommands, "echo ./apex_manifest.json >> "+imageContentFile.String())
|
|
||||||
}
|
|
||||||
for _, fi := range a.filesInfo {
|
|
||||||
emitCommands = append(emitCommands, "echo './"+fi.path()+"' >> "+imageContentFile.String())
|
|
||||||
}
|
|
||||||
emitCommands = append(emitCommands, "sort -o "+imageContentFile.String()+" "+imageContentFile.String())
|
|
||||||
implicitInputs = append(implicitInputs, a.manifestPbOut)
|
implicitInputs = append(implicitInputs, a.manifestPbOut)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Step 1.a: Write the list of files in this APEX to a txt file and compare it against
|
||||||
|
// the allowed list given via the allowed_files property. Build fails when the two lists
|
||||||
|
// differ.
|
||||||
|
//
|
||||||
|
// TODO(jiyong): consider removing this. Nobody other than com.android.apex.cts.shim.* seems
|
||||||
|
// to be using this at this moment. Furthermore, this looks very similar to what
|
||||||
|
// buildInstalledFilesFile does. At least, move this to somewhere else so that this doesn't
|
||||||
|
// hurt readability.
|
||||||
|
// TODO(jiyong): use RuleBuilder
|
||||||
if a.overridableProperties.Allowed_files != nil {
|
if a.overridableProperties.Allowed_files != nil {
|
||||||
|
// Build content.txt
|
||||||
|
var emitCommands []string
|
||||||
|
imageContentFile := android.PathForModuleOut(ctx, "content.txt")
|
||||||
|
emitCommands = append(emitCommands, "echo ./apex_manifest.pb >> "+imageContentFile.String())
|
||||||
|
minSdkVersion := a.minSdkVersion(ctx)
|
||||||
|
if minSdkVersion.EqualTo(android.SdkVersion_Android10) {
|
||||||
|
emitCommands = append(emitCommands, "echo ./apex_manifest.json >> "+imageContentFile.String())
|
||||||
|
}
|
||||||
|
for _, fi := range a.filesInfo {
|
||||||
|
emitCommands = append(emitCommands, "echo './"+fi.path()+"' >> "+imageContentFile.String())
|
||||||
|
}
|
||||||
|
emitCommands = append(emitCommands, "sort -o "+imageContentFile.String()+" "+imageContentFile.String())
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: emitApexContentRule,
|
Rule: emitApexContentRule,
|
||||||
Implicits: implicitInputs,
|
Implicits: implicitInputs,
|
||||||
@@ -460,8 +486,9 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
implicitInputs = append(implicitInputs, imageContentFile)
|
implicitInputs = append(implicitInputs, imageContentFile)
|
||||||
allowedFilesFile := android.PathForModuleSrc(ctx, proptools.String(a.overridableProperties.Allowed_files))
|
|
||||||
|
|
||||||
|
// Compare content.txt against allowed_files.
|
||||||
|
allowedFilesFile := android.PathForModuleSrc(ctx, proptools.String(a.overridableProperties.Allowed_files))
|
||||||
phonyOutput := android.PathForModuleOut(ctx, a.Name()+"-diff-phony-output")
|
phonyOutput := android.PathForModuleOut(ctx, a.Name()+"-diff-phony-output")
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: diffApexContentRule,
|
Rule: diffApexContentRule,
|
||||||
@@ -474,16 +501,19 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
"apex_module_name": a.Name(),
|
"apex_module_name": a.Name(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
implicitInputs = append(implicitInputs, phonyOutput)
|
implicitInputs = append(implicitInputs, phonyOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsignedOutputFile := android.PathForModuleOut(ctx, a.Name()+suffix+".unsigned")
|
||||||
outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
|
outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
|
||||||
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
|
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
|
||||||
|
|
||||||
imageDir := android.PathForModuleOut(ctx, "image"+suffix)
|
|
||||||
if apexType == imageApex {
|
if apexType == imageApex {
|
||||||
// files and dirs that will be created in APEX
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 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.
|
||||||
|
// TODO(jiyong): make this as a function
|
||||||
|
// TODO(jiyong): use the RuleBuilder
|
||||||
var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
|
var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
|
||||||
var executablePaths []string // this also includes dirs
|
var executablePaths []string // this also includes dirs
|
||||||
var extractedAppSetPaths android.Paths
|
var extractedAppSetPaths android.Paths
|
||||||
@@ -528,11 +558,17 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
"apk_paths": strings.Join(extractedAppSetDirs, " "),
|
"apk_paths": strings.Join(extractedAppSetDirs, " "),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
implicitInputs = append(implicitInputs, cannedFsConfig)
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Step 3: Prepare option flags for apexer and invoke it to create an unsigned APEX.
|
||||||
|
// TODO(jiyong): use the RuleBuilder
|
||||||
optFlags := []string{}
|
optFlags := []string{}
|
||||||
|
|
||||||
// Additional implicit inputs.
|
fileContexts := a.buildFileContexts(ctx)
|
||||||
implicitInputs = append(implicitInputs, cannedFsConfig, a.fileContexts, a.private_key_file, a.public_key_file)
|
implicitInputs = append(implicitInputs, fileContexts)
|
||||||
|
|
||||||
|
implicitInputs = append(implicitInputs, a.private_key_file, a.public_key_file)
|
||||||
optFlags = append(optFlags, "--pubkey "+a.public_key_file.String())
|
optFlags = append(optFlags, "--pubkey "+a.public_key_file.String())
|
||||||
|
|
||||||
manifestPackageName := a.getOverrideManifestPackageName(ctx)
|
manifestPackageName := a.getOverrideManifestPackageName(ctx)
|
||||||
@@ -546,15 +582,18 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
optFlags = append(optFlags, "--android_manifest "+androidManifestFile.String())
|
optFlags = append(optFlags, "--android_manifest "+androidManifestFile.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine target/min sdk version from the context
|
||||||
|
// TODO(jiyong): make this as a function
|
||||||
moduleMinSdkVersion := a.minSdkVersion(ctx)
|
moduleMinSdkVersion := a.minSdkVersion(ctx)
|
||||||
minSdkVersion := moduleMinSdkVersion.String()
|
minSdkVersion := moduleMinSdkVersion.String()
|
||||||
|
|
||||||
// bundletool doesn't understand what "current" is. We need to transform it to codename
|
// bundletool doesn't understand what "current" is. We need to transform it to
|
||||||
|
// codename
|
||||||
if moduleMinSdkVersion.IsCurrent() {
|
if moduleMinSdkVersion.IsCurrent() {
|
||||||
minSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String()
|
minSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String()
|
||||||
}
|
}
|
||||||
// apex module doesn't have a concept of target_sdk_version, hence for the time being
|
// apex module doesn't have a concept of target_sdk_version, hence for the time
|
||||||
// targetSdkVersion == default targetSdkVersion of the branch.
|
// being targetSdkVersion == default targetSdkVersion of the branch.
|
||||||
targetSdkVersion := strconv.Itoa(ctx.Config().DefaultAppTargetSdk(ctx).FinalOrFutureInt())
|
targetSdkVersion := strconv.Itoa(ctx.Config().DefaultAppTargetSdk(ctx).FinalOrFutureInt())
|
||||||
|
|
||||||
if java.UseApiFingerprint(ctx) {
|
if java.UseApiFingerprint(ctx) {
|
||||||
@@ -595,8 +634,8 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if a.properties.Apex_name != nil {
|
if a.properties.Apex_name != nil {
|
||||||
// If apex_name is set, apexer can skip checking if key name matches with apex name.
|
// If apex_name is set, apexer can skip checking if key name matches with
|
||||||
// Note that apex_manifest is also mended.
|
// apex name. Note that apex_manifest is also mended.
|
||||||
optFlags = append(optFlags, "--do_not_check_keyname")
|
optFlags = append(optFlags, "--do_not_check_keyname")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,13 +656,14 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
"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": a.fileContexts.String(),
|
"file_contexts": fileContexts.String(),
|
||||||
"canned_fs_config": cannedFsConfig.String(),
|
"canned_fs_config": cannedFsConfig.String(),
|
||||||
"key": a.private_key_file.String(),
|
"key": a.private_key_file.String(),
|
||||||
"opt_flags": strings.Join(optFlags, " "),
|
"opt_flags": strings.Join(optFlags, " "),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// TODO(jiyong): make the two rules below as separate functions
|
||||||
apexProtoFile := android.PathForModuleOut(ctx, a.Name()+".pb"+suffix)
|
apexProtoFile := android.PathForModuleOut(ctx, a.Name()+".pb"+suffix)
|
||||||
bundleModuleFile := android.PathForModuleOut(ctx, a.Name()+suffix+"-base.zip")
|
bundleModuleFile := android.PathForModuleOut(ctx, a.Name()+suffix+"-base.zip")
|
||||||
a.bundleModuleFile = bundleModuleFile
|
a.bundleModuleFile = bundleModuleFile
|
||||||
@@ -637,6 +677,15 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
bundleConfig := a.buildBundleConfig(ctx)
|
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{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: apexBundleRule,
|
Rule: apexBundleRule,
|
||||||
Input: apexProtoFile,
|
Input: apexProtoFile,
|
||||||
@@ -648,7 +697,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
"config": bundleConfig.String(),
|
"config": bundleConfig.String(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else { // zipApex
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: zipApexRule,
|
Rule: zipApexRule,
|
||||||
Implicits: implicitInputs,
|
Implicits: implicitInputs,
|
||||||
@@ -663,16 +712,17 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Step 4: Sign the APEX using signapk
|
||||||
a.outputFile = android.PathForModuleOut(ctx, a.Name()+suffix)
|
a.outputFile = android.PathForModuleOut(ctx, a.Name()+suffix)
|
||||||
|
|
||||||
|
pem, key := a.getCertificateAndPrivateKey(ctx)
|
||||||
rule := java.Signapk
|
rule := java.Signapk
|
||||||
args := map[string]string{
|
args := map[string]string{
|
||||||
"certificates": a.container_certificate_file.String() + " " + a.container_private_key_file.String(),
|
"certificates": pem.String() + " " + key.String(),
|
||||||
"flags": "-a 4096", //alignment
|
"flags": "-a 4096", //alignment
|
||||||
}
|
}
|
||||||
implicits := android.Paths{
|
implicits := android.Paths{pem, key}
|
||||||
a.container_certificate_file,
|
|
||||||
a.container_private_key_file,
|
|
||||||
}
|
|
||||||
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(), ",")
|
||||||
@@ -691,7 +741,6 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
|||||||
if a.installable() {
|
if a.installable() {
|
||||||
ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
|
ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
|
||||||
}
|
}
|
||||||
a.buildFilesInfo(ctx)
|
|
||||||
|
|
||||||
// installed-files.txt is dist'ed
|
// installed-files.txt is dist'ed
|
||||||
a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir)
|
a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir)
|
||||||
@@ -706,58 +755,50 @@ func (c *flattenedApexContext) InstallBypassMake() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buildFlattenedApex creates rules for a flattened APEX. Flattened APEX actually doesn't have a
|
||||||
|
// single output file. It is a phony target for all the files under /system/apex/<name> directory.
|
||||||
|
// This function creates the installation rules for the files.
|
||||||
func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) {
|
func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) {
|
||||||
// Temporarily wrap the original `ctx` into a `flattenedApexContext` to have it
|
bundleName := a.Name()
|
||||||
// reply true to `InstallBypassMake()` (thus making the call
|
|
||||||
// `android.PathForModuleInstall` below use `android.pathForInstallInMakeDir`
|
|
||||||
// instead of `android.PathForOutput`) to return the correct path to the flattened
|
|
||||||
// APEX (as its contents is installed by Make, not Soong).
|
|
||||||
factx := flattenedApexContext{ctx}
|
|
||||||
a.outputFile = android.PathForModuleInstall(&factx, "apex", a.Name())
|
|
||||||
a.buildFilesInfo(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apexBundle) setCertificateAndPrivateKey(ctx android.ModuleContext) {
|
|
||||||
if a.container_certificate_file == nil {
|
|
||||||
cert := String(a.properties.Certificate)
|
|
||||||
if cert == "" {
|
|
||||||
pem, key := ctx.Config().DefaultAppCertificate(ctx)
|
|
||||||
a.container_certificate_file = pem
|
|
||||||
a.container_private_key_file = key
|
|
||||||
} else {
|
|
||||||
defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
|
|
||||||
a.container_certificate_file = defaultDir.Join(ctx, cert+".x509.pem")
|
|
||||||
a.container_private_key_file = defaultDir.Join(ctx, cert+".pk8")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apexBundle) buildFilesInfo(ctx android.ModuleContext) {
|
|
||||||
if a.installable() {
|
if a.installable() {
|
||||||
// For flattened APEX, do nothing but make sure that APEX manifest and apex_pubkey are also copied along
|
for _, fi := range a.filesInfo {
|
||||||
// with other ordinary files.
|
dir := filepath.Join("apex", bundleName, fi.installDir)
|
||||||
a.filesInfo = append(a.filesInfo, newApexFile(ctx, a.manifestPbOut, "apex_manifest.pb", ".", etc, nil))
|
target := ctx.InstallFile(android.PathForModuleInstall(ctx, dir), fi.stem(), fi.builtFile)
|
||||||
|
for _, sym := range fi.symlinks {
|
||||||
// rename to apex_pubkey
|
ctx.InstallSymlink(android.PathForModuleInstall(ctx, dir), sym, target)
|
||||||
copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
|
||||||
Rule: android.Cp,
|
|
||||||
Input: a.public_key_file,
|
|
||||||
Output: copiedPubkey,
|
|
||||||
})
|
|
||||||
a.filesInfo = append(a.filesInfo, newApexFile(ctx, copiedPubkey, "apex_pubkey", ".", etc, nil))
|
|
||||||
|
|
||||||
if a.properties.ApexType == flattenedApex {
|
|
||||||
apexBundleName := a.Name()
|
|
||||||
for _, fi := range a.filesInfo {
|
|
||||||
dir := filepath.Join("apex", apexBundleName, fi.installDir)
|
|
||||||
target := ctx.InstallFile(android.PathForModuleInstall(ctx, dir), fi.stem(), fi.builtFile)
|
|
||||||
for _, sym := range fi.symlinks {
|
|
||||||
ctx.InstallSymlink(android.PathForModuleInstall(ctx, dir), sym, target)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.fileContexts = a.buildFileContexts(ctx)
|
||||||
|
|
||||||
|
// Temporarily wrap the original `ctx` into a `flattenedApexContext` to have it reply true
|
||||||
|
// to `InstallBypassMake()` (thus making the call `android.PathForModuleInstall` below use
|
||||||
|
// `android.pathForInstallInMakeDir` instead of `android.PathForOutput`) to return the
|
||||||
|
// correct path to the flattened APEX (as its contents is installed by Make, not Soong).
|
||||||
|
// TODO(jiyong): Why do we need to set outputFile for flattened APEX? We don't seem to use
|
||||||
|
// it and it actually points to a path that can never be built. Remove this.
|
||||||
|
factx := flattenedApexContext{ctx}
|
||||||
|
a.outputFile = android.PathForModuleInstall(&factx, "apex", bundleName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getCertificateAndPrivateKey retrieves the cert and the private key that will be used to sign
|
||||||
|
// the zip container of this APEX. See the description of the 'certificate' property for how
|
||||||
|
// the cert and the private key are found.
|
||||||
|
func (a *apexBundle) getCertificateAndPrivateKey(ctx android.PathContext) (pem, key android.Path) {
|
||||||
|
if a.container_certificate_file != nil {
|
||||||
|
return a.container_certificate_file, a.container_private_key_file
|
||||||
|
}
|
||||||
|
|
||||||
|
cert := String(a.properties.Certificate)
|
||||||
|
if cert == "" {
|
||||||
|
return ctx.Config().DefaultAppCertificate(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
|
||||||
|
pem = defaultDir.Join(ctx, cert+".x509.pem")
|
||||||
|
key = defaultDir.Join(ctx, cert+".pk8")
|
||||||
|
return pem, key
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apexBundle) getOverrideManifestPackageName(ctx android.ModuleContext) string {
|
func (a *apexBundle) getOverrideManifestPackageName(ctx android.ModuleContext) string {
|
||||||
|
@@ -127,13 +127,14 @@ func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) {
|
|||||||
apexKeyMap := make(map[string]apexKeyEntry)
|
apexKeyMap := make(map[string]apexKeyEntry)
|
||||||
ctx.VisitAllModules(func(module android.Module) {
|
ctx.VisitAllModules(func(module android.Module) {
|
||||||
if m, ok := module.(*apexBundle); ok && m.Enabled() && m.installable() {
|
if m, ok := module.(*apexBundle); ok && m.Enabled() && m.installable() {
|
||||||
|
pem, key := m.getCertificateAndPrivateKey(ctx)
|
||||||
apexKeyMap[m.Name()] = apexKeyEntry{
|
apexKeyMap[m.Name()] = apexKeyEntry{
|
||||||
name: m.Name() + ".apex",
|
name: m.Name() + ".apex",
|
||||||
presigned: false,
|
presigned: false,
|
||||||
public_key: m.public_key_file.String(),
|
public_key: m.public_key_file.String(),
|
||||||
private_key: m.private_key_file.String(),
|
private_key: m.private_key_file.String(),
|
||||||
container_certificate: m.container_certificate_file.String(),
|
container_certificate: pem.String(),
|
||||||
container_private_key: m.container_private_key_file.String(),
|
container_private_key: key.String(),
|
||||||
partition: m.PartitionTag(ctx.DeviceConfig()),
|
partition: m.PartitionTag(ctx.DeviceConfig()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user