From 286957df998636ccd940b9b8c88c8ebfee20d96c Mon Sep 17 00:00:00 2001 From: Jooyung Han Date: Mon, 30 Oct 2023 16:17:56 +0900 Subject: [PATCH] Rewrite how to generate apexkeys.txt Instead of listing all apexes in the source tree, now each apex emits its own fragment for apexkeys.txt, which is pointed by LOCAL_APEX_KEYS_FILE. Makefile collects apexkeys.txt from installed apex files. This is to avoid listing unrelated apexes (not installed, testdata, unexported namespaces, etc.) Bug: 304914238 Test: m apexkeys.txt Test: m blueprint-tests Change-Id: Iefbe6e486cb418955584ad1a282455307e90be95 --- apex/androidmk.go | 1 + apex/apex.go | 4 +++ apex/apex_test.go | 10 ++++---- apex/builder.go | 2 ++ apex/key.go | 62 +++++------------------------------------------ apex/prebuilt.go | 6 +++++ 6 files changed, 24 insertions(+), 61 deletions(-) diff --git a/apex/androidmk.go b/apex/androidmk.go index 2f5d8d4f3..6136cbd7a 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -260,6 +260,7 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_PAIRS :=", a.outputFile.String()+":"+a.installedFile.String()) fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_SYMLINKS := ", strings.Join(a.compatSymlinks.Strings(), " ")) } + fmt.Fprintln(w, "LOCAL_APEX_KEY_PATH := ", a.apexKeysPath.String()) // Because apex writes .mk with Custom(), we need to write manually some common properties // which are available via data.Entries diff --git a/apex/apex.go b/apex/apex.go index f90337301..adabdeefd 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -454,6 +454,9 @@ type apexBundle struct { // Path where this APEX was installed. installedFile android.InstallPath + // fragment for this apex for apexkeys.txt + apexKeysPath android.WritablePath + // Installed locations of symlinks for backward compatibility. compatSymlinks android.InstallPaths @@ -1923,6 +1926,7 @@ func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) { a.filesInfo = append(a.filesInfo, fileInfo) } + a.apexKeysPath = writeApexKeys(ctx, a) } func (a *apexBundle) setCompression(ctx android.ModuleContext) { diff --git a/apex/apex_test.go b/apex/apex_test.go index e70d3af7e..97cc3cbf7 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -9078,8 +9078,8 @@ func TestApexKeysTxt(t *testing.T) { } `) - apexKeysText := ctx.SingletonForTests("apex_keys_text") - content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"] + myapex := ctx.ModuleForTests("myapex", "android_common_myapex") + content := myapex.Output("apexkeys.txt").BuildParams.Args["content"] ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`) } @@ -9119,10 +9119,10 @@ func TestApexKeysTxtOverrides(t *testing.T) { } `) - apexKeysText := ctx.SingletonForTests("apex_keys_text") - content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"] + content := ctx.ModuleForTests("myapex", "android_common_myapex").Output("apexkeys.txt").BuildParams.Args["content"] + ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`) + content = ctx.ModuleForTests("myapex_set", "android_common_myapex_set").Output("apexkeys.txt").BuildParams.Args["content"] ensureContains(t, content, `name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`) - ensureContains(t, content, `name="myapex.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`) } func TestAllowedFiles(t *testing.T) { diff --git a/apex/builder.go b/apex/builder.go index 729917f00..d75cc1df6 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -948,6 +948,8 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) { // installed-files.txt is dist'ed a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir) + + a.apexKeysPath = writeApexKeys(ctx, a) } // getCertificateAndPrivateKey retrieves the cert and the private key that will be used to sign diff --git a/apex/key.go b/apex/key.go index fe8bf307f..2405e9842 100644 --- a/apex/key.go +++ b/apex/key.go @@ -16,8 +16,6 @@ package apex import ( "fmt" - "sort" - "strings" "android/soong/android" "android/soong/bazel" @@ -33,7 +31,6 @@ func init() { func registerApexKeyBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("apex_key", ApexKeyFactory) - ctx.RegisterParallelSingletonType("apex_keys_text", apexKeysTextFactory) } type apexKey struct { @@ -126,7 +123,7 @@ func (e apexKeyEntry) String() string { } } -func apexKeyEntryFor(ctx android.SingletonContext, module android.Module) apexKeyEntry { +func apexKeyEntryFor(ctx android.ModuleContext, module android.Module) apexKeyEntry { switch m := module.(type) { case *apexBundle: pem, key := m.getCertificateAndPrivateKey(ctx) @@ -156,58 +153,11 @@ func apexKeyEntryFor(ctx android.SingletonContext, module android.Module) apexKe panic(fmt.Errorf("unknown type(%t) for apexKeyEntry", module)) } -// ////////////////////////////////////////////////////////////////////// -// apex_keys_text -type apexKeysText struct { - output android.OutputPath -} - -func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) { - s.output = android.PathForOutput(ctx, "apexkeys.txt") - - apexKeyMap := make(map[string]apexKeyEntry) - ctx.VisitAllModules(func(module android.Module) { - if m, ok := module.(*apexBundle); ok && m.Enabled() && m.installable() { - apexKeyMap[m.Name()] = apexKeyEntryFor(ctx, m) - } - }) - - // Find prebuilts and let them override apexBundle if they are preferred - ctx.VisitAllModules(func(module android.Module) { - if m, ok := module.(*Prebuilt); ok && m.Enabled() && m.installable() && - m.Prebuilt().UsePrebuilt() { - apexKeyMap[m.BaseModuleName()] = apexKeyEntryFor(ctx, m) - } - }) - - // Find apex_set and let them override apexBundle or prebuilts. This is done in a separate pass - // so that apex_set are not overridden by prebuilts. - ctx.VisitAllModules(func(module android.Module) { - if m, ok := module.(*ApexSet); ok && m.Enabled() { - apexKeyMap[m.BaseModuleName()] = apexKeyEntryFor(ctx, m) - } - }) - - // iterating over map does not give consistent ordering in golang - var moduleNames []string - for key, _ := range apexKeyMap { - moduleNames = append(moduleNames, key) - } - sort.Strings(moduleNames) - - var filecontent strings.Builder - for _, name := range moduleNames { - filecontent.WriteString(apexKeyMap[name].String()) - } - android.WriteFileRule(ctx, s.output, filecontent.String()) -} - -func apexKeysTextFactory() android.Singleton { - return &apexKeysText{} -} - -func (s *apexKeysText) MakeVars(ctx android.MakeVarsContext) { - ctx.Strict("SOONG_APEX_KEYS_FILE", s.output.String()) +func writeApexKeys(ctx android.ModuleContext, module android.Module) android.WritablePath { + path := android.PathForModuleOut(ctx, "apexkeys.txt") + entry := apexKeyEntryFor(ctx, module) + android.WriteFileRuleVerbatim(ctx, path, entry.String()) + return path } // For Bazel / bp2build diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 1a90c3a73..7a9d23e54 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -60,6 +60,9 @@ type prebuiltCommon struct { installedFile android.InstallPath outputApex android.WritablePath + // fragment for this apex for apexkeys.txt + apexKeysPath android.WritablePath + // A list of apexFile objects created in prebuiltCommon.initApexFilesForAndroidMk which are used // to create make modules in prebuiltCommon.AndroidMkEntries. apexFilesForAndroidMk []apexFile @@ -238,6 +241,7 @@ func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries { entries.AddStrings("LOCAL_SOONG_INSTALL_SYMLINKS", p.compatSymlinks.Strings()...) entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable()) entries.AddStrings("LOCAL_OVERRIDES_MODULES", p.prebuiltCommonProperties.Overrides...) + entries.SetString("LOCAL_APEX_KEY_PATH", p.apexKeysPath.String()) p.addRequiredModules(entries) }, }, @@ -759,6 +763,7 @@ func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) { } func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { + p.apexKeysPath = writeApexKeys(ctx, p) // TODO(jungjw): Check the key validity. p.inputApex = android.OptionalPathForModuleSrc(ctx, p.prebuiltCommonProperties.Selected_apex).Path() p.installDir = android.PathForModuleInstall(ctx, "apex") @@ -975,6 +980,7 @@ func (a *ApexSet) ApexInfoMutator(mctx android.TopDownMutatorContext) { } func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { + a.apexKeysPath = writeApexKeys(ctx, a) a.installFilename = a.InstallFilename() if !strings.HasSuffix(a.installFilename, imageApexSuffix) && !strings.HasSuffix(a.installFilename, imageCapexSuffix) { ctx.ModuleErrorf("filename should end in %s or %s for apex_set", imageApexSuffix, imageCapexSuffix)