Merge changes from topics "prebuilt_build_tool", "prebuilt_build_tool_make"
* changes:
Support per-module MakeVars
Switch cc's use of bison and flex to prebuilt_build_tool
Add prebuilt_build_tool to allow genrules to use prebuilt tools
diff --git a/android/Android.bp b/android/Android.bp
index 1627e9c..96f0983 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -47,6 +47,7 @@
"sdk.go",
"singleton.go",
"soong_config_modules.go",
+ "test_suites.go",
"testing.go",
"util.go",
"variable.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index dfc68c4..94b4b81 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -165,7 +165,7 @@
var ret []string
availableTaggedDists := TaggedDistFiles{}
- if a.DistFiles != nil && len(a.DistFiles[""]) > 0 {
+ if a.DistFiles != nil {
availableTaggedDists = a.DistFiles
} else if a.OutputFile.Valid() {
availableTaggedDists = MakeDefaultDistFiles(a.OutputFile.Path())
diff --git a/android/androidmk_test.go b/android/androidmk_test.go
index 250f086..a558f45 100644
--- a/android/androidmk_test.go
+++ b/android/androidmk_test.go
@@ -45,6 +45,8 @@
return PathsForTesting("one.out"), nil
case ".multiple":
return PathsForTesting("two.out", "three/four.out"), nil
+ case ".another-tag":
+ return PathsForTesting("another.out"), nil
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
@@ -123,6 +125,38 @@
bp: `
custom {
name: "foo",
+ dist: {
+ targets: ["my_goal"],
+ tag: ".another-tag",
+ }
+ }
+ `,
+ expectedAndroidMkLines: []string{
+ ".PHONY: my_goal\n",
+ "$(call dist-for-goals,my_goal,another.out:another.out)\n",
+ },
+ },
+ {
+ bp: `
+ custom {
+ name: "foo",
+ dists: [
+ {
+ targets: ["my_goal"],
+ tag: ".another-tag",
+ },
+ ],
+ }
+ `,
+ expectedAndroidMkLines: []string{
+ ".PHONY: my_goal\n",
+ "$(call dist-for-goals,my_goal,another.out:another.out)\n",
+ },
+ },
+ {
+ bp: `
+ custom {
+ name: "foo",
dists: [
{
targets: ["my_goal"],
diff --git a/android/paths.go b/android/paths.go
index 20ff55e..65f129c 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -1555,3 +1555,15 @@
}
return filepath.Join(absSrcDir, path)
}
+
+// A DataPath represents the path of a file to be used as data, for example
+// a test library to be installed alongside a test.
+// The data file should be installed (copied from `<SrcPath>`) to
+// `<install_root>/<RelativeInstallPath>/<filename>`, or
+// `<install_root>/<filename>` if RelativeInstallPath is empty.
+type DataPath struct {
+ // The path of the data file that should be copied into the data directory
+ SrcPath Path
+ // The install path of the data file, relative to the install root.
+ RelativeInstallPath string
+}
diff --git a/android/sdk.go b/android/sdk.go
index 8115b69..28f5cd5 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -34,10 +34,8 @@
RequiredSdks() SdkRefs
}
-// SdkAware is the interface that must be supported by any module to become a member of SDK or to be
-// built with SDK
-type SdkAware interface {
- Module
+// Provided to improve code navigation with the IDE.
+type sdkAwareWithoutModule interface {
RequiredSdks
sdkBase() *SdkBase
@@ -48,6 +46,13 @@
BuildWithSdks(sdks SdkRefs)
}
+// SdkAware is the interface that must be supported by any module to become a member of SDK or to be
+// built with SDK
+type SdkAware interface {
+ Module
+ sdkAwareWithoutModule
+}
+
// SdkRef refers to a version of an SDK
type SdkRef struct {
Name string
@@ -466,8 +471,7 @@
// Base structure for all implementations of SdkMemberProperties.
//
-// Contains common properties that apply across many different member types. These
-// are not affected by the optimization to extract common values.
+// Contains common properties that apply across many different member types.
type SdkMemberPropertiesBase struct {
// The number of unique os types supported by the member variants.
//
@@ -489,9 +493,7 @@
Os OsType `sdk:"keep"`
// The setting to use for the compile_multilib property.
- //
- // This property is set after optimization so there is no point in trying to optimize it.
- Compile_multilib string `sdk:"keep"`
+ Compile_multilib string `android:"arch_variant"`
}
// The os prefix to use for any file paths in the sdk.
diff --git a/android/test_suites.go b/android/test_suites.go
new file mode 100644
index 0000000..7b2d7dc
--- /dev/null
+++ b/android/test_suites.go
@@ -0,0 +1,75 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+func init() {
+ RegisterSingletonType("testsuites", testSuiteFilesFactory)
+}
+
+func testSuiteFilesFactory() Singleton {
+ return &testSuiteFiles{}
+}
+
+type testSuiteFiles struct {
+ robolectric WritablePath
+}
+
+type TestSuiteModule interface {
+ Module
+ TestSuites() []string
+}
+
+func (t *testSuiteFiles) GenerateBuildActions(ctx SingletonContext) {
+ files := make(map[string]map[string]InstallPaths)
+
+ ctx.VisitAllModules(func(m Module) {
+ if tsm, ok := m.(TestSuiteModule); ok {
+ for _, testSuite := range tsm.TestSuites() {
+ if files[testSuite] == nil {
+ files[testSuite] = make(map[string]InstallPaths)
+ }
+ name := ctx.ModuleName(m)
+ files[testSuite][name] = append(files[testSuite][name], tsm.filesToInstall()...)
+ }
+ }
+ })
+
+ t.robolectric = robolectricTestSuite(ctx, files["robolectric-tests"])
+
+ ctx.Phony("robolectric-tests", t.robolectric)
+}
+
+func (t *testSuiteFiles) MakeVars(ctx MakeVarsContext) {
+ ctx.DistForGoal("robolectric-tests", t.robolectric)
+}
+
+func robolectricTestSuite(ctx SingletonContext, files map[string]InstallPaths) WritablePath {
+ var installedPaths InstallPaths
+ for _, module := range SortedStringKeys(files) {
+ installedPaths = append(installedPaths, files[module]...)
+ }
+ testCasesDir := pathForInstall(ctx, BuildOs, "testcases", false).ToMakePath()
+
+ outputFile := PathForOutput(ctx, "packaging", "robolectric-tests.zip")
+ rule := NewRuleBuilder()
+ rule.Command().BuiltTool(ctx, "soong_zip").
+ FlagWithOutput("-o ", outputFile).
+ FlagWithArg("-P ", "host/testcases").
+ FlagWithArg("-C ", testCasesDir.String()).
+ FlagWithRspFileInputList("-l ", installedPaths.Paths())
+ rule.Build(pctx, ctx, "robolectric_tests_zip", "robolectric-tests.zip")
+
+ return outputFile
+}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index b9bcc3a..10cc4b6 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -116,9 +116,9 @@
if len(fi.symlinks) > 0 {
fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS :=", strings.Join(fi.symlinks, " "))
}
- newDataPaths := []android.Path{}
+ newDataPaths := []android.DataPath{}
for _, path := range fi.dataPaths {
- dataOutPath := modulePath + ":" + path.Rel()
+ dataOutPath := modulePath + ":" + path.SrcPath.Rel()
if ok := seenDataOutPaths[dataOutPath]; !ok {
newDataPaths = append(newDataPaths, path)
seenDataOutPaths[dataOutPath] = true
diff --git a/apex/apex.go b/apex/apex.go
index b29017d..d0c4e6e 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1145,7 +1145,7 @@
module android.Module
// list of symlinks that will be created in installDir that point to this apexFile
symlinks []string
- dataPaths android.Paths
+ dataPaths []android.DataPath
transitiveDep bool
moduleDir string
@@ -2112,7 +2112,7 @@
case android.PrebuiltDepTag:
// If the prebuilt is force disabled, remember to delete the prebuilt file
// that might have been installed in the previous builds
- if prebuilt, ok := child.(*Prebuilt); ok && prebuilt.isForceDisabled() {
+ if prebuilt, ok := child.(prebuilt); ok && prebuilt.isForceDisabled() {
a.prebuiltFileToDelete = prebuilt.InstallFilename()
}
}
diff --git a/apex/builder.go b/apex/builder.go
index 49e4642..a70c767 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -403,16 +403,16 @@
}
for _, d := range fi.dataPaths {
// TODO(eakammer): This is now the third repetition of ~this logic for test paths, refactoring should be possible
- relPath := d.Rel()
- dataPath := d.String()
+ relPath := d.SrcPath.Rel()
+ dataPath := d.SrcPath.String()
if !strings.HasSuffix(dataPath, relPath) {
panic(fmt.Errorf("path %q does not end with %q", dataPath, relPath))
}
- dataDest := android.PathForModuleOut(ctx, "image"+suffix, fi.apexRelativePath(relPath)).String()
+ dataDest := android.PathForModuleOut(ctx, "image"+suffix, fi.apexRelativePath(relPath), d.RelativeInstallPath).String()
- copyCommands = append(copyCommands, "cp -f "+d.String()+" "+dataDest)
- implicitInputs = append(implicitInputs, d)
+ copyCommands = append(copyCommands, "cp -f "+d.SrcPath.String()+" "+dataDest)
+ implicitInputs = append(implicitInputs, d.SrcPath)
}
}
@@ -473,7 +473,7 @@
if f.installDir == "bin" || strings.HasPrefix(f.installDir, "bin/") {
executablePaths = append(executablePaths, pathInApex)
for _, d := range f.dataPaths {
- readOnlyPaths = append(readOnlyPaths, filepath.Join(f.installDir, d.Rel()))
+ readOnlyPaths = append(readOnlyPaths, filepath.Join(f.installDir, d.RelativeInstallPath, d.SrcPath.Rel()))
}
for _, s := range f.symlinks {
executablePaths = append(executablePaths, filepath.Join(f.installDir, s))
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index bf574dc..d459f87 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -21,6 +21,7 @@
"android/soong/android"
"android/soong/java"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -39,9 +40,55 @@
"abis", "allow-prereleased", "sdk-version")
)
+type prebuilt interface {
+ isForceDisabled() bool
+ InstallFilename() string
+}
+
+type prebuiltCommon struct {
+ prebuilt android.Prebuilt
+ properties prebuiltCommonProperties
+}
+
+type prebuiltCommonProperties struct {
+ ForceDisable bool `blueprint:"mutated"`
+}
+
+func (p *prebuiltCommon) Prebuilt() *android.Prebuilt {
+ return &p.prebuilt
+}
+
+func (p *prebuiltCommon) isForceDisabled() bool {
+ return p.properties.ForceDisable
+}
+
+func (p *prebuiltCommon) checkForceDisable(ctx android.ModuleContext) bool {
+ // If the device is configured to use flattened APEX, force disable the prebuilt because
+ // the prebuilt is a non-flattened one.
+ forceDisable := ctx.Config().FlattenApex()
+
+ // Force disable the prebuilts when we are doing unbundled build. We do unbundled build
+ // to build the prebuilts themselves.
+ forceDisable = forceDisable || ctx.Config().UnbundledBuild()
+
+ // Force disable the prebuilts when coverage is enabled.
+ forceDisable = forceDisable || ctx.DeviceConfig().NativeCoverageEnabled()
+ forceDisable = forceDisable || ctx.Config().IsEnvTrue("EMMA_INSTRUMENT")
+
+ // b/137216042 don't use prebuilts when address sanitizer is on
+ forceDisable = forceDisable || android.InList("address", ctx.Config().SanitizeDevice()) ||
+ android.InList("hwaddress", ctx.Config().SanitizeDevice())
+
+ if forceDisable && p.prebuilt.SourceExists() {
+ p.properties.ForceDisable = true
+ return true
+ }
+ return false
+}
+
type Prebuilt struct {
android.ModuleBase
- prebuilt android.Prebuilt
+ prebuiltCommon
properties PrebuiltProperties
@@ -57,8 +104,7 @@
type PrebuiltProperties struct {
// the path to the prebuilt .apex file to import.
- Source string `blueprint:"mutated"`
- ForceDisable bool `blueprint:"mutated"`
+ Source string `blueprint:"mutated"`
Src *string
Arch struct {
@@ -93,10 +139,6 @@
return p.properties.Installable == nil || proptools.Bool(p.properties.Installable)
}
-func (p *Prebuilt) isForceDisabled() bool {
- return p.properties.ForceDisable
-}
-
func (p *Prebuilt) OutputFiles(tag string) (android.Paths, error) {
switch tag {
case "":
@@ -110,12 +152,8 @@
return proptools.StringDefault(p.properties.Filename, p.BaseModuleName()+imageApexSuffix)
}
-func (p *Prebuilt) Prebuilt() *android.Prebuilt {
- return &p.prebuilt
-}
-
func (p *Prebuilt) Name() string {
- return p.prebuilt.Name(p.ModuleBase.Name())
+ return p.prebuiltCommon.prebuilt.Name(p.ModuleBase.Name())
}
// prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex.
@@ -128,27 +166,6 @@
}
func (p *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) {
- // If the device is configured to use flattened APEX, force disable the prebuilt because
- // the prebuilt is a non-flattened one.
- forceDisable := ctx.Config().FlattenApex()
-
- // Force disable the prebuilts when we are doing unbundled build. We do unbundled build
- // to build the prebuilts themselves.
- forceDisable = forceDisable || ctx.Config().UnbundledBuild()
-
- // Force disable the prebuilts when coverage is enabled.
- forceDisable = forceDisable || ctx.DeviceConfig().NativeCoverageEnabled()
- forceDisable = forceDisable || ctx.Config().IsEnvTrue("EMMA_INSTRUMENT")
-
- // b/137216042 don't use prebuilts when address sanitizer is on
- forceDisable = forceDisable || android.InList("address", ctx.Config().SanitizeDevice()) ||
- android.InList("hwaddress", ctx.Config().SanitizeDevice())
-
- if forceDisable && p.prebuilt.SourceExists() {
- p.properties.ForceDisable = true
- return
- }
-
// This is called before prebuilt_select and prebuilt_postdeps mutators
// The mutators requires that src to be set correctly for each arch so that
// arch variants are disabled when src is not provided for the arch.
@@ -177,10 +194,6 @@
}
func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- if p.properties.ForceDisable {
- return
- }
-
// TODO(jungjw): Check the key validity.
p.inputApex = p.Prebuilt().SingleSourcePath(ctx)
p.installDir = android.PathForModuleInstall(ctx, "apex")
@@ -194,6 +207,12 @@
Input: p.inputApex,
Output: p.outputApex,
})
+
+ if p.prebuiltCommon.checkForceDisable(ctx) {
+ p.SkipInstall()
+ return
+ }
+
if p.installable() {
ctx.InstallFile(p.installDir, p.installFilename, p.inputApex)
}
@@ -227,7 +246,7 @@
type ApexSet struct {
android.ModuleBase
- prebuilt android.Prebuilt
+ prebuiltCommon
properties ApexSetProperties
@@ -270,12 +289,8 @@
return proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+imageApexSuffix)
}
-func (a *ApexSet) Prebuilt() *android.Prebuilt {
- return &a.prebuilt
-}
-
func (a *ApexSet) Name() string {
- return a.prebuilt.Name(a.ModuleBase.Name())
+ return a.prebuiltCommon.prebuilt.Name(a.ModuleBase.Name())
}
func (a *ApexSet) Overrides() []string {
@@ -297,7 +312,7 @@
ctx.ModuleErrorf("filename should end in %s for apex_set", imageApexSuffix)
}
- apexSet := a.prebuilt.SingleSourcePath(ctx)
+ apexSet := a.prebuiltCommon.prebuilt.SingleSourcePath(ctx)
a.outputApex = android.PathForModuleOut(ctx, a.installFilename)
ctx.Build(pctx,
android.BuildParams{
@@ -311,6 +326,12 @@
"sdk-version": ctx.Config().PlatformSdkVersion(),
},
})
+
+ if a.prebuiltCommon.checkForceDisable(ctx) {
+ a.SkipInstall()
+ return
+ }
+
a.installDir = android.PathForModuleInstall(ctx, "apex")
if a.installable() {
ctx.InstallFile(a.installDir, a.installFilename, a.outputApex)
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 3f812c2..e91b40a 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -149,21 +149,25 @@
return []android.AndroidMkEntries{entries}
}
-func AndroidMkDataPaths(data android.Paths) []string {
+func AndroidMkDataPaths(data []android.DataPath) []string {
var testFiles []string
for _, d := range data {
- rel := d.Rel()
- path := d.String()
+ 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)
- testFiles = append(testFiles, path+":"+rel)
+ testFileString := path + ":" + rel
+ if len(d.RelativeInstallPath) > 0 {
+ testFileString += ":" + d.RelativeInstallPath
+ }
+ testFiles = append(testFiles, testFileString)
}
return testFiles
}
-func androidMkWriteTestData(data android.Paths, ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+func androidMkWriteTestData(data []android.DataPath, ctx AndroidMkContext, entries *android.AndroidMkEntries) {
testFiles := AndroidMkDataPaths(data)
if len(testFiles) > 0 {
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
@@ -357,8 +361,11 @@
entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true)
}
})
-
- androidMkWriteTestData(benchmark.data, ctx, entries)
+ dataPaths := []android.DataPath{}
+ for _, srcPath := range benchmark.data {
+ dataPaths = append(dataPaths, android.DataPath{SrcPath: srcPath})
+ }
+ androidMkWriteTestData(dataPaths, ctx, entries)
}
func (test *testBinary) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go
index 372a72e..51d8b4e 100644
--- a/cc/binary_sdk_member.go
+++ b/cc/binary_sdk_member.go
@@ -140,10 +140,6 @@
}
func (p *nativeBinaryInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
- if p.Compile_multilib != "" {
- propertySet.AddProperty("compile_multilib", p.Compile_multilib)
- }
-
builder := ctx.SnapshotBuilder()
if p.outputFile != nil {
propertySet.AddProperty("srcs", []string{nativeBinaryPathFor(*p)})
diff --git a/cc/cc.go b/cc/cc.go
index 53528af..4ec98be 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1411,9 +1411,9 @@
return ok && test.isAllTestsVariation()
}
-func (c *Module) DataPaths() android.Paths {
+func (c *Module) DataPaths() []android.DataPath {
if p, ok := c.installer.(interface {
- dataPaths() android.Paths
+ dataPaths() []android.DataPath
}); ok {
return p.dataPaths()
}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 8a1c8ed..38a5c2d 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -539,7 +539,7 @@
data_libs: ["test_lib"],
gtest: false,
}
- `
+ `
config := TestConfig(buildDir, android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
@@ -564,7 +564,7 @@
}
outputPath := outputFiles[0].String()
- testBinaryPath := testBinary.dataPaths()[0].String()
+ testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
if !strings.HasSuffix(outputPath, "/main_test") {
t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
@@ -576,6 +576,53 @@
}
}
+func TestDataLibsRelativeInstallPath(t *testing.T) {
+ bp := `
+ cc_test_library {
+ name: "test_lib",
+ srcs: ["test_lib.cpp"],
+ relative_install_path: "foo/bar/baz",
+ gtest: false,
+ }
+
+ cc_test {
+ name: "main_test",
+ data_libs: ["test_lib"],
+ gtest: false,
+ }
+ `
+
+ config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+ config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+ config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
+
+ ctx := testCcWithConfig(t, config)
+ module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
+ testBinary := module.(*Module).linker.(*testBinary)
+ outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
+ if err != nil {
+ t.Fatalf("Expected cc_test to produce output files, error: %s", err)
+ }
+ if len(outputFiles) != 1 {
+ t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
+ }
+ if len(testBinary.dataPaths()) != 1 {
+ t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
+ }
+
+ outputPath := outputFiles[0].String()
+
+ if !strings.HasSuffix(outputPath, "/main_test") {
+ t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
+ }
+ entries := android.AndroidMkEntriesForTest(t, config, "", module)[0]
+ if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
+ t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
+ " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
+ }
+}
+
func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
ctx := testCcNoVndk(t, `
cc_library {
@@ -2919,6 +2966,52 @@
}
}
+func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
+ bp := `
+ cc_prebuilt_test_library_shared {
+ name: "test_lib",
+ relative_install_path: "foo/bar/baz",
+ srcs: ["srcpath/dontusethispath/baz.so"],
+ }
+
+ cc_test {
+ name: "main_test",
+ data_libs: ["test_lib"],
+ gtest: false,
+ }
+ `
+
+ config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
+ config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
+ config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
+
+ ctx := testCcWithConfig(t, config)
+ module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
+ testBinary := module.(*Module).linker.(*testBinary)
+ outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
+ if err != nil {
+ t.Fatalf("Expected cc_test to produce output files, error: %s", err)
+ }
+ if len(outputFiles) != 1 {
+ t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
+ }
+ if len(testBinary.dataPaths()) != 1 {
+ t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
+ }
+
+ outputPath := outputFiles[0].String()
+
+ if !strings.HasSuffix(outputPath, "/main_test") {
+ t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
+ }
+ entries := android.AndroidMkEntriesForTest(t, config, "", module)[0]
+ if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
+ t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
+ " but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
+ }
+}
+
func TestVersionedStubs(t *testing.T) {
ctx := testCc(t, `
cc_library_shared {
diff --git a/cc/pgo.go b/cc/pgo.go
index 9298e7a..674e1bb 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -199,8 +199,8 @@
return false
}
- // If at least one property exists, validate that all properties exist
- if !profileKindPresent || !filePresent || !benchmarksPresent {
+ // profileKindPresent and filePresent are mandatory properties.
+ if !profileKindPresent || !filePresent {
var missing []string
if !profileKindPresent {
missing = append(missing, "profile kind (either \"instrumentation\" or \"sampling\" property)")
@@ -208,13 +208,15 @@
if !filePresent {
missing = append(missing, "profile_file property")
}
- if !benchmarksPresent {
- missing = append(missing, "non-empty benchmarks property")
- }
missingProps := strings.Join(missing, ", ")
ctx.ModuleErrorf("PGO specification is missing properties: " + missingProps)
}
+ // Benchmark property is mandatory for instrumentation PGO.
+ if isInstrumentation && !benchmarksPresent {
+ ctx.ModuleErrorf("Instrumentation PGO specification is missing benchmark property")
+ }
+
if isSampling && isInstrumentation {
ctx.PropertyErrorf("pgo", "Exactly one of \"instrumentation\" and \"sampling\" properties must be set")
}
@@ -288,15 +290,17 @@
// Add flags to profile this module based on its profile_kind
if props.ShouldProfileModule && props.isInstrumentation() {
- return props.addInstrumentationProfileGatherFlags(ctx, flags)
+ props.addInstrumentationProfileGatherFlags(ctx, flags)
+ // Instrumentation PGO use and gather flags cannot coexist.
+ return flags
} else if props.ShouldProfileModule && props.isSampling() {
- return props.addSamplingProfileGatherFlags(ctx, flags)
+ props.addSamplingProfileGatherFlags(ctx, flags)
} else if ctx.DeviceConfig().SamplingPGO() {
- return props.addSamplingProfileGatherFlags(ctx, flags)
+ props.addSamplingProfileGatherFlags(ctx, flags)
}
if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") {
- return props.addProfileUseFlags(ctx, flags)
+ props.addProfileUseFlags(ctx, flags)
}
return flags
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 0751f1c..653b43e 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -26,6 +26,7 @@
ctx.RegisterModuleType("cc_prebuilt_library", PrebuiltLibraryFactory)
ctx.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
ctx.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
+ ctx.RegisterModuleType("cc_prebuilt_test_library_shared", PrebuiltSharedTestLibraryFactory)
ctx.RegisterModuleType("cc_prebuilt_object", prebuiltObjectFactory)
ctx.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory)
}
@@ -243,6 +244,16 @@
return module.Init()
}
+// cc_prebuilt_test_library_shared installs a precompiled shared library
+// to be used as a data dependency of a test-related module (such as cc_test, or
+// cc_test_library).
+func PrebuiltSharedTestLibraryFactory() android.Module {
+ module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported)
+ library.BuildOnlyShared()
+ library.baseInstaller = NewTestInstaller()
+ return module.Init()
+}
+
func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
module, library := NewPrebuiltLibrary(hod)
library.BuildOnlyShared()
diff --git a/cc/test.go b/cc/test.go
index 37afb0c..9b6864a 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -165,7 +165,7 @@
return test.baseCompiler.Properties.Srcs
}
-func (test *testBinary) dataPaths() android.Paths {
+func (test *testBinary) dataPaths() []android.DataPath {
return test.data
}
@@ -310,7 +310,7 @@
*binaryDecorator
*baseCompiler
Properties TestBinaryProperties
- data android.Paths
+ data []android.DataPath
testConfig android.Path
}
@@ -339,7 +339,11 @@
}
func (test *testBinary) install(ctx ModuleContext, file android.Path) {
- test.data = android.PathsForModuleSrc(ctx, test.Properties.Data)
+ dataSrcPaths := android.PathsForModuleSrc(ctx, test.Properties.Data)
+
+ for _, dataSrcPath := range dataSrcPaths {
+ test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath})
+ }
ctx.VisitDirectDepsWithTag(dataLibDepTag, func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
@@ -348,10 +352,14 @@
if !ok {
ctx.ModuleErrorf("data_lib %q is not a linkable cc module", depName)
}
+ ccModule, ok := dep.(*Module)
+ if !ok {
+ ctx.ModuleErrorf("data_lib %q is not a cc module", depName)
+ }
if ccDep.OutputFile().Valid() {
- test.data = append(test.data, ccDep.OutputFile().Path())
- } else {
- ctx.ModuleErrorf("data_lib %q has no output file", depName)
+ test.data = append(test.data,
+ android.DataPath{SrcPath: ccDep.OutputFile().Path(),
+ RelativeInstallPath: ccModule.installer.relativeInstallPath()})
}
})
diff --git a/java/Android.bp b/java/Android.bp
index 1fda7f7..fd06c46 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -38,6 +38,7 @@
"java_resources.go",
"kotlin.go",
"lint.go",
+ "legacy_core_platform_api_usage.go",
"platform_compat_config.go",
"plugin.go",
"prebuilt_apis.go",
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 8280cb1..84dee16 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -130,7 +130,7 @@
},
})
- return fixedManifest
+ return fixedManifest.WithoutRel()
}
func manifestMerger(ctx android.ModuleContext, manifest android.Path, staticLibManifests android.Paths,
@@ -155,5 +155,5 @@
},
})
- return mergedManifest
+ return mergedManifest.WithoutRel()
}
diff --git a/java/config/config.go b/java/config/config.go
index 0fe74c8..d2f4513 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -30,6 +30,8 @@
LegacyCorePlatformBootclasspathLibraries = []string{"legacy.core.platform.api.stubs", "core-lambda-stubs"}
LegacyCorePlatformSystemModules = "legacy-core-platform-api-stubs-system-modules"
+ StableCorePlatformBootclasspathLibraries = []string{"stable.core.platform.api.stubs", "core-lambda-stubs"}
+ StableCorePlatformSystemModules = "stable-core-platform-api-stubs-system-modules"
FrameworkLibraries = []string{"ext", "framework"}
DefaultLambdaStubsLibrary = "core-lambda-stubs"
SdkLambdaStubsPath = "prebuilts/sdk/tools/core-lambda-stubs.jar"
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
new file mode 100644
index 0000000..8af66d0
--- /dev/null
+++ b/java/legacy_core_platform_api_usage.go
@@ -0,0 +1,162 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "android/soong/android"
+ "android/soong/java/config"
+)
+
+var legacyCorePlatformApiModules = []string{
+ "ahat-test-dump",
+ "android.car",
+ "android.test.mock",
+ "android.test.mock.impl",
+ "AoapTestDeviceApp",
+ "AoapTestHostApp",
+ "api-stubs-docs",
+ "art_cts_jvmti_test_library",
+ "art-gtest-jars-MyClassNatives",
+ "BackupFrameworksServicesRoboTests",
+ "BandwidthEnforcementTest",
+ "BlockedNumberProvider",
+ "BluetoothInstrumentationTests",
+ "BluetoothMidiService",
+ "car-apps-common",
+ "CertInstaller",
+ "ConnectivityManagerTest",
+ "ContactsProvider",
+ "core-tests-support",
+ "CtsContentTestCases",
+ "CtsIkeTestCases",
+ "CtsLibcoreWycheproofBCTestCases",
+ "CtsMediaTestCases",
+ "CtsNetTestCases",
+ "CtsNetTestCasesLatestSdk",
+ "CtsSecurityTestCases",
+ "CtsUsageStatsTestCases",
+ "DisplayCutoutEmulationEmu01Overlay",
+ "DocumentsUIPerfTests",
+ "DocumentsUITests",
+ "DownloadProvider",
+ "DownloadProviderTests",
+ "DownloadProviderUi",
+ "DynamicSystemInstallationService",
+ "EmergencyInfo-lib",
+ "ethernet-service",
+ "EthernetServiceTests",
+ "ExternalStorageProvider",
+ "ExtServices",
+ "ExtServices-core",
+ "framework-all",
+ "framework-minus-apex",
+ "FrameworksCoreTests",
+ "FrameworksIkeTests",
+ "FrameworksNetCommonTests",
+ "FrameworksNetTests",
+ "FrameworksServicesRoboTests",
+ "FrameworksServicesTests",
+ "FrameworksUtilTests",
+ "hid",
+ "hidl_test_java_java",
+ "hwbinder",
+ "ims",
+ "KeyChain",
+ "ksoap2",
+ "LocalTransport",
+ "lockagent",
+ "mediaframeworktest",
+ "MediaProvider",
+ "MmsService",
+ "MtpDocumentsProvider",
+ "MultiDisplayProvider",
+ "NetworkStackIntegrationTestsLib",
+ "NetworkStackNextIntegrationTests",
+ "NetworkStackNextTests",
+ "NetworkStackTests",
+ "NetworkStackTestsLib",
+ "NfcNci",
+ "platform_library-docs",
+ "PrintSpooler",
+ "RollbackTest",
+ "services",
+ "services.accessibility",
+ "services.backup",
+ "services.core.unboosted",
+ "services.devicepolicy",
+ "services.print",
+ "services.usage",
+ "services.usb",
+ "Settings-core",
+ "SettingsLib",
+ "SettingsProvider",
+ "SettingsProviderTest",
+ "SettingsRoboTests",
+ "Shell",
+ "ShellTests",
+ "sl4a.Common",
+ "StatementService",
+ "SystemUI-core",
+ "SystemUISharedLib",
+ "SystemUI-tests",
+ "Telecom",
+ "TelecomUnitTests",
+ "telephony-common",
+ "TelephonyProvider",
+ "TelephonyProviderTests",
+ "TeleService",
+ "testables",
+ "TetheringTests",
+ "TetheringTestsLib",
+ "time_zone_distro_installer",
+ "time_zone_distro_installer-tests",
+ "time_zone_distro-tests",
+ "time_zone_updater",
+ "TvProvider",
+ "uiautomator-stubs-docs",
+ "UsbHostExternalManagementTestApp",
+ "UserDictionaryProvider",
+ "WallpaperBackup",
+ "wifi-service",
+}
+
+var legacyCorePlatformApiLookup = make(map[string]struct{})
+
+func init() {
+ for _, module := range legacyCorePlatformApiModules {
+ legacyCorePlatformApiLookup[module] = struct{}{}
+ }
+}
+
+func useLegacyCorePlatformApi(ctx android.EarlyModuleContext) bool {
+ _, found := legacyCorePlatformApiLookup[ctx.ModuleName()]
+ return found
+}
+
+func corePlatformSystemModules(ctx android.EarlyModuleContext) string {
+ if useLegacyCorePlatformApi(ctx) {
+ return config.LegacyCorePlatformSystemModules
+ } else {
+ return config.StableCorePlatformSystemModules
+ }
+}
+
+func corePlatformBootclasspathLibraries(ctx android.EarlyModuleContext) []string {
+ if useLegacyCorePlatformApi(ctx) {
+ return config.LegacyCorePlatformBootclasspathLibraries
+ } else {
+ return config.StableCorePlatformBootclasspathLibraries
+ }
+}
diff --git a/java/lint.go b/java/lint.go
index 20a7dc4..5d2c4f6 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -17,6 +17,7 @@
import (
"fmt"
"sort"
+ "strings"
"android/soong/android"
)
@@ -104,7 +105,16 @@
return
}
- ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), extraLintCheckTag, l.properties.Lint.Extra_check_modules...)
+ extraCheckModules := l.properties.Lint.Extra_check_modules
+
+ if checkOnly := ctx.Config().Getenv("ANDROID_LINT_CHECK"); checkOnly != "" {
+ if checkOnlyModules := ctx.Config().Getenv("ANDROID_LINT_CHECK_EXTRA_MODULES"); checkOnlyModules != "" {
+ extraCheckModules = strings.Split(checkOnlyModules, ",")
+ }
+ }
+
+ ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(),
+ extraLintCheckTag, extraCheckModules...)
}
func (l *linter) writeLintProjectXML(ctx android.ModuleContext,
@@ -262,7 +272,7 @@
apiVersionsXMLPath = copiedAPIVersionsXmlPath(ctx)
}
- rule.Command().
+ cmd := rule.Command().
Text("(").
Flag("JAVA_OPTS=-Xmx2048m").
FlagWithArg("ANDROID_SDK_HOME=", homeDir.String()).
@@ -282,9 +292,13 @@
FlagWithArg("--url ", fmt.Sprintf(".=.,%s=out", android.PathForOutput(ctx).String())).
Flag("--exitcode").
Flags(l.properties.Lint.Flags).
- Implicits(deps).
- Text("|| (").Text("cat").Input(text).Text("; exit 7)").
- Text(")")
+ Implicits(deps)
+
+ if checkOnly := ctx.Config().Getenv("ANDROID_LINT_CHECK"); checkOnly != "" {
+ cmd.FlagWithArg("--check ", checkOnly)
+ }
+
+ cmd.Text("|| (").Text("cat").Input(text).Text("; exit 7)").Text(")")
rule.Command().Text("rm -rf").Flag(cacheDir.String()).Flag(homeDir.String())
diff --git a/java/robolectric.go b/java/robolectric.go
index c6b07a1..4d68fd9 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -21,10 +21,13 @@
"strings"
"android/soong/android"
+ "android/soong/java/config"
+ "android/soong/tradefed"
)
func init() {
android.RegisterModuleType("android_robolectric_test", RobolectricTestFactory)
+ android.RegisterModuleType("android_robolectric_runtimes", robolectricRuntimesFactory)
}
var robolectricDefaultLibs = []string{
@@ -32,10 +35,13 @@
"Robolectric_all-target",
"mockito-robolectric-prebuilt",
"truth-prebuilt",
+ // TODO(ccross): this is not needed at link time
+ "junitxml",
}
var (
- roboCoverageLibsTag = dependencyTag{name: "roboSrcs"}
+ roboCoverageLibsTag = dependencyTag{name: "roboCoverageLibs"}
+ roboRuntimesTag = dependencyTag{name: "roboRuntimes"}
)
type robolectricProperties struct {
@@ -58,13 +64,28 @@
Library
robolectricProperties robolectricProperties
+ testProperties testProperties
libs []string
tests []string
+ manifest android.Path
+ resourceApk android.Path
+
+ combinedJar android.WritablePath
+
roboSrcJar android.Path
+
+ testConfig android.Path
+ data android.Paths
}
+func (r *robolectricTest) TestSuites() []string {
+ return r.testProperties.Test_suites
+}
+
+var _ android.TestSuiteModule = (*robolectricTest)(nil)
+
func (r *robolectricTest) DepsMutator(ctx android.BottomUpMutatorContext) {
r.Library.DepsMutator(ctx)
@@ -77,9 +98,16 @@
ctx.AddVariationDependencies(nil, libTag, robolectricDefaultLibs...)
ctx.AddVariationDependencies(nil, roboCoverageLibsTag, r.robolectricProperties.Coverage_libs...)
+
+ ctx.AddVariationDependencies(nil, roboRuntimesTag, "robolectric-android-all-prebuilts")
}
func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ r.testConfig = tradefed.AutoGenRobolectricTestConfig(ctx, r.testProperties.Test_config,
+ r.testProperties.Test_config_template, r.testProperties.Test_suites,
+ r.testProperties.Auto_gen_config)
+ r.data = android.PathsForModuleSrc(ctx, r.testProperties.Data)
+
roboTestConfig := android.PathForModuleGen(ctx, "robolectric").
Join(ctx, "com/android/tools/test_config.properties")
@@ -95,6 +123,9 @@
ctx.PropertyErrorf("instrumentation_for", "dependency must be an android_app")
}
+ r.manifest = instrumentedApp.mergedManifestFile
+ r.resourceApk = instrumentedApp.outputFile
+
generateRoboTestConfig(ctx, roboTestConfig, instrumentedApp)
r.extraResources = android.Paths{roboTestConfig}
@@ -104,10 +135,30 @@
r.generateRoboSrcJar(ctx, roboSrcJar, instrumentedApp)
r.roboSrcJar = roboSrcJar
- for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
- r.libs = append(r.libs, dep.(Dependency).BaseModuleName())
+ roboTestConfigJar := android.PathForModuleOut(ctx, "robolectric_samedir", "samedir_config.jar")
+ generateSameDirRoboTestConfigJar(ctx, roboTestConfigJar)
+
+ combinedJarJars := android.Paths{
+ // roboTestConfigJar comes first so that its com/android/tools/test_config.properties
+ // overrides the one from r.extraResources. The r.extraResources one can be removed
+ // once the Make test runner is removed.
+ roboTestConfigJar,
+ r.outputFile,
+ instrumentedApp.implementationAndResourcesJar,
}
+ for _, dep := range ctx.GetDirectDepsWithTag(libTag) {
+ m := dep.(Dependency)
+ r.libs = append(r.libs, m.BaseModuleName())
+ if !android.InList(m.BaseModuleName(), config.FrameworkLibraries) {
+ combinedJarJars = append(combinedJarJars, m.ImplementationAndResourcesJars()...)
+ }
+ }
+
+ r.combinedJar = android.PathForModuleOut(ctx, "robolectric_combined", r.outputFile.Base())
+ TransformJarsToJar(ctx, r.combinedJar, "combine jars", combinedJarJars, android.OptionalPath{},
+ false, nil, nil)
+
// TODO: this could all be removed if tradefed was used as the test runner, it will find everything
// annotated as a test and run it.
for _, src := range r.compiledJavaSrcs {
@@ -121,14 +172,38 @@
}
r.tests = append(r.tests, s)
}
+
+ r.data = append(r.data, r.manifest, r.resourceApk)
+
+ runtimes := ctx.GetDirectDepWithTag("robolectric-android-all-prebuilts", roboRuntimesTag)
+
+ installPath := android.PathForModuleInstall(ctx, r.BaseModuleName())
+
+ installedResourceApk := ctx.InstallFile(installPath, ctx.ModuleName()+".apk", r.resourceApk)
+ installedManifest := ctx.InstallFile(installPath, ctx.ModuleName()+"-AndroidManifest.xml", r.manifest)
+ installedConfig := ctx.InstallFile(installPath, ctx.ModuleName()+".config", r.testConfig)
+
+ var installDeps android.Paths
+ for _, runtime := range runtimes.(*robolectricRuntimes).runtimes {
+ installDeps = append(installDeps, runtime)
+ }
+ installDeps = append(installDeps, installedResourceApk, installedManifest, installedConfig)
+
+ for _, data := range android.PathsForModuleSrc(ctx, r.testProperties.Data) {
+ installedData := ctx.InstallFile(installPath, data.Rel(), data)
+ installDeps = append(installDeps, installedData)
+ }
+
+ ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.combinedJar, installDeps...)
}
-func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath, instrumentedApp *AndroidApp) {
+func generateRoboTestConfig(ctx android.ModuleContext, outputFile android.WritablePath,
+ instrumentedApp *AndroidApp) {
+ rule := android.NewRuleBuilder()
+
manifest := instrumentedApp.mergedManifestFile
resourceApk := instrumentedApp.outputFile
- rule := android.NewRuleBuilder()
-
rule.Command().Text("rm -f").Output(outputFile)
rule.Command().
Textf(`echo "android_merged_manifest=%s" >>`, manifest.String()).Output(outputFile).Text("&&").
@@ -141,6 +216,28 @@
rule.Build(pctx, ctx, "generate_test_config", "generate test_config.properties")
}
+func generateSameDirRoboTestConfigJar(ctx android.ModuleContext, outputFile android.ModuleOutPath) {
+ rule := android.NewRuleBuilder()
+
+ outputDir := outputFile.InSameDir(ctx)
+ configFile := outputDir.Join(ctx, "com/android/tools/test_config.properties")
+ rule.Temporary(configFile)
+ rule.Command().Text("rm -f").Output(outputFile).Output(configFile)
+ rule.Command().Textf("mkdir -p $(dirname %s)", configFile.String())
+ rule.Command().
+ Text("(").
+ Textf(`echo "android_merged_manifest=%s-AndroidManifest.xml" &&`, ctx.ModuleName()).
+ Textf(`echo "android_resource_apk=%s.apk"`, ctx.ModuleName()).
+ Text(") >>").Output(configFile)
+ rule.Command().
+ BuiltTool(ctx, "soong_zip").
+ FlagWithArg("-C ", outputDir.String()).
+ FlagWithInput("-f ", configFile).
+ FlagWithOutput("-o ", outputFile)
+
+ rule.Build(pctx, ctx, "generate_test_config_samedir", "generate test_config.properties")
+}
+
func (r *robolectricTest) generateRoboSrcJar(ctx android.ModuleContext, outputFile android.WritablePath,
instrumentedApp *AndroidApp) {
@@ -202,7 +299,6 @@
fmt.Fprintln(w, "LOCAL_ROBOTEST_TIMEOUT :=", *t)
}
fmt.Fprintln(w, "-include external/robolectric-shadows/run_robotests.mk")
-
}
// An android_robolectric_test module compiles tests against the Robolectric framework that can run on the local host
@@ -218,11 +314,74 @@
module.addHostProperties()
module.AddProperties(
&module.Module.deviceProperties,
- &module.robolectricProperties)
+ &module.robolectricProperties,
+ &module.testProperties)
module.Module.dexpreopter.isTest = true
module.Module.linter.test = true
+ module.testProperties.Test_suites = []string{"robolectric-tests"}
+
InitJavaModule(module, android.DeviceSupported)
return module
}
+
+func (r *robolectricTest) InstallBypassMake() bool { return true }
+func (r *robolectricTest) InstallInTestcases() bool { return true }
+func (r *robolectricTest) InstallForceOS() *android.OsType { return &android.BuildOs }
+
+func robolectricRuntimesFactory() android.Module {
+ module := &robolectricRuntimes{}
+ module.AddProperties(&module.props)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ return module
+}
+
+type robolectricRuntimesProperties struct {
+ Jars []string `android:"path"`
+ Lib *string
+}
+
+type robolectricRuntimes struct {
+ android.ModuleBase
+
+ props robolectricRuntimesProperties
+
+ runtimes []android.InstallPath
+}
+
+func (r *robolectricRuntimes) TestSuites() []string {
+ return []string{"robolectric-tests"}
+}
+
+var _ android.TestSuiteModule = (*robolectricRuntimes)(nil)
+
+func (r *robolectricRuntimes) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if !ctx.Config().UnbundledBuildUsePrebuiltSdks() && r.props.Lib != nil {
+ ctx.AddVariationDependencies(nil, libTag, String(r.props.Lib))
+ }
+}
+
+func (r *robolectricRuntimes) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ files := android.PathsForModuleSrc(ctx, r.props.Jars)
+
+ androidAllDir := android.PathForModuleInstall(ctx, "android-all")
+ for _, from := range files {
+ installedRuntime := ctx.InstallFile(androidAllDir, from.Base(), from)
+ r.runtimes = append(r.runtimes, installedRuntime)
+ }
+
+ if !ctx.Config().UnbundledBuildUsePrebuiltSdks() && r.props.Lib != nil {
+ runtimeFromSourceModule := ctx.GetDirectDepWithTag(String(r.props.Lib), libTag)
+ runtimeFromSourceJar := android.OutputFileForModule(ctx, runtimeFromSourceModule, "")
+
+ runtimeName := fmt.Sprintf("android-all-%s-robolectric-r0.jar",
+ ctx.Config().PlatformSdkCodename())
+ installedRuntime := ctx.InstallFile(androidAllDir, runtimeName, runtimeFromSourceJar)
+ r.runtimes = append(r.runtimes, installedRuntime)
+ }
+}
+
+func (r *robolectricRuntimes) InstallBypassMake() bool { return true }
+func (r *robolectricRuntimes) InstallInTestcases() bool { return true }
+func (r *robolectricRuntimes) InstallForceOS() *android.OsType { return &android.BuildOs }
diff --git a/java/sdk.go b/java/sdk.go
index 6564f6d..6e67a13 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -413,8 +413,8 @@
case sdkPrivate:
return sdkDep{
useModule: true,
- systemModules: config.LegacyCorePlatformSystemModules,
- bootclasspath: config.LegacyCorePlatformBootclasspathLibraries,
+ systemModules: corePlatformSystemModules(ctx),
+ bootclasspath: corePlatformBootclasspathLibraries(ctx),
classpath: config.FrameworkLibraries,
frameworkResModule: "framework-res",
}
@@ -438,8 +438,8 @@
case sdkCorePlatform:
return sdkDep{
useModule: true,
- systemModules: config.LegacyCorePlatformSystemModules,
- bootclasspath: config.LegacyCorePlatformBootclasspathLibraries,
+ systemModules: corePlatformSystemModules(ctx),
+ bootclasspath: corePlatformBootclasspathLibraries(ctx),
noFrameworksLibs: true,
}
case sdkPublic:
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 58e05e5..e3ba2c7 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -126,25 +126,23 @@
// the prebuilt jar.
sdkVersion string
+ // The annotation that identifies this API level, empty for the public API scope.
+ annotation string
+
// Extra arguments to pass to droidstubs for this scope.
- droidstubsArgs []string
-
- // The args that must be passed to droidstubs to generate the stubs source
- // for this scope.
//
- // The stubs source must include the definitions of everything that is in this
- // api scope and all the scopes that this one extends.
- droidstubsArgsForGeneratingStubsSource []string
+ // This is not used directly but is used to construct the droidstubsArgs.
+ extraArgs []string
- // The args that must be passed to droidstubs to generate the API for this scope.
+ // The args that must be passed to droidstubs to generate the API and stubs source
+ // for this scope, constructed dynamically by initApiScope().
//
// The API only includes the additional members that this scope adds over the scope
// that it extends.
- droidstubsArgsForGeneratingApi []string
-
- // True if the stubs source and api can be created by the same metalava invocation.
- // TODO(b/146727827) Now that metalava supports "API hierarchy", do we still need it?
- createStubsSourceAndApiTogether bool
+ //
+ // The stubs source must include the definitions of everything that is in this
+ // api scope and all the scopes that this one extends.
+ droidstubsArgs []string
// Whether the api scope can be treated as unstable, and should skip compat checks.
unstable bool
@@ -181,21 +179,23 @@
// To get the args needed to generate the stubs source append all the args from
// this scope and all the scopes it extends as each set of args adds additional
// members to the stubs.
- var stubsSourceArgs []string
- for s := scope; s != nil; s = s.extends {
- stubsSourceArgs = append(stubsSourceArgs, s.droidstubsArgs...)
+ var scopeSpecificArgs []string
+ if scope.annotation != "" {
+ scopeSpecificArgs = []string{"--show-annotation", scope.annotation}
}
- scope.droidstubsArgsForGeneratingStubsSource = stubsSourceArgs
+ for s := scope; s != nil; s = s.extends {
+ scopeSpecificArgs = append(scopeSpecificArgs, s.extraArgs...)
- // Currently the args needed to generate the API are the same as the args
- // needed to add additional members.
- apiArgs := scope.droidstubsArgs
- scope.droidstubsArgsForGeneratingApi = apiArgs
+ // Ensure that the generated stubs includes all the API elements from the API scope
+ // that this scope extends.
+ if s != scope && s.annotation != "" {
+ scopeSpecificArgs = append(scopeSpecificArgs, "--show-for-stub-purposes-annotation", s.annotation)
+ }
+ }
- // If the args needed to generate the stubs and API are the same then they
- // can be generated in a single invocation of metalava, otherwise they will
- // need separate invocations.
- scope.createStubsSourceAndApiTogether = reflect.DeepEqual(stubsSourceArgs, apiArgs)
+ // Escape any special characters in the arguments. This is needed because droidstubs
+ // passes these directly to the shell command.
+ scope.droidstubsArgs = proptools.ShellEscapeList(scopeSpecificArgs)
return scope
}
@@ -250,10 +250,10 @@
scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
return &module.sdkLibraryProperties.System
},
- apiFilePrefix: "system-",
- moduleSuffix: ".system",
- sdkVersion: "system_current",
- droidstubsArgs: []string{"-showAnnotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)"},
+ apiFilePrefix: "system-",
+ moduleSuffix: ".system",
+ sdkVersion: "system_current",
+ annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS)",
})
apiScopeTest = initApiScope(&apiScope{
name: "test",
@@ -262,11 +262,11 @@
scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
return &module.sdkLibraryProperties.Test
},
- apiFilePrefix: "test-",
- moduleSuffix: ".test",
- sdkVersion: "test_current",
- droidstubsArgs: []string{"-showAnnotation android.annotation.TestApi"},
- unstable: true,
+ apiFilePrefix: "test-",
+ moduleSuffix: ".test",
+ sdkVersion: "test_current",
+ annotation: "android.annotation.TestApi",
+ unstable: true,
})
apiScopeModuleLib = initApiScope(&apiScope{
name: "module-lib",
@@ -283,10 +283,7 @@
apiFilePrefix: "module-lib-",
moduleSuffix: ".module_lib",
sdkVersion: "module_current",
- droidstubsArgs: []string{
- "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES\\)",
- "--show-for-stub-purposes-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\)",
- },
+ annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES)",
})
apiScopeSystemServer = initApiScope(&apiScope{
name: "system-server",
@@ -303,11 +300,11 @@
apiFilePrefix: "system-server-",
moduleSuffix: ".system_server",
sdkVersion: "system_server_current",
- droidstubsArgs: []string{
- "--show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.SYSTEM_SERVER\\) ",
- "--hide-annotation android.annotation.Hide",
+ annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.SYSTEM_SERVER)",
+ extraArgs: []string{
+ "--hide-annotation", "android.annotation.Hide",
// com.android.* classes are okay in this interface"
- "--hide InternalClasses",
+ "--hide", "InternalClasses",
},
})
allApiScopes = apiScopes{
@@ -987,16 +984,8 @@
// Add dependencies to the stubs library
ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope))
- // If the stubs source and API cannot be generated together then add an additional dependency on
- // the API module.
- if apiScope.createStubsSourceAndApiTogether {
- // Add a dependency on the stubs source in order to access both stubs source and api information.
- ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.stubsSourceModuleName(apiScope))
- } else {
- // Add separate dependencies on the creators of the stubs source files and the API.
- ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, module.stubsSourceModuleName(apiScope))
- ctx.AddVariationDependencies(nil, apiScope.apiFileTag, module.apiModuleName(apiScope))
- }
+ // Add a dependency on the stubs source in order to access both stubs source and api information.
+ ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.stubsSourceModuleName(apiScope))
}
if module.requiresRuntimeImplementationLibrary() {
@@ -1199,7 +1188,7 @@
// Creates a droidstubs module that creates stubs source files from the given full source
// files and also updates and checks the API specification files.
-func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookContext, apiScope *apiScope, name string, createStubSources, createApi bool, scopeSpecificDroidstubsArgs []string) {
+func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookContext, apiScope *apiScope, name string, scopeSpecificDroidstubsArgs []string) {
props := struct {
Name *string
Visibility []string
@@ -1286,64 +1275,57 @@
}
droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
- if !createStubSources {
- // Stubs are not required.
- props.Generate_stubs = proptools.BoolPtr(false)
- }
-
// Add in scope specific arguments.
droidstubsArgs = append(droidstubsArgs, scopeSpecificDroidstubsArgs...)
props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
props.Args = proptools.StringPtr(strings.Join(droidstubsArgs, " "))
- if createApi {
- // List of APIs identified from the provided source files are created. They are later
- // compared against to the not-yet-released (a.k.a current) list of APIs and to the
- // last-released (a.k.a numbered) list of API.
- currentApiFileName := apiScope.apiFilePrefix + "current.txt"
- removedApiFileName := apiScope.apiFilePrefix + "removed.txt"
- apiDir := module.getApiDir()
- currentApiFileName = path.Join(apiDir, currentApiFileName)
- removedApiFileName = path.Join(apiDir, removedApiFileName)
+ // List of APIs identified from the provided source files are created. They are later
+ // compared against to the not-yet-released (a.k.a current) list of APIs and to the
+ // last-released (a.k.a numbered) list of API.
+ currentApiFileName := apiScope.apiFilePrefix + "current.txt"
+ removedApiFileName := apiScope.apiFilePrefix + "removed.txt"
+ apiDir := module.getApiDir()
+ currentApiFileName = path.Join(apiDir, currentApiFileName)
+ removedApiFileName = path.Join(apiDir, removedApiFileName)
- // check against the not-yet-release API
- props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
- props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
+ // check against the not-yet-release API
+ props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
+ props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
- if !apiScope.unstable {
- // check against the latest released API
- latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
- props.Check_api.Last_released.Api_file = latestApiFilegroupName
- props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
- module.latestRemovedApiFilegroupName(apiScope))
- props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
+ if !apiScope.unstable {
+ // check against the latest released API
+ latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
+ props.Check_api.Last_released.Api_file = latestApiFilegroupName
+ props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
+ module.latestRemovedApiFilegroupName(apiScope))
+ props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
- if proptools.Bool(module.sdkLibraryProperties.Api_lint.Enabled) {
- // Enable api lint.
- props.Check_api.Api_lint.Enabled = proptools.BoolPtr(true)
- props.Check_api.Api_lint.New_since = latestApiFilegroupName
+ if proptools.Bool(module.sdkLibraryProperties.Api_lint.Enabled) {
+ // Enable api lint.
+ props.Check_api.Api_lint.Enabled = proptools.BoolPtr(true)
+ props.Check_api.Api_lint.New_since = latestApiFilegroupName
- // If it exists then pass a lint-baseline.txt through to droidstubs.
- baselinePath := path.Join(apiDir, apiScope.apiFilePrefix+"lint-baseline.txt")
- baselinePathRelativeToRoot := path.Join(mctx.ModuleDir(), baselinePath)
- paths, err := mctx.GlobWithDeps(baselinePathRelativeToRoot, nil)
- if err != nil {
- mctx.ModuleErrorf("error checking for presence of %s: %s", baselinePathRelativeToRoot, err)
- }
- if len(paths) == 1 {
- props.Check_api.Api_lint.Baseline_file = proptools.StringPtr(baselinePath)
- } else if len(paths) != 0 {
- mctx.ModuleErrorf("error checking for presence of %s: expected one path, found: %v", baselinePathRelativeToRoot, paths)
- }
+ // If it exists then pass a lint-baseline.txt through to droidstubs.
+ baselinePath := path.Join(apiDir, apiScope.apiFilePrefix+"lint-baseline.txt")
+ baselinePathRelativeToRoot := path.Join(mctx.ModuleDir(), baselinePath)
+ paths, err := mctx.GlobWithDeps(baselinePathRelativeToRoot, nil)
+ if err != nil {
+ mctx.ModuleErrorf("error checking for presence of %s: %s", baselinePathRelativeToRoot, err)
+ }
+ if len(paths) == 1 {
+ props.Check_api.Api_lint.Baseline_file = proptools.StringPtr(baselinePath)
+ } else if len(paths) != 0 {
+ mctx.ModuleErrorf("error checking for presence of %s: expected one path, found: %v", baselinePathRelativeToRoot, paths)
}
}
+ }
- // Dist the api txt artifact for sdk builds.
- if !Bool(module.sdkLibraryProperties.No_dist) {
- props.Dist.Targets = []string{"sdk", "win_sdk"}
- props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.txt", module.BaseModuleName()))
- props.Dist.Dir = proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
- }
+ // Dist the api txt artifact for sdk builds.
+ if !Bool(module.sdkLibraryProperties.No_dist) {
+ props.Dist.Targets = []string{"sdk", "win_sdk"}
+ props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.txt", module.BaseModuleName()))
+ props.Dist.Dir = proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
}
mctx.CreateModule(DroidstubsFactory, &props)
@@ -1526,22 +1508,8 @@
}
for _, scope := range generatedScopes {
- stubsSourceArgs := scope.droidstubsArgsForGeneratingStubsSource
- stubsSourceModuleName := module.stubsSourceModuleName(scope)
-
- // If the args needed to generate the stubs and API are the same then they
- // can be generated in a single invocation of metalava, otherwise they will
- // need separate invocations.
- if scope.createStubsSourceAndApiTogether {
- // Use the stubs source name for legacy reasons.
- module.createStubsSourcesAndApi(mctx, scope, stubsSourceModuleName, true, true, stubsSourceArgs)
- } else {
- module.createStubsSourcesAndApi(mctx, scope, stubsSourceModuleName, true, false, stubsSourceArgs)
-
- apiArgs := scope.droidstubsArgsForGeneratingApi
- apiName := module.apiModuleName(scope)
- module.createStubsSourcesAndApi(mctx, scope, apiName, false, true, apiArgs)
- }
+ // Use the stubs source name for legacy reasons.
+ module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs)
module.createStubsLibrary(mctx, scope)
}
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 1f23b14..395da79 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -49,8 +49,8 @@
}{
{
name: "default",
- bootclasspath: config.LegacyCorePlatformBootclasspathLibraries,
- system: config.LegacyCorePlatformSystemModules,
+ bootclasspath: config.StableCorePlatformBootclasspathLibraries,
+ system: config.StableCorePlatformSystemModules,
java8classpath: config.FrameworkLibraries,
java9classpath: config.FrameworkLibraries,
aidl: "-Iframework/aidl",
@@ -58,16 +58,16 @@
{
name: `sdk_version:"core_platform"`,
properties: `sdk_version:"core_platform"`,
- bootclasspath: config.LegacyCorePlatformBootclasspathLibraries,
- system: config.LegacyCorePlatformSystemModules,
+ bootclasspath: config.StableCorePlatformBootclasspathLibraries,
+ system: config.StableCorePlatformSystemModules,
java8classpath: []string{},
aidl: "",
},
{
name: "blank sdk version",
properties: `sdk_version: "",`,
- bootclasspath: config.LegacyCorePlatformBootclasspathLibraries,
- system: config.LegacyCorePlatformSystemModules,
+ bootclasspath: config.StableCorePlatformBootclasspathLibraries,
+ system: config.StableCorePlatformSystemModules,
java8classpath: config.FrameworkLibraries,
java9classpath: config.FrameworkLibraries,
aidl: "-Iframework/aidl",
@@ -155,9 +155,9 @@
{
name: "nostdlib system_modules",
- properties: `sdk_version: "none", system_modules: "legacy-core-platform-api-stubs-system-modules"`,
- system: "legacy-core-platform-api-stubs-system-modules",
- bootclasspath: []string{"legacy-core-platform-api-stubs-system-modules-lib"},
+ properties: `sdk_version: "none", system_modules: "stable-core-platform-api-stubs-system-modules"`,
+ system: "stable-core-platform-api-stubs-system-modules",
+ bootclasspath: []string{"stable-core-platform-api-stubs-system-modules-lib"},
java8classpath: []string{},
},
{
diff --git a/java/testing.go b/java/testing.go
index 94f054e..e761743 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -136,7 +136,7 @@
name: "%s",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "legacy-core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
}
`, extra)
}
@@ -146,7 +146,7 @@
name: "framework",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "legacy-core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
aidl: {
export_include_dirs: ["framework/aidl"],
},
@@ -161,7 +161,7 @@
name: "android.hidl.base-V1.0-java",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "legacy-core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
installable: true,
}
@@ -169,7 +169,7 @@
name: "android.hidl.manager-V1.0-java",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "legacy-core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
installable: true,
}
@@ -177,7 +177,7 @@
name: "org.apache.http.legacy",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "legacy-core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
installable: true,
}
@@ -185,7 +185,7 @@
name: "android.test.base",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "legacy-core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
installable: true,
}
@@ -193,7 +193,7 @@
name: "android.test.mock",
srcs: ["a.java"],
sdk_version: "none",
- system_modules: "legacy-core-platform-api-stubs-system-modules",
+ system_modules: "stable-core-platform-api-stubs-system-modules",
installable: true,
}
`
diff --git a/rust/Android.bp b/rust/Android.bp
index d56de87..e03bf4f 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -10,6 +10,7 @@
srcs: [
"androidmk.go",
"binary.go",
+ "bindgen.go",
"builder.go",
"clippy.go",
"compiler.go",
@@ -19,11 +20,14 @@
"proc_macro.go",
"project_json.go",
"rust.go",
+ "source_provider.go",
"test.go",
"testing.go",
],
testSrcs: [
"binary_test.go",
+ "bindgen_test.go",
+ "builder_test.go",
"clippy_test.go",
"compiler_test.go",
"coverage_test.go",
diff --git a/rust/androidmk.go b/rust/androidmk.go
index aea899b..babbf91 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -55,6 +55,7 @@
ret := android.AndroidMkData{
OutputFile: mod.outputFile,
Include: "$(BUILD_SYSTEM)/soong_rust_prebuilt.mk",
+ SubName: mod.subName,
Extra: []android.AndroidMkExtraFunc{
func(w io.Writer, outputFile android.Path) {
if len(mod.Properties.AndroidMkRlibs) > 0 {
@@ -75,9 +76,11 @@
},
},
}
-
- mod.subAndroidMk(&ret, mod.compiler)
-
+ if mod.compiler != nil {
+ mod.subAndroidMk(&ret, mod.compiler)
+ } else if mod.sourceProvider != nil {
+ mod.subAndroidMk(&ret, mod.sourceProvider)
+ }
ret.SubName += mod.Properties.SubName
return ret
@@ -155,6 +158,25 @@
}
+func (sourceProvider *baseSourceProvider) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+ outFile := sourceProvider.outputFile
+ ret.Class = "ETC"
+ ret.OutputFile = android.OptionalPathForPath(outFile)
+ ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+ _, file := filepath.Split(outFile.String())
+ stem, suffix, _ := android.SplitFileExt(file)
+ fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
+ fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
+ })
+}
+
+func (bindgen *bindgenDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+ ctx.subAndroidMk(ret, bindgen.baseSourceProvider)
+ ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+ fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+ })
+}
+
func (compiler *baseCompiler) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
// Soong installation is only supported for host modules. Have Make
// installation trigger Soong installation.
diff --git a/rust/binary.go b/rust/binary.go
index 9fc52cd..48f51db 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -107,7 +107,7 @@
fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
srcPath, paths := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
- deps.SrcDeps = paths
+ deps.SrcDeps = append(deps.SrcDeps, paths...)
outputFile := android.PathForModuleOut(ctx, fileName)
binary.unstrippedOutputFile = outputFile
diff --git a/rust/bindgen.go b/rust/bindgen.go
new file mode 100644
index 0000000..132b1fd
--- /dev/null
+++ b/rust/bindgen.go
@@ -0,0 +1,176 @@
+// Copyright 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package rust
+
+import (
+ "github.com/google/blueprint"
+ "strings"
+
+ "android/soong/android"
+ "android/soong/cc"
+ ccConfig "android/soong/cc/config"
+)
+
+var (
+ defaultBindgenFlags = []string{""}
+
+ // bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures.
+ bindgenClangVersion = "clang-r383902c"
+ bindgenLibClangSoGit = "11git"
+
+ //TODO(b/160803703) Use a prebuilt bindgen instead of the built bindgen.
+ _ = pctx.SourcePathVariable("bindgenCmd", "out/host/${config.HostPrebuiltTag}/bin/bindgen")
+ _ = pctx.SourcePathVariable("bindgenClang",
+ "${ccConfig.ClangBase}/${config.HostPrebuiltTag}/"+bindgenClangVersion+"/bin/clang")
+ _ = pctx.SourcePathVariable("bindgenLibClang",
+ "${ccConfig.ClangBase}/${config.HostPrebuiltTag}/"+bindgenClangVersion+"/lib64/libclang.so."+bindgenLibClangSoGit)
+
+ //TODO(ivanlozano) Switch this to RuleBuilder
+ bindgen = pctx.AndroidStaticRule("bindgen",
+ blueprint.RuleParams{
+ Command: "CLANG_PATH=$bindgenClang LIBCLANG_PATH=$bindgenLibClang RUSTFMT=${config.RustBin}/rustfmt " +
+ "$bindgenCmd $flags $in -o $out -- $cflags",
+ CommandDeps: []string{"$bindgenCmd"},
+ },
+ "flags", "cflags")
+)
+
+func init() {
+ android.RegisterModuleType("rust_bindgen", RustBindgenFactory)
+}
+
+var _ SourceProvider = (*bindgenDecorator)(nil)
+
+type BindgenProperties struct {
+ // The wrapper header file
+ Wrapper_src *string `android:"path,arch_variant"`
+
+ // list of bindgen-specific flags and options
+ Flags []string `android:"arch_variant"`
+
+ // list of clang flags required to correctly interpret the headers.
+ Cflags []string `android:"arch_variant"`
+
+ // list of directories relative to the Blueprints file that will
+ // be added to the include path using -I
+ Local_include_dirs []string `android:"arch_variant,variant_prepend"`
+
+ // list of static libraries that provide headers for this binding.
+ Static_libs []string `android:"arch_variant,variant_prepend"`
+
+ // list of shared libraries that provide headers for this binding.
+ Shared_libs []string `android:"arch_variant"`
+
+ //TODO(b/161141999) Add support for headers from cc_library_header modules.
+}
+
+type bindgenDecorator struct {
+ *baseSourceProvider
+
+ Properties BindgenProperties
+}
+
+func (b *bindgenDecorator) libraryExports(ctx android.ModuleContext) (android.Paths, []string) {
+ var libraryPaths android.Paths
+ var libraryFlags []string
+
+ for _, static_lib := range b.Properties.Static_libs {
+ if dep, ok := ctx.GetDirectDepWithTag(static_lib, cc.StaticDepTag).(*cc.Module); ok {
+ libraryPaths = append(libraryPaths, dep.ExportedIncludeDirs()...)
+ libraryFlags = append(libraryFlags, dep.ExportedFlags()...)
+ }
+ }
+ for _, shared_lib := range b.Properties.Shared_libs {
+ if dep, ok := ctx.GetDirectDepWithTag(shared_lib, cc.SharedDepTag).(*cc.Module); ok {
+ libraryPaths = append(libraryPaths, dep.ExportedIncludeDirs()...)
+ libraryFlags = append(libraryFlags, dep.ExportedFlags()...)
+ }
+ }
+
+ return libraryPaths, libraryFlags
+}
+
+func (b *bindgenDecorator) generateSource(ctx android.ModuleContext) android.Path {
+ ccToolchain := ccConfig.FindToolchain(ctx.Os(), ctx.Arch())
+ includes, exportedFlags := b.libraryExports(ctx)
+
+ var cflags []string
+ cflags = append(cflags, b.Properties.Cflags...)
+ cflags = append(cflags, "-target "+ccToolchain.ClangTriple())
+ cflags = append(cflags, strings.ReplaceAll(ccToolchain.ToolchainClangCflags(), "${config.", "${ccConfig."))
+ cflags = append(cflags, exportedFlags...)
+ for _, include := range includes {
+ cflags = append(cflags, "-I"+include.String())
+ }
+ for _, include := range b.Properties.Local_include_dirs {
+ cflags = append(cflags, "-I"+android.PathForModuleSrc(ctx, include).String())
+ }
+
+ bindgenFlags := defaultBindgenFlags
+ bindgenFlags = append(bindgenFlags, strings.Join(b.Properties.Flags, " "))
+
+ wrapperFile := android.OptionalPathForModuleSrc(ctx, b.Properties.Wrapper_src)
+ if !wrapperFile.Valid() {
+ ctx.PropertyErrorf("wrapper_src", "invalid path to wrapper source")
+ }
+
+ outputFile := android.PathForModuleOut(ctx, b.baseSourceProvider.getStem(ctx)+".rs")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: bindgen,
+ Description: "bindgen " + wrapperFile.Path().Rel(),
+ Output: outputFile,
+ Input: wrapperFile.Path(),
+ Implicits: includes,
+ Args: map[string]string{
+ "flags": strings.Join(bindgenFlags, " "),
+ "cflags": strings.Join(cflags, " "),
+ },
+ })
+ b.baseSourceProvider.outputFile = outputFile
+ return outputFile
+}
+
+func (b *bindgenDecorator) sourceProviderProps() []interface{} {
+ return append(b.baseSourceProvider.sourceProviderProps(),
+ &b.Properties)
+}
+
+// rust_bindgen generates Rust FFI bindings to C libraries using bindgen given a wrapper header as the primary input.
+// Bindgen has a number of flags to control the generated source, and additional flags can be passed to clang to ensure
+// the header and generated source is appropriately handled.
+func RustBindgenFactory() android.Module {
+ module, _ := NewRustBindgen(android.HostAndDeviceSupported)
+ return module.Init()
+}
+
+func NewRustBindgen(hod android.HostOrDeviceSupported) (*Module, *bindgenDecorator) {
+ module := newModule(hod, android.MultilibBoth)
+
+ bindgen := &bindgenDecorator{
+ baseSourceProvider: NewSourceProvider(),
+ Properties: BindgenProperties{},
+ }
+ module.sourceProvider = bindgen
+
+ return module, bindgen
+}
+
+func (b *bindgenDecorator) sourceProviderDeps(ctx DepsContext, deps Deps) Deps {
+ deps = b.baseSourceProvider.sourceProviderDeps(ctx, deps)
+ deps.SharedLibs = append(deps.SharedLibs, b.Properties.Shared_libs...)
+ deps.StaticLibs = append(deps.StaticLibs, b.Properties.Static_libs...)
+ return deps
+}
diff --git a/rust/bindgen_test.go b/rust/bindgen_test.go
new file mode 100644
index 0000000..18e188f
--- /dev/null
+++ b/rust/bindgen_test.go
@@ -0,0 +1,56 @@
+// Copyright 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package rust
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestRustBindgen(t *testing.T) {
+ ctx := testRust(t, `
+ rust_bindgen {
+ name: "libbindgen",
+ wrapper_src: "src/any.h",
+ stem: "bindings",
+ flags: ["--bindgen-flag"],
+ cflags: ["--clang-flag"],
+ shared_libs: ["libfoo_shared"],
+ static_libs: ["libfoo_static"],
+ }
+ cc_library_shared {
+ name: "libfoo_shared",
+ export_include_dirs: ["shared_include"],
+ }
+ cc_library_static {
+ name: "libfoo_static",
+ export_include_dirs: ["static_include"],
+ }
+
+ `)
+ libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a").Output("bindings.rs")
+ if !strings.Contains(libbindgen.Args["flags"], "--bindgen-flag") {
+ t.Errorf("missing bindgen flags in rust_bindgen rule: flags %#v", libbindgen.Args["flags"])
+ }
+ if !strings.Contains(libbindgen.Args["cflags"], "--clang-flag") {
+ t.Errorf("missing clang cflags in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
+ }
+ if !strings.Contains(libbindgen.Args["cflags"], "-Ishared_include") {
+ t.Errorf("missing clang cflags in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
+ }
+ if !strings.Contains(libbindgen.Args["cflags"], "-Istatic_include") {
+ t.Errorf("missing clang cflags in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
+ }
+}
diff --git a/rust/builder.go b/rust/builder.go
index 7f94bb5..45cd268 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -28,7 +28,7 @@
_ = pctx.SourcePathVariable("rustcCmd", "${config.RustBin}/rustc")
rustc = pctx.AndroidStaticRule("rustc",
blueprint.RuleParams{
- Command: "$rustcCmd " +
+ Command: "$envVars $rustcCmd " +
"-C linker=${config.RustLinker} " +
"-C link-args=\"${crtBegin} ${config.RustLinkerArgs} ${linkFlags} ${crtEnd}\" " +
"--emit link -o $out --emit dep-info=$out.d $in ${libFlags} $rustcFlags",
@@ -37,19 +37,19 @@
Deps: blueprint.DepsGCC,
Depfile: "$out.d",
},
- "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd")
+ "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars")
_ = pctx.SourcePathVariable("clippyCmd", "${config.RustBin}/clippy-driver")
clippyDriver = pctx.AndroidStaticRule("clippy",
blueprint.RuleParams{
- Command: "$clippyCmd " +
+ Command: "$envVars $clippyCmd " +
// Because clippy-driver uses rustc as backend, we need to have some output even during the linting.
// Use the metadata output as it has the smallest footprint.
"--emit metadata -o $out $in ${libFlags} " +
"$rustcFlags $clippyFlags",
CommandDeps: []string{"$clippyCmd"},
},
- "rustcFlags", "libFlags", "clippyFlags")
+ "rustcFlags", "libFlags", "clippyFlags", "envVars")
zip = pctx.AndroidStaticRule("zip",
blueprint.RuleParams{
@@ -58,6 +58,14 @@
Rspfile: "$out.rsp",
RspfileContent: "$in",
})
+
+ cp = pctx.AndroidStaticRule("cp",
+ blueprint.RuleParams{
+ Command: "cp `cat $outDir.rsp` $outDir",
+ Rspfile: "${outDir}.rsp",
+ RspfileContent: "$in",
+ },
+ "outDir")
)
type buildOutput struct {
@@ -116,6 +124,7 @@
var inputs android.Paths
var implicits android.Paths
+ var envVars []string
var output buildOutput
var libFlags, rustcFlags, linkFlags []string
var implicitOutputs android.WritablePaths
@@ -166,7 +175,7 @@
implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
implicits = append(implicits, deps.StaticLibs...)
implicits = append(implicits, deps.SharedLibs...)
- implicits = append(implicits, deps.SrcDeps...)
+
if deps.CrtBegin.Valid() {
implicits = append(implicits, deps.CrtBegin.Path(), deps.CrtEnd.Path())
}
@@ -190,6 +199,32 @@
output.coverageFile = gcnoFile
}
+ if len(deps.SrcDeps) > 0 {
+ genSubDir := "out/"
+ moduleGenDir := android.PathForModuleOut(ctx, genSubDir)
+ var outputs android.WritablePaths
+
+ for _, genSrc := range deps.SrcDeps {
+ if android.SuffixInList(outputs.Strings(), genSubDir+genSrc.Base()) {
+ ctx.PropertyErrorf("srcs",
+ "multiple source providers generate the same filename output: "+genSrc.Base())
+ }
+ outputs = append(outputs, android.PathForModuleOut(ctx, genSubDir+genSrc.Base()))
+ }
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: cp,
+ Description: "cp " + moduleGenDir.Rel(),
+ Outputs: outputs,
+ Inputs: deps.SrcDeps,
+ Args: map[string]string{
+ "outDir": moduleGenDir.String(),
+ },
+ })
+ implicits = append(implicits, outputs.Paths()...)
+ envVars = append(envVars, "OUT_DIR=$$PWD/"+moduleGenDir.String())
+ }
+
if flags.Clippy {
clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
ctx.Build(pctx, android.BuildParams{
@@ -203,6 +238,7 @@
"rustcFlags": strings.Join(rustcFlags, " "),
"libFlags": strings.Join(libFlags, " "),
"clippyFlags": strings.Join(flags.ClippyFlags, " "),
+ "envVars": strings.Join(envVars, " "),
},
})
// Declare the clippy build as an implicit dependency of the original crate.
@@ -222,6 +258,7 @@
"libFlags": strings.Join(libFlags, " "),
"crtBegin": deps.CrtBegin.String(),
"crtEnd": deps.CrtEnd.String(),
+ "envVars": strings.Join(envVars, " "),
},
})
diff --git a/rust/builder_test.go b/rust/builder_test.go
new file mode 100644
index 0000000..04b67d9
--- /dev/null
+++ b/rust/builder_test.go
@@ -0,0 +1,40 @@
+// Copyright 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package rust
+
+import "testing"
+
+func TestSourceProviderCollision(t *testing.T) {
+ testRustError(t, "multiple source providers generate the same filename output: bindings.rs", `
+ rust_binary {
+ name: "source_collider",
+ srcs: [
+ "foo.rs",
+ ":libbindings1",
+ ":libbindings2",
+ ],
+ }
+ rust_bindgen {
+ name: "libbindings1",
+ stem: "bindings",
+ wrapper_src: "src/any.h",
+ }
+ rust_bindgen {
+ name: "libbindings2",
+ stem: "bindings",
+ wrapper_src: "src/any.h",
+ }
+ `)
+}
diff --git a/rust/compiler.go b/rust/compiler.go
index c20179b..ab3d2f4 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -46,6 +46,8 @@
const (
InstallInSystem installLocation = 0
InstallInData = iota
+
+ incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\""
)
type BaseCompilerProperties struct {
@@ -253,6 +255,7 @@
return String(compiler.Properties.Relative_install_path)
}
+// Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs.
func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
// The srcs can contain strings with prefix ":".
// They are dependent modules of this module, with android.SourceDepTag.
@@ -266,11 +269,11 @@
}
}
if numSrcs != 1 {
- ctx.PropertyErrorf("srcs", "srcs can only contain one path for a rust file")
+ ctx.PropertyErrorf("srcs", incorrectSourcesError)
}
if srcIndex != 0 {
ctx.PropertyErrorf("srcs", "main source file must be the first in srcs")
}
paths := android.PathsForModuleSrc(ctx, srcs)
- return paths[srcIndex], paths
+ return paths[srcIndex], paths[1:]
}
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index 58ca52a..b853196 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -43,7 +43,7 @@
// Test that we reject multiple source files.
func TestEnforceSingleSourceFile(t *testing.T) {
- singleSrcError := "srcs can only contain one path for a rust file"
+ singleSrcError := "srcs can only contain one path for a rust file and source providers prefixed by \":\""
// Test libraries
testRustError(t, singleSrcError, `
diff --git a/rust/library.go b/rust/library.go
index d718eb8..acca256 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -369,7 +369,7 @@
var outputFile android.WritablePath
srcPath, paths := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
- deps.SrcDeps = paths
+ deps.SrcDeps = append(deps.SrcDeps, paths...)
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
diff --git a/rust/prebuilt.go b/rust/prebuilt.go
index 3b4f40a..3d081c1 100644
--- a/rust/prebuilt.go
+++ b/rust/prebuilt.go
@@ -96,7 +96,9 @@
prebuilt.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs())
- deps.SrcDeps = paths
+ if len(paths) > 0 {
+ ctx.PropertyErrorf("srcs", "prebuilt libraries can only have one entry in srcs (the prebuilt path)")
+ }
prebuilt.unstrippedOutputFile = srcPath
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 49dbd8d..2752dc3 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -66,7 +66,7 @@
outputFile := android.PathForModuleOut(ctx, fileName)
srcPath, paths := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
- deps.SrcDeps = paths
+ deps.SrcDeps = append(deps.SrcDeps, paths...)
procMacro.unstrippedOutputFile = outputFile
diff --git a/rust/rust.go b/rust/rust.go
index 7a98c64..28f8e1a 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -42,6 +42,7 @@
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
})
pctx.Import("android/soong/rust/config")
+ pctx.ImportAs("ccConfig", "android/soong/cc/config")
}
type Flags struct {
@@ -61,9 +62,10 @@
AndroidMkProcMacroLibs []string
AndroidMkSharedLibs []string
AndroidMkStaticLibs []string
- SubName string `blueprint:"mutated"`
- PreventInstall bool
- HideFromMake bool
+
+ SubName string `blueprint:"mutated"`
+ PreventInstall bool
+ HideFromMake bool
}
type Module struct {
@@ -79,8 +81,27 @@
coverage *coverage
clippy *clippy
cachedToolchain config.Toolchain
+ sourceProvider SourceProvider
subAndroidMkOnce map[subAndroidMkProvider]bool
outputFile android.OptionalPath
+
+ subName string
+}
+
+func (mod *Module) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ if mod.sourceProvider != nil {
+ return mod.sourceProvider.Srcs(), nil
+ } else {
+ if mod.outputFile.Valid() {
+ return android.Paths{mod.outputFile.Path()}, nil
+ }
+ return android.Paths{}, nil
+ }
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
}
var _ android.ImageInterface = (*Module)(nil)
@@ -348,6 +369,7 @@
&LibraryCompilerProperties{},
&ProcMacroCompilerProperties{},
&PrebuiltProperties{},
+ &SourceProviderProperties{},
&TestProperties{},
&cc.CoverageProperties{},
&ClippyProperties{},
@@ -507,6 +529,9 @@
if mod.clippy != nil {
mod.AddProperties(mod.clippy.props()...)
}
+ if mod.sourceProvider != nil {
+ mod.AddProperties(mod.sourceProvider.sourceProviderProps()...)
+ }
android.InitAndroidArchModule(mod, mod.hod, mod.multilib)
@@ -645,6 +670,10 @@
if !mod.Properties.PreventInstall {
mod.compiler.install(ctx, mod.outputFile.Path())
}
+ } else if mod.sourceProvider != nil {
+ outputFile := mod.sourceProvider.generateSource(ctx)
+ mod.outputFile = android.OptionalPathForPath(outputFile)
+ mod.subName = ctx.ModuleSubDir()
}
}
@@ -653,6 +682,8 @@
if mod.compiler != nil {
deps = mod.compiler.compilerDeps(ctx, deps)
+ } else if mod.sourceProvider != nil {
+ deps = mod.sourceProvider.sourceProviderDeps(ctx, deps)
}
if mod.coverage != nil {
@@ -846,7 +877,6 @@
// Dedup exported flags from dependencies
depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
- depPaths.SrcDeps = android.FirstUniquePaths(depPaths.SrcDeps)
return depPaths
}
@@ -963,3 +993,5 @@
var BoolDefault = proptools.BoolDefault
var String = proptools.String
var StringPtr = proptools.StringPtr
+
+var _ android.OutputFileProducer = (*Module)(nil)
diff --git a/rust/rust_test.go b/rust/rust_test.go
index e803925..89dfb67 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -182,7 +182,7 @@
}
rust_library_host_rlib {
name: "librlib",
- srcs: ["foo.rs", ":my_generator"],
+ srcs: ["foo.rs"],
crate_name: "rlib",
}
rust_proc_macro {
@@ -190,38 +190,17 @@
srcs: ["foo.rs"],
crate_name: "pm",
}
- genrule {
- name: "my_generator",
- tools: ["any_rust_binary"],
- cmd: "$(location) -o $(out) $(in)",
- srcs: ["src/any.h"],
- out: ["src/any.rs"],
- }
rust_binary_host {
- name: "fizz-buzz-dep",
+ name: "fizz-buzz",
dylibs: ["libdylib"],
rlibs: ["librlib"],
proc_macros: ["libpm"],
static_libs: ["libstatic"],
shared_libs: ["libshared"],
- srcs: [
- "foo.rs",
- ":my_generator",
- ],
+ srcs: ["foo.rs"],
}
`)
- module := ctx.ModuleForTests("fizz-buzz-dep", "linux_glibc_x86_64").Module().(*Module)
- rlibmodule := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib").Module().(*Module)
-
- srcs := module.compiler.(*binaryDecorator).baseCompiler.Properties.Srcs
- if len(srcs) != 2 || !android.InList(":my_generator", srcs) {
- t.Errorf("missing module dependency in fizz-buzz)")
- }
-
- srcs = rlibmodule.compiler.(*libraryDecorator).baseCompiler.Properties.Srcs
- if len(srcs) != 2 || !android.InList(":my_generator", srcs) {
- t.Errorf("missing module dependency in rlib")
- }
+ module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
if !android.InList("libdylib", module.Properties.AndroidMkDylibs) {
@@ -245,6 +224,73 @@
}
}
+func TestSourceProviderDeps(t *testing.T) {
+ ctx := testRust(t, `
+ rust_binary {
+ name: "fizz-buzz-dep",
+ srcs: [
+ "foo.rs",
+ ":my_generator",
+ ":libbindings",
+ ],
+ }
+ rust_proc_macro {
+ name: "libprocmacro",
+ srcs: [
+ "foo.rs",
+ ":my_generator",
+ ":libbindings",
+ ],
+ crate_name: "procmacro",
+ }
+ rust_library {
+ name: "libfoo",
+ srcs: [
+ "foo.rs",
+ ":my_generator",
+ ":libbindings"],
+ crate_name: "foo",
+ }
+ genrule {
+ name: "my_generator",
+ tools: ["any_rust_binary"],
+ cmd: "$(location) -o $(out) $(in)",
+ srcs: ["src/any.h"],
+ out: ["src/any.rs"],
+ }
+ rust_bindgen {
+ name: "libbindings",
+ stem: "bindings",
+ host_supported: true,
+ wrapper_src: "src/any.h",
+ }
+ `)
+
+ libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib").Rule("rustc")
+ if !android.SuffixInList(libfoo.Implicits.Strings(), "/out/bindings.rs") {
+ t.Errorf("rust_bindgen generated source not included as implicit input for libfoo; Implicits %#v", libfoo.Implicits.Strings())
+ }
+ if !android.SuffixInList(libfoo.Implicits.Strings(), "/out/any.rs") {
+ t.Errorf("genrule generated source not included as implicit input for libfoo; Implicits %#v", libfoo.Implicits.Strings())
+ }
+
+ fizzBuzz := ctx.ModuleForTests("fizz-buzz-dep", "android_arm64_armv8-a").Rule("rustc")
+ if !android.SuffixInList(fizzBuzz.Implicits.Strings(), "/out/bindings.rs") {
+ t.Errorf("rust_bindgen generated source not included as implicit input for fizz-buzz-dep; Implicits %#v", libfoo.Implicits.Strings())
+ }
+ if !android.SuffixInList(fizzBuzz.Implicits.Strings(), "/out/any.rs") {
+ t.Errorf("genrule generated source not included as implicit input for fizz-buzz-dep; Implicits %#v", libfoo.Implicits.Strings())
+ }
+
+ libprocmacro := ctx.ModuleForTests("libprocmacro", "linux_glibc_x86_64").Rule("rustc")
+ if !android.SuffixInList(libprocmacro.Implicits.Strings(), "/out/bindings.rs") {
+ t.Errorf("rust_bindgen generated source not included as implicit input for libprocmacro; Implicits %#v", libfoo.Implicits.Strings())
+ }
+ if !android.SuffixInList(libprocmacro.Implicits.Strings(), "/out/any.rs") {
+ t.Errorf("genrule generated source not included as implicit input for libprocmacro; Implicits %#v", libfoo.Implicits.Strings())
+ }
+}
+
// Test to make sure proc_macros use host variants when building device modules.
func TestProcMacroDeviceDeps(t *testing.T) {
ctx := testRust(t, `
diff --git a/rust/source_provider.go b/rust/source_provider.go
new file mode 100644
index 0000000..e034d2c
--- /dev/null
+++ b/rust/source_provider.go
@@ -0,0 +1,70 @@
+// Copyright 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package rust
+
+import (
+ "android/soong/android"
+)
+
+type SourceProviderProperties struct {
+ // sets name of the output
+ Stem *string `android:"arch_variant"`
+}
+
+type baseSourceProvider struct {
+ Properties SourceProviderProperties
+
+ outputFile android.Path
+ subAndroidMkOnce map[subAndroidMkProvider]bool
+}
+
+var _ SourceProvider = (*baseSourceProvider)(nil)
+
+type SourceProvider interface {
+ generateSource(ctx android.ModuleContext) android.Path
+ Srcs() android.Paths
+ sourceProviderProps() []interface{}
+ sourceProviderDeps(ctx DepsContext, deps Deps) Deps
+}
+
+func (sp *baseSourceProvider) Srcs() android.Paths {
+ return android.Paths{sp.outputFile}
+}
+
+func (sp *baseSourceProvider) generateSource(ctx android.ModuleContext) android.Path {
+ panic("baseSourceProviderModule does not implement generateSource()")
+}
+
+func (sp *baseSourceProvider) sourceProviderProps() []interface{} {
+ return []interface{}{&sp.Properties}
+}
+
+func NewSourceProvider() *baseSourceProvider {
+ return &baseSourceProvider{
+ Properties: SourceProviderProperties{},
+ }
+}
+
+func (sp *baseSourceProvider) getStem(ctx android.ModuleContext) string {
+ stem := ctx.ModuleName()
+ if String(sp.Properties.Stem) != "" {
+ stem = String(sp.Properties.Stem)
+ }
+ return stem
+}
+
+func (sp *baseSourceProvider) sourceProviderDeps(ctx DepsContext, deps Deps) Deps {
+ return deps
+}
diff --git a/rust/testing.go b/rust/testing.go
index 430b40b..f2d4c5e 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -81,6 +81,7 @@
ctx.RegisterModuleType("genrule", genrule.GenRuleFactory)
ctx.RegisterModuleType("rust_binary", RustBinaryFactory)
ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
+ ctx.RegisterModuleType("rust_bindgen", RustBindgenFactory)
ctx.RegisterModuleType("rust_test", RustTestFactory)
ctx.RegisterModuleType("rust_test_host", RustTestHostFactory)
ctx.RegisterModuleType("rust_library", RustLibraryFactory)
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 935d348..497f14b 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -73,12 +73,16 @@
result := testSdkWithCc(t, `
sdk {
name: "mysdk",
+ device_supported: false,
+ host_supported: true,
native_shared_libs: ["sdkmember"],
compile_multilib: "64",
}
cc_library_shared {
name: "sdkmember",
+ device_supported: false,
+ host_supported: true,
srcs: ["Test.cpp"],
stl: "none",
compile_multilib: "64",
@@ -86,8 +90,52 @@
`)
result.CheckSnapshot("mysdk", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_shared {
+ name: "mysdk_sdkmember@current",
+ sdk_member_name: "sdkmember",
+ device_supported: false,
+ host_supported: true,
+ installable: false,
+ stl: "none",
+ compile_multilib: "64",
+ arch: {
+ x86_64: {
+ srcs: ["x86_64/lib/sdkmember.so"],
+ },
+ },
+}
+
+cc_prebuilt_library_shared {
+ name: "sdkmember",
+ prefer: false,
+ device_supported: false,
+ host_supported: true,
+ stl: "none",
+ compile_multilib: "64",
+ arch: {
+ x86_64: {
+ srcs: ["x86_64/lib/sdkmember.so"],
+ },
+ },
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ device_supported: false,
+ host_supported: true,
+ native_shared_libs: ["mysdk_sdkmember@current"],
+ target: {
+ linux_glibc: {
+ compile_multilib: "64",
+ },
+ },
+}
+`),
checkAllCopyRules(`
-.intermediates/sdkmember/android_arm64_armv8-a_shared/sdkmember.so -> arm64/lib/sdkmember.so
+.intermediates/sdkmember/linux_glibc_x86_64_shared/sdkmember.so -> x86_64/lib/sdkmember.so
`))
}
@@ -271,6 +319,7 @@
name: "mysdk_crtobj@current",
sdk_member_name: "crtobj",
stl: "none",
+ compile_multilib: "both",
arch: {
arm64: {
srcs: ["arm64/lib/crtobj.o"],
@@ -285,6 +334,7 @@
name: "crtobj",
prefer: false,
stl: "none",
+ compile_multilib: "both",
arch: {
arm64: {
srcs: ["arm64/lib/crtobj.o"],
@@ -378,6 +428,7 @@
sdk_member_name: "mynativelib",
installable: false,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
arm64: {
@@ -394,6 +445,7 @@
name: "mynativelib",
prefer: false,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
arm64: {
@@ -621,9 +673,9 @@
host_supported: true,
installable: false,
stl: "none",
+ compile_multilib: "both",
static_executable: true,
nocrt: true,
- compile_multilib: "both",
arch: {
x86_64: {
srcs: ["x86_64/bin/linker"],
@@ -640,9 +692,9 @@
device_supported: false,
host_supported: true,
stl: "none",
+ compile_multilib: "both",
static_executable: true,
nocrt: true,
- compile_multilib: "both",
arch: {
x86_64: {
srcs: ["x86_64/bin/linker"],
@@ -702,6 +754,7 @@
],
installable: false,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
arm64: {
@@ -723,6 +776,7 @@
"apex2",
],
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
arm64: {
@@ -824,6 +878,7 @@
sdk_member_name: "mynativelib",
installable: false,
stl: "none",
+ compile_multilib: "both",
shared_libs: [
"mysdk_myothernativelib@current",
"libc",
@@ -842,6 +897,7 @@
name: "mynativelib",
prefer: false,
stl: "none",
+ compile_multilib: "both",
shared_libs: [
"myothernativelib",
"libc",
@@ -861,6 +917,7 @@
sdk_member_name: "myothernativelib",
installable: false,
stl: "none",
+ compile_multilib: "both",
system_shared_libs: ["libm"],
arch: {
arm64: {
@@ -876,6 +933,7 @@
name: "myothernativelib",
prefer: false,
stl: "none",
+ compile_multilib: "both",
system_shared_libs: ["libm"],
arch: {
arm64: {
@@ -892,6 +950,7 @@
sdk_member_name: "mysystemnativelib",
installable: false,
stl: "none",
+ compile_multilib: "both",
arch: {
arm64: {
srcs: ["arm64/lib/mysystemnativelib.so"],
@@ -906,6 +965,7 @@
name: "mysystemnativelib",
prefer: false,
stl: "none",
+ compile_multilib: "both",
arch: {
arm64: {
srcs: ["arm64/lib/mysystemnativelib.so"],
@@ -974,6 +1034,7 @@
installable: false,
sdk_version: "minimum",
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
x86_64: {
@@ -994,6 +1055,7 @@
host_supported: true,
sdk_version: "minimum",
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
x86_64: {
@@ -1070,12 +1132,18 @@
installable: false,
stl: "none",
target: {
+ linux_glibc: {
+ compile_multilib: "both",
+ },
linux_glibc_x86_64: {
srcs: ["linux_glibc/x86_64/lib/mynativelib.so"],
},
linux_glibc_x86: {
srcs: ["linux_glibc/x86/lib/mynativelib.so"],
},
+ windows: {
+ compile_multilib: "64",
+ },
windows_x86_64: {
srcs: ["windows/x86_64/lib/mynativelib.dll"],
},
@@ -1089,12 +1157,18 @@
host_supported: true,
stl: "none",
target: {
+ linux_glibc: {
+ compile_multilib: "both",
+ },
linux_glibc_x86_64: {
srcs: ["linux_glibc/x86_64/lib/mynativelib.so"],
},
linux_glibc_x86: {
srcs: ["linux_glibc/x86/lib/mynativelib.so"],
},
+ windows: {
+ compile_multilib: "64",
+ },
windows_x86_64: {
srcs: ["windows/x86_64/lib/mynativelib.dll"],
},
@@ -1151,6 +1225,7 @@
sdk_member_name: "mynativelib",
installable: false,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
arm64: {
@@ -1168,6 +1243,7 @@
name: "mynativelib",
prefer: false,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
arm64: {
@@ -1236,6 +1312,7 @@
host_supported: true,
installable: false,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
x86_64: {
@@ -1255,6 +1332,7 @@
device_supported: false,
host_supported: true,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
x86_64: {
@@ -1315,6 +1393,7 @@
sdk_member_name: "mynativelib",
installable: false,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
arm64: {
@@ -1340,6 +1419,7 @@
name: "mynativelib",
prefer: false,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
arch: {
arm64: {
@@ -1416,6 +1496,7 @@
host_supported: true,
installable: false,
stl: "none",
+ compile_multilib: "64",
export_include_dirs: ["include/include"],
arch: {
x86_64: {
@@ -1431,6 +1512,7 @@
device_supported: false,
host_supported: true,
stl: "none",
+ compile_multilib: "64",
export_include_dirs: ["include/include"],
arch: {
x86_64: {
@@ -1483,6 +1565,7 @@
name: "mysdk_mynativeheaders@current",
sdk_member_name: "mynativeheaders",
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
}
@@ -1490,6 +1573,7 @@
name: "mynativeheaders",
prefer: false,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
}
@@ -1532,6 +1616,7 @@
device_supported: false,
host_supported: true,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
}
@@ -1541,6 +1626,7 @@
device_supported: false,
host_supported: true,
stl: "none",
+ compile_multilib: "both",
export_include_dirs: ["include/include"],
}
@@ -1590,6 +1676,7 @@
sdk_member_name: "mynativeheaders",
host_supported: true,
stl: "none",
+ compile_multilib: "both",
export_system_include_dirs: ["common_os/include/include"],
target: {
android: {
@@ -1606,6 +1693,7 @@
prefer: false,
host_supported: true,
stl: "none",
+ compile_multilib: "both",
export_system_include_dirs: ["common_os/include/include"],
target: {
android: {
@@ -1662,6 +1750,7 @@
name: "mysdk_sslnil@current",
sdk_member_name: "sslnil",
installable: false,
+ compile_multilib: "both",
arch: {
arm64: {
srcs: ["arm64/lib/sslnil.so"],
@@ -1675,6 +1764,7 @@
cc_prebuilt_library_shared {
name: "sslnil",
prefer: false,
+ compile_multilib: "both",
arch: {
arm64: {
srcs: ["arm64/lib/sslnil.so"],
@@ -1689,6 +1779,7 @@
name: "mysdk_sslempty@current",
sdk_member_name: "sslempty",
installable: false,
+ compile_multilib: "both",
system_shared_libs: [],
arch: {
arm64: {
@@ -1703,6 +1794,7 @@
cc_prebuilt_library_shared {
name: "sslempty",
prefer: false,
+ compile_multilib: "both",
system_shared_libs: [],
arch: {
arm64: {
@@ -1718,6 +1810,7 @@
name: "mysdk_sslnonempty@current",
sdk_member_name: "sslnonempty",
installable: false,
+ compile_multilib: "both",
system_shared_libs: ["mysdk_sslnil@current"],
arch: {
arm64: {
@@ -1732,6 +1825,7 @@
cc_prebuilt_library_shared {
name: "sslnonempty",
prefer: false,
+ compile_multilib: "both",
system_shared_libs: ["sslnil"],
arch: {
arm64: {
@@ -1780,6 +1874,7 @@
sdk_member_name: "sslvariants",
host_supported: true,
installable: false,
+ compile_multilib: "both",
target: {
android: {
system_shared_libs: [],
@@ -1803,6 +1898,7 @@
name: "sslvariants",
prefer: false,
host_supported: true,
+ compile_multilib: "both",
target: {
android: {
system_shared_libs: [],
@@ -1859,6 +1955,7 @@
name: "mysdk_stubslib@current",
sdk_member_name: "stubslib",
installable: false,
+ compile_multilib: "both",
stubs: {
versions: ["3"],
},
@@ -1875,6 +1972,7 @@
cc_prebuilt_library_shared {
name: "stubslib",
prefer: false,
+ compile_multilib: "both",
stubs: {
versions: ["3"],
},
@@ -1928,6 +2026,7 @@
sdk_member_name: "stubslib",
host_supported: true,
installable: false,
+ compile_multilib: "both",
stubs: {
versions: ["3"],
},
@@ -1951,6 +2050,7 @@
name: "stubslib",
prefer: false,
host_supported: true,
+ compile_multilib: "both",
stubs: {
versions: ["3"],
},
@@ -2003,6 +2103,7 @@
host_supported: true,
installable: false,
unique_host_soname: true,
+ compile_multilib: "both",
target: {
android_arm64: {
srcs: ["android/arm64/lib/mylib.so"],
@@ -2024,6 +2125,7 @@
prefer: false,
host_supported: true,
unique_host_soname: true,
+ compile_multilib: "both",
target: {
android_arm64: {
srcs: ["android/arm64/lib/mylib.so"],
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index aee04a1..a2198e9 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -51,10 +51,10 @@
name: "core-current-stubs-system-modules",
}
java_system_modules_import {
- name: "legacy-core-platform-api-stubs-system-modules",
+ name: "stable-core-platform-api-stubs-system-modules",
}
java_import {
- name: "legacy.core.platform.api.stubs",
+ name: "stable.core.platform.api.stubs",
}
java_import {
name: "android_stubs_current",
@@ -1424,8 +1424,8 @@
.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib.txt
.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_removed.txt -> sdk_library/system/myjavalib-removed.txt
.intermediates/myjavalib.stubs.module_lib/android_common/javac/myjavalib.stubs.module_lib.jar -> sdk_library/module-lib/myjavalib-stubs.jar
-.intermediates/myjavalib.api.module_lib/android_common/myjavalib.api.module_lib_api.txt -> sdk_library/module-lib/myjavalib.txt
-.intermediates/myjavalib.api.module_lib/android_common/myjavalib.api.module_lib_removed.txt -> sdk_library/module-lib/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.source.module_lib/android_common/myjavalib.stubs.source.module_lib_api.txt -> sdk_library/module-lib/myjavalib.txt
+.intermediates/myjavalib.stubs.source.module_lib/android_common/myjavalib.stubs.source.module_lib_removed.txt -> sdk_library/module-lib/myjavalib-removed.txt
`),
checkMergeZips(
".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
diff --git a/sdk/update.go b/sdk/update.go
index cf25008..b8d73c6 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -794,6 +794,17 @@
return !ok
}
+// Add the properties from the given SdkMemberProperties to the blueprint
+// property set. This handles common properties in SdkMemberPropertiesBase and
+// calls the member-specific AddToPropertySet for the rest.
+func addSdkMemberPropertiesToSet(ctx *memberContext, memberProperties android.SdkMemberProperties, targetPropertySet android.BpPropertySet) {
+ if memberProperties.Base().Compile_multilib != "" {
+ targetPropertySet.AddProperty("compile_multilib", memberProperties.Base().Compile_multilib)
+ }
+
+ memberProperties.AddToPropertySet(ctx, targetPropertySet)
+}
+
type sdkMemberRef struct {
memberType android.SdkMemberType
variant android.SdkAware
@@ -1009,7 +1020,7 @@
}
// Add the os specific but arch independent properties to the module.
- osInfo.Properties.AddToPropertySet(ctx, osPropertySet)
+ addSdkMemberPropertiesToSet(ctx, osInfo.Properties, osPropertySet)
// Add arch (and possibly os) specific sections for each set of arch (and possibly
// os) specific properties.
@@ -1111,11 +1122,11 @@
func (archInfo *archTypeSpecificInfo) addToPropertySet(ctx *memberContext, archPropertySet android.BpPropertySet, archOsPrefix string) {
archTypeName := archInfo.archType.Name
archTypePropertySet := archPropertySet.AddPropertySet(archOsPrefix + archTypeName)
- archInfo.Properties.AddToPropertySet(ctx, archTypePropertySet)
+ addSdkMemberPropertiesToSet(ctx, archInfo.Properties, archTypePropertySet)
for _, linkInfo := range archInfo.linkInfos {
linkPropertySet := archTypePropertySet.AddPropertySet(linkInfo.linkType)
- linkInfo.Properties.AddToPropertySet(ctx, linkPropertySet)
+ addSdkMemberPropertiesToSet(ctx, linkInfo.Properties, linkPropertySet)
}
}
@@ -1221,7 +1232,7 @@
extractCommonProperties(ctx.sdkMemberContext, commonValueExtractor, commonProperties, osSpecificPropertiesContainers)
// Add the common properties to the module.
- commonProperties.AddToPropertySet(ctx, bpModule)
+ addSdkMemberPropertiesToSet(ctx, commonProperties, bpModule)
// Create a target property set into which target specific properties can be
// added.
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index 1cb874d..798fc40 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -239,6 +239,21 @@
return path
}
+func AutoGenRobolectricTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string,
+ testSuites []string, autoGenConfig *bool) android.Path {
+ path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+ if autogenPath != nil {
+ templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+ if templatePath.Valid() {
+ autogenTemplate(ctx, autogenPath, templatePath.String(), nil)
+ } else {
+ autogenTemplate(ctx, autogenPath, "${RobolectricTestConfigTemplate}", nil)
+ }
+ return autogenPath
+ }
+ return path
+}
+
var autogenInstrumentationTest = pctx.StaticRule("autogenInstrumentationTest", blueprint.RuleParams{
Command: "${AutoGenTestConfigScript} $out $in ${EmptyTestConfig} $template ${extraConfigs}",
CommandDeps: []string{
diff --git a/tradefed/config.go b/tradefed/config.go
index 34195c3..f7e8349 100644
--- a/tradefed/config.go
+++ b/tradefed/config.go
@@ -33,6 +33,7 @@
pctx.SourcePathVariable("PythonBinaryHostTestConfigTemplate", "build/make/core/python_binary_host_test_config_template.xml")
pctx.SourcePathVariable("RustDeviceTestConfigTemplate", "build/make/core/rust_device_test_config_template.xml")
pctx.SourcePathVariable("RustHostTestConfigTemplate", "build/make/core/rust_host_test_config_template.xml")
+ pctx.SourcePathVariable("RobolectricTestConfigTemplate", "build/make/core/robolectric_test_config_template.xml")
pctx.SourcePathVariable("ShellTestConfigTemplate", "build/make/core/shell_test_config_template.xml")
pctx.SourcePathVariable("EmptyTestConfig", "build/make/core/empty_test_config.xml")