Merge "Add support for using sdk_version: "module_<ver>""
diff --git a/android/androidmk.go b/android/androidmk.go
index e90e5f0..ddd51ff 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -639,3 +639,21 @@
// Make does not understand LinuxBionic
module.Os() == LinuxBionic
}
+
+func AndroidMkDataPaths(data []DataPath) []string {
+ var testFiles []string
+ for _, d := range data {
+ rel := d.SrcPath.Rel()
+ path := d.SrcPath.String()
+ if !strings.HasSuffix(path, rel) {
+ panic(fmt.Errorf("path %q does not end with %q", path, rel))
+ }
+ path = strings.TrimSuffix(path, rel)
+ testFileString := path + ":" + rel
+ if len(d.RelativeInstallPath) > 0 {
+ testFileString += ":" + d.RelativeInstallPath
+ }
+ testFiles = append(testFiles, testFileString)
+ }
+ return testFiles
+}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index c4fe3a3..f76181d 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -135,7 +135,7 @@
}
}
if len(newDataPaths) > 0 {
- fmt.Fprintln(w, "LOCAL_TEST_DATA :=", strings.Join(cc.AndroidMkDataPaths(newDataPaths), " "))
+ fmt.Fprintln(w, "LOCAL_TEST_DATA :=", strings.Join(android.AndroidMkDataPaths(newDataPaths), " "))
}
if fi.module != nil && len(fi.module.NoticeFiles()) > 0 {
diff --git a/cc/androidmk.go b/cc/androidmk.go
index f0e6152..4f149af 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -156,24 +156,6 @@
return []android.AndroidMkEntries{entries}
}
-func AndroidMkDataPaths(data []android.DataPath) []string {
- var testFiles []string
- for _, d := range data {
- rel := d.SrcPath.Rel()
- path := d.SrcPath.String()
- if !strings.HasSuffix(path, rel) {
- panic(fmt.Errorf("path %q does not end with %q", path, rel))
- }
- path = strings.TrimSuffix(path, rel)
- testFileString := path + ":" + rel
- if len(d.RelativeInstallPath) > 0 {
- testFileString += ":" + d.RelativeInstallPath
- }
- testFiles = append(testFiles, testFileString)
- }
- return testFiles
-}
-
func androidMkWriteExtraTestConfigs(extraTestConfigs android.Paths, entries *android.AndroidMkEntries) {
if len(extraTestConfigs) > 0 {
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
@@ -183,7 +165,7 @@
}
func androidMkWriteTestData(data []android.DataPath, ctx AndroidMkContext, entries *android.AndroidMkEntries) {
- testFiles := AndroidMkDataPaths(data)
+ testFiles := android.AndroidMkDataPaths(data)
if len(testFiles) > 0 {
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
entries.AddStrings("LOCAL_TEST_DATA", testFiles...)
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/python/androidmk.go b/python/androidmk.go
index 247b80d..8ad5889 100644
--- a/python/androidmk.go
+++ b/python/androidmk.go
@@ -15,11 +15,12 @@
package python
import (
- "android/soong/android"
"fmt"
"io"
"path/filepath"
"strings"
+
+ "android/soong/android"
)
type subAndroidMkProvider interface {
@@ -74,6 +75,11 @@
if !BoolDefault(p.binaryProperties.Auto_gen_config, true) {
fmt.Fprintln(w, "LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG := true")
}
+
+ if len(p.data) > 0 {
+ fmt.Fprintln(w, "LOCAL_TEST_DATA :=",
+ strings.Join(android.AndroidMkDataPaths(p.data), " "))
+ }
})
base.subAndroidMk(ret, p.binaryDecorator.pythonInstaller)
}
diff --git a/python/test.go b/python/test.go
index a669c73..434e71a 100644
--- a/python/test.go
+++ b/python/test.go
@@ -34,6 +34,10 @@
// the name of the test configuration template (for example "AndroidTestTemplate.xml") that
// should be installed with the module.
Test_config_template *string `android:"path,arch_variant"`
+
+ // list of files or filegroup modules that provide data that should be installed alongside
+ // the test
+ Data []string `android:"path,arch_variant"`
}
type testDecorator struct {
@@ -42,6 +46,8 @@
testProperties TestProperties
testConfig android.Path
+
+ data []android.DataPath
}
func (test *testDecorator) bootstrapperProps() []interface{} {
@@ -59,6 +65,12 @@
test.binaryDecorator.pythonInstaller.relative = ctx.ModuleName()
test.binaryDecorator.pythonInstaller.install(ctx, file)
+
+ dataSrcPaths := android.PathsForModuleSrc(ctx, test.testProperties.Data)
+
+ for _, dataSrcPath := range dataSrcPaths {
+ test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath})
+ }
}
func NewTest(hod android.HostOrDeviceSupported) *Module {
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/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/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)