Improve error reporting when depending on prebuilt implementation jar

The sdk snapshot must not be including implementation code for boot
libraries, the implementation is provided by dex jars within the
corresponding APEX. However, the snapshot does need a module for each
boot library so that the build can seamlessly access the dex files from
the APEX.

A java_library boot library (like core-oj) is represented in the
snapshot by a java_import module which requires a jar file to be
provided, otherwise it is disabled. However, that is provided purely
to keep Soong happy and should never be used.

Previously, the snapshot would contain an empty file for the jar. As
an empty file is an invalid jar any tool (like compiler) that tried
to consume it would fail which was the correct behavior. Unfortunately,
the error message that was produced was not very helpful, it was just
some variant on `invalid file` which lead to a lot of bugs being
raised.

This change replaces that empty file with a reference to the output
from a genrule which runs a script which produces a more useful error
message, with information on how to fix the issue, and fails the build.

It also adds a Name() method to the SdkMemberProperties type as that is
needed in AddInternalModule() to construct the name of the additional
module.

Tested as follows:

In AOSP/master make the following changes:
1. Temporarily set visibility on core-oj and core-libart to
   //visibility:public.
2. Run packages/modules/common/build/mainline_modules_sdks.py to create
   the snapshots.

For each of the S, T and latest snapshots I did the following in the
s-aml-prebuilt-test, t-aml-prebuilt-test and aosp/master branches:

1. Created an Android.bp file containing the following:
  java_library {
    name: "broken",
    static_libs: [
      "prebuilt_core-libart",
      "prebuilt_core-oj",
    ],
  }

2. Fix the visibility issues and run `m broken` where it fails with an
   invalid file.

3. Delete the contents of the prebuilts/module_sdk/art/current/sdk
   directory.

4. Unpack the relevant version of the art-module-sdk snapshot into the
   directory.

5. Run `m broken` where it fails with the helpful message.

6. Test the instructions on how to use the ninja -t path tool to
   identify the cause of the problem and fix it.

Bug: 257969510
Test: See above.
Change-Id: I125bde2d7202afff84c97daebcef37e21c548a3a
This commit is contained in:
Paul Duffin
2022-10-20 17:21:40 +01:00
parent 7cc632d3d6
commit c61783b20d
7 changed files with 256 additions and 72 deletions

View File

@@ -232,12 +232,6 @@ type SnapshotBuilder interface {
// relative path) and add the dest to the zip.
CopyToSnapshot(src Path, dest string)
// EmptyFile returns the path to an empty file.
//
// This can be used by sdk member types that need to create an empty file in the snapshot, simply
// pass the value returned from this to the CopyToSnapshot() method.
EmptyFile() Path
// UnzipToSnapshot generates a rule that will unzip the supplied zip into the snapshot relative
// directory destDir.
UnzipToSnapshot(zipPath Path, destDir string)
@@ -264,6 +258,14 @@ type SnapshotBuilder interface {
// See sdk/update.go for more information.
AddPrebuiltModule(member SdkMember, moduleType string) BpModule
// AddInternalModule creates a new module in the generated Android.bp file that can only be
// referenced by one of the other modules in the snapshot.
//
// The created module's name is constructed by concatenating the name of this member and the
// nameSuffix, separated by "-". It also has the visibility property set to "//visibility:private"
// to prevent it from being inadvertently accessed from outside the snapshot.
AddInternalModule(properties SdkMemberProperties, moduleType string, nameSuffix string) BpModule
// SdkMemberReferencePropertyTag returns a property tag to use when adding a property to a
// BpModule that contains references to other sdk members.
//
@@ -922,6 +924,12 @@ func RegisterSdkMemberType(memberType SdkMemberType) {
//
// Contains common properties that apply across many different member types.
type SdkMemberPropertiesBase struct {
// The name of the member.
//
// Ignore this property during optimization. This is needed because this property is the same for
// all variants of a member and so would be optimized away if it was not ignored.
MemberName string `sdk:"ignore"`
// The number of unique os types supported by the member variants.
//
// If a member has a variant with more than one os type then it will need to differentiate
@@ -945,6 +953,10 @@ type SdkMemberPropertiesBase struct {
Compile_multilib string `android:"arch_variant"`
}
func (b *SdkMemberPropertiesBase) Name() string {
return b.MemberName
}
// OsPrefix returns the os prefix to use for any file paths in the sdk.
//
// Is an empty string if the member only provides variants for a single os type, otherwise
@@ -970,6 +982,8 @@ type SdkMemberProperties interface {
// Base returns the base structure.
Base() *SdkMemberPropertiesBase
Name() string
// PopulateFromVariant populates this structure with information from a module variant.
//
// It will typically be called once for each variant of a member module that the SDK depends upon.