Merge changes from topic "rust_stubs" into main
* changes:
rust: Add stub support for rust_ffi modules
rust: Add CcInfo.LinkerInfo to Rust modules
cc: Pull out common library compilation flags
Refactor cc/rust to prep for Rust stubs
diff --git a/apex/apex.go b/apex/apex.go
index d39a17f..428d57e 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1386,12 +1386,12 @@
// apexFileFor<Type> functions below create an apexFile struct for a given Soong module. The
// returned apexFile saves information about the Soong module that will be used for creating the
// build rules.
-func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
+func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod cc.VersionedLinkableInterface, handleSpecialLibs bool) apexFile {
// Decide the APEX-local directory by the multilib of the library In the future, we may
// query this to the module.
// TODO(jiyong): use the new PackagingSpec
var dirInApex string
- switch ccMod.Arch().ArchType.Multilib {
+ switch ccMod.Multilib() {
case "lib32":
dirInApex = "lib"
case "lib64":
@@ -1418,7 +1418,7 @@
dirInApex = filepath.Join(dirInApex, ccMod.RelativeInstallPath())
fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
- androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
+ androidMkModuleName := ccMod.BaseModuleName() + ccMod.SubName()
return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
}
@@ -1448,25 +1448,6 @@
return af
}
-func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
- // Decide the APEX-local directory by the multilib of the library
- // In the future, we may query this to the module.
- var dirInApex string
- switch rustm.Arch().ArchType.Multilib {
- case "lib32":
- dirInApex = "lib"
- case "lib64":
- dirInApex = "lib64"
- }
- if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
- dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
- }
- dirInApex = filepath.Join(dirInApex, rustm.RelativeInstallPath())
- fileToCopy := android.OutputFileForModule(ctx, rustm, "")
- androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
- return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
-}
-
func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile {
dirInApex := filepath.Join("bin", sh.SubDir())
if sh.Target().NativeBridge == android.NativeBridgeEnabled {
@@ -1900,8 +1881,8 @@
if isJniLib {
propertyName = "jni_libs"
}
- switch ch := child.(type) {
- case *cc.Module:
+
+ if ch, ok := child.(cc.VersionedLinkableInterface); ok {
if ch.IsStubs() {
ctx.PropertyErrorf(propertyName, "%q is a stub. Remove it from the list.", depName)
}
@@ -1915,14 +1896,11 @@
vctx.provideNativeLibs = append(vctx.provideNativeLibs, fi.stem())
}
return true // track transitive dependencies
- case *rust.Module:
- fi := apexFileForRustLibrary(ctx, ch)
- fi.isJniLib = isJniLib
- vctx.filesInfo = append(vctx.filesInfo, fi)
- return true // track transitive dependencies
- default:
- ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
+ } else {
+ ctx.PropertyErrorf(propertyName,
+ "%q is not a VersionLinkableInterface (e.g. cc_library or rust_ffi module)", depName)
}
+
case executableTag:
switch ch := child.(type) {
case *cc.Module:
@@ -2074,7 +2052,7 @@
// We cannot use a switch statement on `depTag` here as the checked
// tags used below are private (e.g. `cc.sharedDepTag`).
if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
- if ch, ok := child.(*cc.Module); ok {
+ if ch, ok := child.(cc.VersionedLinkableInterface); ok {
af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
af.transitiveDep = true
@@ -2089,9 +2067,10 @@
//
// Skip the dependency in unbundled builds where the device image is not
// being built.
- if ch.IsStubsImplementationRequired() && !am.NotInPlatform() && !ctx.Config().UnbundledBuild() {
+ if ch.VersionedInterface().IsStubsImplementationRequired() &&
+ !am.NotInPlatform() && !ctx.Config().UnbundledBuild() {
// we need a module name for Make
- name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
+ name := ch.ImplementationModuleNameForMake(ctx) + ch.SubName()
if !android.InList(name, a.makeModulesToInstall) {
a.makeModulesToInstall = append(a.makeModulesToInstall, name)
}
@@ -2116,15 +2095,6 @@
vctx.filesInfo = append(vctx.filesInfo, af)
return true // track transitive dependencies
- } else if rm, ok := child.(*rust.Module); ok {
- if !android.IsDepInSameApex(ctx, parent, am) {
- return false
- }
-
- af := apexFileForRustLibrary(ctx, rm)
- af.transitiveDep = true
- vctx.filesInfo = append(vctx.filesInfo, af)
- return true // track transitive dependencies
}
} else if cc.IsHeaderDepTag(depTag) {
// nothing
@@ -2143,7 +2113,7 @@
return false
}
- af := apexFileForRustLibrary(ctx, rustm)
+ af := apexFileForNativeLibrary(ctx, child.(cc.VersionedLinkableInterface), vctx.handleSpecialLibs)
af.transitiveDep = true
vctx.filesInfo = append(vctx.filesInfo, af)
return true // track transitive dependencies
diff --git a/apex/apex_test.go b/apex/apex_test.go
index c123d03..2f7757b 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -897,7 +897,11 @@
apex {
name: "myapex",
key: "myapex.key",
- native_shared_libs: ["mylib", "mylib3"],
+ native_shared_libs: [
+ "mylib",
+ "mylib3",
+ "libmylib3_rs",
+ ],
binaries: ["foo.rust"],
updatable: false,
}
@@ -911,7 +915,14 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["mylib2", "mylib3#impl", "my_prebuilt_platform_lib", "my_prebuilt_platform_stub_only_lib"],
+ shared_libs: [
+ "mylib2",
+ "mylib3#impl",
+ "libmylib2_rs",
+ "libmylib3_rs#impl",
+ "my_prebuilt_platform_lib",
+ "my_prebuilt_platform_stub_only_lib",
+ ],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex" ],
@@ -929,6 +940,16 @@
},
}
+ rust_ffi {
+ name: "libmylib2_rs",
+ crate_name: "mylib2",
+ srcs: ["mylib.rs"],
+ stubs: {
+ symbol_file: "mylib2.map.txt",
+ versions: ["1", "2", "3"],
+ },
+ }
+
cc_library {
name: "mylib3",
srcs: ["mylib.cpp"],
@@ -942,6 +963,18 @@
apex_available: [ "myapex" ],
}
+ rust_ffi {
+ name: "libmylib3_rs",
+ crate_name: "mylib3",
+ srcs: ["mylib.rs"],
+ shared_libs: ["mylib4.from_rust"],
+ stubs: {
+ symbol_file: "mylib3.map.txt",
+ versions: ["10", "11", "12"],
+ },
+ apex_available: [ "myapex" ],
+ }
+
cc_library {
name: "mylib4",
srcs: ["mylib.cpp"],
@@ -950,6 +983,14 @@
apex_available: [ "myapex" ],
}
+ cc_library {
+ name: "mylib4.from_rust",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ }
+
cc_prebuilt_library_shared {
name: "my_prebuilt_platform_lib",
stubs: {
@@ -971,7 +1012,10 @@
rust_binary {
name: "foo.rust",
srcs: ["foo.rs"],
- shared_libs: ["libfoo.shared_from_rust"],
+ shared_libs: [
+ "libfoo.shared_from_rust",
+ "libfoo_rs.shared_from_rust",
+ ],
prefer_rlib: true,
apex_available: ["myapex"],
}
@@ -986,6 +1030,15 @@
},
}
+ rust_ffi {
+ name: "libfoo_rs.shared_from_rust",
+ crate_name: "foo_rs",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["10", "11", "12"],
+ },
+ }
+
`)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
@@ -996,21 +1049,27 @@
// Ensure that indirect stubs dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libmylib2_rs.so")
// Ensure that direct stubs dep is included
ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libmylib3_rs.so")
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
// Ensure that mylib is linking with the latest version of stubs for mylib2
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
+ ensureContains(t, mylibLdFlags, "libmylib2_rs/android_arm64_armv8-a_shared_current/unstripped/libmylib2_rs.so")
// ... and not linking to the non-stub (impl) variant of mylib2
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
+ ensureNotContains(t, mylibLdFlags, "libmylib2_rs/android_arm64_armv8-a_shared/unstripped/libmylib2_rs.so")
// Ensure that mylib is linking with the non-stub (impl) of mylib3 (because the dependency is added with mylib3#impl)
ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex10000/mylib3.so")
+ ensureContains(t, mylibLdFlags, "libmylib3_rs/android_arm64_armv8-a_shared_apex10000/unstripped/libmylib3_rs.so")
// .. and not linking to the stubs variant of mylib3
ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12/mylib3.so")
+ ensureNotContains(t, mylibLdFlags, "libmylib3_rs/android_arm64_armv8-a_shared_12/unstripped/mylib3.so")
// Comment out this test. Now it fails after the optimization of sharing "cflags" in cc/cc.go
// is replaced by sharing of "cFlags" in cc/builder.go.
@@ -1026,27 +1085,35 @@
// Ensure that genstub for platform-provided lib is invoked with --systemapi
ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
+ ensureContains(t, ctx.ModuleForTests("libmylib2_rs", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
// Ensure that genstub for apex-provided lib is invoked with --apex
ensureContains(t, ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_shared_12").Rule("genStubSrc").Args["flags"], "--apex")
+ ensureContains(t, ctx.ModuleForTests("libmylib3_rs", "android_arm64_armv8-a_shared_12").Rule("genStubSrc").Args["flags"], "--apex")
ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{
"lib64/mylib.so",
"lib64/mylib3.so",
+ "lib64/libmylib3_rs.so",
"lib64/mylib4.so",
+ "lib64/mylib4.from_rust.so",
"bin/foo.rust",
- "lib64/libc++.so", // by the implicit dependency from foo.rust
- "lib64/liblog.so", // by the implicit dependency from foo.rust
+
+ "lib64/libstd.dylib.so", // implicit rust ffi dep
})
// Ensure that stub dependency from a rust module is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo_rs.shared_from_rust.so")
// The rust module is linked to the stub cc library
rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
+ ensureContains(t, rustDeps, "libfoo_rs.shared_from_rust/android_arm64_armv8-a_shared_current/unstripped/libfoo_rs.shared_from_rust.so")
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
+ ensureNotContains(t, rustDeps, "libfoo_rs.shared_from_rust/android_arm64_armv8-a_shared/unstripped/libfoo_rs.shared_from_rust.so")
apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.shared_from_rust.so")
+ ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo_rs.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")
@@ -1111,7 +1178,10 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["mylib2"],
+ shared_libs: [
+ "mylib2",
+ "libmylib2_rust"
+ ],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex" ],
@@ -1128,10 +1198,22 @@
},
}
+ rust_ffi {
+ name: "libmylib2_rust",
+ crate_name: "mylib2_rust",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["1", "2", "3"],
+ },
+ }
+
rust_binary {
name: "foo.rust",
srcs: ["foo.rs"],
- shared_libs: ["libfoo.shared_from_rust"],
+ shared_libs: [
+ "libfoo.shared_from_rust",
+ "libmylib_rust.shared_from_rust"
+ ],
prefer_rlib: true,
apex_available: ["myapex"],
}
@@ -1145,6 +1227,15 @@
versions: ["10", "11", "12"],
},
}
+ rust_ffi {
+ name: "libmylib_rust.shared_from_rust",
+ crate_name: "mylib_rust",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["1", "2", "3"],
+ },
+ }
+
`)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
@@ -1152,6 +1243,8 @@
// Ensure that indirect stubs dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libmylib_rust.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libmylib_rust.shared_from_rust.so")
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
// Ensure that we are using non-stub variants of mylib2 and libfoo.shared_from_rust (because
@@ -1159,9 +1252,13 @@
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
+ ensureNotContains(t, mylibLdFlags, "libmylib2_rust/android_arm64_armv8-a_shared_current/unstripped/libmylib2_rust.so")
+ ensureContains(t, mylibLdFlags, "libmylib2_rust/android_arm64_armv8-a_shared/unstripped/libmylib2_rust.so")
rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
+ ensureNotContains(t, rustDeps, "libmylib_rust.shared_from_rust/android_arm64_armv8-a_shared_current/unstripped/libmylib_rust.shared_from_rust.so")
+ ensureContains(t, rustDeps, "libmylib_rust.shared_from_rust/android_arm64_armv8-a_shared/unstripped/libmylib_rust.shared_from_rust.so")
}
func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
@@ -1170,7 +1267,11 @@
apex {
name: "myapex",
key: "myapex.key",
- native_shared_libs: ["mylib", "mylib3"],
+ native_shared_libs: [
+ "mylib",
+ "mylib3",
+ "libmylib3_rust",
+ ],
min_sdk_version: "29",
}
@@ -1183,7 +1284,12 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["mylib2", "mylib3#impl"],
+ shared_libs: [
+ "mylib2",
+ "mylib3#impl",
+ "libmylib2_rust",
+ "libmylib3_rust#impl",
+ ],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex" ],
@@ -1203,6 +1309,17 @@
min_sdk_version: "28",
}
+ rust_ffi {
+ name: "libmylib2_rust",
+ crate_name: "mylib2_rust",
+ srcs: ["mylib.rs"],
+ stubs: {
+ symbol_file: "mylib2.map.txt",
+ versions: ["28", "29", "30", "current"],
+ },
+ min_sdk_version: "28",
+ }
+
cc_library {
name: "mylib3",
srcs: ["mylib.cpp"],
@@ -1217,6 +1334,19 @@
min_sdk_version: "28",
}
+ rust_ffi {
+ name: "libmylib3_rust",
+ crate_name: "mylib3_rust",
+ srcs: ["mylib.rs"],
+ shared_libs: ["libmylib4.from_rust"],
+ stubs: {
+ symbol_file: "mylib3.map.txt",
+ versions: ["28", "29", "30", "current"],
+ },
+ apex_available: [ "myapex" ],
+ min_sdk_version: "28",
+ }
+
cc_library {
name: "mylib4",
srcs: ["mylib.cpp"],
@@ -1225,6 +1355,14 @@
apex_available: [ "myapex" ],
min_sdk_version: "28",
}
+
+ rust_ffi {
+ name: "libmylib4.from_rust",
+ crate_name: "mylib4",
+ srcs: ["mylib.rs"],
+ apex_available: [ "myapex" ],
+ min_sdk_version: "28",
+ }
`)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
@@ -1232,9 +1370,12 @@
// Ensure that direct non-stubs dep is always included
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libmylib3_rust.so")
// Ensure that indirect stubs dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libmylib2_rust.so")
// Ensure that direct stubs dep is included
ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
@@ -1243,13 +1384,17 @@
// Ensure that mylib is linking with the latest version of stub for mylib2
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
+ ensureContains(t, mylibLdFlags, "libmylib2_rust/android_arm64_armv8-a_shared_current/unstripped/libmylib2_rust.so")
// ... and not linking to the non-stub (impl) variant of mylib2
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
+ ensureNotContains(t, mylibLdFlags, "libmylib2_rust/android_arm64_armv8-a_shared/unstripped/libmylib2_rust.so")
// Ensure that mylib is linking with the non-stub (impl) of mylib3 (because the dependency is added with mylib3#impl)
ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex29/mylib3.so")
+ ensureContains(t, mylibLdFlags, "libmylib3_rust/android_arm64_armv8-a_shared_apex29/unstripped/libmylib3_rust.so")
// .. and not linking to the stubs variant of mylib3
ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_29/mylib3.so")
+ ensureNotContains(t, mylibLdFlags, "libmylib3_rust/android_arm64_armv8-a_shared_29/unstripped/libmylib3_rust.so")
// Ensure that stubs libs are built without -include flags
mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"]
@@ -1257,11 +1402,16 @@
// Ensure that genstub is invoked with --systemapi
ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"], "--systemapi")
+ ensureContains(t, ctx.ModuleForTests("libmylib2_rust", "android_arm64_armv8-a_shared_29").Rule("cc.genStubSrc").Args["flags"], "--systemapi")
ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{
"lib64/mylib.so",
"lib64/mylib3.so",
+ "lib64/libmylib3_rust.so",
"lib64/mylib4.so",
+ "lib64/libmylib4.from_rust.so",
+
+ "lib64/libstd.dylib.so", // by the implicit dependency from foo.rust
})
}
@@ -1286,7 +1436,10 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["libstub"],
+ shared_libs: [
+ "libstub",
+ "libstub_rust",
+ ],
apex_available: ["myapex"],
min_sdk_version: "Z",
}
@@ -1300,7 +1453,10 @@
apex {
name: "otherapex",
key: "myapex.key",
- native_shared_libs: ["libstub"],
+ native_shared_libs: [
+ "libstub",
+ "libstub_rust",
+ ],
min_sdk_version: "29",
}
@@ -1314,11 +1470,25 @@
min_sdk_version: "29",
}
+ rust_ffi {
+ name: "libstub_rust",
+ crate_name: "stub_rust",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["29", "Z", "current"],
+ },
+ apex_available: ["otherapex"],
+ min_sdk_version: "29",
+ }
+
// platform module depending on libstub from otherapex should use the latest stub("current")
cc_library {
name: "libplatform",
srcs: ["mylib.cpp"],
- shared_libs: ["libstub"],
+ shared_libs: [
+ "libstub",
+ "libstub_rust",
+ ],
}
`,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -1331,14 +1501,20 @@
// Ensure that mylib from myapex is built against the latest stub (current)
mylibCflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
ensureContains(t, mylibCflags, "-D__LIBSTUB_API__=10000 ")
+ // rust stubs do not emit -D__LIBFOO_API__ flags as this is deprecated behavior for cc stubs
+
mylibLdflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
ensureContains(t, mylibLdflags, "libstub/android_arm64_armv8-a_shared_current/libstub.so ")
+ ensureContains(t, mylibLdflags, "libstub_rust/android_arm64_armv8-a_shared_current/unstripped/libstub_rust.so ")
// Ensure that libplatform is built against latest stub ("current") of mylib3 from the apex
libplatformCflags := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureContains(t, libplatformCflags, "-D__LIBSTUB_API__=10000 ") // "current" maps to 10000
+ // rust stubs do not emit -D__LIBFOO_API__ flags as this is deprecated behavior for cc stubs
+
libplatformLdflags := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
ensureContains(t, libplatformLdflags, "libstub/android_arm64_armv8-a_shared_current/libstub.so ")
+ ensureContains(t, libplatformLdflags, "libstub_rust/android_arm64_armv8-a_shared_current/unstripped/libstub_rust.so ")
}
func TestApexWithExplicitStubsDependency(t *testing.T) {
@@ -1360,7 +1536,10 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["libfoo#10"],
+ shared_libs: [
+ "libfoo#10",
+ "libfoo_rust#10"
+ ],
static_libs: ["libbaz"],
system_shared_libs: [],
stl: "none",
@@ -1378,6 +1557,16 @@
},
}
+ rust_ffi {
+ name: "libfoo_rust",
+ crate_name: "foo_rust",
+ srcs: ["mylib.cpp"],
+ shared_libs: ["libbar.from_rust"],
+ stubs: {
+ versions: ["10", "20", "30"],
+ },
+ }
+
cc_library {
name: "libbar",
srcs: ["mylib.cpp"],
@@ -1385,6 +1574,13 @@
stl: "none",
}
+ cc_library {
+ name: "libbar.from_rust",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
cc_library_static {
name: "libbaz",
srcs: ["mylib.cpp"],
@@ -1403,21 +1599,27 @@
// Ensure that indirect stubs dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo_rust.so")
// Ensure that dependency of stubs is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.from_rust.so")
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
// Ensure that mylib is linking with version 10 of libfoo
ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
+ ensureContains(t, mylibLdFlags, "libfoo_rust/android_arm64_armv8-a_shared_10/unstripped/libfoo_rust.so")
// ... and not linking to the non-stub (impl) variant of libfoo
ensureNotContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared/libfoo.so")
+ ensureNotContains(t, mylibLdFlags, "libfoo_rust/android_arm64_armv8-a_shared/unstripped/libfoo_rust.so")
libFooStubsLdFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_10").Rule("ld").Args["libFlags"]
+ libFooRustStubsLdFlags := ctx.ModuleForTests("libfoo_rust", "android_arm64_armv8-a_shared_10").Rule("ld").Args["libFlags"]
// Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
+ ensureNotContains(t, libFooRustStubsLdFlags, "libbar.from_rust.so")
fullDepsInfo := strings.Split(android.ContentFromFileRuleForTests(t, ctx,
ctx.ModuleForTests("myapex2", "android_common_myapex2").Output("depsinfo/fulllist.txt")), "\n")
@@ -1457,7 +1659,11 @@
srcs: ["mylib.cpp"],
static_libs: ["libstatic"],
shared_libs: ["libshared"],
- runtime_libs: ["libfoo", "libbar"],
+ runtime_libs: [
+ "libfoo",
+ "libbar",
+ "libfoo_rs",
+ ],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex" ],
@@ -1473,6 +1679,15 @@
},
}
+ rust_ffi {
+ name: "libfoo_rs",
+ crate_name: "foo_rs",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["10", "20", "30"],
+ },
+ }
+
cc_library {
name: "libbar",
srcs: ["mylib.cpp"],
@@ -1524,6 +1739,7 @@
// Ensure that indirect stubs dep is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo_rs.so")
// Ensure that runtime_libs dep in included
ensureContains(t, copyCmds, "image.apex/lib64/libbar.so")
@@ -1535,6 +1751,7 @@
apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.so")
+ ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo_rs.so")
}
var prepareForTestOfRuntimeApexWithHwasan = android.GroupFixturePreparers(
@@ -1766,7 +1983,7 @@
apex {
name: "myapex",
key: "myapex.key",
- native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"],
+ native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm", "libmylib_rs"],
updatable: false,
}
@@ -1785,6 +2002,14 @@
apex_available: [ "myapex" ],
}
+ rust_ffi {
+ name: "libmylib_rs",
+ crate_name: "mylib_rs",
+ shared_libs: ["libvers#27", "libm#impl"],
+ srcs: ["mylib.rs"],
+ apex_available: [ "myapex" ],
+ }
+
cc_library_shared {
name: "mylib_shared",
srcs: ["mylib.cpp"],
@@ -1799,20 +2024,38 @@
stl: "none",
bootstrap: true,
}
+
+ rust_ffi {
+ name: "libbootstrap_rs",
+ srcs: ["mylib.cpp"],
+ crate_name: "bootstrap_rs",
+ bootstrap: true,
+ }
+
+ cc_library {
+ name: "libvers",
+ srcs: ["mylib.cpp"],
+ stl: "none",
+ stubs: { versions: ["27","30"] },
+ }
`)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
- // Ensure that mylib, libm, libdl are included.
+ // Ensure that mylib, libmylib_rs, libm, libdl, libstd.dylib.so (from Rust) are included.
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libmylib_rs.so")
ensureContains(t, copyCmds, "image.apex/lib64/bionic/libm.so")
ensureContains(t, copyCmds, "image.apex/lib64/bionic/libdl.so")
+ ensureContains(t, copyCmds, "image.apex/lib64/libstd.dylib.so")
- // Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
+ // Ensure that libc and liblog (from Rust) is not included (since it has stubs and not listed in native_shared_libs)
ensureNotContains(t, copyCmds, "image.apex/lib64/bionic/libc.so")
+ ensureNotContains(t, copyCmds, "image.apex/lib64/liblog.so")
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
+ mylibRsFlags := ctx.ModuleForTests("libmylib_rs", "android_arm64_armv8-a_shared_apex10000").Rule("rustc").Args["linkFlags"]
mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_apex10000").Rule("cc").Args["cFlags"]
@@ -1846,11 +2089,42 @@
ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
+ // Rust checks
+ // For dependency to libc, liblog
+ // Ensure that libmylib_rs is linking with the latest versions of stubs
+ ensureContains(t, mylibRsFlags, "libc/android_arm64_armv8-a_shared_current/libc.so")
+ ensureContains(t, mylibRsFlags, "liblog/android_arm64_armv8-a_shared_current/liblog.so")
+ // ... and not linking to the non-stub (impl) variants
+ ensureNotContains(t, mylibRsFlags, "libc/android_arm64_armv8-a_shared/libc.so")
+ ensureNotContains(t, mylibRsFlags, "liblog/android_arm64_armv8-a_shared/liblog.so")
+
+ // For libm dependency (explicit)
+ // Ensure that mylib is linking with the non-stub (impl) variant
+ ensureContains(t, mylibRsFlags, "libm/android_arm64_armv8-a_shared_apex10000/libm.so")
+ // ... and not linking to the stub variant
+ ensureNotContains(t, mylibRsFlags, "libm/android_arm64_armv8-a_shared_29/libm.so")
+
+ // For dependency to libvers
+ // (We do not use libdl#27 as Rust links the system libs implicitly and does
+ // not currently have a system_shared_libs equivalent to prevent this)
+ // Ensure that mylib is linking with the specified version of stubs
+ ensureContains(t, mylibRsFlags, "libvers/android_arm64_armv8-a_shared_27/libvers.so")
+ // ... and not linking to the other versions of stubs
+ ensureNotContains(t, mylibRsFlags, "libvers/android_arm64_armv8-a_shared_30/libvers.so")
+ // ... and not linking to the non-stub (impl) variant
+ ensureNotContains(t, mylibRsFlags, "libvers/android_arm64_armv8-a_shared_apex10000/libvers.so")
+
// Ensure that libBootstrap is depending on the platform variant of bionic libs
libFlags := ctx.ModuleForTests("libBootstrap", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
ensureContains(t, libFlags, "libc/android_arm64_armv8-a_shared/libc.so")
ensureContains(t, libFlags, "libm/android_arm64_armv8-a_shared/libm.so")
ensureContains(t, libFlags, "libdl/android_arm64_armv8-a_shared/libdl.so")
+
+ // Ensure that libbootstrap_rs is depending on the platform variant of bionic libs
+ libRsFlags := ctx.ModuleForTests("libbootstrap_rs", "android_arm64_armv8-a_shared").Rule("rustc").Args["linkFlags"]
+ ensureContains(t, libRsFlags, "libc/android_arm64_armv8-a_shared/libc.so")
+ ensureContains(t, libRsFlags, "libm/android_arm64_armv8-a_shared/libm.so")
+ ensureContains(t, libRsFlags, "libdl/android_arm64_armv8-a_shared/libdl.so")
}
func TestApexMinSdkVersion_NativeModulesShouldBeBuiltAgainstStubs(t *testing.T) {
@@ -1900,7 +2174,7 @@
cc_library {
name: "liba",
- shared_libs: ["libz"],
+ shared_libs: ["libz", "libz_rs"],
system_shared_libs: [],
stl: "none",
apex_available: [
@@ -1918,6 +2192,15 @@
versions: ["28", "30"],
},
}
+
+ rust_ffi {
+ name: "libz_rs",
+ crate_name: "z_rs",
+ srcs: ["foo.rs"],
+ stubs: {
+ versions: ["28", "30"],
+ },
+ }
`)
expectLink := func(from, from_variant, to, to_variant string) {
@@ -1930,16 +2213,25 @@
}
// platform liba is linked to non-stub version
expectLink("liba", "shared", "libz", "shared")
+ expectLink("liba", "shared", "unstripped/libz_rs", "shared")
// liba in myapex is linked to current
expectLink("liba", "shared_apex29", "libz", "shared_current")
expectNoLink("liba", "shared_apex29", "libz", "shared_30")
expectNoLink("liba", "shared_apex29", "libz", "shared_28")
expectNoLink("liba", "shared_apex29", "libz", "shared")
+ expectLink("liba", "shared_apex29", "unstripped/libz_rs", "shared_current")
+ expectNoLink("liba", "shared_apex29", "unstripped/libz_rs", "shared_30")
+ expectNoLink("liba", "shared_apex29", "unstripped/libz_rs", "shared_28")
+ expectNoLink("liba", "shared_apex29", "unstripped/libz_rs", "shared")
// liba in otherapex is linked to current
expectLink("liba", "shared_apex30", "libz", "shared_current")
expectNoLink("liba", "shared_apex30", "libz", "shared_30")
expectNoLink("liba", "shared_apex30", "libz", "shared_28")
expectNoLink("liba", "shared_apex30", "libz", "shared")
+ expectLink("liba", "shared_apex30", "unstripped/libz_rs", "shared_current")
+ expectNoLink("liba", "shared_apex30", "unstripped/libz_rs", "shared_30")
+ expectNoLink("liba", "shared_apex30", "unstripped/libz_rs", "shared_28")
+ expectNoLink("liba", "shared_apex30", "unstripped/libz_rs", "shared")
}
func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
@@ -2159,7 +2451,7 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["libbar"],
+ shared_libs: ["libbar", "libbar_rs"],
min_sdk_version: "29",
apex_available: ["myapex"],
}
@@ -2169,6 +2461,13 @@
stubs: { versions: ["29", "30"] },
}
+ rust_ffi {
+ name: "libbar_rs",
+ crate_name: "bar_rs",
+ srcs: ["bar.rs"],
+ stubs: { versions: ["29", "30"] },
+ }
+
cc_library {
name: "yourlib",
srcs: ["mylib.cpp"],
@@ -2191,6 +2490,8 @@
myapex.Output("depsinfo/flatlist.txt")), "\n")
android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
flatlist, "libbar(minSdkVersion:(no version)) (external)")
+ android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
+ flatlist, "libbar_rs(minSdkVersion:(no version)) (external)")
android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
flatlist, "mylib:(minSdkVersion:29)")
android.AssertStringListContains(t, "track platform-available lib",
@@ -2227,7 +2528,7 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["libbar"],
+ shared_libs: ["libbar", "libbar_rs",],
min_sdk_version: "29",
apex_available: ["myapex"],
}
@@ -2237,6 +2538,13 @@
stubs: { versions: ["29", "30"] },
}
+ rust_ffi {
+ name: "libbar_rs",
+ crate_name: "bar_rs",
+ srcs: ["bar.rs"],
+ stubs: { versions: ["29", "30"] },
+ }
+
cc_library {
name: "yourlib",
srcs: ["mylib.cpp"],
@@ -2264,6 +2572,8 @@
myapex.Output("depsinfo/flatlist.txt")), "\n")
android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
flatlist, "libbar(minSdkVersion:(no version)) (external)")
+ android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
+ flatlist, "libbar_rs(minSdkVersion:(no version)) (external)")
android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
flatlist, "mylib:(minSdkVersion:29)")
android.AssertStringListContains(t, "track platform-available lib",
@@ -2300,7 +2610,7 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["libbar"],
+ shared_libs: ["libbar", "libbar_rs"],
min_sdk_version: "29",
apex_available: ["myapex"],
}
@@ -2310,6 +2620,13 @@
stubs: { versions: ["29", "30"] },
}
+ rust_ffi {
+ name: "libbar_rs",
+ crate_name: "bar_rs",
+ srcs: ["bar.rs"],
+ stubs: { versions: ["29", "30"] },
+ }
+
cc_library {
name: "yourlib",
srcs: ["mylib.cpp"],
@@ -2338,6 +2655,8 @@
myapex.Output("depsinfo/flatlist.txt")), "\n")
android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
flatlist, "libbar(minSdkVersion:(no version)) (external)")
+ android.AssertStringListContains(t, "deps with stubs should be tracked in depsinfo as external dep",
+ flatlist, "libbar_rs(minSdkVersion:(no version)) (external)")
android.AssertStringListDoesNotContain(t, "do not track if not available for platform",
flatlist, "mylib:(minSdkVersion:29)")
android.AssertStringListContains(t, "track platform-available lib",
@@ -2372,7 +2691,7 @@
apex {
name: "myapex",
key: "myapex.key",
- native_shared_libs: ["libx"],
+ native_shared_libs: ["libx", "libx_rs"],
updatable: false,
}
@@ -2392,9 +2711,19 @@
},
}
+ rust_ffi {
+ name: "libx_rs",
+ crate_name: "x_rs",
+ srcs: ["x.rs"],
+ apex_available: [ "myapex" ],
+ stubs: {
+ versions: ["1", "2"],
+ },
+ }
+
cc_library {
name: "libz",
- shared_libs: ["libx"],
+ shared_libs: ["libx", "libx_rs",],
system_shared_libs: [],
stl: "none",
}
@@ -2412,6 +2741,8 @@
}
expectLink("libz", "shared", "libx", "shared_current")
expectNoLink("libz", "shared", "libx", "shared_2")
+ expectLink("libz", "shared", "unstripped/libx_rs", "shared_current")
+ expectNoLink("libz", "shared", "unstripped/libx_rs", "shared_2")
expectNoLink("libz", "shared", "libz", "shared_1")
expectNoLink("libz", "shared", "libz", "shared")
}
@@ -2440,11 +2771,18 @@
cc_library {
name: "libx",
- shared_libs: ["libbar"],
+ shared_libs: ["libbar", "libbar_rs"],
apex_available: [ "myapex" ],
min_sdk_version: "29",
}
+ rust_ffi {
+ name: "libbar_rs",
+ crate_name: "bar_rs",
+ srcs: ["bar.rs"],
+ stubs: { versions: ["29", "30"] },
+ }
+
cc_library {
name: "libbar",
stubs: {
@@ -2460,6 +2798,7 @@
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
expectLink("libx", "shared_hwasan_apex29", "libbar", "shared_current")
+ expectLink("libx", "shared_hwasan_apex29", "unstripped/libbar_rs", "shared_current")
}
func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
@@ -3404,10 +3743,20 @@
apex_available: ["myapex"],
}
+ rust_ffi {
+ name: "libmylib_rs",
+ crate_name: "mylib_rs",
+ srcs: ["mylib.rs"],
+ stubs: {
+ versions: ["1", "2", "3"],
+ },
+ apex_available: ["myapex"],
+ }
+
cc_binary {
name: "not_in_apex",
srcs: ["mylib.cpp"],
- static_libs: ["mylib"],
+ static_libs: ["mylib", "libmylib_rs"],
static_executable: true,
system_shared_libs: [],
stl: "none",
@@ -3418,6 +3767,7 @@
// Ensure that not_in_apex is linking with the static variant of mylib
ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_static/mylib.a")
+ ensureContains(t, ldFlags, "generated_rust_staticlib/librustlibs.a")
}
func TestKeys(t *testing.T) {
@@ -8245,8 +8595,6 @@
"lib64/mylib2.so",
"lib64/mylib3.so",
"lib64/libfoo.rust.so",
- "lib64/libc++.so", // auto-added to libfoo.rust by Soong
- "lib64/liblog.so", // auto-added to libfoo.rust by Soong
})
// b/220397949
@@ -10704,8 +11052,8 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 38 {
- t.Fatalf("Expected 38 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 34 {
+ t.Fatalf("Expected 34 commands, got %d in:\n%s", len(copyCmds), s)
}
ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 8037272..03f229e 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -231,7 +231,7 @@
} else if library.shared() {
entries.Class = "SHARED_LIBRARIES"
entries.SetString("LOCAL_SOONG_TOC", library.toc().String())
- if !library.buildStubs() && library.unstrippedOutputFile != nil {
+ if !library.BuildStubs() && library.unstrippedOutputFile != nil {
entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", library.unstrippedOutputFile.String())
}
if len(library.Properties.Overrides) > 0 {
@@ -260,16 +260,16 @@
entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String())
}
- if library.shared() && !library.buildStubs() {
+ if library.shared() && !library.BuildStubs() {
ctx.subAndroidMk(config, entries, library.baseInstaller)
} else {
- if library.buildStubs() && library.stubsVersion() != "" {
- entries.SubName = "." + library.stubsVersion()
+ if library.BuildStubs() && library.StubsVersion() != "" {
+ entries.SubName = "." + library.StubsVersion()
}
// library.makeUninstallable() depends on this to bypass HideFromMake() for
// static libraries.
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
- if library.buildStubs() {
+ if library.BuildStubs() {
entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
}
}
@@ -281,10 +281,10 @@
// very early stage in the boot process).
if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.NotInPlatform() &&
!ctx.InRamdisk() && !ctx.InVendorRamdisk() && !ctx.InRecovery() && !ctx.InVendorOrProduct() && !ctx.static() {
- if library.buildStubs() && library.isLatestStubVersion() {
+ if library.BuildStubs() && library.isLatestStubVersion() {
entries.SubName = ""
}
- if !library.buildStubs() {
+ if !library.BuildStubs() {
entries.SubName = ".bootstrap"
}
}
@@ -423,7 +423,7 @@
entries.SubName = ndkLibrarySuffix + "." + c.apiLevel.String()
entries.Class = "SHARED_LIBRARIES"
- if !c.buildStubs() {
+ if !c.BuildStubs() {
entries.Disabled = true
return
}
diff --git a/cc/api_level.go b/cc/api_level.go
index 3dac571..deca723 100644
--- a/cc/api_level.go
+++ b/cc/api_level.go
@@ -55,7 +55,7 @@
return apiLevel
}
-func nativeApiLevelFromUser(ctx android.BaseModuleContext,
+func NativeApiLevelFromUser(ctx android.BaseModuleContext,
raw string) (android.ApiLevel, error) {
if raw == "minimum" {
@@ -73,7 +73,7 @@
func nativeApiLevelOrPanic(ctx android.BaseModuleContext,
raw string) android.ApiLevel {
- value, err := nativeApiLevelFromUser(ctx, raw)
+ value, err := NativeApiLevelFromUser(ctx, raw)
if err != nil {
panic(err.Error())
}
diff --git a/cc/builder.go b/cc/builder.go
index b98bef9..5325116 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -472,8 +472,8 @@
}
// Generate rules for compiling multiple .c, .cpp, or .S files to individual .o files
-func transformSourceToObj(ctx ModuleContext, subdir string, srcFiles, noTidySrcs, timeoutTidySrcs android.Paths,
- flags builderFlags, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
+func transformSourceToObj(ctx android.ModuleContext, subdir string, srcFiles, noTidySrcs, timeoutTidySrcs android.Paths,
+ flags builderFlags, pathDeps android.Paths, cFlagsDeps android.Paths, sharedFlags *SharedFlags) Objects {
// Source files are one-to-one with tidy, coverage, or kythe files, if enabled.
objFiles := make(android.Paths, len(srcFiles))
var tidyFiles android.Paths
@@ -552,10 +552,8 @@
}
// Multiple source files have build rules usually share the same cFlags or tidyFlags.
- // Define only one version in this module and share it in multiple build rules.
- // To simplify the code, the shared variables are all named as $flags<nnn>.
- shared := ctx.getSharedFlags()
-
+ // SharedFlags provides one version for this module and shares it in multiple build rules.
+ // To simplify the code, the SharedFlags variables are all named as $flags<nnn>.
// Share flags only when there are multiple files or tidy rules.
var hasMultipleRules = len(srcFiles) > 1 || flags.tidy
@@ -566,11 +564,11 @@
return flags
}
mapKey := kind + flags
- n, ok := shared.flagsMap[mapKey]
+ n, ok := sharedFlags.FlagsMap[mapKey]
if !ok {
- shared.numSharedFlags += 1
- n = strconv.Itoa(shared.numSharedFlags)
- shared.flagsMap[mapKey] = n
+ sharedFlags.NumSharedFlags += 1
+ n = strconv.Itoa(sharedFlags.NumSharedFlags)
+ sharedFlags.FlagsMap[mapKey] = n
ctx.Variable(pctx, kind+n, flags)
}
return "$" + kind + n
@@ -853,6 +851,25 @@
return strings.Join(lines, "\n")
}
+func BuildRustStubs(ctx android.ModuleContext, outputFile android.ModuleOutPath,
+ crtBegin, crtEnd android.Paths, stubObjs Objects, ccFlags Flags) {
+
+ // Instantiate paths
+ sharedLibs := android.Paths{}
+ staticLibs := android.Paths{}
+ lateStaticLibs := android.Paths{}
+ wholeStaticLibs := android.Paths{}
+ deps := android.Paths{}
+ implicitOutputs := android.WritablePaths{}
+ validations := android.Paths{}
+ groupLate := false
+
+ builderFlags := flagsToBuilderFlags(ccFlags)
+ transformObjToDynamicBinary(ctx, stubObjs.objFiles, sharedLibs, staticLibs,
+ lateStaticLibs, wholeStaticLibs, deps, crtBegin, crtEnd,
+ groupLate, builderFlags, outputFile, implicitOutputs, validations)
+}
+
// Generate a rule for compiling multiple .o files, plus static libraries, whole static libraries,
// and shared libraries, to a shared library (.so) or dynamic executable
func transformObjToDynamicBinary(ctx android.ModuleContext,
diff --git a/cc/cc.go b/cc/cc.go
index af1b259..57b5e3c 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -160,6 +160,8 @@
Installable *bool
// RelativeInstallPath returns the relative install path for this module.
RelativeInstallPath string
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
+ RustApexExclude bool
}
var LinkableInfoProvider = blueprint.NewProvider[*LinkableInfo]()
@@ -623,7 +625,6 @@
binary() bool
object() bool
toolchain() config.Toolchain
- canUseSdk() bool
useSdk() bool
sdkVersion() string
minSdkVersion() string
@@ -647,9 +648,7 @@
isFuzzer() bool
isNDKStubLibrary() bool
useClangLld(actx ModuleContext) bool
- isForPlatform() bool
apexVariationName() string
- apexSdkVersion() android.ApiLevel
bootstrap() bool
nativeCoverage() bool
isPreventInstall() bool
@@ -661,8 +660,8 @@
}
type SharedFlags struct {
- numSharedFlags int
- flagsMap map[string]string
+ NumSharedFlags int
+ FlagsMap map[string]string
}
type ModuleContext interface {
@@ -920,7 +919,7 @@
dataLibDepTag = dependencyTag{name: "data lib"}
dataBinDepTag = dependencyTag{name: "data bin"}
runtimeDepTag = installDependencyTag{name: "runtime lib"}
- stubImplDepTag = dependencyTag{name: "stub_impl"}
+ StubImplDepTag = dependencyTag{name: "stub_impl"}
JniFuzzLibTag = dependencyTag{name: "jni_fuzz_lib_tag"}
FdoProfileTag = dependencyTag{name: "fdo_profile"}
aidlLibraryTag = dependencyTag{name: "aidl_library"}
@@ -946,6 +945,11 @@
return depTag == runtimeDepTag
}
+func ExcludeInApexDepTag(depTag blueprint.DependencyTag) bool {
+ ccLibDepTag, ok := depTag.(libraryDependencyTag)
+ return ok && ccLibDepTag.excludeInApex
+}
+
// Module contains the properties and members used by all C/C++ module types, and implements
// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
// to construct the output file. Behavior can be customized with a Customizer, or "decorator",
@@ -1169,7 +1173,21 @@
return String(c.Properties.Min_sdk_version)
}
-func (c *Module) isCrt() bool {
+func (c *Module) SetSdkVersion(s string) {
+ c.Properties.Sdk_version = StringPtr(s)
+}
+
+func (c *Module) SetMinSdkVersion(s string) {
+ c.Properties.Min_sdk_version = StringPtr(s)
+}
+
+func (c *Module) SetStl(s string) {
+ if c.stl != nil {
+ c.stl.Properties.Stl = StringPtr(s)
+ }
+}
+
+func (c *Module) IsCrt() bool {
if linker, ok := c.linker.(*objectLinker); ok {
return linker.isCrt()
}
@@ -1177,7 +1195,7 @@
}
func (c *Module) SplitPerApiLevel() bool {
- return c.canUseSdk() && c.isCrt()
+ return CanUseSdk(c) && c.IsCrt()
}
func (c *Module) AlwaysSdk() bool {
@@ -1197,7 +1215,7 @@
}
func (c *Module) CcLibraryInterface() bool {
- if _, ok := c.linker.(libraryInterface); ok {
+ if c.library != nil {
return true
}
return false
@@ -1310,6 +1328,13 @@
var _ LinkableInterface = (*Module)(nil)
+func (c *Module) VersionedInterface() VersionedInterface {
+ if c.library != nil {
+ return c.library
+ }
+ return nil
+}
+
func (c *Module) UnstrippedOutputFile() android.Path {
if c.linker != nil {
return c.linker.unstrippedOutputFilePath()
@@ -1394,13 +1419,13 @@
return c.Properties.VndkVersion != ""
}
-func (c *Module) canUseSdk() bool {
- return c.Os() == android.Android && c.Target().NativeBridge == android.NativeBridgeDisabled &&
+func CanUseSdk(c LinkableInterface) bool {
+ return c.Module().Target().Os == android.Android && c.Target().NativeBridge == android.NativeBridgeDisabled &&
!c.InVendorOrProduct() && !c.InRamdisk() && !c.InRecovery() && !c.InVendorRamdisk()
}
func (c *Module) UseSdk() bool {
- if c.canUseSdk() {
+ if CanUseSdk(c) {
return String(c.Properties.Sdk_version) != ""
}
return false
@@ -1419,13 +1444,13 @@
}
func (m *Module) NeedsLlndkVariants() bool {
- lib := moduleLibraryInterface(m)
- return lib != nil && (lib.hasLLNDKStubs() || lib.hasLLNDKHeaders())
+ lib := moduleVersionedInterface(m)
+ return lib != nil && (lib.HasLLNDKStubs() || lib.HasLLNDKHeaders())
}
func (m *Module) NeedsVendorPublicLibraryVariants() bool {
- lib := moduleLibraryInterface(m)
- return lib != nil && (lib.hasVendorPublicLibrary())
+ lib := moduleVersionedInterface(m)
+ return lib != nil && (lib.HasVendorPublicLibrary())
}
// IsVendorPublicLibrary returns true for vendor public libraries.
@@ -1445,13 +1470,13 @@
}
func (c *Module) HasLlndkStubs() bool {
- lib := moduleLibraryInterface(c)
- return lib != nil && lib.hasLLNDKStubs()
+ lib := moduleVersionedInterface(c)
+ return lib != nil && lib.HasLLNDKStubs()
}
func (c *Module) StubsVersion() string {
- if lib, ok := c.linker.(versionedInterface); ok {
- return lib.stubsVersion()
+ if lib, ok := c.linker.(VersionedInterface); ok {
+ return lib.StubsVersion()
}
panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", c.BaseModuleName()))
}
@@ -1460,7 +1485,7 @@
// and does not set llndk.vendor_available: false.
func (c *Module) isImplementationForLLNDKPublic() bool {
library, _ := c.library.(*libraryDecorator)
- return library != nil && library.hasLLNDKStubs() &&
+ return library != nil && library.HasLLNDKStubs() &&
!Bool(library.Properties.Llndk.Private)
}
@@ -1499,21 +1524,25 @@
func (c *Module) IsStubs() bool {
if lib := c.library; lib != nil {
- return lib.buildStubs()
+ return lib.BuildStubs()
}
return false
}
func (c *Module) HasStubsVariants() bool {
if lib := c.library; lib != nil {
- return lib.hasStubsVariants()
+ return lib.HasStubsVariants()
}
return false
}
+func (c *Module) RustApexExclude() bool {
+ return false
+}
+
func (c *Module) IsStubsImplementationRequired() bool {
if lib := c.library; lib != nil {
- return lib.isStubsImplementationRequired()
+ return lib.IsStubsImplementationRequired()
}
return false
}
@@ -1522,21 +1551,21 @@
// the implementation. If it is an implementation library it returns its own name.
func (c *Module) ImplementationModuleName(ctx android.BaseModuleContext) string {
name := ctx.OtherModuleName(c)
- if versioned, ok := c.linker.(versionedInterface); ok {
- name = versioned.implementationModuleName(name)
+ if versioned, ok := c.linker.(VersionedInterface); ok {
+ name = versioned.ImplementationModuleName(name)
}
return name
}
-// Similar to ImplementationModuleName, but uses the Make variant of the module
+// Similar to ImplementationModuleNameByCtx, but uses the Make variant of the module
// name as base name, for use in AndroidMk output. E.g. for a prebuilt module
// where the Soong name is prebuilt_foo, this returns foo (which works in Make
// under the premise that the prebuilt module overrides its source counterpart
// if it is exposed to Make).
func (c *Module) ImplementationModuleNameForMake(ctx android.BaseModuleContext) string {
name := c.BaseModuleName()
- if versioned, ok := c.linker.(versionedInterface); ok {
- name = versioned.implementationModuleName(name)
+ if versioned, ok := c.linker.(VersionedInterface); ok {
+ name = versioned.ImplementationModuleName(name)
}
return name
}
@@ -1644,10 +1673,6 @@
return ctx.mod.OptimizeForSize()
}
-func (ctx *moduleContextImpl) canUseSdk() bool {
- return ctx.mod.canUseSdk()
-}
-
func (ctx *moduleContextImpl) useSdk() bool {
return ctx.mod.UseSdk()
}
@@ -1659,21 +1684,23 @@
return ""
}
-func (ctx *moduleContextImpl) minSdkVersion() string {
- ver := ctx.mod.MinSdkVersion()
- if ver == "apex_inherit" && !ctx.isForPlatform() {
- ver = ctx.apexSdkVersion().String()
+func MinSdkVersion(mod VersionedLinkableInterface, ctxIsForPlatform bool, device bool,
+ platformSdkVersion string) string {
+
+ ver := mod.MinSdkVersion()
+ if ver == "apex_inherit" && !ctxIsForPlatform {
+ ver = mod.ApexSdkVersion().String()
}
if ver == "apex_inherit" || ver == "" {
- ver = ctx.sdkVersion()
+ ver = mod.SdkVersion()
}
- if ctx.ctx.Device() {
+ if device {
// When building for vendor/product, use the latest _stable_ API as "current".
// This is passed to clang/aidl compilers so that compiled/generated code works
// with the system.
- if (ctx.inVendor() || ctx.inProduct()) && (ver == "" || ver == "current") {
- ver = ctx.ctx.Config().PlatformSdkVersion().String()
+ if (mod.InVendor() || mod.InProduct()) && (ver == "" || ver == "current") {
+ ver = platformSdkVersion
}
}
@@ -1687,19 +1714,19 @@
// support such an old version. The version is set to the later version in case when the
// non-sdk variant is for the platform, or the min_sdk_version of the containing APEX if
// it's for an APEX.
- if ctx.mod.isCrt() && !ctx.isSdkVariant() {
- if ctx.isForPlatform() {
+ if mod.IsCrt() && !mod.IsSdkVariant() {
+ if ctxIsForPlatform {
ver = strconv.Itoa(android.FutureApiLevelInt)
} else { // for apex
- ver = ctx.apexSdkVersion().String()
+ ver = mod.ApexSdkVersion().String()
if ver == "" { // in case when min_sdk_version was not set by the APEX
- ver = ctx.sdkVersion()
+ ver = mod.SdkVersion()
}
}
}
// Also make sure that minSdkVersion is not greater than sdkVersion, if they are both numbers
- sdkVersionInt, err := strconv.Atoi(ctx.sdkVersion())
+ sdkVersionInt, err := strconv.Atoi(mod.SdkVersion())
minSdkVersionInt, err2 := strconv.Atoi(ver)
if err == nil && err2 == nil {
if sdkVersionInt < minSdkVersionInt {
@@ -1709,6 +1736,14 @@
return ver
}
+func (ctx *moduleContextImpl) minSdkVersion() string {
+ platformSdkVersion := ""
+ if ctx.ctx.Device() {
+ platformSdkVersion = ctx.ctx.Config().PlatformSdkVersion().String()
+ }
+ return MinSdkVersion(ctx.mod, CtxIsForPlatform(ctx.ctx), ctx.ctx.Device(), platformSdkVersion)
+}
+
func (ctx *moduleContextImpl) isSdkVariant() bool {
return ctx.mod.IsSdkVariant()
}
@@ -1772,8 +1807,8 @@
return ctx.mod.BaseModuleName()
}
-func (ctx *moduleContextImpl) isForPlatform() bool {
- apexInfo, _ := android.ModuleProvider(ctx.ctx, android.ApexInfoProvider)
+func CtxIsForPlatform(ctx android.BaseModuleContext) bool {
+ apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
return apexInfo.IsForPlatform()
}
@@ -1782,10 +1817,6 @@
return apexInfo.ApexVariationName
}
-func (ctx *moduleContextImpl) apexSdkVersion() android.ApiLevel {
- return ctx.mod.apexSdkVersion
-}
-
func (ctx *moduleContextImpl) bootstrap() bool {
return ctx.mod.Bootstrap()
}
@@ -1800,9 +1831,9 @@
func (ctx *moduleContextImpl) getSharedFlags() *SharedFlags {
shared := &ctx.mod.sharedFlags
- if shared.flagsMap == nil {
- shared.numSharedFlags = 0
- shared.flagsMap = make(map[string]string)
+ if shared.FlagsMap == nil {
+ shared.NumSharedFlags = 0
+ shared.FlagsMap = make(map[string]string)
}
return shared
}
@@ -1866,6 +1897,14 @@
return name
}
+func (c *Module) Multilib() string {
+ return c.Arch().ArchType.Multilib
+}
+
+func (c *Module) ApexSdkVersion() android.ApiLevel {
+ return c.apexSdkVersion
+}
+
func (c *Module) Symlinks() []string {
if p, ok := c.installer.(interface {
symlinkList() []string
@@ -2223,8 +2262,8 @@
}
linkableInfo := CreateCommonLinkableInfo(c)
- if lib, ok := c.linker.(versionedInterface); ok {
- linkableInfo.StubsVersion = lib.stubsVersion()
+ if lib, ok := c.linker.(VersionedInterface); ok {
+ linkableInfo.StubsVersion = lib.StubsVersion()
}
if c.linker != nil {
if library, ok := c.linker.(libraryInterface); ok {
@@ -2290,14 +2329,14 @@
SnapshotAndroidMkSuffix: s.SnapshotAndroidMkSuffix(),
}
}
- if v, ok := c.linker.(versionedInterface); ok {
- name := v.implementationModuleName(ctx.OtherModuleName(c))
+ if v, ok := c.linker.(VersionedInterface); ok {
+ name := v.ImplementationModuleName(ctx.OtherModuleName(c))
ccInfo.LinkerInfo.ImplementationModuleName = &name
}
}
if c.library != nil {
ccInfo.LibraryInfo = &LibraryInfo{
- BuildStubs: c.library.buildStubs(),
+ BuildStubs: c.library.BuildStubs(),
}
}
android.SetProvider(ctx, CcInfoProvider, &ccInfo)
@@ -2309,7 +2348,7 @@
}
}
-func CreateCommonLinkableInfo(mod LinkableInterface) *LinkableInfo {
+func CreateCommonLinkableInfo(mod VersionedLinkableInterface) *LinkableInfo {
return &LinkableInfo{
StaticExecutable: mod.StaticExecutable(),
HasStubsVariants: mod.HasStubsVariants(),
@@ -2332,6 +2371,8 @@
OnlyInRecovery: mod.OnlyInRecovery(),
Installable: mod.Installable(),
RelativeInstallPath: mod.RelativeInstallPath(),
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
+ RustApexExclude: mod.RustApexExclude(),
}
}
@@ -2465,7 +2506,7 @@
c.orderfile.begin(ctx)
}
if ctx.useSdk() && c.IsSdkVariant() {
- version, err := nativeApiLevelFromUser(ctx, ctx.sdkVersion())
+ version, err := NativeApiLevelFromUser(ctx, ctx.sdkVersion())
if err != nil {
ctx.PropertyErrorf("sdk_version", err.Error())
c.Properties.Sdk_version = nil
@@ -2979,6 +3020,7 @@
// Recovery code is not NDK
return
}
+ // Change this to LinkableInterface if Rust gets NDK support, which stubDecorators are for
if c, ok := to.(*Module); ok {
if c.StubDecorator() {
// These aren't real libraries, but are the stub shared libraries that are included in
@@ -3085,7 +3127,7 @@
if depTag == staticVariantTag {
return false
}
- if depTag == stubImplDepTag {
+ if depTag == StubImplDepTag {
return false
}
if depTag == android.RequiredDepTag {
@@ -3116,7 +3158,7 @@
}
if module, ok := ctx.Module().(*Module); ok {
if lib, ok := module.linker.(*libraryDecorator); ok && lib.shared() {
- if lib.hasLLNDKStubs() {
+ if lib.HasLLNDKStubs() {
ctx.WalkDeps(check)
}
}
@@ -3254,7 +3296,7 @@
// The reuseObjTag dependency still exists because the LinkageMutator runs before the
// version mutator, so the stubs variant is created from the shared variant that
// already has the reuseObjTag dependency on the static variant.
- if !c.library.buildStubs() {
+ if !c.library.BuildStubs() {
staticAnalogue, _ := android.OtherModuleProvider(ctx, dep, StaticLibraryInfoProvider)
objs := staticAnalogue.ReuseObjects
depPaths.Objs = depPaths.Objs.Append(objs)
@@ -3325,9 +3367,12 @@
depFile = sharedLibraryInfo.TableOfContents
if !sharedLibraryInfo.IsStubs {
- depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
- if info, ok := android.OtherModuleProvider(ctx, dep, ImplementationDepInfoProvider); ok {
- depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ // TODO(b/362509506): remove this additional check once all apex_exclude uses are switched to stubs.
+ if !linkableInfo.RustApexExclude {
+ depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
+ if info, ok := android.OtherModuleProvider(ctx, dep, ImplementationDepInfoProvider); ok {
+ depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ }
}
}
@@ -3820,6 +3865,10 @@
return false
}
+func (c *Module) ForceDisableSanitizers() {
+ c.sanitize.Properties.ForceDisable = true
+}
+
func (c *Module) StaticExecutable() bool {
if b, ok := c.linker.(*binaryDecorator); ok {
return b.static()
@@ -3875,7 +3924,7 @@
if lib := c.library; lib != nil {
// Stub libs and prebuilt libs in a versioned SDK are not
// installable to APEX even though they are shared libs.
- return lib.shared() && !lib.buildStubs()
+ return lib.shared() && !lib.BuildStubs()
}
return false
}
@@ -3951,7 +4000,7 @@
// Implements android.ApexModule
func (c *Module) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
- if depTag == stubImplDepTag {
+ if depTag == StubImplDepTag {
// We don't track from an implementation library to its stubs.
return false
}
diff --git a/cc/compiler.go b/cc/compiler.go
index f2bced1..3730bbe 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -360,6 +360,29 @@
}
}
+func AddTargetFlags(ctx android.ModuleContext, flags Flags, tc config.Toolchain, version string, bpf bool) Flags {
+ target := "-target " + tc.ClangTriple()
+ if ctx.Os().Class == android.Device {
+ if version == "" || version == "current" {
+ target += strconv.Itoa(android.FutureApiLevelInt)
+ } else {
+ apiLevel := nativeApiLevelOrPanic(ctx, version)
+ target += strconv.Itoa(apiLevel.FinalOrFutureInt())
+ }
+ }
+
+ // bpf targets don't need the default target triple. b/308826679
+ if bpf {
+ target = "--target=bpf"
+ }
+
+ flags.Global.CFlags = append(flags.Global.CFlags, target)
+ flags.Global.AsFlags = append(flags.Global.AsFlags, target)
+ flags.Global.LdFlags = append(flags.Global.LdFlags, target)
+
+ return flags
+}
+
// Create a Flags struct that collects the compile flags from global values,
// per-target values, module type values, and per-module Blueprints properties
func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
@@ -513,25 +536,7 @@
flags.Local.ConlyFlags = config.ClangFilterUnknownCflags(flags.Local.ConlyFlags)
flags.Local.LdFlags = config.ClangFilterUnknownCflags(flags.Local.LdFlags)
- target := "-target " + tc.ClangTriple()
- if ctx.Os().Class == android.Device {
- version := ctx.minSdkVersion()
- if version == "" || version == "current" {
- target += strconv.Itoa(android.FutureApiLevelInt)
- } else {
- apiLevel := nativeApiLevelOrPanic(ctx, version)
- target += strconv.Itoa(apiLevel.FinalOrFutureInt())
- }
- }
-
- // bpf targets don't need the default target triple. b/308826679
- if proptools.Bool(compiler.Properties.Bpf_target) {
- target = "--target=bpf"
- }
-
- flags.Global.CFlags = append(flags.Global.CFlags, target)
- flags.Global.AsFlags = append(flags.Global.AsFlags, target)
- flags.Global.LdFlags = append(flags.Global.LdFlags, target)
+ flags = AddTargetFlags(ctx, flags, tc, ctx.minSdkVersion(), Bool(compiler.Properties.Bpf_target))
hod := "Host"
if ctx.Os().Class == android.Device {
@@ -785,7 +790,7 @@
objs := compileObjs(ctx, buildFlags, "", srcs,
append(android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_disabled_srcs), compiler.generatedSources...),
android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_timeout_srcs),
- pathDeps, compiler.cFlagsDeps)
+ pathDeps, compiler.cFlagsDeps, ctx.getSharedFlags())
if ctx.Failed() {
return Objects{}
@@ -795,10 +800,12 @@
}
// Compile a list of source files into objects a specified subdirectory
-func compileObjs(ctx ModuleContext, flags builderFlags, subdir string,
- srcFiles, noTidySrcs, timeoutTidySrcs, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
+func compileObjs(ctx android.ModuleContext, flags builderFlags, subdir string,
+ srcFiles, noTidySrcs, timeoutTidySrcs, pathDeps android.Paths, cFlagsDeps android.Paths,
+ sharedFlags *SharedFlags) Objects {
- return transformSourceToObj(ctx, subdir, srcFiles, noTidySrcs, timeoutTidySrcs, flags, pathDeps, cFlagsDeps)
+ return transformSourceToObj(ctx, subdir, srcFiles, noTidySrcs, timeoutTidySrcs, flags, pathDeps, cFlagsDeps,
+ sharedFlags)
}
// Properties for rust_bindgen related to generating rust bindings.
diff --git a/cc/coverage.go b/cc/coverage.go
index dbb424f..c8ff82b 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -354,10 +354,10 @@
}
}
-func parseSymbolFileForAPICoverage(ctx ModuleContext, symbolFile string) android.ModuleOutPath {
+func ParseSymbolFileForAPICoverage(ctx android.ModuleContext, symbolFile string) android.ModuleOutPath {
apiLevelsJson := android.GetApiLevelsJson(ctx)
symbolFilePath := android.PathForModuleSrc(ctx, symbolFile)
- outputFile := ctx.baseModuleName() + ".xml"
+ outputFile := ctx.Module().(LinkableInterface).BaseModuleName() + ".xml"
parsedApiCoveragePath := android.PathForModuleOut(ctx, outputFile)
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 056b0da..a8e4cb7 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -244,7 +244,7 @@
// libraries must be handled differently - by looking for the stubDecorator.
// Discard LLNDK prebuilts stubs as well.
if hasCcInfo {
- if ccInfo.LinkerInfo.StubDecoratorInfo != nil {
+ if ccInfo.LinkerInfo != nil && ccInfo.LinkerInfo.StubDecoratorInfo != nil {
return false
}
// Discard installable:false libraries because they are expected to be absent
diff --git a/cc/library.go b/cc/library.go
index 0566182..950ea91 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -25,6 +25,7 @@
"sync"
"android/soong/android"
+ "android/soong/cc/config"
"github.com/google/blueprint"
"github.com/google/blueprint/depset"
@@ -64,21 +65,7 @@
Static_ndk_lib *bool
// Generate stubs to make this library accessible to APEXes.
- Stubs struct {
- // Relative path to the symbol map. The symbol map provides the list of
- // symbols that are exported for stubs variant of this library.
- Symbol_file *string `android:"path,arch_variant"`
-
- // List versions to generate stubs libs for. The version name "current" is always
- // implicitly added.
- Versions []string
-
- // Whether to not require the implementation of the library to be installed if a
- // client of the stubs is installed. Defaults to true; set to false if the
- // implementation is made available by some other means, e.g. in a Microdroid
- // virtual machine.
- Implementation_installable *bool
- } `android:"arch_variant"`
+ Stubs StubsProperties `android:"arch_variant"`
// set the name of the output
Stem *string `android:"arch_variant"`
@@ -127,6 +114,22 @@
Vendor_public_library vendorPublicLibraryProperties
}
+type StubsProperties struct {
+ // Relative path to the symbol map. The symbol map provides the list of
+ // symbols that are exported for stubs variant of this library.
+ Symbol_file *string `android:"path,arch_variant"`
+
+ // List versions to generate stubs libs for. The version name "current" is always
+ // implicitly added.
+ Versions []string
+
+ // Whether to not require the implementation of the library to be installed if a
+ // client of the stubs is installed. Defaults to true; set to false if the
+ // implementation is made available by some other means, e.g. in a Microdroid
+ // virtual machine.
+ Implementation_installable *bool
+}
+
// StaticProperties is a properties stanza to affect only attributes of the "static" variants of a
// library module.
type StaticProperties struct {
@@ -457,11 +460,15 @@
return props
}
-// linkerFlags takes a Flags struct and augments it to contain linker flags that are defined by this
-// library, or that are implied by attributes of this library (such as whether this library is a
-// shared library).
-func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
- flags = library.baseLinker.linkerFlags(ctx, flags)
+func CommonLibraryLinkerFlags(ctx android.ModuleContext, flags Flags,
+ toolchain config.Toolchain, libName string) Flags {
+
+ mod, ok := ctx.Module().(LinkableInterface)
+
+ if !ok {
+ ctx.ModuleErrorf("trying to add linker flags to a non-LinkableInterface module.")
+ return flags
+ }
// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
// all code is position independent, and then those warnings get promoted to
@@ -469,27 +476,18 @@
if !ctx.Windows() {
flags.Global.CFlags = append(flags.Global.CFlags, "-fPIC")
}
-
- if library.static() {
- flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags.GetOrDefault(ctx, nil)...)
- } else if library.shared() {
- flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags.GetOrDefault(ctx, nil)...)
- }
-
- if library.shared() {
- libName := library.getLibName(ctx)
+ if mod.Shared() {
var f []string
- if ctx.toolchain().Bionic() {
+ if toolchain.Bionic() {
f = append(f,
"-nostdlib",
"-Wl,--gc-sections",
)
}
-
if ctx.Darwin() {
f = append(f,
"-dynamiclib",
- "-install_name @rpath/"+libName+flags.Toolchain.ShlibSuffix(),
+ "-install_name @rpath/"+libName+toolchain.ShlibSuffix(),
)
if ctx.Arch().ArchType == android.X86 {
f = append(f,
@@ -499,16 +497,30 @@
} else {
f = append(f, "-shared")
if !ctx.Windows() {
- f = append(f, "-Wl,-soname,"+libName+flags.Toolchain.ShlibSuffix())
+ f = append(f, "-Wl,-soname,"+libName+toolchain.ShlibSuffix())
}
}
-
flags.Global.LdFlags = append(flags.Global.LdFlags, f...)
}
return flags
}
+// linkerFlags takes a Flags struct and augments it to contain linker flags that are defined by this
+// library, or that are implied by attributes of this library (such as whether this library is a
+// shared library).
+func (library *libraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
+ flags = library.baseLinker.linkerFlags(ctx, flags)
+ flags = CommonLibraryLinkerFlags(ctx, flags, ctx.toolchain(), library.getLibName(ctx))
+ if library.static() {
+ flags.Local.CFlags = append(flags.Local.CFlags, library.StaticProperties.Static.Cflags.GetOrDefault(ctx, nil)...)
+ } else if library.shared() {
+ flags.Local.CFlags = append(flags.Local.CFlags, library.SharedProperties.Shared.Cflags.GetOrDefault(ctx, nil)...)
+ }
+
+ return flags
+}
+
// compilerFlags takes a Flags and augments it to contain compile flags from global values,
// per-target values, module type values, per-module Blueprints properties, extra flags from
// `flags`, and generated sources from `deps`.
@@ -527,7 +539,7 @@
// Wipe all the module-local properties, leaving only the global properties.
flags.Local = LocalOrGlobalFlags{}
}
- if library.buildStubs() {
+ if library.BuildStubs() {
// Remove -include <file> when compiling stubs. Otherwise, the force included
// headers might cause conflicting types error with the symbols in the
// generated stubs source code. e.g.
@@ -546,7 +558,7 @@
flags.Local.CommonFlags = removeInclude(flags.Local.CommonFlags)
flags.Local.CFlags = removeInclude(flags.Local.CFlags)
- flags = addStubLibraryCompilerFlags(flags)
+ flags = AddStubLibraryCompilerFlags(flags)
}
return flags
}
@@ -567,6 +579,8 @@
}
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
+ sharedFlags := ctx.getSharedFlags()
+
if ctx.IsLlndk() {
// Get the matching SDK version for the vendor API level.
version, err := android.GetSdkVersionForVendorApiLevel(ctx.Config().VendorApiLevel())
@@ -575,27 +589,27 @@
}
// This is the vendor variant of an LLNDK library, build the LLNDK stubs.
- nativeAbiResult := parseNativeAbiDefinition(ctx,
+ nativeAbiResult := ParseNativeAbiDefinition(ctx,
String(library.Properties.Llndk.Symbol_file),
nativeClampedApiLevel(ctx, version), "--llndk")
- objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
+ objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, sharedFlags)
if !Bool(library.Properties.Llndk.Unversioned) {
library.versionScriptPath = android.OptionalPathForPath(
- nativeAbiResult.versionScript)
+ nativeAbiResult.VersionScript)
}
return objs
}
if ctx.IsVendorPublicLibrary() {
- nativeAbiResult := parseNativeAbiDefinition(ctx,
+ nativeAbiResult := ParseNativeAbiDefinition(ctx,
String(library.Properties.Vendor_public_library.Symbol_file),
android.FutureApiLevel, "")
- objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
+ objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, sharedFlags)
if !Bool(library.Properties.Vendor_public_library.Unversioned) {
- library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.versionScript)
+ library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.VersionScript)
}
return objs
}
- if library.buildStubs() {
+ if library.BuildStubs() {
return library.compileModuleLibApiStubs(ctx, flags, deps)
}
@@ -635,18 +649,65 @@
objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary, srcs,
android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_disabled_srcs),
android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_timeout_srcs),
- library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
+ library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps, sharedFlags))
} else if library.shared() {
srcs := android.PathsForModuleSrc(ctx, sharedSrcs)
objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary, srcs,
android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_disabled_srcs),
android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_timeout_srcs),
- library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
+ library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps, sharedFlags))
}
return objs
}
+type ApiStubsParams struct {
+ NotInPlatform bool
+ IsNdk bool
+ BaseModuleName string
+ ModuleName string
+}
+
+// GetApiStubsFlags calculates the genstubFlags string to pass to ParseNativeAbiDefinition
+func GetApiStubsFlags(api ApiStubsParams) string {
+ var flag string
+
+ // b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
+ // systemapi, respectively. The former is for symbols defined in platform libraries
+ // and the latter is for symbols defined in APEXes.
+ // A single library can contain either # apex or # systemapi, but not both.
+ // The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op.
+ // However, having this distinction helps guard accidental
+ // promotion or demotion of API and also helps the API review process b/191371676
+ if api.NotInPlatform {
+ flag = "--apex"
+ } else {
+ flag = "--systemapi"
+ }
+
+ // b/184712170, unless the lib is an NDK library, exclude all public symbols from
+ // the stub so that it is mandated that all symbols are explicitly marked with
+ // either apex or systemapi.
+ if !api.IsNdk &&
+ // the symbol files of libclang libs are autogenerated and do not contain systemapi tags
+ // TODO (spandandas): Update mapfile.py to include #systemapi tag on all symbols
+ !strings.Contains(api.ModuleName, "libclang_rt") {
+ flag = flag + " --no-ndk"
+ }
+
+ // TODO(b/361303067): Remove this special case if bionic/ projects are added to ART development branches.
+ if isBionic(api.BaseModuleName) {
+ // set the flags explicitly for bionic libs.
+ // this is necessary for development in minimal branches which does not contain bionic/*.
+ // In such minimal branches, e.g. on the prebuilt libc stubs
+ // 1. IsNdk will return false (since the ndk_library definition for libc does not exist)
+ // 2. NotInPlatform will return true (since the source com.android.runtime does not exist)
+ flag = "--apex"
+ }
+
+ return flag
+}
+
// Compile stubs for the API surface between platform and apex
// This method will be used by source and prebuilt cc module types.
func (library *libraryDecorator) compileModuleLibApiStubs(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
@@ -654,56 +715,34 @@
if library.Properties.Stubs.Symbol_file == nil {
return Objects{}
}
+
symbolFile := String(library.Properties.Stubs.Symbol_file)
library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
- // b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
- // systemapi, respectively. The former is for symbols defined in platform libraries
- // and the latter is for symbols defined in APEXes.
- // A single library can contain either # apex or # systemapi, but not both.
- // The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op.
- // However, having this distinction helps guard accidental
- // promotion or demotion of API and also helps the API review process b/191371676
- var flag string
- if ctx.notInPlatform() {
- flag = "--apex"
- } else {
- flag = "--systemapi"
+
+ apiParams := ApiStubsParams{
+ NotInPlatform: ctx.notInPlatform(),
+ IsNdk: ctx.Module().(*Module).IsNdk(ctx.Config()),
+ BaseModuleName: ctx.baseModuleName(),
+ ModuleName: ctx.ModuleName(),
}
- // b/184712170, unless the lib is an NDK library, exclude all public symbols from
- // the stub so that it is mandated that all symbols are explicitly marked with
- // either apex or systemapi.
- if !ctx.Module().(*Module).IsNdk(ctx.Config()) &&
- // the symbol files of libclang libs are autogenerated and do not contain systemapi tags
- // TODO (spandandas): Update mapfile.py to include #systemapi tag on all symbols
- !strings.Contains(ctx.ModuleName(), "libclang_rt") {
- flag = flag + " --no-ndk"
- }
- // TODO(b/361303067): Remove this special case if bionic/ projects are added to ART development branches.
- if isBionic(ctx.baseModuleName()) {
- // set the flags explicitly for bionic libs.
- // this is necessary for development in minimal branches which does not contain bionic/*.
- // In such minimal branches, e.g. on the prebuilt libc stubs
- // 1. IsNdk will return false (since the ndk_library definition for libc does not exist)
- // 2. NotInPlatform will return true (since the source com.android.runtime does not exist)
- flag = "--apex"
- }
- nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
+ flag := GetApiStubsFlags(apiParams)
+
+ nativeAbiResult := ParseNativeAbiDefinition(ctx, symbolFile,
android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
- objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
+ objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, ctx.getSharedFlags())
library.versionScriptPath = android.OptionalPathForPath(
- nativeAbiResult.versionScript)
-
+ nativeAbiResult.VersionScript)
// Parse symbol file to get API list for coverage
- if library.stubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
- library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
+ if library.StubsVersion() == "current" && ctx.PrimaryArch() && !ctx.inRecovery() && !ctx.inProduct() && !ctx.inVendor() {
+ library.apiListCoverageXmlPath = ParseSymbolFileForAPICoverage(ctx, symbolFile)
}
return objs
}
type libraryInterface interface {
- versionedInterface
+ VersionedInterface
static() bool
shared() bool
@@ -727,32 +766,49 @@
apexAvailable() []string
- getAPIListCoverageXMLPath() android.ModuleOutPath
+ setAPIListCoverageXMLPath(out android.ModuleOutPath)
+ symbolsFile() *string
+ setSymbolFilePath(path android.Path)
+ setVersionScriptPath(path android.OptionalPath)
installable() *bool
}
-type versionedInterface interface {
- buildStubs() bool
- setBuildStubs(isLatest bool)
- hasStubsVariants() bool
- isStubsImplementationRequired() bool
- setStubsVersion(string)
- stubsVersion() string
+func (library *libraryDecorator) symbolsFile() *string {
+ return library.Properties.Stubs.Symbol_file
+}
- stubsVersions(ctx android.BaseModuleContext) []string
- setAllStubsVersions([]string)
- allStubsVersions() []string
+func (library *libraryDecorator) setSymbolFilePath(path android.Path) {
+ library.stubsSymbolFilePath = path
+}
- implementationModuleName(name string) string
- hasLLNDKStubs() bool
- hasLLNDKHeaders() bool
- hasVendorPublicLibrary() bool
- isLLNDKMovedToApex() bool
+func (library *libraryDecorator) setVersionScriptPath(path android.OptionalPath) {
+ library.versionScriptPath = path
+}
+
+type VersionedInterface interface {
+ BuildStubs() bool
+ SetBuildStubs(isLatest bool)
+ HasStubsVariants() bool
+ IsStubsImplementationRequired() bool
+ SetStubsVersion(string)
+ StubsVersion() string
+
+ StubsVersions(ctx android.BaseModuleContext) []string
+ SetAllStubsVersions([]string)
+ AllStubsVersions() []string
+
+ ImplementationModuleName(name string) string
+ HasLLNDKStubs() bool
+ HasLLNDKHeaders() bool
+ HasVendorPublicLibrary() bool
+ IsLLNDKMovedToApex() bool
+
+ GetAPIListCoverageXMLPath() android.ModuleOutPath
}
var _ libraryInterface = (*libraryDecorator)(nil)
-var _ versionedInterface = (*libraryDecorator)(nil)
+var _ VersionedInterface = (*libraryDecorator)(nil)
func (library *libraryDecorator) getLibNameHelper(baseModuleName string, inVendor bool, inProduct bool) string {
name := library.libName
@@ -801,9 +857,9 @@
library.baseLinker.linkerInit(ctx)
// Let baseLinker know whether this variant is for stubs or not, so that
// it can omit things that are not required for linking stubs.
- library.baseLinker.dynamicProperties.BuildStubs = library.buildStubs()
+ library.baseLinker.dynamicProperties.BuildStubs = library.BuildStubs()
- if library.buildStubs() {
+ if library.BuildStubs() {
macroNames := versioningMacroNamesList(ctx.Config())
myName := versioningMacroName(ctx.ModuleName())
versioningMacroNamesListMutex.Lock()
@@ -962,8 +1018,8 @@
moduleInfoJSON.Uninstallable = true
}
- if library.buildStubs() && library.stubsVersion() != "" {
- moduleInfoJSON.SubName += "." + library.stubsVersion()
+ if library.BuildStubs() && library.StubsVersion() != "" {
+ moduleInfoJSON.SubName += "." + library.StubsVersion()
}
// If a library providing a stub is included in an APEX, the private APIs of the library
@@ -974,10 +1030,10 @@
// very early stage in the boot process).
if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.notInPlatform() &&
!ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && !ctx.useVndk() && !ctx.static() {
- if library.buildStubs() && library.isLatestStubVersion() {
+ if library.BuildStubs() && library.isLatestStubVersion() {
moduleInfoJSON.SubName = ""
}
- if !library.buildStubs() {
+ if !library.BuildStubs() {
moduleInfoJSON.SubName = ".bootstrap"
}
}
@@ -1120,7 +1176,7 @@
stripFlags := flagsToStripFlags(flags)
needsStrip := library.stripper.NeedsStrip(ctx)
- if library.buildStubs() {
+ if library.BuildStubs() {
// No need to strip stubs libraries
needsStrip = false
}
@@ -1174,7 +1230,7 @@
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
- if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil && !library.buildStubs() {
+ if generatedLib := generateRustStaticlib(ctx, deps.RustRlibDeps); generatedLib != nil && !library.BuildStubs() {
if ctx.Module().(*Module).WholeRustStaticlib {
deps.WholeStaticLibs = append(deps.WholeStaticLibs, generatedLib)
} else {
@@ -1205,18 +1261,18 @@
SharedLibrary: unstrippedOutputFile,
TransitiveStaticLibrariesForOrdering: transitiveStaticLibrariesForOrdering,
Target: ctx.Target(),
- IsStubs: library.buildStubs(),
+ IsStubs: library.BuildStubs(),
})
- addStubDependencyProviders(ctx)
+ AddStubDependencyProviders(ctx)
return unstrippedOutputFile
}
// Visits the stub variants of the library and returns a struct containing the stub .so paths
-func addStubDependencyProviders(ctx ModuleContext) []SharedStubLibrary {
+func AddStubDependencyProviders(ctx android.BaseModuleContext) []SharedStubLibrary {
stubsInfo := []SharedStubLibrary{}
- stubs := ctx.GetDirectDepsProxyWithTag(stubImplDepTag)
+ stubs := ctx.GetDirectDepsProxyWithTag(StubImplDepTag)
if len(stubs) > 0 {
for _, stub := range stubs {
stubInfo, ok := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
@@ -1237,10 +1293,11 @@
if len(stubsInfo) > 0 {
android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{
SharedStubLibraries: stubsInfo,
- IsLLNDK: ctx.IsLlndk(),
+ IsLLNDK: ctx.Module().(LinkableInterface).IsLlndk(),
})
}
}
+
return stubsInfo
}
@@ -1257,7 +1314,7 @@
}
func (library *libraryDecorator) nativeCoverage() bool {
- if library.header() || library.buildStubs() {
+ if library.header() || library.BuildStubs() {
return false
}
return true
@@ -1726,9 +1783,9 @@
}
func (library *libraryDecorator) exportVersioningMacroIfNeeded(ctx android.BaseModuleContext) {
- if library.buildStubs() && library.stubsVersion() != "" && !library.skipAPIDefine {
+ if library.BuildStubs() && library.StubsVersion() != "" && !library.skipAPIDefine {
name := versioningMacroName(ctx.Module().(*Module).ImplementationModuleName(ctx))
- apiLevel, err := android.ApiLevelFromUser(ctx, library.stubsVersion())
+ apiLevel, err := android.ApiLevelFromUser(ctx, library.StubsVersion())
if err != nil {
ctx.ModuleErrorf("Can't export version macro: %s", err.Error())
}
@@ -1780,8 +1837,8 @@
func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
if library.shared() {
translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
- if library.hasStubsVariants() && !ctx.Host() && !ctx.isSdkVariant() &&
- InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() &&
+ if library.HasStubsVariants() && !ctx.Host() && !ctx.isSdkVariant() &&
+ InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.BuildStubs() &&
!translatedArch && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() {
// Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory.
// The original path becomes a symlink to the corresponding file in the
@@ -1798,7 +1855,7 @@
if Bool(library.Properties.Static_ndk_lib) && library.static() &&
!ctx.InVendorOrProduct() && !ctx.inRamdisk() && !ctx.inVendorRamdisk() && !ctx.inRecovery() && ctx.Device() &&
library.baseLinker.sanitize.isUnsanitizedVariant() &&
- ctx.isForPlatform() && !ctx.isPreventInstall() {
+ CtxIsForPlatform(ctx) && !ctx.isPreventInstall() {
installPath := getUnversionedLibraryInstallPath(ctx).Join(ctx, file.Base())
ctx.ModuleBuild(pctx, android.ModuleBuildParams{
@@ -1868,32 +1925,32 @@
library.MutatedProperties.BuildStatic = false
}
-// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
-func (library *libraryDecorator) hasLLNDKStubs() bool {
+// HasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
+func (library *libraryDecorator) HasLLNDKStubs() bool {
return String(library.Properties.Llndk.Symbol_file) != ""
}
// hasLLNDKStubs returns true if this cc_library module has a variant that will build LLNDK stubs.
-func (library *libraryDecorator) hasLLNDKHeaders() bool {
+func (library *libraryDecorator) HasLLNDKHeaders() bool {
return Bool(library.Properties.Llndk.Llndk_headers)
}
-// isLLNDKMovedToApex returns true if this cc_library module sets the llndk.moved_to_apex property.
-func (library *libraryDecorator) isLLNDKMovedToApex() bool {
+// IsLLNDKMovedToApex returns true if this cc_library module sets the llndk.moved_to_apex property.
+func (library *libraryDecorator) IsLLNDKMovedToApex() bool {
return Bool(library.Properties.Llndk.Moved_to_apex)
}
-// hasVendorPublicLibrary returns true if this cc_library module has a variant that will build
+// HasVendorPublicLibrary returns true if this cc_library module has a variant that will build
// vendor public library stubs.
-func (library *libraryDecorator) hasVendorPublicLibrary() bool {
+func (library *libraryDecorator) HasVendorPublicLibrary() bool {
return String(library.Properties.Vendor_public_library.Symbol_file) != ""
}
-func (library *libraryDecorator) implementationModuleName(name string) string {
+func (library *libraryDecorator) ImplementationModuleName(name string) string {
return name
}
-func (library *libraryDecorator) buildStubs() bool {
+func (library *libraryDecorator) BuildStubs() bool {
return library.MutatedProperties.BuildStubs
}
@@ -1901,7 +1958,7 @@
if props := library.getHeaderAbiCheckerProperties(ctx.Module().(*Module)); props.Symbol_file != nil {
return props.Symbol_file
}
- if library.hasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
+ if library.HasStubsVariants() && library.Properties.Stubs.Symbol_file != nil {
return library.Properties.Stubs.Symbol_file
}
// TODO(b/309880485): Distinguish platform, NDK, LLNDK, and APEX version scripts.
@@ -1911,35 +1968,35 @@
return nil
}
-func (library *libraryDecorator) hasStubsVariants() bool {
+func (library *libraryDecorator) HasStubsVariants() bool {
// Just having stubs.symbol_file is enough to create a stub variant. In that case
// the stub for the future API level is created.
return library.Properties.Stubs.Symbol_file != nil ||
len(library.Properties.Stubs.Versions) > 0
}
-func (library *libraryDecorator) isStubsImplementationRequired() bool {
+func (library *libraryDecorator) IsStubsImplementationRequired() bool {
return BoolDefault(library.Properties.Stubs.Implementation_installable, true)
}
-func (library *libraryDecorator) stubsVersions(ctx android.BaseModuleContext) []string {
- if !library.hasStubsVariants() {
+func (library *libraryDecorator) StubsVersions(ctx android.BaseModuleContext) []string {
+ if !library.HasStubsVariants() {
return nil
}
- if library.hasLLNDKStubs() && ctx.Module().(*Module).InVendorOrProduct() {
+ if library.HasLLNDKStubs() && ctx.Module().(*Module).InVendorOrProduct() {
// LLNDK libraries only need a single stubs variant (""), which is
// added automatically in createVersionVariations().
return nil
}
// Future API level is implicitly added if there isn't
- versions := addCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
- normalizeVersions(ctx, versions)
+ versions := AddCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
+ NormalizeVersions(ctx, versions)
return versions
}
-func addCurrentVersionIfNotPresent(vers []string) []string {
+func AddCurrentVersionIfNotPresent(vers []string) []string {
if inList(android.FutureApiLevel.String(), vers) {
return vers
}
@@ -1952,24 +2009,24 @@
return append(vers, android.FutureApiLevel.String())
}
-func (library *libraryDecorator) setStubsVersion(version string) {
+func (library *libraryDecorator) SetStubsVersion(version string) {
library.MutatedProperties.StubsVersion = version
}
-func (library *libraryDecorator) stubsVersion() string {
+func (library *libraryDecorator) StubsVersion() string {
return library.MutatedProperties.StubsVersion
}
-func (library *libraryDecorator) setBuildStubs(isLatest bool) {
+func (library *libraryDecorator) SetBuildStubs(isLatest bool) {
library.MutatedProperties.BuildStubs = true
library.MutatedProperties.IsLatestVersion = isLatest
}
-func (library *libraryDecorator) setAllStubsVersions(versions []string) {
+func (library *libraryDecorator) SetAllStubsVersions(versions []string) {
library.MutatedProperties.AllStubsVersions = versions
}
-func (library *libraryDecorator) allStubsVersions() []string {
+func (library *libraryDecorator) AllStubsVersions() []string {
return library.MutatedProperties.AllStubsVersions
}
@@ -1998,7 +2055,7 @@
}
func (library *libraryDecorator) makeUninstallable(mod *Module) {
- if library.static() && library.buildStatic() && !library.buildStubs() {
+ if library.static() && library.buildStatic() && !library.BuildStubs() {
// If we're asked to make a static library uninstallable we don't do
// anything since AndroidMkEntries always sets LOCAL_UNINSTALLABLE_MODULE
// for these entries. This is done to still get the make targets for NOTICE
@@ -2012,10 +2069,14 @@
return library.path.Partition()
}
-func (library *libraryDecorator) getAPIListCoverageXMLPath() android.ModuleOutPath {
+func (library *libraryDecorator) GetAPIListCoverageXMLPath() android.ModuleOutPath {
return library.apiListCoverageXmlPath
}
+func (library *libraryDecorator) setAPIListCoverageXMLPath(xml android.ModuleOutPath) {
+ library.apiListCoverageXmlPath = xml
+}
+
func (library *libraryDecorator) overriddenModules() []string {
return library.Properties.Overrides
}
@@ -2242,10 +2303,10 @@
}
}
-// normalizeVersions modifies `versions` in place, so that each raw version
+// NormalizeVersions modifies `versions` in place, so that each raw version
// string becomes its normalized canonical form.
// Validates that the versions in `versions` are specified in least to greatest order.
-func normalizeVersions(ctx android.BaseModuleContext, versions []string) {
+func NormalizeVersions(ctx android.BaseModuleContext, versions []string) {
var previous android.ApiLevel
for i, v := range versions {
ver, err := android.ApiLevelFromUser(ctx, v)
@@ -2262,7 +2323,7 @@
}
func perApiVersionVariations(mctx android.BaseModuleContext, minSdkVersion string) []string {
- from, err := nativeApiLevelFromUser(mctx, minSdkVersion)
+ from, err := NativeApiLevelFromUser(mctx, minSdkVersion)
if err != nil {
mctx.PropertyErrorf("min_sdk_version", err.Error())
return []string{""}
@@ -2290,25 +2351,25 @@
module.CcLibraryInterface() && module.Shared()
}
-func moduleLibraryInterface(module blueprint.Module) libraryInterface {
- if m, ok := module.(*Module); ok {
- return m.library
+func moduleVersionedInterface(module blueprint.Module) VersionedInterface {
+ if m, ok := module.(VersionedLinkableInterface); ok {
+ return m.VersionedInterface()
}
return nil
}
// setStubsVersions normalizes the versions in the Stubs.Versions property into MutatedProperties.AllStubsVersions.
-func setStubsVersions(mctx android.BaseModuleContext, library libraryInterface, module *Module) {
- if !library.buildShared() || !canBeVersionVariant(module) {
+func setStubsVersions(mctx android.BaseModuleContext, module VersionedLinkableInterface) {
+ if !module.BuildSharedVariant() || !canBeVersionVariant(module) {
return
}
- versions := library.stubsVersions(mctx)
+ versions := module.VersionedInterface().StubsVersions(mctx)
if mctx.Failed() {
return
}
// Set the versions on the pre-mutated module so they can be read by any llndk modules that
// depend on the implementation library and haven't been mutated yet.
- library.setAllStubsVersions(versions)
+ module.VersionedInterface().SetAllStubsVersions(versions)
}
// versionTransitionMutator splits a module into the mandatory non-stubs variant
@@ -2319,14 +2380,13 @@
if ctx.Os() != android.Android {
return []string{""}
}
-
- m, ok := ctx.Module().(*Module)
- if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
- setStubsVersions(ctx, library, m)
-
- return append(slices.Clone(library.allStubsVersions()), "")
- } else if ok && m.SplitPerApiLevel() && m.IsSdkVariant() {
- return perApiVersionVariations(ctx, m.MinSdkVersion())
+ if m, ok := ctx.Module().(VersionedLinkableInterface); ok {
+ if m.CcLibraryInterface() && canBeVersionVariant(m) {
+ setStubsVersions(ctx, m)
+ return append(slices.Clone(m.VersionedInterface().AllStubsVersions()), "")
+ } else if m.SplitPerApiLevel() && m.IsSdkVariant() {
+ return perApiVersionVariations(ctx, m.MinSdkVersion())
+ }
}
return []string{""}
@@ -2340,11 +2400,11 @@
if ctx.Os() != android.Android {
return ""
}
- m, ok := ctx.Module().(*Module)
- if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
+ m, ok := ctx.Module().(VersionedLinkableInterface)
+ if library := moduleVersionedInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
if incomingVariation == "latest" {
latestVersion := ""
- versions := library.allStubsVersions()
+ versions := library.AllStubsVersions()
if len(versions) > 0 {
latestVersion = versions[len(versions)-1]
}
@@ -2369,39 +2429,39 @@
return
}
- m, ok := ctx.Module().(*Module)
- if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
+ m, ok := ctx.Module().(VersionedLinkableInterface)
+ if library := moduleVersionedInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
isLLNDK := m.IsLlndk()
isVendorPublicLibrary := m.IsVendorPublicLibrary()
if variation != "" || isLLNDK || isVendorPublicLibrary {
// A stubs or LLNDK stubs variant.
- if m.sanitize != nil {
- m.sanitize.Properties.ForceDisable = true
+ if sm, ok := ctx.Module().(PlatformSanitizeable); ok && sm.SanitizePropDefined() {
+ sm.ForceDisableSanitizers()
}
- if m.stl != nil {
- m.stl.Properties.Stl = StringPtr("none")
- }
- m.Properties.PreventInstall = true
- lib := moduleLibraryInterface(m)
- allStubsVersions := library.allStubsVersions()
+ m.SetStl("none")
+ m.SetPreventInstall()
+ allStubsVersions := m.VersionedInterface().AllStubsVersions()
isLatest := len(allStubsVersions) > 0 && variation == allStubsVersions[len(allStubsVersions)-1]
- lib.setBuildStubs(isLatest)
+ m.VersionedInterface().SetBuildStubs(isLatest)
}
if variation != "" {
// A non-LLNDK stubs module is hidden from make
- library.setStubsVersion(variation)
- m.Properties.HideFromMake = true
+ m.VersionedInterface().SetStubsVersion(variation)
+ m.SetHideFromMake()
} else {
// A non-LLNDK implementation module has a dependency to all stubs versions
- for _, version := range library.allStubsVersions() {
- ctx.AddVariationDependencies([]blueprint.Variation{{"version", version}},
- stubImplDepTag, ctx.ModuleName())
+ for _, version := range m.VersionedInterface().AllStubsVersions() {
+ ctx.AddVariationDependencies(
+ []blueprint.Variation{
+ {Mutator: "version", Variation: version},
+ {Mutator: "link", Variation: "shared"}},
+ StubImplDepTag, ctx.ModuleName())
}
}
} else if ok && m.SplitPerApiLevel() && m.IsSdkVariant() {
- m.Properties.Sdk_version = StringPtr(variation)
- m.Properties.Min_sdk_version = StringPtr(variation)
+ m.SetSdkVersion(variation)
+ m.SetMinSdkVersion(variation)
}
}
@@ -2415,7 +2475,8 @@
injectBoringSSLHash := Bool(inject)
ctx.VisitDirectDepsProxy(func(dep android.ModuleProxy) {
if tag, ok := ctx.OtherModuleDependencyTag(dep).(libraryDependencyTag); ok && tag.static() {
- if ccInfo, ok := android.OtherModuleProvider(ctx, dep, CcInfoProvider); ok && ccInfo.LinkerInfo.LibraryDecoratorInfo != nil {
+ if ccInfo, ok := android.OtherModuleProvider(ctx, dep, CcInfoProvider); ok &&
+ ccInfo.LinkerInfo != nil && ccInfo.LinkerInfo.LibraryDecoratorInfo != nil {
if ccInfo.LinkerInfo.LibraryDecoratorInfo.InjectBsslHash {
injectBoringSSLHash = true
}
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index af3658d..d1440ea 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -546,7 +546,7 @@
specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx.SdkModuleContext(), ccModule, specifiedDeps)
if lib := ccModule.library; lib != nil {
- if !lib.hasStubsVariants() {
+ if !lib.HasStubsVariants() {
// Propagate dynamic dependencies for implementation libs, but not stubs.
p.SharedLibs = specifiedDeps.sharedLibs
} else {
@@ -554,8 +554,8 @@
// ccModule.StubsVersion()) if the module is versioned. 2. Ensure that all
// the versioned stub libs are retained in the prebuilt tree; currently only
// the stub corresponding to ccModule.StubsVersion() is.
- p.StubsVersions = lib.allStubsVersions()
- if lib.buildStubs() && ccModule.stubsSymbolFilePath() == nil {
+ p.StubsVersions = lib.AllStubsVersions()
+ if lib.BuildStubs() && ccModule.stubsSymbolFilePath() == nil {
ctx.ModuleErrorf("Could not determine symbol_file")
} else {
p.StubsSymbolFilePath = ccModule.stubsSymbolFilePath()
diff --git a/cc/linkable.go b/cc/linkable.go
index 78ea71c..337b459 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -53,6 +53,9 @@
// SanitizableDepTagChecker returns a SantizableDependencyTagChecker function type.
SanitizableDepTagChecker() SantizableDependencyTagChecker
+
+ // ForceDisableSanitizers sets the ForceDisable sanitize property
+ ForceDisableSanitizers()
}
// SantizableDependencyTagChecker functions check whether or not a dependency
@@ -63,6 +66,30 @@
// implementation should handle tags from both.
type SantizableDependencyTagChecker func(tag blueprint.DependencyTag) bool
+type VersionedLinkableInterface interface {
+ LinkableInterface
+ android.ApexModule
+
+ // VersionedInterface returns the VersionedInterface for this module
+ // (e.g. c.library), or nil if this is module is not a VersionedInterface.
+ VersionedInterface() VersionedInterface
+
+ // HasStubsVariants true if this module is a stub or has a sibling variant
+ // that is a stub.
+ HasStubsVariants() bool
+
+ // SetStl sets the stl property for CC modules. Does not panic if for other module types.
+ SetStl(string)
+ SetSdkVersion(string)
+ SetMinSdkVersion(version string)
+ ApexSdkVersion() android.ApiLevel
+ ImplementationModuleNameForMake(ctx android.BaseModuleContext) string
+
+ // RustApexExclude returns ApexExclude() for Rust modules; always returns false for all non-Rust modules.
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
+ RustApexExclude() bool
+}
+
// LinkableInterface is an interface for a type of module that is linkable in a C++ library.
type LinkableInterface interface {
android.Module
@@ -132,28 +159,18 @@
// IsNdk returns true if the library is in the configs known NDK list.
IsNdk(config android.Config) bool
- // HasStubsVariants true if this module is a stub or has a sibling variant
- // that is a stub.
- HasStubsVariants() bool
-
// IsStubs returns true if the this is a stubs library.
IsStubs() bool
// IsLlndk returns true for both LLNDK (public) and LLNDK-private libs.
IsLlndk() bool
- // HasLlndkStubs returns true if this library has a variant that will build LLNDK stubs.
- HasLlndkStubs() bool
-
// NeedsLlndkVariants returns true if this module has LLNDK stubs or provides LLNDK headers.
NeedsLlndkVariants() bool
// NeedsVendorPublicLibraryVariants returns true if this module has vendor public library stubs.
NeedsVendorPublicLibraryVariants() bool
- //StubsVersion returns the stubs version for this module.
- StubsVersion() string
-
// UseVndk returns true if the module is using VNDK libraries instead of the libraries in /system/lib or /system/lib64.
// "product" and "vendor" variant modules return true for this function.
// When BOARD_VNDK_VERSION is set, vendor variants of "vendor_available: true", "vendor: true",
@@ -182,6 +199,7 @@
MinSdkVersion() string
AlwaysSdk() bool
IsSdkVariant() bool
+ Multilib() string
SplitPerApiLevel() bool
@@ -250,6 +268,7 @@
// FuzzModule returns the fuzz.FuzzModule associated with the module.
FuzzModuleStruct() fuzz.FuzzModule
+ IsCrt() bool
}
var (
diff --git a/cc/linker.go b/cc/linker.go
index b96d139..f854937 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -457,7 +457,7 @@
if ctx.minSdkVersion() == "current" {
return true
}
- parsedSdkVersion, err := nativeApiLevelFromUser(ctx, ctx.minSdkVersion())
+ parsedSdkVersion, err := NativeApiLevelFromUser(ctx, ctx.minSdkVersion())
if err != nil {
ctx.PropertyErrorf("min_sdk_version",
"Invalid min_sdk_version value (must be int or current): %q",
@@ -471,16 +471,77 @@
// ModuleContext extends BaseModuleContext
// BaseModuleContext should know if LLD is used?
-func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
- toolchain := ctx.toolchain()
-
+func CommonLinkerFlags(ctx android.ModuleContext, flags Flags, useClangLld bool,
+ toolchain config.Toolchain, allow_undefined_symbols bool) Flags {
hod := "Host"
if ctx.Os().Class == android.Device {
hod = "Device"
}
- if linker.useClangLld(ctx) {
+ mod, ok := ctx.Module().(LinkableInterface)
+ if !ok {
+ ctx.ModuleErrorf("trying to add CommonLinkerFlags to non-LinkableInterface module.")
+ return flags
+ }
+ if useClangLld {
flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod))
+ } else {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod))
+ }
+
+ if allow_undefined_symbols {
+ if ctx.Darwin() {
+ // darwin defaults to treating undefined symbols as errors
+ flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-undefined,dynamic_lookup")
+ }
+ } else if !ctx.Darwin() && !ctx.Windows() {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--no-undefined")
+ }
+
+ if useClangLld {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Lldflags())
+ } else {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Ldflags())
+ }
+
+ if !toolchain.Bionic() && ctx.Os() != android.LinuxMusl {
+ if !ctx.Windows() {
+ // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device
+ // builds
+ flags.Global.LdFlags = append(flags.Global.LdFlags,
+ "-ldl",
+ "-lpthread",
+ "-lm",
+ )
+ if !ctx.Darwin() {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, "-lrt")
+ }
+ }
+ }
+ staticLib := mod.CcLibraryInterface() && mod.Static()
+ if ctx.Host() && !ctx.Windows() && !staticLib {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, RpathFlags(ctx)...)
+ }
+
+ flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainLdflags())
+ return flags
+}
+
+func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
+ toolchain := ctx.toolchain()
+ allow_undefined_symbols := Bool(linker.Properties.Allow_undefined_symbols)
+
+ flags = CommonLinkerFlags(ctx, flags, linker.useClangLld(ctx), toolchain,
+ allow_undefined_symbols)
+
+ if !toolchain.Bionic() && ctx.Os() != android.LinuxMusl {
+ CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs)
+ flags.Local.LdFlags = append(flags.Local.LdFlags, linker.Properties.Host_ldlibs...)
+ }
+
+ CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags)
+
+ if linker.useClangLld(ctx) {
if !BoolDefault(linker.Properties.Pack_relocations, packRelocationsDefault) {
flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none")
} else if ctx.Device() {
@@ -498,53 +559,10 @@
flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android")
}
}
- } else {
- flags.Global.LdFlags = append(flags.Global.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod))
}
- if Bool(linker.Properties.Allow_undefined_symbols) {
- if ctx.Darwin() {
- // darwin defaults to treating undefined symbols as errors
- flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-undefined,dynamic_lookup")
- }
- } else if !ctx.Darwin() && !ctx.Windows() {
- flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--no-undefined")
- }
-
- if linker.useClangLld(ctx) {
- flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Lldflags())
- } else {
- flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.Ldflags())
- }
-
- if !ctx.toolchain().Bionic() && ctx.Os() != android.LinuxMusl {
- CheckBadHostLdlibs(ctx, "host_ldlibs", linker.Properties.Host_ldlibs)
-
- flags.Local.LdFlags = append(flags.Local.LdFlags, linker.Properties.Host_ldlibs...)
-
- if !ctx.Windows() {
- // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device
- // builds
- flags.Global.LdFlags = append(flags.Global.LdFlags,
- "-ldl",
- "-lpthread",
- "-lm",
- )
- if !ctx.Darwin() {
- flags.Global.LdFlags = append(flags.Global.LdFlags, "-lrt")
- }
- }
- }
-
- CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags)
flags.Local.LdFlags = append(flags.Local.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...)
- if ctx.Host() && !ctx.Windows() && !ctx.static() {
- flags.Global.LdFlags = append(flags.Global.LdFlags, RpathFlags(ctx)...)
- }
-
- flags.Global.LdFlags = append(flags.Global.LdFlags, toolchain.ToolchainLdflags())
-
// Version_script is not needed when linking stubs lib where the version
// script is created from the symbol map file.
if !linker.dynamicProperties.BuildStubs {
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 8cc3852..5586576 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -83,9 +83,9 @@
// Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to generate the linker config.
movedToApexLlndkLibrariesMap := make(map[string]bool)
ctx.VisitAllModules(func(module android.Module) {
- if library := moduleLibraryInterface(module); library != nil && library.hasLLNDKStubs() {
- if library.isLLNDKMovedToApex() {
- name := library.implementationModuleName(module.(*Module).BaseModuleName())
+ if library := moduleVersionedInterface(module); library != nil && library.HasLLNDKStubs() {
+ if library.IsLLNDKMovedToApex() {
+ name := library.ImplementationModuleName(module.(*Module).BaseModuleName())
movedToApexLlndkLibrariesMap[name] = true
}
}
@@ -223,10 +223,10 @@
lib, isLib := m.linker.(*libraryDecorator)
prebuiltLib, isPrebuiltLib := m.linker.(*prebuiltLibraryLinker)
- if m.InVendorOrProduct() && isLib && lib.hasLLNDKStubs() {
+ if m.InVendorOrProduct() && isLib && lib.HasLLNDKStubs() {
m.VendorProperties.IsLLNDK = true
}
- if m.InVendorOrProduct() && isPrebuiltLib && prebuiltLib.hasLLNDKStubs() {
+ if m.InVendorOrProduct() && isPrebuiltLib && prebuiltLib.HasLLNDKStubs() {
m.VendorProperties.IsLLNDK = true
}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 27a9f66..1f0fc07 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -133,13 +133,13 @@
unversionedUntil android.ApiLevel
}
-var _ versionedInterface = (*stubDecorator)(nil)
+var _ VersionedInterface = (*stubDecorator)(nil)
func shouldUseVersionScript(ctx BaseModuleContext, stub *stubDecorator) bool {
return stub.apiLevel.GreaterThanOrEqualTo(stub.unversionedUntil)
}
-func (stub *stubDecorator) implementationModuleName(name string) string {
+func (stub *stubDecorator) ImplementationModuleName(name string) string {
return strings.TrimSuffix(name, ndkLibrarySuffix)
}
@@ -155,7 +155,7 @@
return versionStrs
}
-func (this *stubDecorator) stubsVersions(ctx android.BaseModuleContext) []string {
+func (this *stubDecorator) StubsVersions(ctx android.BaseModuleContext) []string {
if !ctx.Module().Enabled(ctx) {
return nil
}
@@ -163,7 +163,7 @@
ctx.Module().Disable()
return nil
}
- firstVersion, err := nativeApiLevelFromUser(ctx,
+ firstVersion, err := NativeApiLevelFromUser(ctx,
String(this.properties.First_version))
if err != nil {
ctx.PropertyErrorf("first_version", err.Error())
@@ -173,10 +173,10 @@
}
func (this *stubDecorator) initializeProperties(ctx BaseModuleContext) bool {
- this.apiLevel = nativeApiLevelOrPanic(ctx, this.stubsVersion())
+ this.apiLevel = nativeApiLevelOrPanic(ctx, this.StubsVersion())
var err error
- this.firstVersion, err = nativeApiLevelFromUser(ctx,
+ this.firstVersion, err = NativeApiLevelFromUser(ctx,
String(this.properties.First_version))
if err != nil {
ctx.PropertyErrorf("first_version", err.Error())
@@ -184,7 +184,7 @@
}
str := proptools.StringDefault(this.properties.Unversioned_until, "minimum")
- this.unversionedUntil, err = nativeApiLevelFromUser(ctx, str)
+ this.unversionedUntil, err = NativeApiLevelFromUser(ctx, str)
if err != nil {
ctx.PropertyErrorf("unversioned_until", err.Error())
return false
@@ -236,7 +236,7 @@
pctx.StaticVariable("StubLibraryCompilerFlags", strings.Join(stubLibraryCompilerFlags, " "))
}
-func addStubLibraryCompilerFlags(flags Flags) Flags {
+func AddStubLibraryCompilerFlags(flags Flags) Flags {
flags.Global.CFlags = append(flags.Global.CFlags, stubLibraryCompilerFlags...)
// All symbols in the stubs library should be visible.
if inList("-fvisibility=hidden", flags.Local.CFlags) {
@@ -247,17 +247,17 @@
func (stub *stubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
flags = stub.baseCompiler.compilerFlags(ctx, flags, deps)
- return addStubLibraryCompilerFlags(flags)
+ return AddStubLibraryCompilerFlags(flags)
}
-type ndkApiOutputs struct {
- stubSrc android.ModuleGenPath
- versionScript android.ModuleGenPath
+type NdkApiOutputs struct {
+ StubSrc android.ModuleGenPath
+ VersionScript android.ModuleGenPath
symbolList android.ModuleGenPath
}
-func parseNativeAbiDefinition(ctx ModuleContext, symbolFile string,
- apiLevel android.ApiLevel, genstubFlags string) ndkApiOutputs {
+func ParseNativeAbiDefinition(ctx android.ModuleContext, symbolFile string,
+ apiLevel android.ApiLevel, genstubFlags string) NdkApiOutputs {
stubSrcPath := android.PathForModuleGen(ctx, "stub.c")
versionScriptPath := android.PathForModuleGen(ctx, "stub.map")
@@ -279,20 +279,20 @@
},
})
- return ndkApiOutputs{
- stubSrc: stubSrcPath,
- versionScript: versionScriptPath,
+ return NdkApiOutputs{
+ StubSrc: stubSrcPath,
+ VersionScript: versionScriptPath,
symbolList: symbolListPath,
}
}
-func compileStubLibrary(ctx ModuleContext, flags Flags, src android.Path) Objects {
+func CompileStubLibrary(ctx android.ModuleContext, flags Flags, src android.Path, sharedFlags *SharedFlags) Objects {
// libc/libm stubs libraries end up mismatching with clang's internal definition of these
// functions (which have noreturn attributes and other things). Because we just want to create a
// stub with symbol definitions, and types aren't important in C, ignore the mismatch.
flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, "-fno-builtin")
return compileObjs(ctx, flagsToBuilderFlags(flags), "",
- android.Paths{src}, nil, nil, nil, nil)
+ android.Paths{src}, nil, nil, nil, nil, sharedFlags)
}
func (this *stubDecorator) findImplementationLibrary(ctx ModuleContext) android.Path {
@@ -489,7 +489,7 @@
ctx.PropertyErrorf("symbol_file", "must end with .map.txt")
}
- if !c.buildStubs() {
+ if !c.BuildStubs() {
// NDK libraries have no implementation variant, nothing to do
return Objects{}
}
@@ -500,9 +500,9 @@
}
symbolFile := String(c.properties.Symbol_file)
- nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile, c.apiLevel, "")
- objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
- c.versionScriptPath = nativeAbiResult.versionScript
+ nativeAbiResult := ParseNativeAbiDefinition(ctx, symbolFile, c.apiLevel, "")
+ objs := CompileStubLibrary(ctx, flags, nativeAbiResult.StubSrc, ctx.getSharedFlags())
+ c.versionScriptPath = nativeAbiResult.VersionScript
if c.canDumpAbi(ctx) {
c.dumpAbi(ctx, nativeAbiResult.symbolList)
if c.canDiffAbi(ctx.Config()) {
@@ -510,7 +510,7 @@
}
}
if c.apiLevel.IsCurrent() && ctx.PrimaryArch() {
- c.parsedCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
+ c.parsedCoverageXmlPath = ParseSymbolFileForAPICoverage(ctx, symbolFile)
}
return objs
}
@@ -541,7 +541,7 @@
func (stub *stubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps,
objs Objects) android.Path {
- if !stub.buildStubs() {
+ if !stub.BuildStubs() {
// NDK libraries have no implementation variant, nothing to do
return nil
}
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index 92da172..a5f014b 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -245,7 +245,7 @@
}
if m, ok := module.(*Module); ok {
- if installer, ok := m.installer.(*stubDecorator); ok && m.library.buildStubs() {
+ if installer, ok := m.installer.(*stubDecorator); ok && m.library.BuildStubs() {
installPaths = append(installPaths, installer.installPath)
}
diff --git a/cc/object.go b/cc/object.go
index c89520a..bbfca94 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -159,7 +159,7 @@
// isForPlatform is terribly named and actually means isNotApex.
if Bool(object.Properties.Crt) &&
!Bool(object.Properties.Exclude_from_ndk_sysroot) && ctx.useSdk() &&
- ctx.isSdkVariant() && ctx.isForPlatform() {
+ ctx.isSdkVariant() && CtxIsForPlatform(ctx) {
output = getVersionedLibraryInstallPath(ctx,
nativeApiLevelOrPanic(ctx, ctx.sdkVersion())).Join(ctx, outputName)
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 96a07bc..70ee5e3 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -114,10 +114,10 @@
// TODO(ccross): verify shared library dependencies
srcs := p.prebuiltSrcs(ctx)
- stubInfo := addStubDependencyProviders(ctx)
+ stubInfo := AddStubDependencyProviders(ctx)
// Stub variants will create a stub .so file from stub .c files
- if p.buildStubs() && objs.objFiles != nil {
+ if p.BuildStubs() && objs.objFiles != nil {
// TODO (b/275273834): Make objs.objFiles == nil a hard error when the symbol files have been added to module sdk.
return p.linkShared(ctx, flags, deps, objs)
}
@@ -204,7 +204,7 @@
Target: ctx.Target(),
TableOfContents: p.tocFile,
- IsStubs: p.buildStubs(),
+ IsStubs: p.BuildStubs(),
})
return outputFile
@@ -268,7 +268,7 @@
}
// Implements versionedInterface
-func (p *prebuiltLibraryLinker) implementationModuleName(name string) string {
+func (p *prebuiltLibraryLinker) ImplementationModuleName(name string) string {
return android.RemoveOptionalPrebuiltPrefix(name)
}
@@ -298,7 +298,7 @@
}
func (p *prebuiltLibraryLinker) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
- if p.buildStubs() && p.stubsVersion() != "" {
+ if p.BuildStubs() && p.StubsVersion() != "" {
return p.compileModuleLibApiStubs(ctx, flags, deps)
}
return Objects{}
diff --git a/cc/sabi.go b/cc/sabi.go
index bc61b6c..06ab6ec 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -137,7 +137,7 @@
if m.isImplementationForLLNDKPublic() {
result = append(result, llndkLsdumpTag)
}
- if m.library.hasStubsVariants() {
+ if m.library.HasStubsVariants() {
result = append(result, apexLsdumpTag)
}
if headerAbiChecker.enabled() {
diff --git a/cc/stub_library.go b/cc/stub_library.go
index 75d649f..9d7b5bc 100644
--- a/cc/stub_library.go
+++ b/cc/stub_library.go
@@ -43,7 +43,7 @@
}
// Get target file name to be installed from this module
-func getInstalledFileName(ctx android.SingletonContext, m *Module) string {
+func getInstalledFileName(ctx android.SingletonContext, m LinkableInterface) string {
for _, ps := range android.OtherModuleProviderOrDefault(
ctx, m.Module(), android.InstallFilesProvider).PackagingSpecs {
if name := ps.FileName(); name != "" {
@@ -58,7 +58,7 @@
stubLibraryMap := make(map[string]bool)
vendorStubLibraryMap := make(map[string]bool)
ctx.VisitAllModules(func(module android.Module) {
- if m, ok := module.(*Module); ok {
+ if m, ok := module.(VersionedLinkableInterface); ok {
if IsStubTarget(android.OtherModuleProviderOrDefault(ctx, m, LinkableInfoProvider)) {
if name := getInstalledFileName(ctx, m); name != "" {
stubLibraryMap[name] = true
@@ -67,8 +67,8 @@
}
}
}
- if m.library != nil && android.IsModulePreferred(m) {
- if p := m.library.getAPIListCoverageXMLPath().String(); p != "" {
+ if m.CcLibraryInterface() && android.IsModulePreferred(m) {
+ if p := m.VersionedInterface().GetAPIListCoverageXMLPath().String(); p != "" {
s.apiListCoverageXmlPaths = append(s.apiListCoverageXmlPaths, p)
}
}
diff --git a/java/app.go b/java/app.go
index c6fad60..6a4cd4b 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1119,9 +1119,10 @@
parentLinkable, _ := parent.(cc.LinkableInterface)
useStubsOfDep := childLinkable.IsStubs()
if apkInApex && parentLinkable != nil {
+ vintf := childLinkable.(cc.VersionedLinkableInterface).VersionedInterface()
// APK-in-APEX
// If the parent is a linkable interface, use stubs if the dependency edge crosses an apex boundary.
- useStubsOfDep = useStubsOfDep || (childLinkable.HasStubsVariants() && cc.ShouldUseStubForApex(ctx, parent, child))
+ useStubsOfDep = useStubsOfDep || (vintf.HasStubsVariants() && cc.ShouldUseStubForApex(ctx, parent, child))
}
return !childLinkable.IsNdk(ctx.Config()) && !useStubsOfDep
})
diff --git a/rust/compiler.go b/rust/compiler.go
index b93019b..1d2fb58 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -39,6 +39,7 @@
compilerFlags(ctx ModuleContext, flags Flags) Flags
cfgFlags(ctx ModuleContext, flags Flags) Flags
featureFlags(ctx ModuleContext, module *Module, flags Flags) Flags
+ baseCompilerProps() BaseCompilerProperties
compilerProps() []interface{}
compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput
compilerDeps(ctx DepsContext, deps Deps) Deps
@@ -149,21 +150,21 @@
Aliases []string
// list of rust rlib crate dependencies
- Rlibs []string `android:"arch_variant"`
+ Rlibs proptools.Configurable[[]string] `android:"arch_variant"`
// list of rust automatic crate dependencies.
// Rustlibs linkage is rlib for host targets and dylib for device targets.
Rustlibs proptools.Configurable[[]string] `android:"arch_variant"`
// list of rust proc_macro crate dependencies
- Proc_macros []string `android:"arch_variant"`
+ Proc_macros proptools.Configurable[[]string] `android:"arch_variant"`
// list of C shared library dependencies
- Shared_libs []string `android:"arch_variant"`
+ Shared_libs proptools.Configurable[[]string] `android:"arch_variant"`
// list of C static library dependencies. These dependencies do not normally propagate to dependents
// and may need to be redeclared. See whole_static_libs for bundling static dependencies into a library.
- Static_libs []string `android:"arch_variant"`
+ Static_libs proptools.Configurable[[]string] `android:"arch_variant"`
// Similar to static_libs, but will bundle the static library dependency into a library. This is helpful
// to avoid having to redeclare the dependency for dependents of this library, but in some cases may also
@@ -178,13 +179,13 @@
//
// For rust_library rlib variants, these libraries will be bundled into the resulting rlib library. This will
// include all of the static libraries symbols in any dylibs or binaries which use this rlib as well.
- Whole_static_libs []string `android:"arch_variant"`
+ Whole_static_libs proptools.Configurable[[]string] `android:"arch_variant"`
// list of Rust system library dependencies.
//
// This is usually only needed when `no_stdlibs` is true, in which case it can be used to depend on system crates
// like `core` and `alloc`.
- Stdlibs []string `android:"arch_variant"`
+ Stdlibs proptools.Configurable[[]string] `android:"arch_variant"`
// crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
// modules which create library variants (rust_bindgen). This must be the expected extern crate name used in
@@ -336,6 +337,10 @@
return []interface{}{&compiler.Properties}
}
+func (compiler *baseCompiler) baseCompilerProps() BaseCompilerProperties {
+ return compiler.Properties
+}
+
func cfgsToFlags(cfgs []string) []string {
flags := make([]string, 0, len(cfgs))
for _, cfg := range cfgs {
@@ -495,13 +500,13 @@
}
func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
- deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
+ deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs.GetOrDefault(ctx, nil)...)
deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs.GetOrDefault(ctx, nil)...)
- deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
- deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
- deps.WholeStaticLibs = append(deps.WholeStaticLibs, compiler.Properties.Whole_static_libs...)
- deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
- deps.Stdlibs = append(deps.Stdlibs, compiler.Properties.Stdlibs...)
+ deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros.GetOrDefault(ctx, nil)...)
+ deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs.GetOrDefault(ctx, nil)...)
+ deps.WholeStaticLibs = append(deps.WholeStaticLibs, compiler.Properties.Whole_static_libs.GetOrDefault(ctx, nil)...)
+ deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs.GetOrDefault(ctx, nil)...)
+ deps.Stdlibs = append(deps.Stdlibs, compiler.Properties.Stdlibs.GetOrDefault(ctx, nil)...)
if !Bool(compiler.Properties.No_stdlibs) {
for _, stdlib := range config.Stdlibs {
diff --git a/rust/library.go b/rust/library.go
index 2d62dcf..49169ac 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -25,6 +25,7 @@
"android/soong/android"
"android/soong/cc"
+ cc_config "android/soong/cc/config"
)
var (
@@ -79,9 +80,13 @@
// Whether this library is part of the Rust toolchain sysroot.
Sysroot *bool
- // Exclude this rust_ffi target from being included in APEXes.
- // TODO(b/362509506): remove this once stubs are properly supported by rust_ffi targets.
+ // Deprecated - exclude this rust_ffi target from being included in APEXes.
+ // TODO(b/362509506): remove this once all apex_exclude uses are switched to stubs.
Apex_exclude *bool
+
+ // Generate stubs to make this library accessible to APEXes.
+ // Can only be set for modules producing shared libraries.
+ Stubs cc.StubsProperties `android:"arch_variant"`
}
type LibraryMutatedProperties struct {
@@ -109,6 +114,15 @@
// Whether this library variant should be link libstd via rlibs
VariantIsStaticStd bool `blueprint:"mutated"`
+
+ // This variant is a stubs lib
+ BuildStubs bool `blueprint:"mutated"`
+ // This variant is the latest version
+ IsLatestVersion bool `blueprint:"mutated"`
+ // Version of the stubs lib
+ StubsVersion string `blueprint:"mutated"`
+ // List of all stubs versions associated with an implementation lib
+ AllStubsVersions []string `blueprint:"mutated"`
}
type libraryDecorator struct {
@@ -123,9 +137,28 @@
// table-of-contents file for cdylib crates to optimize out relinking when possible
tocFile android.OptionalPath
+
+ // Path to the file containing the APIs exported by this library
+ stubsSymbolFilePath android.Path
+ apiListCoverageXmlPath android.ModuleOutPath
+ versionScriptPath android.OptionalPath
+}
+
+func (library *libraryDecorator) stubs() bool {
+ return library.MutatedProperties.BuildStubs
+}
+
+func (library *libraryDecorator) setAPIListCoverageXMLPath(xml android.ModuleOutPath) {
+ library.apiListCoverageXmlPath = xml
+}
+
+func (library *libraryDecorator) libraryProperties() LibraryCompilerProperties {
+ return library.Properties
}
type libraryInterface interface {
+ cc.VersionedInterface
+
rlib() bool
dylib() bool
static() bool
@@ -161,6 +194,11 @@
BuildOnlyShared()
toc() android.OptionalPath
+
+ IsStubsImplementationRequired() bool
+ setAPIListCoverageXMLPath(out android.ModuleOutPath)
+
+ libraryProperties() LibraryCompilerProperties
}
func (library *libraryDecorator) nativeCoverage() bool {
@@ -276,7 +314,85 @@
var _ compiler = (*libraryDecorator)(nil)
var _ libraryInterface = (*libraryDecorator)(nil)
+var _ cc.VersionedInterface = (*libraryDecorator)(nil)
var _ exportedFlagsProducer = (*libraryDecorator)(nil)
+var _ cc.VersionedInterface = (*libraryDecorator)(nil)
+
+func (library *libraryDecorator) HasLLNDKStubs() bool {
+ // Rust LLNDK is currently unsupported
+ return false
+}
+
+func (library *libraryDecorator) HasVendorPublicLibrary() bool {
+ // Rust does not support vendor_public_library yet.
+ return false
+}
+
+func (library *libraryDecorator) HasLLNDKHeaders() bool {
+ // Rust LLNDK is currently unsupported
+ return false
+}
+
+func (library *libraryDecorator) HasStubsVariants() bool {
+ // Just having stubs.symbol_file is enough to create a stub variant. In that case
+ // the stub for the future API level is created.
+ return library.Properties.Stubs.Symbol_file != nil ||
+ len(library.Properties.Stubs.Versions) > 0
+}
+
+func (library *libraryDecorator) IsStubsImplementationRequired() bool {
+ return BoolDefault(library.Properties.Stubs.Implementation_installable, true)
+}
+
+func (library *libraryDecorator) GetAPIListCoverageXMLPath() android.ModuleOutPath {
+ return library.apiListCoverageXmlPath
+}
+
+func (library *libraryDecorator) AllStubsVersions() []string {
+ return library.MutatedProperties.AllStubsVersions
+}
+
+func (library *libraryDecorator) SetAllStubsVersions(versions []string) {
+ library.MutatedProperties.AllStubsVersions = versions
+}
+
+func (library *libraryDecorator) SetStubsVersion(version string) {
+ library.MutatedProperties.StubsVersion = version
+}
+
+func (library *libraryDecorator) SetBuildStubs(isLatest bool) {
+ library.MutatedProperties.BuildStubs = true
+ library.MutatedProperties.IsLatestVersion = isLatest
+}
+
+func (library *libraryDecorator) BuildStubs() bool {
+ return library.MutatedProperties.BuildStubs
+}
+
+func (library *libraryDecorator) ImplementationModuleName(name string) string {
+ return name
+}
+
+func (library *libraryDecorator) IsLLNDKMovedToApex() bool {
+ // Rust does not support LLNDK.
+ return false
+}
+
+func (library *libraryDecorator) StubsVersion() string {
+ return library.MutatedProperties.StubsVersion
+}
+
+// stubsVersions implements cc.VersionedInterface.
+func (library *libraryDecorator) StubsVersions(ctx android.BaseModuleContext) []string {
+ if !library.HasStubsVariants() {
+ return nil
+ }
+
+ // Future API level is implicitly added if there isn't
+ versions := cc.AddCurrentVersionIfNotPresent(library.Properties.Stubs.Versions)
+ cc.NormalizeVersions(ctx, versions)
+ return versions
+}
// rust_library produces all Rust variants (rust_library_dylib and
// rust_library_rlib).
@@ -355,6 +471,18 @@
return module.Init()
}
+func CheckRustLibraryProperties(mctx android.DefaultableHookContext) {
+ lib := mctx.Module().(*Module).compiler.(libraryInterface)
+ if !lib.buildShared() {
+ if lib.libraryProperties().Stubs.Symbol_file != nil ||
+ lib.libraryProperties().Stubs.Implementation_installable != nil ||
+ len(lib.libraryProperties().Stubs.Versions) > 0 {
+
+ mctx.PropertyErrorf("stubs", "stubs properties can only be set for rust_ffi or rust_ffi_shared modules")
+ }
+ }
+}
+
func (library *libraryDecorator) BuildOnlyFFI() {
library.MutatedProperties.BuildDylib = false
// we build rlibs for later static ffi linkage.
@@ -414,6 +542,7 @@
module.compiler = library
+ module.SetDefaultableHook(CheckRustLibraryProperties)
return module, library
}
@@ -576,7 +705,11 @@
}
// Call the appropriate builder for this library type
- if library.rlib() {
+ if library.stubs() {
+ ccFlags := library.getApiStubsCcFlags(ctx)
+ stubObjs := library.compileModuleLibApiStubs(ctx, ccFlags)
+ cc.BuildRustStubs(ctx, outputFile, deps.CrtBegin, deps.CrtEnd, stubObjs, ccFlags)
+ } else if library.rlib() {
ret.kytheFile = TransformSrctoRlib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
} else if library.dylib() {
ret.kytheFile = TransformSrctoDylib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
@@ -592,13 +725,13 @@
}
// Since we have FFI rlibs, we need to collect their includes as well
- if library.static() || library.shared() || library.rlib() {
+ if library.static() || library.shared() || library.rlib() || library.stubs() {
android.SetProvider(ctx, cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
IncludeDirs: android.FirstUniquePaths(library.includeDirs),
})
}
- if library.shared() {
+ if library.shared() || library.stubs() {
// Optimize out relinking against shared libraries whose interface hasn't changed by
// depending on a table of contents file instead of the library itself.
tocFile := outputFile.ReplaceExtension(ctx, flags.Toolchain.SharedLibSuffix()[1:]+".toc")
@@ -609,9 +742,7 @@
TableOfContents: android.OptionalPathForPath(tocFile),
SharedLibrary: outputFile,
Target: ctx.Target(),
- // TODO: when rust supports stubs uses the stubs state rather than inferring it from
- // apex_exclude.
- IsStubs: Bool(library.Properties.Apex_exclude),
+ IsStubs: library.BuildStubs(),
})
}
@@ -623,6 +754,7 @@
TransitiveStaticLibrariesForOrdering: depSet,
})
}
+ cc.AddStubDependencyProviders(ctx)
library.flagExporter.setProvider(ctx)
@@ -642,6 +774,53 @@
}
}
+func (library *libraryDecorator) getApiStubsCcFlags(ctx ModuleContext) cc.Flags {
+ ccFlags := cc.Flags{}
+ toolchain := cc_config.FindToolchain(ctx.Os(), ctx.Arch())
+
+ platformSdkVersion := ""
+ if ctx.Device() {
+ platformSdkVersion = ctx.Config().PlatformSdkVersion().String()
+ }
+ minSdkVersion := cc.MinSdkVersion(ctx.RustModule(), cc.CtxIsForPlatform(ctx), ctx.Device(), platformSdkVersion)
+
+ // Collect common CC compilation flags
+ ccFlags = cc.CommonLinkerFlags(ctx, ccFlags, true, toolchain, false)
+ ccFlags = cc.CommonLibraryLinkerFlags(ctx, ccFlags, toolchain, library.getStem(ctx))
+ ccFlags = cc.AddStubLibraryCompilerFlags(ccFlags)
+ ccFlags = cc.AddTargetFlags(ctx, ccFlags, toolchain, minSdkVersion, false)
+
+ return ccFlags
+}
+
+func (library *libraryDecorator) compileModuleLibApiStubs(ctx ModuleContext, ccFlags cc.Flags) cc.Objects {
+ mod := ctx.RustModule()
+
+ symbolFile := String(library.Properties.Stubs.Symbol_file)
+ library.stubsSymbolFilePath = android.PathForModuleSrc(ctx, symbolFile)
+
+ apiParams := cc.ApiStubsParams{
+ NotInPlatform: mod.NotInPlatform(),
+ IsNdk: mod.IsNdk(ctx.Config()),
+ BaseModuleName: mod.BaseModuleName(),
+ ModuleName: ctx.ModuleName(),
+ }
+ flag := cc.GetApiStubsFlags(apiParams)
+
+ nativeAbiResult := cc.ParseNativeAbiDefinition(ctx, symbolFile,
+ android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
+ objs := cc.CompileStubLibrary(ctx, ccFlags, nativeAbiResult.StubSrc, mod.getSharedFlags())
+
+ library.versionScriptPath = android.OptionalPathForPath(nativeAbiResult.VersionScript)
+
+ // Parse symbol file to get API list for coverage
+ if library.StubsVersion() == "current" && ctx.PrimaryArch() && !mod.InRecovery() && !mod.InProduct() && !mod.InVendor() {
+ library.apiListCoverageXmlPath = cc.ParseSymbolFileForAPICoverage(ctx, symbolFile)
+ }
+
+ return objs
+}
+
func (library *libraryDecorator) rustdoc(ctx ModuleContext, flags Flags,
deps PathDeps) android.OptionalPath {
// rustdoc has builtin support for documenting config specific information
diff --git a/rust/library_test.go b/rust/library_test.go
index e5fd5e0..1198fcc 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -482,3 +482,289 @@
extra_exported_symbols: "libbar.map.txt",
}`)
}
+
+func TestStubsVersions(t *testing.T) {
+ t.Parallel()
+ bp := `
+ rust_ffi {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ stubs: {
+ versions: ["29", "R", "current"],
+ },
+ }
+ `
+ ctx := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture(),
+ android.FixtureModifyConfigAndContext(func(config android.Config, ctx *android.TestContext) {
+ config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
+ })).RunTestWithBp(t, bp)
+
+ variants := ctx.ModuleVariantsForTests("libfoo")
+ for _, expectedVer := range []string{"29", "R", "current"} {
+ expectedVariant := "android_arm_armv7-a-neon_shared_" + expectedVer
+ if !android.InList(expectedVariant, variants) {
+ t.Errorf("missing expected variant: %q", expectedVariant)
+ }
+ }
+}
+
+func TestStubsVersions_NotSorted(t *testing.T) {
+ t.Parallel()
+ bp := `
+ rust_ffi_shared {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ stubs: {
+ versions: ["29", "current", "R"],
+ },
+ }
+ `
+ fixture := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture(),
+
+ android.FixtureModifyConfigAndContext(func(config android.Config, ctx *android.TestContext) {
+ config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
+ }))
+
+ fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(`"libfoo" .*: versions: not sorted`)).RunTestWithBp(t, bp)
+}
+
+func TestStubsVersions_ParseError(t *testing.T) {
+ t.Parallel()
+ bp := `
+ rust_ffi_shared {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ stubs: {
+ versions: ["29", "current", "X"],
+ },
+ }
+ `
+ fixture := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture(),
+
+ android.FixtureModifyConfigAndContext(func(config android.Config, ctx *android.TestContext) {
+ config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
+ }))
+
+ fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(`"libfoo" .*: versions: "X" could not be parsed as an integer and is not a recognized codename`)).RunTestWithBp(t, bp)
+}
+
+func TestVersionedStubs(t *testing.T) {
+ t.Parallel()
+ bp := `
+ rust_ffi_shared {
+ name: "libFoo",
+ crate_name: "Foo",
+ srcs: ["foo.rs"],
+ stubs: {
+ symbol_file: "foo.map.txt",
+ versions: ["1", "2", "3"],
+ },
+ }
+
+ cc_library_shared {
+ name: "libBar",
+ srcs: ["bar.c"],
+ shared_libs: ["libFoo#1"],
+ }
+
+ rust_library {
+ name: "libbar_rs",
+ crate_name: "bar_rs",
+ srcs: ["bar.rs"],
+ shared_libs: ["libFoo#1"],
+ }
+ rust_ffi {
+ name: "libbar_ffi_rs",
+ crate_name: "bar_ffi_rs",
+ srcs: ["bar.rs"],
+ shared_libs: ["libFoo#1"],
+ }
+ `
+
+ ctx := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture()).RunTestWithBp(t, bp)
+
+ variants := ctx.ModuleVariantsForTests("libFoo")
+ expectedVariants := []string{
+ "android_arm64_armv8-a_shared",
+ "android_arm64_armv8-a_shared_1",
+ "android_arm64_armv8-a_shared_2",
+ "android_arm64_armv8-a_shared_3",
+ "android_arm64_armv8-a_shared_current",
+ "android_arm_armv7-a-neon_shared",
+ "android_arm_armv7-a-neon_shared_1",
+ "android_arm_armv7-a-neon_shared_2",
+ "android_arm_armv7-a-neon_shared_3",
+ "android_arm_armv7-a-neon_shared_current",
+ }
+ variantsMismatch := false
+ if len(variants) != len(expectedVariants) {
+ variantsMismatch = true
+ } else {
+ for _, v := range expectedVariants {
+ if !android.InList(v, variants) {
+ variantsMismatch = false
+ }
+ }
+ }
+ if variantsMismatch {
+ t.Errorf("variants of libFoo expected:\n")
+ for _, v := range expectedVariants {
+ t.Errorf("%q\n", v)
+ }
+ t.Errorf(", but got:\n")
+ for _, v := range variants {
+ t.Errorf("%q\n", v)
+ }
+ }
+
+ libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
+ libBarFlags := libBarLinkRule.Args["libFlags"]
+
+ libBarRsRustcRule := ctx.ModuleForTests("libbar_rs", "android_arm64_armv8-a_dylib").Rule("rustc")
+ libBarRsFlags := libBarRsRustcRule.Args["linkFlags"]
+
+ libBarFfiRsRustcRule := ctx.ModuleForTests("libbar_ffi_rs", "android_arm64_armv8-a_shared").Rule("rustc")
+ libBarFfiRsFlags := libBarFfiRsRustcRule.Args["linkFlags"]
+
+ libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/unstripped/libFoo.so"
+ if !strings.Contains(libBarFlags, libFoo1StubPath) {
+ t.Errorf("%q is not found in %q", libFoo1StubPath, libBarFlags)
+ }
+ if !strings.Contains(libBarRsFlags, libFoo1StubPath) {
+ t.Errorf("%q is not found in %q", libFoo1StubPath, libBarRsFlags)
+ }
+ if !strings.Contains(libBarFfiRsFlags, libFoo1StubPath) {
+ t.Errorf("%q is not found in %q", libFoo1StubPath, libBarFfiRsFlags)
+ }
+}
+
+func TestCheckConflictingExplicitVersions(t *testing.T) {
+ t.Parallel()
+ bp := `
+ cc_library_shared {
+ name: "libbar",
+ srcs: ["bar.c"],
+ shared_libs: ["libfoo", "libfoo#impl"],
+ }
+
+ rust_ffi_shared {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ stubs: {
+ versions: ["29", "current"],
+ },
+ }
+ `
+ fixture := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture())
+
+ fixture.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(`duplicate shared libraries with different explicit versions`)).RunTestWithBp(t, bp)
+}
+
+func TestAddnoOverride64GlobalCflags(t *testing.T) {
+ t.Parallel()
+ bp := `
+ cc_library_shared {
+ name: "libclient",
+ srcs: ["foo.c"],
+ shared_libs: ["libfoo#1"],
+ }
+
+ rust_ffi_shared {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.c"],
+ shared_libs: ["libbar"],
+ stubs: {
+ symbol_file: "foo.map.txt",
+ versions: ["1", "2", "3"],
+ },
+ }
+
+ cc_library_shared {
+ name: "libbar",
+ export_include_dirs: ["include/libbar"],
+ srcs: ["foo.c"],
+ }`
+ ctx := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.PrepareForTestWithVisibility,
+ rustMockedFiles.AddToFixture()).RunTestWithBp(t, bp)
+
+ cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
+
+ if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
+ t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
+ }
+}
+
+// Make sure the stubs properties can only be used in modules producing shared libs
+func TestRustStubsFFIOnly(t *testing.T) {
+ testRustError(t, "stubs properties", `
+ rust_library {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.c"],
+ shared_libs: ["libbar"],
+ stubs: {
+ symbol_file: "foo.map.txt",
+ },
+ }
+ `)
+
+ testRustError(t, "stubs properties", `
+ rust_library {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.c"],
+ shared_libs: ["libbar"],
+ stubs: {
+ versions: ["1"],
+ },
+ }
+ `)
+
+ testRustError(t, "stubs properties", `
+ rust_ffi_static {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.c"],
+ shared_libs: ["libbar"],
+ stubs: {
+ symbol_file: "foo.map.txt",
+ },
+ }
+ `)
+ testRustError(t, "stubs properties", `
+ rust_ffi_static {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.c"],
+ shared_libs: ["libbar"],
+ stubs: {
+ versions: ["1"],
+ },
+ }
+ `)
+}
+
+// TODO: When rust_ffi libraries support export_*_lib_headers,
+// add a test similar to cc.TestStubsLibReexportsHeaders
diff --git a/rust/rust.go b/rust/rust.go
index ba6e293..557bdc3 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -162,9 +162,36 @@
// Make this module available when building for recovery
Recovery_available *bool
- // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
+ // The API level that this module is built against. The APIs of this API level will be
+ // visible at build time, but use of any APIs newer than min_sdk_version will render the
+ // module unloadable on older devices. In the future it will be possible to weakly-link new
+ // APIs, making the behavior match Java: such modules will load on older devices, but
+ // calling new APIs on devices that do not support them will result in a crash.
+ //
+ // This property has the same behavior as sdk_version does for Java modules. For those
+ // familiar with Android Gradle, the property behaves similarly to how compileSdkVersion
+ // does for Java code.
+ //
+ // In addition, setting this property causes two variants to be built, one for the platform
+ // and one for apps.
+ Sdk_version *string
+
+ // Minimum OS API level supported by this C or C++ module. This property becomes the value
+ // of the __ANDROID_API__ macro. When the C or C++ module is included in an APEX or an APK,
+ // this property is also used to ensure that the min_sdk_version of the containing module is
+ // not older (i.e. less) than this module's min_sdk_version. When not set, this property
+ // defaults to the value of sdk_version. When this is set to "apex_inherit", this tracks
+ // min_sdk_version of the containing APEX. When the module
+ // is not built for an APEX, "apex_inherit" defaults to sdk_version.
Min_sdk_version *string
+ // Variant is an SDK variant created by sdkMutator
+ IsSdkVariant bool `blueprint:"mutated"`
+
+ // Set by factories of module types that can only be referenced from variants compiled against
+ // the SDK.
+ AlwaysSdk bool `blueprint:"mutated"`
+
HideFromMake bool `blueprint:"mutated"`
PreventInstall bool `blueprint:"mutated"`
@@ -209,6 +236,9 @@
apexSdkVersion android.ApiLevel
transitiveAndroidMkSharedLibs depset.DepSet[string]
+
+ // Shared flags among stubs build rules of this module
+ sharedFlags cc.SharedFlags
}
func (mod *Module) Header() bool {
@@ -374,7 +404,8 @@
}
func (mod *Module) IsVendorPublicLibrary() bool {
- return mod.VendorProperties.IsVendorPublicLibrary
+ // Rust modules do not currently support vendor_public_library
+ return false
}
func (mod *Module) SdkAndPlatformVariantVisibleToMake() bool {
@@ -383,10 +414,12 @@
}
func (c *Module) IsVndkPrivate() bool {
+ // Rust modules do not currently support VNDK variants
return false
}
func (c *Module) IsLlndk() bool {
+ // Rust modules do not currently support LLNDK variants
return false
}
@@ -395,35 +428,34 @@
}
func (m *Module) NeedsLlndkVariants() bool {
+ // Rust modules do not currently support LLNDK variants
return false
}
func (m *Module) NeedsVendorPublicLibraryVariants() bool {
+ // Rust modules do not currently support vendor_public_library
return false
}
func (mod *Module) HasLlndkStubs() bool {
+ // Rust modules do not currently support LLNDK stubs
return false
}
-func (mod *Module) StubsVersion() string {
- panic(fmt.Errorf("StubsVersion called on non-versioned module: %q", mod.BaseModuleName()))
-}
-
func (mod *Module) SdkVersion() string {
- return ""
+ return String(mod.Properties.Sdk_version)
}
func (mod *Module) AlwaysSdk() bool {
- return false
+ return mod.Properties.AlwaysSdk
}
func (mod *Module) IsSdkVariant() bool {
- return false
+ return mod.Properties.IsSdkVariant
}
func (mod *Module) SplitPerApiLevel() bool {
- return false
+ return cc.CanUseSdk(mod) && mod.IsCrt()
}
func (mod *Module) XrefRustFiles() android.Paths {
@@ -561,6 +593,9 @@
func (mod *Module) PreventInstall() bool {
return mod.Properties.PreventInstall
}
+func (c *Module) ForceDisableSanitizers() {
+ c.sanitize.Properties.ForceDisable = true
+}
func (mod *Module) MarkAsCoverageVariant(coverage bool) {
mod.coverage.Properties.IsCoverageVariant = coverage
@@ -743,11 +778,51 @@
return false
}
-func (mod *Module) HasStubsVariants() bool {
+func (mod *Module) IsStubs() bool {
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ return lib.BuildStubs()
+ }
return false
}
-func (mod *Module) IsStubs() bool {
+func (mod *Module) HasStubsVariants() bool {
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ return lib.HasStubsVariants()
+ }
+ return false
+}
+
+func (mod *Module) ApexSdkVersion() android.ApiLevel {
+ return mod.apexSdkVersion
+}
+
+func (mod *Module) RustApexExclude() bool {
+ return mod.ApexExclude()
+}
+
+func (mod *Module) getSharedFlags() *cc.SharedFlags {
+ shared := &mod.sharedFlags
+ if shared.FlagsMap == nil {
+ shared.NumSharedFlags = 0
+ shared.FlagsMap = make(map[string]string)
+ }
+ return shared
+}
+
+func (mod *Module) ImplementationModuleNameForMake(ctx android.BaseModuleContext) string {
+ name := mod.BaseModuleName()
+ if versioned, ok := mod.compiler.(cc.VersionedInterface); ok {
+ name = versioned.ImplementationModuleName(name)
+ }
+ return name
+}
+
+func (mod *Module) Multilib() string {
+ return mod.Arch().ArchType.Multilib
+}
+
+func (mod *Module) IsCrt() bool {
+ // Rust does not currently provide any crt modules.
return false
}
@@ -771,6 +846,7 @@
}
var _ cc.LinkableInterface = (*Module)(nil)
+var _ cc.VersionedLinkableInterface = (*Module)(nil)
func (mod *Module) Init() android.Module {
mod.AddProperties(&mod.Properties)
@@ -881,6 +957,25 @@
return mod.compiler != nil && mod.compiler.nativeCoverage()
}
+func (mod *Module) SetStl(s string) {
+ // STL is a CC concept; do nothing for Rust
+}
+
+func (mod *Module) SetSdkVersion(s string) {
+ mod.Properties.Sdk_version = StringPtr(s)
+}
+
+func (mod *Module) SetMinSdkVersion(s string) {
+ mod.Properties.Min_sdk_version = StringPtr(s)
+}
+
+func (mod *Module) VersionedInterface() cc.VersionedInterface {
+ if _, ok := mod.compiler.(cc.VersionedInterface); ok {
+ return mod.compiler.(cc.VersionedInterface)
+ }
+ return nil
+}
+
func (mod *Module) EverInstallable() bool {
return mod.compiler != nil &&
// Check to see whether the module is actually ever installable.
@@ -1030,6 +1125,10 @@
linkableInfo.Shared = mod.Shared()
linkableInfo.CrateName = mod.CrateName()
linkableInfo.ExportedCrateLinkDirs = mod.ExportedCrateLinkDirs()
+ if lib, ok := mod.compiler.(cc.VersionedInterface); ok {
+ linkableInfo.StubsVersion = lib.StubsVersion()
+ }
+
android.SetProvider(ctx, cc.LinkableInfoProvider, linkableInfo)
rustInfo := &RustInfo{
@@ -1064,6 +1163,21 @@
}
android.SetProvider(ctx, RustInfoProvider, rustInfo)
+ ccInfo := &cc.CcInfo{
+ IsPrebuilt: mod.IsPrebuilt(),
+ }
+
+ // Define the linker info if compiler != nil because Rust currently
+ // does compilation and linking in one step. If this changes in the future,
+ // move this as appropriate.
+ ccInfo.LinkerInfo = &cc.LinkerInfo{
+ WholeStaticLibs: mod.compiler.baseCompilerProps().Whole_static_libs,
+ StaticLibs: mod.compiler.baseCompilerProps().Static_libs,
+ SharedLibs: mod.compiler.baseCompilerProps().Shared_libs,
+ }
+
+ android.SetProvider(ctx, cc.CcInfoProvider, ccInfo)
+
mod.setOutputFiles(ctx)
buildComplianceMetadataInfo(ctx, mod, deps)
@@ -1225,6 +1339,21 @@
if mod.sanitize != nil {
mod.sanitize.begin(ctx)
}
+
+ if mod.UseSdk() && mod.IsSdkVariant() {
+ sdkVersion := ""
+ if ctx.Device() {
+ sdkVersion = mod.SdkVersion()
+ }
+ version, err := cc.NativeApiLevelFromUser(ctx, sdkVersion)
+ if err != nil {
+ ctx.PropertyErrorf("sdk_version", err.Error())
+ mod.Properties.Sdk_version = nil
+ } else {
+ mod.Properties.Sdk_version = StringPtr(version.String())
+ }
+ }
+
}
func (mod *Module) Prebuilt() *android.Prebuilt {
@@ -1500,9 +1629,12 @@
sharedLibraryInfo, exportedInfo := cc.ChooseStubOrImpl(ctx, dep)
if !sharedLibraryInfo.IsStubs {
- depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
- if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
- depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ // TODO(b/362509506): remove this additional check once all apex_exclude uses are switched to stubs.
+ if !linkableInfo.RustApexExclude {
+ depPaths.directImplementationDeps = append(depPaths.directImplementationDeps, android.OutputFileForModule(ctx, dep, ""))
+ if info, ok := android.OtherModuleProvider(ctx, dep, cc.ImplementationDepInfoProvider); ok {
+ depPaths.transitiveImplementationDeps = append(depPaths.transitiveImplementationDeps, info.ImplementationDeps)
+ }
}
}
@@ -1870,7 +2002,7 @@
var _ android.ApexModule = (*Module)(nil)
// If a module is marked for exclusion from apexes, don't provide apex variants.
-// TODO(b/362509506): remove this once stubs are properly supported by rust_ffi targets.
+// TODO(b/362509506): remove this once all apex_exclude usages are removed.
func (m *Module) CanHaveApexVariants() bool {
if m.ApexExclude() {
return false
@@ -1907,6 +2039,13 @@
}
// Implements android.ApexModule
+func (mod *Module) AlwaysRequiresPlatformApexVariant() bool {
+ // stub libraries and native bridge libraries are always available to platform
+ // TODO(b/362509506): remove the ApexExclude() check once all apex_exclude uses are switched to stubs.
+ return mod.IsStubs() || mod.Target().NativeBridge == android.NativeBridgeEnabled || mod.ApexExclude()
+}
+
+// Implements android.ApexModule
func (mod *Module) OutgoingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
if depTag == procMacroDepTag || depTag == customBindgenDepTag {
return false
@@ -1919,18 +2058,55 @@
return false
}
+ if depTag == cc.StubImplDepTag {
+ // We don't track from an implementation library to its stubs.
+ return false
+ }
+
+ if cc.ExcludeInApexDepTag(depTag) {
+ return false
+ }
+
+ // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs.
+ if mod.ApexExclude() {
+ return false
+ }
+
return true
}
func (mod *Module) IncomingDepIsInSameApex(depTag blueprint.DependencyTag) bool {
- return !mod.ApexExclude()
+ // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs.
+ if mod.ApexExclude() {
+ return false
+ }
+
+ if mod.HasStubsVariants() {
+ if cc.IsSharedDepTag(depTag) {
+ // dynamic dep to a stubs lib crosses APEX boundary
+ return false
+ }
+ if cc.IsRuntimeDepTag(depTag) {
+ // runtime dep to a stubs lib also crosses APEX boundary
+ return false
+ }
+ if cc.IsHeaderDepTag(depTag) {
+ return false
+ }
+ }
+ return true
}
// Overrides ApexModule.IsInstallabeToApex()
func (mod *Module) IsInstallableToApex() bool {
+ // TODO(b/362509506): remove once all apex_exclude uses are switched to stubs.
+ if mod.ApexExclude() {
+ return false
+ }
+
if mod.compiler != nil {
- if lib, ok := mod.compiler.(libraryInterface); ok && (lib.shared() || lib.dylib()) {
- return true
+ if lib, ok := mod.compiler.(libraryInterface); ok {
+ return (lib.shared() || lib.dylib()) && !lib.BuildStubs()
}
if _, ok := mod.compiler.(*binaryDecorator); ok {
return true
diff --git a/rust/sanitize.go b/rust/sanitize.go
index b8f922f..50f55ce 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -53,6 +53,9 @@
// Used when we need to place libraries in their own directory, such as ASAN.
InSanitizerDir bool `blueprint:"mutated"`
+
+ // ForceDisable is set by the version mutator to disable sanitization of stubs variants
+ ForceDisable bool `blueprint:"mutated"`
}
var fuzzerFlags = []string{
@@ -103,6 +106,10 @@
func (sanitize *sanitize) begin(ctx BaseModuleContext) {
s := &sanitize.Properties.Sanitize
+ if sanitize.Properties.ForceDisable {
+ return
+ }
+
// Disable sanitizers for musl x86 modules, rustc does not support any sanitizers.
if ctx.Os() == android.LinuxMusl && ctx.Arch().ArchType == android.X86 {
s.Never = proptools.BoolPtr(true)
@@ -221,6 +228,10 @@
}
func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags, PathDeps) {
+ if sanitize.Properties.ForceDisable {
+ return flags, deps
+ }
+
if !sanitize.Properties.SanitizerEnabled {
return flags, deps
}
@@ -253,6 +264,9 @@
if !mod.Enabled(mctx) {
return
}
+ if mod.sanitize.Properties.ForceDisable {
+ return
+ }
if Bool(mod.sanitize.Properties.Sanitize.Memtag_heap) && mod.Binary() {
noteDep := "note_memtag_heap_async"
@@ -364,7 +378,7 @@
// distinguish between the cases. It isn't needed though - both cases can be
// treated identically.
func (sanitize *sanitize) isSanitizerEnabled(t cc.SanitizerType) bool {
- if sanitize == nil || !sanitize.Properties.SanitizerEnabled {
+ if sanitize == nil || !sanitize.Properties.SanitizerEnabled || sanitize.Properties.ForceDisable {
return false
}
@@ -453,7 +467,7 @@
}
func (mod *Module) SanitizeNever() bool {
- return Bool(mod.sanitize.Properties.Sanitize.Never)
+ return Bool(mod.sanitize.Properties.Sanitize.Never) || mod.sanitize.Properties.ForceDisable
}
var _ cc.PlatformSanitizeable = (*Module)(nil)
diff --git a/rust/testing.go b/rust/testing.go
index 0ce1b66..2082b52 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -80,7 +80,6 @@
no_libcrt: true,
nocrt: true,
system_shared_libs: [],
- apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
vendor_available: true,
host_supported: true,
@@ -88,6 +87,13 @@
llndk: {
symbol_file: "liblog.map.txt",
},
+ stubs: {
+ symbol_file: "liblog.map.txt",
+ versions: [
+ "29",
+ "30",
+ ],
+ },
}
cc_library {
name: "libprotobuf-cpp-full",