Merge "add acknowledgements field to fuzz_config"
diff --git a/cc/lto.go b/cc/lto.go
index acdc767..abd8dfb 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -45,8 +45,6 @@
 		Thin  *bool `android:"arch_variant"`
 	} `android:"arch_variant"`
 
-	GlobalThin *bool `blueprint:"mutated"`
-
 	// Dep properties indicate that this module needs to be built with LTO
 	// since it is an object dependency of an LTO module.
 	FullDep bool `blueprint:"mutated"`
@@ -71,7 +69,13 @@
 	if ctx.Config().IsEnvTrue("DISABLE_LTO") {
 		lto.Properties.Lto.Never = boolPtr(true)
 	} else if ctx.Config().IsEnvTrue("GLOBAL_THINLTO") {
-		lto.Properties.GlobalThin = boolPtr(true)
+		staticLib := ctx.static() && !ctx.staticBinary()
+		hostBin := ctx.Host()
+		if !staticLib && !hostBin {
+			if !lto.Never() && !lto.FullLTO() {
+				lto.Properties.Lto.Thin = boolPtr(true)
+			}
+		}
 	}
 }
 
@@ -145,12 +149,6 @@
 }
 
 func (lto *lto) ThinLTO() bool {
-	if Bool(lto.Properties.GlobalThin) {
-		if !lto.Never() && !lto.FullLTO() {
-			return true
-		}
-	}
-
 	return Bool(lto.Properties.Lto.Thin)
 }
 
diff --git a/java/java_test.go b/java/java_test.go
index 9e63577..f16639a 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1487,6 +1487,12 @@
 			libs: ["foo"],
 			sdk_version: "system_29",
 		}
