Merge "rust modules can be included in apex" am: fdea25781f

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1508096

Change-Id: I0e33459ce8207779367bdf6b3abee79718f8adba
This commit is contained in:
Jiyong Park 2020-11-30 16:36:39 +00:00 committed by Automerger Merge Worker
commit 88365d1894
11 changed files with 177 additions and 11 deletions

View file

@ -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: {

View file

@ -9,6 +9,7 @@ bootstrap_go_package {
"soong-cc",
"soong-java",
"soong-python",
"soong-rust",
"soong-sh",
],
srcs: [

View file

@ -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
@ -511,13 +515,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
@ -527,6 +533,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) {
@ -1263,6 +1270,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()
@ -1500,8 +1536,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) {
@ -1662,6 +1701,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() {

View file

@ -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")

View file

@ -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 {

View file

@ -43,7 +43,7 @@ func (mod *Module) SubAndroidMk(data *android.AndroidMkEntries, obj interface{})
}
func (mod *Module) AndroidMkEntries() []android.AndroidMkEntries {
if mod.Properties.HideFromMake {
if mod.Properties.HideFromMake || mod.hideApexVariantFromMake {
return []android.AndroidMkEntries{android.AndroidMkEntries{Disabled: true}}
}

View file

@ -18,6 +18,7 @@ import (
"testing"
"android/soong/android"
"android/soong/cc"
)
func TestClippy(t *testing.T) {
@ -45,6 +46,7 @@ func TestClippy(t *testing.T) {
}`
bp = bp + GatherRequiredDepsForTest()
bp = bp + cc.GatherRequiredDepsForTest(android.NoOsType)
fs := map[string][]byte{
// Reuse the same blueprint file for subdirectories.

View file

@ -19,6 +19,7 @@ import (
"testing"
"android/soong/android"
"android/soong/cc"
)
// Test that feature flags are being correctly generated.
@ -132,6 +133,7 @@ func TestLints(t *testing.T) {
}`
bp = bp + GatherRequiredDepsForTest()
bp = bp + cc.GatherRequiredDepsForTest(android.NoOsType)
fs := map[string][]byte{
// Reuse the same blueprint file for subdirectories.

View file

@ -74,6 +74,7 @@ type BaseProperties struct {
type Module struct {
android.ModuleBase
android.DefaultableModuleBase
android.ApexModuleBase
Properties BaseProperties
@ -88,6 +89,8 @@ type Module struct {
subAndroidMkOnce map[SubAndroidMkProvider]bool
outputFile android.OptionalPath
hideApexVariantFromMake bool
}
func (mod *Module) OutputFiles(tag string) (android.Paths, error) {
@ -508,6 +511,7 @@ func (mod *Module) Init() android.Module {
}
android.InitAndroidArchModule(mod, mod.hod, mod.multilib)
android.InitApexModule(mod)
android.InitDefaultableModule(mod)
return mod
@ -605,6 +609,11 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
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 @@ var (
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 @@ func (mod *Module) HostToolPath() android.OptionalPath {
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

View file

@ -120,6 +120,7 @@ func (tctx *testRustCtx) useMockedFs() {
// 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

View file

@ -77,6 +77,7 @@ func GatherRequiredDepsForTest() string {
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 @@ func GatherRequiredDepsForTest() string {
host_supported: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
}
rust_library {
name: "libtest",
@ -102,6 +104,7 @@ func GatherRequiredDepsForTest() string {
host_supported: true,
native_coverage: false,
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
}
rust_library {
name: "libprotobuf",
@ -122,15 +125,11 @@ func GatherRequiredDepsForTest() string {
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 @@ func CreateTestContext(config android.Config) *android.TestContext {
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
}