Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99644e92 authored by Jiyong Park's avatar Jiyong Park
Browse files

rust modules can be included in apex

We will have some APEXes having rust binaries and libraries. So, adding
the support for the types of modules.

rust.Module now inherits from android.ApexModuleBase and implements
the android.ApexModule interface.

Bug: 172414324
Test: m

Exempt-From-Owner-Approval: rebased after +2 from the owner
Change-Id: I356ef4c45f782a6460f001e83af96d1710642d80
parent d35d92a7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -75,6 +75,10 @@ toolchain_library {
    product_available: true,
    recovery_available: true,
    native_bridge_supported: true,
    apex_available: [
        "//apex_available:platform",
        "//apex_available:anyapex",
    ],

    arch: {
        arm: {
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ bootstrap_go_package {
        "soong-cc",
        "soong-java",
        "soong-python",
        "soong-rust",
        "soong-sh",
    ],
    srcs: [
+49 −3
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import (
	prebuilt_etc "android/soong/etc"
	"android/soong/java"
	"android/soong/python"
	"android/soong/rust"
	"android/soong/sh"
)

@@ -179,6 +180,9 @@ type ApexNativeDependencies struct {
	// 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

@@ -513,13 +517,15 @@ var (
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
@@ -529,6 +535,7 @@ func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeM
	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) {
@@ -1264,6 +1271,35 @@ func apexFileForExecutable(ctx android.BaseModuleContext, cc *cc.Module) apexFil
	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()
@@ -1501,8 +1537,11 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
					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) {
@@ -1663,6 +1702,13 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
					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() {
+34 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import (
	"android/soong/dexpreopt"
	prebuilt_etc "android/soong/etc"
	"android/soong/java"
	"android/soong/rust"
	"android/soong/sh"
)

@@ -136,6 +137,8 @@ func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*andr

	bp = bp + cc.GatherRequiredDepsForTest(android.Android)

	bp = bp + rust.GatherRequiredDepsForTest()

	bp = bp + java.GatherRequiredDepsForTest()

	fs := map[string][]byte{
@@ -185,6 +188,7 @@ func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*andr
		"bar/baz":                                    nil,
		"testdata/baz":                               nil,
		"AppSet.apks":                                nil,
		"foo.rs":                                     nil,
	}

	cc.GatherRequiredFilesForTest(fs)
@@ -241,6 +245,7 @@ func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*andr
	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 @@ func TestBasicApex(t *testing.T) {
			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 @@ func TestBasicApex(t *testing.T) {
			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 @@ func TestBasicApex(t *testing.T) {
	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")
+4 −0
Original line number Diff line number Diff line
@@ -166,6 +166,10 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string {
			product_available: true,
			recovery_available: true,
			src: "",
			apex_available: [
				"//apex_available:platform",
				"//apex_available:anyapex",
			],
		}

		toolchain_library {
Loading