+		java_library {
+			name: "baz-module-30",
+			srcs: ["c.java"],
+			libs: ["foo"],
+			sdk_version: "module_30",
+		}
 		`)
 
 	// check the existence of the internal modules
@@ -1533,6 +1539,13 @@
 			"prebuilts/sdk/29/system/foo.jar")
 	}
 
+	bazModule30Javac := ctx.ModuleForTests("baz-module-30", "android_common").Rule("javac")
+	// tests if "baz-module-30" is actually linked to the module 30 stubs lib
+	if !strings.Contains(bazModule30Javac.Args["classpath"], "prebuilts/sdk/30/module-lib/foo.jar") {
+		t.Errorf("baz-module-30 javac classpath %v does not contain %q", bazModule30Javac.Args["classpath"],
+			"prebuilts/sdk/30/module-lib/foo.jar")
+	}
+
 	// test if baz has exported SDK lib names foo and bar to qux
 	qux := ctx.ModuleForTests("qux", "android_common")
 	if quxLib, ok := qux.Module().(*Library); ok {
diff --git a/java/sdk.go b/java/sdk.go
index f599265..971791f 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -222,7 +222,7 @@
 		return ctx.Config().AlwaysUsePrebuiltSdks()
 	} else if s.version.isNumbered() {
 		// validation check
-		if s.kind != sdkPublic && s.kind != sdkSystem && s.kind != sdkTest {
+		if s.kind != sdkPublic && s.kind != sdkSystem && s.kind != sdkTest && s.kind != sdkModule {
 			panic(fmt.Errorf("prebuilt SDK is not not available for sdkKind=%q", s.kind))
 			return false
 		}
diff --git a/java/testing.go b/java/testing.go
index a472413..461fd3f 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -55,6 +55,8 @@
 		"prebuilts/sdk/30/public/framework.aidl":                   nil,
 		"prebuilts/sdk/30/system/android.jar":                      nil,
 		"prebuilts/sdk/30/system/foo.jar":                          nil,
+		"prebuilts/sdk/30/module-lib/android.jar":                  nil,
+		"prebuilts/sdk/30/module-lib/foo.jar":                      nil,
 		"prebuilts/sdk/30/public/core-for-system-modules.jar":      nil,
 		"prebuilts/sdk/current/core/android.jar":                   nil,
 		"prebuilts/sdk/current/public/android.jar":                 nil,
diff --git a/rust/binary.go b/rust/binary.go
index e95cb3a..2758ae0 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -145,6 +145,9 @@
 	}
 }
 
-func (binary *binaryDecorator) staticStd(ctx *depsContext) bool {
-	return binary.baseCompiler.staticStd(ctx) || Bool(binary.Properties.Prefer_rlib)
+func (binary *binaryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+	if Bool(binary.Properties.Prefer_rlib) {
+		return RlibLinkage
+	}
+	return binary.baseCompiler.stdLinkage(ctx)
 }
diff --git a/rust/compiler.go b/rust/compiler.go
index aeb904b..102f9dc 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -24,6 +24,14 @@
 	"android/soong/rust/config"
 )
 
+type RustLinkage int
+
+const (
+	DefaultLinkage RustLinkage = iota
+	RlibLinkage
+	DylibLinkage
+)
+
 func (compiler *baseCompiler) edition() string {
 	return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition)
 }
@@ -146,12 +154,12 @@
 	panic("baseCompiler does not implement coverageOutputZipPath()")
 }
 
-func (compiler *baseCompiler) staticStd(ctx *depsContext) bool {
+func (compiler *baseCompiler) stdLinkage(ctx *depsContext) RustLinkage {
 	// For devices, we always link stdlibs in as dylibs by default.
 	if ctx.Device() {
-		return false
+		return DylibLinkage
 	} else {
-		return true
+		return RlibLinkage
 	}
 }
 
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
index 62d469e..483dddb 100644
--- a/rust/config/allowed_list.go
+++ b/rust/config/allowed_list.go
@@ -1,6 +1,10 @@
 package config
 
 var (
+	// When adding a new path below, add a rustfmt.toml file at the root of
+	// the repository and enable the rustfmt repo hook. See aosp/1347562
+	// for an example.
+	// TODO(b/160223496): enable rustfmt globally.
 	RustAllowedPaths = []string{
 		"external/minijail",
 		"external/rust",
diff --git a/rust/library.go b/rust/library.go
index 2792c5b..7a77706 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -158,9 +158,12 @@
 	return library.MutatedProperties.VariantIsStatic
 }
 
-func (library *libraryDecorator) staticStd(ctx *depsContext) bool {
-	// libraries should only request the staticStd when building a static FFI or when variant is staticStd
-	return library.static() || library.MutatedProperties.VariantIsStaticStd
+func (library *libraryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+	// libraries should only request the RlibLinkage when building a static FFI or when variant is StaticStd
+	if library.static() || library.MutatedProperties.VariantIsStaticStd {
+		return RlibLinkage
+	}
+	return DefaultLinkage
 }
 
 func (library *libraryDecorator) source() bool {
diff --git a/rust/project_json.go b/rust/project_json.go
index 8310479..8d161b2 100644
--- a/rust/project_json.go
+++ b/rust/project_json.go
@@ -30,16 +30,6 @@
 //
 //   $ SOONG_GEN_RUST_PROJECT=1 m nothing
 
-func init() {
-	android.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
-}
-
-func rustProjectGeneratorSingleton() android.Singleton {
-	return &projectGeneratorSingleton{}
-}
-
-type projectGeneratorSingleton struct{}
-
 const (
 	// Environment variables used to control the behavior of this singleton.
 	envVariableCollectRustDeps = "SOONG_GEN_RUST_PROJECT"
@@ -49,6 +39,7 @@
 // The format of rust-project.json is not yet finalized. A current description is available at:
 // https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/manual.adoc#non-cargo-based-projects
 type rustProjectDep struct {
+	// The Crate attribute is the index of the dependency in the Crates array in rustProjectJson.
 	Crate int    `json:"crate"`
 	Name  string `json:"name"`
 }
@@ -71,12 +62,50 @@
 	Deps map[string]int
 }
 
-func mergeDependencies(ctx android.SingletonContext, project *rustProjectJson,
-	knownCrates map[string]crateInfo, module android.Module,
-	crate *rustProjectCrate, deps map[string]int) {
+type projectGeneratorSingleton struct {
+	project     rustProjectJson
+	knownCrates map[string]crateInfo
+}
+
+func rustProjectGeneratorSingleton() android.Singleton {
+	return &projectGeneratorSingleton{}
+}
+
+func init() {
+	android.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
+}
+
+// librarySource finds the main source file (.rs) for a crate.
+func librarySource(ctx android.SingletonContext, rModule *Module, rustLib *libraryDecorator) (string, bool) {
+	srcs := rustLib.baseCompiler.Properties.Srcs
+	if len(srcs) != 0 {
+		return path.Join(ctx.ModuleDir(rModule), srcs[0]), true
+	}
+	if !rustLib.source() {
+		return "", false
+	}
+	// It is a SourceProvider module. If this module is host only, uses the variation for the host.
+	// Otherwise, use the variation for the primary target.
+	switch rModule.hod {
+	case android.HostSupported:
+	case android.HostSupportedNoCross:
+		if rModule.Target().String() != ctx.Config().BuildOSTarget.String() {
+			return "", false
+		}
+	default:
+		if rModule.Target().String() != ctx.Config().Targets[android.Android][0].String() {
+			return "", false
+		}
+	}
+	src := rustLib.sourceProvider.Srcs()[0]
+	return src.String(), true
+}
+
+func (singleton *projectGeneratorSingleton) mergeDependencies(ctx android.SingletonContext,
+	module android.Module, crate *rustProjectCrate, deps map[string]int) {
 
 	ctx.VisitDirectDeps(module, func(child android.Module) {
-		childId, childCrateName, ok := appendLibraryAndDeps(ctx, project, knownCrates, child)
+		childId, childCrateName, ok := singleton.appendLibraryAndDeps(ctx, child)
 		if !ok {
 			return
 		}
@@ -88,12 +117,10 @@
 	})
 }
 
-// appendLibraryAndDeps creates a rustProjectCrate for the module argument and
-// appends it to the rustProjectJson struct.  It visits the dependencies of the
-// module depth-first. If the current module is already in knownCrates, its
-// dependencies are merged. Returns a tuple (id, crate_name, ok).
-func appendLibraryAndDeps(ctx android.SingletonContext, project *rustProjectJson,
-	knownCrates map[string]crateInfo, module android.Module) (int, string, bool) {
+// appendLibraryAndDeps creates a rustProjectCrate for the module argument and appends it to singleton.project.
+// It visits the dependencies of the module depth-first so the dependency ID can be added to the current module. If the
+// current module is already in singleton.knownCrates, its dependencies are merged. Returns a tuple (id, crate_name, ok).
+func (singleton *projectGeneratorSingleton) appendLibraryAndDeps(ctx android.SingletonContext, module android.Module) (int, string, bool) {
 	rModule, ok := module.(*Module)
 	if !ok {
 		return 0, "", false
@@ -107,46 +134,45 @@
 	}
 	moduleName := ctx.ModuleName(module)
 	crateName := rModule.CrateName()
-	if cInfo, ok := knownCrates[moduleName]; ok {
+	if cInfo, ok := singleton.knownCrates[moduleName]; ok {
 		// We have seen this crate already; merge any new dependencies.
-		crate := project.Crates[cInfo.ID]
-		mergeDependencies(ctx, project, knownCrates, module, &crate, cInfo.Deps)
-		project.Crates[cInfo.ID] = crate
+		crate := singleton.project.Crates[cInfo.ID]
+		singleton.mergeDependencies(ctx, module, &crate, cInfo.Deps)
+		singleton.project.Crates[cInfo.ID] = crate
 		return cInfo.ID, crateName, true
 	}
 	crate := rustProjectCrate{Deps: make([]rustProjectDep, 0), Cfgs: make([]string, 0)}
-	srcs := rustLib.baseCompiler.Properties.Srcs
-	if len(srcs) == 0 {
+	rootModule, ok := librarySource(ctx, rModule, rustLib)
+	if !ok {
 		return 0, "", false
 	}
-	crate.RootModule = path.Join(ctx.ModuleDir(rModule), srcs[0])
+	crate.RootModule = rootModule
 	crate.Edition = rustLib.baseCompiler.edition()
 
 	deps := make(map[string]int)
-	mergeDependencies(ctx, project, knownCrates, module, &crate, deps)
+	singleton.mergeDependencies(ctx, module, &crate, deps)
 
-	id := len(project.Crates)
-	knownCrates[moduleName] = crateInfo{ID: id, Deps: deps}
-	project.Crates = append(project.Crates, crate)
+	id := len(singleton.project.Crates)
+	singleton.knownCrates[moduleName] = crateInfo{ID: id, Deps: deps}
+	singleton.project.Crates = append(singleton.project.Crates, crate)
 	// rust-analyzer requires that all crates belong to at least one root:
 	// https://github.com/rust-analyzer/rust-analyzer/issues/4735.
-	project.Roots = append(project.Roots, path.Dir(crate.RootModule))
+	singleton.project.Roots = append(singleton.project.Roots, path.Dir(crate.RootModule))
 	return id, crateName, true
 }
 
-func (r *projectGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+func (singleton *projectGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
 	if !ctx.Config().IsEnvTrue(envVariableCollectRustDeps) {
 		return
 	}
 
-	project := rustProjectJson{}
-	knownCrates := make(map[string]crateInfo)
+	singleton.knownCrates = make(map[string]crateInfo)
 	ctx.VisitAllModules(func(module android.Module) {
-		appendLibraryAndDeps(ctx, &project, knownCrates, module)
+		singleton.appendLibraryAndDeps(ctx, module)
 	})
 
 	path := android.PathForOutput(ctx, rustProjectJsonFileName)
-	err := createJsonFile(project, path)
+	err := createJsonFile(singleton.project, path)
 	if err != nil {
 		ctx.Errorf(err.Error())
 	}
diff --git a/rust/project_json_test.go b/rust/project_json_test.go
index 8521940..11964f3 100644
--- a/rust/project_json_test.go
+++ b/rust/project_json_test.go
@@ -18,6 +18,7 @@
 	"encoding/json"
 	"io/ioutil"
 	"path/filepath"
+	"strings"
 	"testing"
 
 	"android/soong/android"
@@ -100,22 +101,51 @@
 	rust_library {
 		name: "liba",
 		srcs: ["src/lib.rs"],
-		rlibs: ["libbindings"],
+		rlibs: ["libbindings1"],
 		crate_name: "a"
 	}
 	rust_bindgen {
-		name: "libbindings",
-		crate_name: "bindings",
-		source_stem: "bindings",
+		name: "libbindings1",
+		crate_name: "bindings1",
+		source_stem: "bindings1",
 		host_supported: true,
 		wrapper_src: "src/any.h",
 	}
+	rust_library_host {
+		name: "libb",
+		srcs: ["src/lib.rs"],
+		rustlibs: ["libbindings2"],
+		crate_name: "b"
+	}
+	rust_bindgen_host {
+		name: "libbindings2",
+		crate_name: "bindings2",
+		source_stem: "bindings2",
+		wrapper_src: "src/any.h",
+	}
 	` + GatherRequiredDepsForTest()
 	fs := map[string][]byte{
 		"src/lib.rs": nil,
 	}
 	jsonContent := testProjectJson(t, bp, fs)
