Add stub generation support to cc_prebuilt_library

The `stubs` property in `cc_prebuilt_library` currently does not support
generating stubs from an API symbol file. Reverse dependencies are
always linked against the .so file listed in `srcs`. This CL adds
support to generate the shared library from the .map.txt symbol file of
the prebuilt library.

Implementation details:
1. Add a compiler. This will convert the .map.txt file to a stub .c file.
  The build rules for this are common to the compiler of the source cc_*
moudule types. This has been refactored into a new function named
`compileModuleLibApiStubs`
2. Update the linker to link the aforementioned stub.c file into a .so
  file. Since this happens only for stub variants, it is conditionally
called only when p.buildStubs is true.
3. Call `addStubDependencyProviders`. This will populate the impl
   variant of the library with Stub information. cc#ChooseStubOrImpl
will use this information to resolve rdeps to the stub .so file if the
dependency crosses an api domain boundary.

(2) requires some special casing for now, since the module sdk at HEAD
does not contain symbol files, so the stub.c files will be empty. Once
the symbol files are added to module sdk, the special casing will be
removed.

Test: m nothing --no-skip-soong-tests
Bug: 275273834
Change-Id: I57f5b0a97fac4dfc8c24e07b06a330015add977d
This commit is contained in:
Spandan Das
2024-07-24 18:07:48 +00:00
parent 24b3e534c3
commit 357ffcc146
4 changed files with 127 additions and 52 deletions

View File

@@ -914,7 +914,7 @@ func TestApexWithStubs(t *testing.T) {
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
shared_libs: ["mylib2", "mylib3"],
shared_libs: ["mylib2", "mylib3", "my_prebuilt_platform_lib", "my_prebuilt_platform_stub_only_lib"],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex" ],
@@ -927,6 +927,7 @@ func TestApexWithStubs(t *testing.T) {
system_shared_libs: [],
stl: "none",
stubs: {
symbol_file: "mylib2.map.txt",
versions: ["1", "2", "3"],
},
}
@@ -938,6 +939,7 @@ func TestApexWithStubs(t *testing.T) {
system_shared_libs: [],
stl: "none",
stubs: {
symbol_file: "mylib3.map.txt",
versions: ["10", "11", "12"],
},
apex_available: [ "myapex" ],
@@ -951,6 +953,24 @@ func TestApexWithStubs(t *testing.T) {
apex_available: [ "myapex" ],
}
cc_prebuilt_library_shared {
name: "my_prebuilt_platform_lib",
stubs: {
symbol_file: "my_prebuilt_platform_lib.map.txt",
versions: ["1", "2", "3"],
},
srcs: ["foo.so"],
}
// Similar to my_prebuilt_platform_lib, but this library only provides stubs, i.e. srcs is empty
cc_prebuilt_library_shared {
name: "my_prebuilt_platform_stub_only_lib",
stubs: {
symbol_file: "my_prebuilt_platform_stub_only_lib.map.txt",
versions: ["1", "2", "3"],
}
}
rust_binary {
name: "foo.rust",
srcs: ["foo.rs"],
@@ -1030,6 +1050,20 @@ func TestApexWithStubs(t *testing.T) {
apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so")
// Ensure that mylib is linking with the latest version of stubs for my_prebuilt_platform_lib
ensureContains(t, mylibLdFlags, "my_prebuilt_platform_lib/android_arm64_armv8-a_shared_current/my_prebuilt_platform_lib.so")
// ... and not linking to the non-stub (impl) variant of my_prebuilt_platform_lib
ensureNotContains(t, mylibLdFlags, "my_prebuilt_platform_lib/android_arm64_armv8-a_shared/my_prebuilt_platform_lib.so")
// Ensure that genstub for platform-provided lib is invoked with --systemapi
ensureContains(t, ctx.ModuleForTests("my_prebuilt_platform_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
// Ensure that mylib is linking with the latest version of stubs for my_prebuilt_platform_lib
ensureContains(t, mylibLdFlags, "my_prebuilt_platform_stub_only_lib/android_arm64_armv8-a_shared_current/my_prebuilt_platform_stub_only_lib.so")
// ... and not linking to the non-stub (impl) variant of my_prebuilt_platform_lib
ensureNotContains(t, mylibLdFlags, "my_prebuilt_platform_stub_only_lib/android_arm64_armv8-a_shared/my_prebuilt_platform_stub_only_lib.so")
// Ensure that genstub for platform-provided lib is invoked with --systemapi
ensureContains(t, ctx.ModuleForTests("my_prebuilt_platform_stub_only_lib", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
}
func TestApexShouldNotEmbedStubVariant(t *testing.T) {
@@ -1164,6 +1198,7 @@ func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
system_shared_libs: [],
stl: "none",
stubs: {
symbol_file: "mylib2.map.txt",
versions: ["28", "29", "30", "current"],
},
min_sdk_version: "28",
@@ -1176,6 +1211,7 @@ func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
system_shared_libs: [],
stl: "none",
stubs: {
symbol_file: "mylib3.map.txt",
versions: ["28", "29", "30", "current"],
},
apex_available: [ "myapex" ],
@@ -11855,7 +11891,7 @@ func TestPrebuiltStubNoinstall(t *testing.T) {
).RunTest(t)
ldRule := result.ModuleForTests("installedlib", "android_arm64_armv8-a_shared").Rule("ld")
android.AssertStringDoesContain(t, "", ldRule.Args["libFlags"], "android_arm64_armv8-a_shared/libfoo.so")
android.AssertStringDoesContain(t, "", ldRule.Args["libFlags"], "android_arm64_armv8-a_shared_current/libfoo.so")
installRules := result.InstallMakeRulesForTesting(t)