Merge "Generate module lib API and scope together"
diff --git a/android/Android.bp b/android/Android.bp
index 977345b..6ddcc14 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -46,6 +46,7 @@
"sdk.go",
"singleton.go",
"soong_config_modules.go",
+ "test_suites.go",
"testing.go",
"util.go",
"variable.go",
diff --git a/android/sdk.go b/android/sdk.go
index 8115b69..2c38f56 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -466,8 +466,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 +488,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/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/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/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/rust/Android.bp b/rust/Android.bp
index d56de87..26a5a08 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,13 @@
"proc_macro.go",
"project_json.go",
"rust.go",
+ "source_provider.go",
"test.go",
"testing.go",
],
testSrcs: [
"binary_test.go",
+ "bindgen_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..859223a
--- /dev/null
+++ b/rust/bindgen.go
@@ -0,0 +1,172 @@
+// 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{"--no-rustfmt-bindings"}
+
+ // 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 $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)
+}
+
+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..d1d1012 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,7 +37,7 @@
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",
@@ -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())
}
@@ -209,6 +218,31 @@
implicits = append(implicits, clippyFile)
}
+ if len(deps.SrcDeps) > 0 {
+ moduleGenDir := android.PathForModuleOut(ctx, "out/")
+ var outputs android.WritablePaths
+
+ for _, genSrc := range deps.SrcDeps {
+ if android.SuffixInList(outputs.Strings(), "out/"+genSrc.Base()) {
+ ctx.PropertyErrorf("srcs",
+ "multiple source providers generate the same filename output: "+genSrc.Base())
+ }
+ outputs = append(outputs, android.PathForModuleOut(ctx, "out/"+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())
+ }
+
ctx.Build(pctx, android.BuildParams{
Rule: rustc,
Description: "rustc " + main.Rel(),
@@ -222,6 +256,7 @@
"libFlags": strings.Join(libFlags, " "),
"crtBegin": deps.CrtBegin.String(),
"crtEnd": deps.CrtEnd.String(),
+ "envVars": strings.Join(envVars, " "),
},
})
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/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")