-	validateJsonCrates(t, jsonContent)
+	crates := validateJsonCrates(t, jsonContent)
+	for _, c := range crates {
+		crate, ok := c.(map[string]interface{})
+		if !ok {
+			t.Fatalf("Unexpected type for crate: %v", c)
+		}
+		rootModule, ok := crate["root_module"].(string)
+		if !ok {
+			t.Fatalf("Unexpected type for root_module: %v", crate["root_module"])
+		}
+		if strings.Contains(rootModule, "libbindings1") && !strings.Contains(rootModule, "android_arm64") {
+			t.Errorf("The source path for libbindings1 does not contain android_arm64, got %v", rootModule)
+		}
+		if strings.Contains(rootModule, "libbindings2") && !strings.Contains(rootModule, android.BuildOs.String()) {
+			t.Errorf("The source path for libbindings2 does not contain the BuildOs, got %v; want %v",
+				rootModule, android.BuildOs.String())
+		}
+	}
 }
 
 func TestProjectJsonMultiVersion(t *testing.T) {
diff --git a/rust/rust.go b/rust/rust.go
index 1f8b904..68e5a5b 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -294,7 +294,7 @@
 	Disabled() bool
 	SetDisabled()
 
-	staticStd(ctx *depsContext) bool
+	stdLinkage(ctx *depsContext) RustLinkage
 }
 
 type exportedFlagsProducer interface {
@@ -1002,8 +1002,9 @@
 		commonDepVariations = append(commonDepVariations,
 			blueprint.Variation{Mutator: "image", Variation: android.CoreVariation})
 	}
