Merge "rust modules can be included in apex"
diff --git a/Android.bp b/Android.bp
index e7a5de2..866ed25 100644
--- a/Android.bp
+++ b/Android.bp
@@ -75,6 +75,10 @@
product_available: true,
recovery_available: true,
native_bridge_supported: true,
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
arch: {
arm: {
diff --git a/apex/Android.bp b/apex/Android.bp
index 1a5f683..9e8c30d 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -9,6 +9,7 @@
"soong-cc",
"soong-java",
"soong-python",
+ "soong-rust",
"soong-sh",
],
srcs: [
diff --git a/apex/apex.go b/apex/apex.go
index df63932..f127757 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -32,6 +32,7 @@
prebuilt_etc "android/soong/etc"
"android/soong/java"
"android/soong/python"
+ "android/soong/rust"
"android/soong/sh"
)
@@ -179,6 +180,9 @@
// List of JNI libraries that are embedded inside this APEX.
Jni_libs []string
+ // List of rust dyn libraries
+ Rust_dyn_libs []string
+
// List of native executables that are embedded inside this APEX.
Binaries []string
@@ -511,13 +515,15 @@
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeModules ApexNativeDependencies, target android.Target, imageVariation string) {
binVariations := target.Variations()
libVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"})
+ rustLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"})
if ctx.Device() {
binVariations = append(binVariations, blueprint.Variation{Mutator: "image", Variation: imageVariation})
libVariations = append(libVariations,
blueprint.Variation{Mutator: "image", Variation: imageVariation},
- blueprint.Variation{Mutator: "version", Variation: ""}, // "" is the non-stub variant
- )
+ blueprint.Variation{Mutator: "version", Variation: ""}) // "" is the non-stub variant
+ rustLibVariations = append(rustLibVariations,
+ blueprint.Variation{Mutator: "image", Variation: imageVariation})
}
// Use *FarVariation* to be able to depend on modules having conflicting variations with
@@ -527,6 +533,7 @@
ctx.AddFarVariationDependencies(binVariations, testTag, nativeModules.Tests...)
ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
+ ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag, nativeModules.Rust_dyn_libs...)
}
func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
@@ -1263,6 +1270,35 @@
return af
}
+func apexFileForRustExecutable(ctx android.BaseModuleContext, rustm *rust.Module) apexFile {
+ dirInApex := "bin"
+ if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
+ dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
+ }
+ fileToCopy := rustm.OutputFile().Path()
+ androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
+ af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
+ 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)
+ }
+ fileToCopy := rustm.OutputFile().Path()
+ androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
+ return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
+}
+
func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile {
dirInApex := "bin"
fileToCopy := py.HostToolPath().Path()
@@ -1500,8 +1536,11 @@
filesInfo = append(filesInfo, apexFileForPyBinary(ctx, py))
} else if gb, ok := child.(bootstrap.GoBinaryTool); ok && a.Host() {
filesInfo = append(filesInfo, apexFileForGoBinary(ctx, depName, gb))
+ } else if rust, ok := child.(*rust.Module); ok {
+ filesInfo = append(filesInfo, apexFileForRustExecutable(ctx, rust))
+ return true // track transitive dependencies
} else {
- ctx.PropertyErrorf("binaries", "%q is neither cc_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
+ ctx.PropertyErrorf("binaries", "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
}
case javaLibTag:
switch child.(type) {
@@ -1662,6 +1701,13 @@
if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok {
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
}
+ } else if rust.IsDylibDepTag(depTag) {
+ if rustm, ok := child.(*rust.Module); ok && rustm.IsInstallableToApex() {
+ af := apexFileForRustLibrary(ctx, rustm)
+ af.transitiveDep = true
+ filesInfo = append(filesInfo, af)
+ return true // track transitive dependencies
+ }
} else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok {
// nothing
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 33e5077..a94e3b4 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -32,6 +32,7 @@
"android/soong/dexpreopt"
prebuilt_etc "android/soong/etc"
"android/soong/java"
+ "android/soong/rust"
"android/soong/sh"
)
@@ -136,6 +137,8 @@
bp = bp + cc.GatherRequiredDepsForTest(android.Android)
+ bp = bp + rust.GatherRequiredDepsForTest()
+
bp = bp + java.GatherRequiredDepsForTest()
fs := map[string][]byte{
@@ -185,6 +188,7 @@
"bar/baz": nil,
"testdata/baz": nil,
"AppSet.apks": nil,
+ "foo.rs": nil,
}
cc.GatherRequiredFilesForTest(fs)
@@ -241,6 +245,7 @@
ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)
cc.RegisterRequiredBuildComponentsForTest(ctx)
+ rust.RegisterRequiredBuildComponentsForTest(ctx)
ctx.RegisterModuleType("cc_test", cc.TestFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory)
@@ -349,10 +354,12 @@
manifest: ":myapex.manifest",
androidManifest: ":myapex.androidmanifest",
key: "myapex.key",
+ binaries: ["foo.rust"],
native_shared_libs: ["mylib"],
+ rust_dyn_libs: ["libfoo.dylib.rust"],
multilib: {
both: {
- binaries: ["foo",],
+ binaries: ["foo"],
}
},
java_libs: [
@@ -415,6 +422,28 @@
apex_available: [ "myapex", "com.android.gki.*" ],
}
+ rust_binary {
+ name: "foo.rust",
+ srcs: ["foo.rs"],
+ rlibs: ["libfoo.rlib.rust"],
+ dylibs: ["libfoo.dylib.rust"],
+ apex_available: ["myapex"],
+ }
+
+ rust_library_rlib {
+ name: "libfoo.rlib.rust",
+ srcs: ["foo.rs"],
+ crate_name: "foo",
+ apex_available: ["myapex"],
+ }
+
+ rust_library_dylib {
+ name: "libfoo.dylib.rust",
+ srcs: ["foo.rs"],
+ crate_name: "foo",
+ apex_available: ["myapex"],
+ }
+
apex {
name: "com.android.gki.fake",
binaries: ["foo"],
@@ -529,16 +558,20 @@
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_apex10000")
ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("foo.rust"), "android_arm64_armv8-a_apex10000")
// Ensure that apex variant is created for the indirect dep
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000")
ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.rlib.rust"), "android_arm64_armv8-a_rlib_dylib-std_apex10000")
+ ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.dylib.rust"), "android_arm64_armv8-a_dylib_apex10000")
// Ensure that both direct and indirect deps are copied into apex
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
ensureContains(t, copyCmds, "image.apex/javalib/myjar_stem.jar")
ensureContains(t, copyCmds, "image.apex/javalib/myjar_dex.jar")
+ ensureContains(t, copyCmds, "image.apex/lib64/libfoo.dylib.rust.dylib.so")
// .. but not for java libs
ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar")
ensureNotContains(t, copyCmds, "image.apex/javalib/msharedjar.jar")
diff --git a/cc/testing.go b/cc/testing.go
index 198764b..95a93a0 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -166,6 +166,10 @@
product_available: true,
recovery_available: true,
src: "",
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
}
toolchain_library {
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 74cd9bf..4e8b14d 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -43,7 +43,7 @@
}
func (mod *Module) AndroidMkEntries() []android.AndroidMkEntries {
- if mod.Properties.HideFromMake {
+ if mod.Properties.HideFromMake || mod.hideApexVariantFromMake {
return []android.AndroidMkEntries{android.AndroidMkEntries{Disabled: true}}
}
diff --git a/rust/clippy_test.go b/rust/clippy_test.go
index 132b7b8..e24f666 100644
--- a/rust/clippy_test.go
+++ b/rust/clippy_test.go
@@ -18,6 +18,7 @@
"testing"
"android/soong/android"
+ "android/soong/cc"
)
func TestClippy(t *testing.T) {
@@ -45,6 +46,7 @@
}`
bp = bp + GatherRequiredDepsForTest()
+ bp = bp + cc.GatherRequiredDepsForTest(android.NoOsType)
fs := map[string][]byte{
// Reuse the same blueprint file for subdirectories.
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index a6dba9e..2b40727 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -19,6 +19,7 @@
"testing"
"android/soong/android"
+ "android/soong/cc"
)
// Test that feature flags are being correctly generated.
@@ -132,6 +133,7 @@
}`
bp = bp + GatherRequiredDepsForTest()
+ bp = bp + cc.GatherRequiredDepsForTest(android.NoOsType)
fs := map[string][]byte{
// Reuse the same blueprint file for subdirectories.
diff --git a/rust/rust.go b/rust/rust.go
index 5b94045..b277afc 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -74,6 +74,7 @@
type Module struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.ApexModuleBase
Properties BaseProperties
@@ -88,6 +89,8 @@
subAndroidMkOnce map[SubAndroidMkProvider]bool
outputFile android.OptionalPath
+
+ hideApexVariantFromMake bool
}
func (mod *Module) OutputFiles(tag string) (android.Paths, error) {
@@ -508,6 +511,7 @@
}
android.InitAndroidArchModule(mod, mod.hod, mod.multilib)
+ android.InitApexModule(mod)
android.InitDefaultableModule(mod)
return mod
@@ -605,6 +609,11 @@
ModuleContext: actx,
}
+ apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+ if !apexInfo.IsForPlatform() {
+ mod.hideApexVariantFromMake = true
+ }
+
toolchain := mod.toolchain(ctx)
if !toolchain.Supported() {
@@ -694,6 +703,11 @@
sourceDepTag = dependencyTag{name: "source"}
)
+func IsDylibDepTag(depTag blueprint.DependencyTag) bool {
+ tag, ok := depTag.(dependencyTag)
+ return ok && tag == dylibDepTag
+}
+
type autoDep struct {
variation string
depTag dependencyTag
@@ -1052,6 +1066,58 @@
return android.OptionalPath{}
}
+var _ android.ApexModule = (*Module)(nil)
+
+func (mod *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
+ return nil
+}
+
+func (mod *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
+ depTag := ctx.OtherModuleDependencyTag(dep)
+
+ if ccm, ok := dep.(*cc.Module); ok {
+ if ccm.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
+ }
+ }
+ if mod.Static() && cc.IsSharedDepTag(depTag) {
+ // shared_lib dependency from a static lib is considered as crossing
+ // the APEX boundary because the dependency doesn't actually is
+ // linked; the dependency is used only during the compilation phase.
+ return false
+ }
+ }
+
+ if depTag == procMacroDepTag {
+ return false
+ }
+
+ return true
+}
+
+// Overrides ApexModule.IsInstallabeToApex()
+func (mod *Module) IsInstallableToApex() bool {
+ if mod.compiler != nil {
+ if lib, ok := mod.compiler.(*libraryDecorator); ok && (lib.shared() || lib.dylib()) {
+ return true
+ }
+ if _, ok := mod.compiler.(*binaryDecorator); ok {
+ return true
+ }
+ }
+ return false
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 187f0b6..646b252 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -120,6 +120,7 @@
// attributes of the testRustCtx.
func (tctx *testRustCtx) generateConfig() {
tctx.bp = tctx.bp + GatherRequiredDepsForTest()
+ tctx.bp = tctx.bp + cc.GatherRequiredDepsForTest(android.NoOsType)
cc.GatherRequiredFilesForTest(tctx.fs)
config := android.TestArchConfig(buildDir, tctx.env, tctx.bp, tctx.fs)
tctx.config = &config
diff --git a/rust/testing.go b/rust/testing.go
index 001f322..a8496d9 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -77,6 +77,7 @@
no_libcrt: true,
nocrt: true,
system_shared_libs: [],
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
}
cc_library {
name: "libprotobuf-cpp-full",
@@ -93,6 +94,7 @@
host_supported: true,
native_coverage: false,
sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
}
rust_library {
name: "libtest",
@@ -102,6 +104,7 @@
host_supported: true,
native_coverage: false,
sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
}
rust_library {
name: "libprotobuf",
@@ -122,15 +125,11 @@
host_supported: true,
}
-` + cc.GatherRequiredDepsForTest(android.NoOsType)
+`
return bp
}
-func CreateTestContext(config android.Config) *android.TestContext {
- ctx := android.NewTestArchContext(config)
- android.RegisterPrebuiltMutators(ctx)
- ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
- cc.RegisterRequiredBuildComponentsForTest(ctx)
+func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
ctx.RegisterModuleType("rust_binary", RustBinaryFactory)
ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
ctx.RegisterModuleType("rust_bindgen", RustBindgenFactory)
@@ -164,6 +163,14 @@
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
})
ctx.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
+}
+
+func CreateTestContext(config android.Config) *android.TestContext {
+ ctx := android.NewTestArchContext(config)
+ android.RegisterPrebuiltMutators(ctx)
+ ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+ cc.RegisterRequiredBuildComponentsForTest(ctx)
+ RegisterRequiredBuildComponentsForTest(ctx)
return ctx
}