+
 	stdLinkage := "dylib-std"
-	if mod.compiler.staticStd(ctx) {
+	if mod.compiler.stdLinkage(ctx) == RlibLinkage {
 		stdLinkage = "rlib-std"
 	}
 
@@ -1035,7 +1036,7 @@
 		}
 	}
 	if deps.Stdlibs != nil {
-		if mod.compiler.staticStd(ctx) {
+		if mod.compiler.stdLinkage(ctx) == RlibLinkage {
 			actx.AddVariationDependencies(
 				append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "rlib"}),
 				rlibDepTag, deps.Stdlibs...)
diff --git a/rust/test.go b/rust/test.go
index 0679448..bc7f53c 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -134,6 +134,6 @@
 	return module.Init()
 }
 
-func (test *testDecorator) staticStd(ctx *depsContext) bool {
-	return true
+func (test *testDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+	return RlibLinkage
 }
diff --git a/rust/testing.go b/rust/testing.go
index ee303ed..42b0da1 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -117,6 +117,7 @@
 	ctx.RegisterModuleType("rust_binary", RustBinaryFactory)
 	ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
 	ctx.RegisterModuleType("rust_bindgen", RustBindgenFactory)
+	ctx.RegisterModuleType("rust_bindgen_host", RustBindgenHostFactory)
 	ctx.RegisterModuleType("rust_test", RustTestFactory)
 	ctx.RegisterModuleType("rust_test_host", RustTestHostFactory)
 	ctx.RegisterModuleType("rust_library", RustLibraryFactory)