summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
Diffstat (limited to 'rust')
-rw-r--r--rust/androidmk.go5
-rw-r--r--rust/binary.go15
-rw-r--r--rust/builder.go42
-rw-r--r--rust/compiler.go45
-rw-r--r--rust/compiler_test.go1
-rw-r--r--rust/config/arm64_device.go92
-rw-r--r--rust/config/arm_device.go92
-rw-r--r--rust/config/global.go37
-rw-r--r--rust/config/toolchain.go6
-rw-r--r--rust/config/whitelist.go21
-rw-r--r--rust/config/x86_linux_host.go8
-rw-r--r--rust/library.go10
-rw-r--r--rust/prebuilt.go5
-rw-r--r--rust/proc_macro.go2
-rw-r--r--rust/rust.go62
-rw-r--r--rust/rust_test.go27
-rw-r--r--rust/testing.go97
17 files changed, 487 insertions, 80 deletions
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 107959f84..a6208dbcd 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -116,11 +116,10 @@ func (compiler *baseCompiler) AndroidMk(ctx AndroidMkContext, ret *android.Andro
ret.OutputFile = android.OptionalPathForPath(compiler.path)
}
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- path := compiler.path.RelPathString()
- dir, file := filepath.Split(path)
+ path, file := filepath.Split(compiler.path.ToMakePath().String())
stem, suffix, _ := android.SplitFileExt(file)
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
- fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(OUT_DIR)/"+filepath.Clean(dir))
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
})
}
diff --git a/rust/binary.go b/rust/binary.go
index 279c6f50f..52f840e7a 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -71,6 +71,15 @@ func (binary *binaryDecorator) preferDynamic() bool {
func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
flags = binary.baseCompiler.compilerFlags(ctx, flags)
+
+ if ctx.toolchain().Bionic() {
+ // no-undefined-version breaks dylib compilation since __rust_*alloc* functions aren't defined, but we can apply this to binaries.
+ flags.LinkFlags = append(flags.LinkFlags,
+ "-Wl,--gc-sections",
+ "-Wl,-z,nocopyreloc",
+ "-Wl,--no-undefined-version")
+ }
+
if binary.preferDynamic() {
flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
}
@@ -86,6 +95,12 @@ func (binary *binaryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
}
}
+ if ctx.toolchain().Bionic() {
+ deps = binary.baseCompiler.bionicDeps(ctx, deps)
+ deps.CrtBegin = "crtbegin_dynamic"
+ deps.CrtEnd = "crtend_android"
+ }
+
return deps
}
diff --git a/rust/builder.go b/rust/builder.go
index 64e387b9f..104313f8a 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -28,14 +28,13 @@ var (
blueprint.RuleParams{
Command: "$rustcCmd " +
"-C linker=${config.RustLinker} " +
- "-C link-args=\"${config.RustLinkerArgs} ${linkFlags}\" " +
- "-o $out $in ${libFlags} $rustcFlags " +
- "&& $rustcCmd --emit=dep-info -o $out.d $in ${libFlags} $rustcFlags",
+ "-C link-args=\"${crtBegin} ${config.RustLinkerArgs} ${linkFlags} ${crtEnd}\" " +
+ "--emit link -o $out --emit dep-info=$out.d $in ${libFlags} $rustcFlags",
CommandDeps: []string{"$rustcCmd"},
Depfile: "$out.d",
Deps: blueprint.DepsGCC, // Rustc deps-info writes out make compatible dep files: https://github.com/rust-lang/rust/issues/7633
},
- "rustcFlags", "linkFlags", "libFlags")
+ "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd")
)
func init() {
@@ -43,28 +42,19 @@ func init() {
}
func TransformSrcToBinary(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, outputFile android.WritablePath, includeDirs []string) {
- targetTriple := ctx.(ModuleContext).toolchain().RustTriple()
-
- transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, flags, outputFile, "bin", includeDirs, targetTriple)
+ transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, deps.CrtBegin, deps.CrtEnd, flags, outputFile, "bin", includeDirs)
}
func TransformSrctoRlib(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, outputFile android.WritablePath, includeDirs []string) {
- targetTriple := ctx.(ModuleContext).toolchain().RustTriple()
-
- transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, flags, outputFile, "rlib", includeDirs, targetTriple)
+ transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, deps.CrtBegin, deps.CrtEnd, flags, outputFile, "rlib", includeDirs)
}
func TransformSrctoDylib(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, outputFile android.WritablePath, includeDirs []string) {
- targetTriple := ctx.(ModuleContext).toolchain().RustTriple()
-
- transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, flags, outputFile, "dylib", includeDirs, targetTriple)
+ transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, deps.CrtBegin, deps.CrtEnd, flags, outputFile, "dylib", includeDirs)
}
func TransformSrctoProcMacro(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, outputFile android.WritablePath, includeDirs []string) {
- // Proc macros are compiler plugins, and thus should target the host compiler
- targetTriple := ""
-
- transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, flags, outputFile, "proc-macro", includeDirs, targetTriple)
+ transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, deps.CrtBegin, deps.CrtEnd, flags, outputFile, "proc-macro", includeDirs)
}
func rustLibsToPaths(libs RustLibraries) android.Paths {
@@ -76,23 +66,28 @@ func rustLibsToPaths(libs RustLibraries) android.Paths {
}
func transformSrctoCrate(ctx android.ModuleContext, main android.Path,
- rlibs, dylibs, proc_macros RustLibraries, static_libs, shared_libs android.Paths, flags Flags, outputFile android.WritablePath, crate_type string, includeDirs []string, targetTriple string) {
+ rlibs, dylibs, proc_macros RustLibraries, static_libs, shared_libs android.Paths, crtBegin, crtEnd android.OptionalPath, flags Flags, outputFile android.WritablePath, crate_type string, includeDirs []string) {
var inputs android.Paths
var deps android.Paths
- var libFlags, rustcFlags []string
+ var libFlags, rustcFlags, linkFlags []string
crate_name := ctx.(ModuleContext).CrateName()
+ targetTriple := ctx.(ModuleContext).toolchain().RustTriple()
inputs = append(inputs, main)
// Collect rustc flags
- rustcFlags = append(rustcFlags, flags.GlobalFlags...)
+ rustcFlags = append(rustcFlags, flags.GlobalRustFlags...)
rustcFlags = append(rustcFlags, flags.RustFlags...)
rustcFlags = append(rustcFlags, "--crate-type="+crate_type)
rustcFlags = append(rustcFlags, "--crate-name="+crate_name)
if targetTriple != "" {
rustcFlags = append(rustcFlags, "--target="+targetTriple)
+ linkFlags = append(linkFlags, "-target "+targetTriple)
}
+ // Collect linker flags
+ linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
+ linkFlags = append(linkFlags, flags.LinkFlags...)
// Collect library/crate flags
for _, lib := range rlibs {
@@ -115,6 +110,9 @@ func transformSrctoCrate(ctx android.ModuleContext, main android.Path,
deps = append(deps, rustLibsToPaths(proc_macros)...)
deps = append(deps, static_libs...)
deps = append(deps, shared_libs...)
+ if crtBegin.Valid() {
+ deps = append(deps, crtBegin.Path(), crtEnd.Path())
+ }
ctx.Build(pctx, android.BuildParams{
Rule: rustc,
@@ -124,8 +122,10 @@ func transformSrctoCrate(ctx android.ModuleContext, main android.Path,
Implicits: deps,
Args: map[string]string{
"rustcFlags": strings.Join(rustcFlags, " "),
- "linkFlags": strings.Join(flags.LinkFlags, " "),
+ "linkFlags": strings.Join(linkFlags, " "),
"libFlags": strings.Join(libFlags, " "),
+ "crtBegin": crtBegin.String(),
+ "crtEnd": crtEnd.String(),
},
})
diff --git a/rust/compiler.go b/rust/compiler.go
index 4e0118325..3f028350a 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -20,19 +20,29 @@ import (
"android/soong/android"
"android/soong/rust/config"
+ "github.com/google/blueprint/proptools"
)
+func getEdition(compiler *baseCompiler) string {
+ return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition)
+}
+
+func getDenyWarnings(compiler *baseCompiler) bool {
+ return BoolDefault(compiler.Properties.Deny_warnings, config.DefaultDenyWarnings)
+}
+
func NewBaseCompiler(dir, dir64 string) *baseCompiler {
return &baseCompiler{
- Properties: BaseCompilerProperties{
- Edition: &config.DefaultEdition,
- },
- dir: dir,
- dir64: dir64,
+ Properties: BaseCompilerProperties{},
+ dir: dir,
+ dir64: dir64,
}
}
type BaseCompilerProperties struct {
+ // whether to pass "-D warnings" to rustc. Defaults to true.
+ Deny_warnings *bool
+
// flags to pass to rustc
Flags []string `android:"path,arch_variant"`
@@ -90,7 +100,7 @@ type baseCompiler struct {
dir64 string
subDir string
relative string
- path android.OutputPath
+ path android.InstallPath
}
var _ compiler = (*baseCompiler)(nil)
@@ -109,11 +119,16 @@ func (compiler *baseCompiler) featuresToFlags(features []string) []string {
func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
+ if getDenyWarnings(compiler) {
+ flags.RustFlags = append(flags.RustFlags, "-D warnings")
+ }
flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
- flags.RustFlags = append(flags.RustFlags, "--edition="+*compiler.Properties.Edition)
+ flags.RustFlags = append(flags.RustFlags, "--edition="+getEdition(compiler))
flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
- flags.GlobalFlags = append(flags.GlobalFlags, ctx.toolchain().ToolchainRustFlags())
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
+ flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
if ctx.Host() && !ctx.Windows() {
rpath_prefix := `\$$ORIGIN/`
@@ -148,11 +163,23 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
return deps
}
+func (compiler *baseCompiler) bionicDeps(ctx DepsContext, deps Deps) Deps {
+ deps.SharedLibs = append(deps.SharedLibs, "liblog")
+ deps.SharedLibs = append(deps.SharedLibs, "libc")
+ deps.SharedLibs = append(deps.SharedLibs, "libm")
+ deps.SharedLibs = append(deps.SharedLibs, "libdl")
+
+ //TODO(b/141331117) libstd requires libgcc on Android
+ deps.StaticLibs = append(deps.StaticLibs, "libgcc")
+
+ return deps
+}
+
func (compiler *baseCompiler) crateName() string {
return compiler.Properties.Crate_name
}
-func (compiler *baseCompiler) installDir(ctx ModuleContext) android.OutputPath {
+func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
dir := compiler.dir
if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
dir = compiler.dir64
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index 536909641..bbf9f8d11 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -64,7 +64,6 @@ func TestEnforceSingleSourceFile(t *testing.T) {
rust_proc_macro {
name: "foo-bar-proc-macro",
srcs: ["foo.rs", "src/bar.rs"],
- host_supported: true,
}`)
// Test prebuilts
diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go
new file mode 100644
index 000000000..0264052db
--- /dev/null
+++ b/rust/config/arm64_device.go
@@ -0,0 +1,92 @@
+// Copyright 2019 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 config
+
+import (
+ "strings"
+
+ "android/soong/android"
+)
+
+var (
+ Arm64RustFlags = []string{}
+ Arm64ArchFeatureRustFlags = map[string][]string{}
+ Arm64LinkFlags = []string{
+ "-Wl,--icf=safe",
+ "-Wl,-z,max-page-size=4096",
+
+ "-Wl,-execute-only",
+ }
+
+ Arm64ArchVariantRustFlags = map[string][]string{
+ "armv8-a": []string{},
+ "armv8-2a": []string{},
+ }
+)
+
+func init() {
+ registerToolchainFactory(android.Android, android.Arm64, Arm64ToolchainFactory)
+
+ pctx.StaticVariable("Arm64ToolchainRustFlags", strings.Join(Arm64RustFlags, " "))
+ pctx.StaticVariable("Arm64ToolchainLinkFlags", strings.Join(Arm64LinkFlags, " "))
+
+ for variant, rustFlags := range Arm64ArchVariantRustFlags {
+ pctx.StaticVariable("Arm64"+variant+"VariantRustFlags",
+ strings.Join(rustFlags, " "))
+ }
+
+}
+
+type toolchainArm64 struct {
+ toolchain64Bit
+ toolchainRustFlags string
+}
+
+func (t *toolchainArm64) RustTriple() string {
+ return "aarch64-linux-android"
+}
+
+func (t *toolchainArm64) ToolchainLinkFlags() string {
+ return "${config.DeviceGlobalLinkFlags} ${config.Arm64ToolchainLinkFlags}"
+}
+
+func (t *toolchainArm64) ToolchainRustFlags() string {
+ return t.toolchainRustFlags
+}
+
+func (t *toolchainArm64) RustFlags() string {
+ return "${config.Arm64ToolchainRustFlags}"
+}
+
+func (t *toolchainArm64) Supported() bool {
+ return true
+}
+
+func Arm64ToolchainFactory(arch android.Arch) Toolchain {
+ toolchainRustFlags := []string{
+ "${config.Arm64ToolchainRustFlags}",
+ "${config.Arm64" + arch.ArchVariant + "VariantRustFlags}",
+ }
+
+ toolchainRustFlags = append(toolchainRustFlags, deviceGlobalRustFlags...)
+
+ for _, feature := range arch.ArchFeatures {
+ toolchainRustFlags = append(toolchainRustFlags, Arm64ArchFeatureRustFlags[feature]...)
+ }
+
+ return &toolchainArm64{
+ toolchainRustFlags: strings.Join(toolchainRustFlags, " "),
+ }
+}
diff --git a/rust/config/arm_device.go b/rust/config/arm_device.go
new file mode 100644
index 000000000..aedb42b31
--- /dev/null
+++ b/rust/config/arm_device.go
@@ -0,0 +1,92 @@
+// Copyright 2019 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 config
+
+import (
+ "strings"
+
+ "android/soong/android"
+)
+
+var (
+ ArmRustFlags = []string{}
+ ArmArchFeatureRustFlags = map[string][]string{}
+ ArmLinkFlags = []string{
+ "-Wl,--icf=safe",
+ "-Wl,-m,armelf",
+ }
+
+ ArmArchVariantRustFlags = map[string][]string{
+ "armv7-a": []string{},
+ "armv7-a-neon": []string{},
+ "armv8-a": []string{},
+ "armv8-2a": []string{},
+ }
+)
+
+func init() {
+ registerToolchainFactory(android.Android, android.Arm, ArmToolchainFactory)
+
+ pctx.StaticVariable("ArmToolchainRustFlags", strings.Join(ArmRustFlags, " "))
+ pctx.StaticVariable("ArmToolchainLinkFlags", strings.Join(ArmLinkFlags, " "))
+
+ for variant, rustFlags := range ArmArchVariantRustFlags {
+ pctx.StaticVariable("Arm"+variant+"VariantRustFlags",
+ strings.Join(rustFlags, " "))
+ }
+
+}
+
+type toolchainArm struct {
+ toolchain64Bit
+ toolchainRustFlags string
+}
+
+func (t *toolchainArm) RustTriple() string {
+ return "arm-linux-androideabi"
+}
+
+func (t *toolchainArm) ToolchainLinkFlags() string {
+ return "${config.DeviceGlobalLinkFlags} ${config.ArmToolchainLinkFlags}"
+}
+
+func (t *toolchainArm) ToolchainRustFlags() string {
+ return t.toolchainRustFlags
+}
+
+func (t *toolchainArm) RustFlags() string {
+ return "${config.ArmToolchainRustFlags}"
+}
+
+func (t *toolchainArm) Supported() bool {
+ return true
+}
+
+func ArmToolchainFactory(arch android.Arch) Toolchain {
+ toolchainRustFlags := []string{
+ "${config.ArmToolchainRustFlags}",
+ "${config.Arm" + arch.ArchVariant + "VariantRustFlags}",
+ }
+
+ toolchainRustFlags = append(toolchainRustFlags, deviceGlobalRustFlags...)
+
+ for _, feature := range arch.ArchFeatures {
+ toolchainRustFlags = append(toolchainRustFlags, ArmArchFeatureRustFlags[feature]...)
+ }
+
+ return &toolchainArm{
+ toolchainRustFlags: strings.Join(toolchainRustFlags, " "),
+ }
+}
diff --git a/rust/config/global.go b/rust/config/global.go
index 7f9f9930c..7846d212e 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -15,6 +15,8 @@
package config
import (
+ "strings"
+
"android/soong/android"
_ "android/soong/cc/config"
)
@@ -26,15 +28,33 @@ var (
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2018"
Stdlibs = []string{
- "libarena",
- "libfmt_macros",
- "libgraphviz",
- "libserialize",
"libstd",
- "libsyntax",
- "libsyntax_ext",
- "libsyntax_pos",
"libterm",
+ "libtest",
+ }
+
+ DefaultDenyWarnings = true
+
+ GlobalRustFlags = []string{
+ "--remap-path-prefix $$(pwd)=",
+ }
+
+ deviceGlobalRustFlags = []string{}
+
+ deviceGlobalLinkFlags = []string{
+ "-Bdynamic",
+ "-nostdlib",
+ "-Wl,-z,noexecstack",
+ "-Wl,-z,relro",
+ "-Wl,-z,now",
+ "-Wl,--build-id=md5",
+ "-Wl,--warn-shared-textrel",
+ "-Wl,--fatal-warnings",
+
+ "-Wl,--pack-dyn-relocs=android+relr",
+ "-Wl,--use-android-relr-tags",
+ "-Wl,--no-undefined",
+ "-Wl,--hash-style=gnu",
}
)
@@ -62,4 +82,7 @@ func init() {
pctx.ImportAs("ccConfig", "android/soong/cc/config")
pctx.StaticVariable("RustLinker", "${ccConfig.ClangBin}/clang++")
pctx.StaticVariable("RustLinkerArgs", "-B ${ccConfig.ClangBin} -fuse-ld=lld")
+
+ pctx.StaticVariable("DeviceGlobalLinkFlags", strings.Join(deviceGlobalLinkFlags, " "))
+
}
diff --git a/rust/config/toolchain.go b/rust/config/toolchain.go
index a36d61bfd..328bca3b9 100644
--- a/rust/config/toolchain.go
+++ b/rust/config/toolchain.go
@@ -32,6 +32,8 @@ type Toolchain interface {
Is64Bit() bool
Supported() bool
+
+ Bionic() bool
}
type toolchainBase struct {
@@ -53,6 +55,10 @@ func (toolchainBase) Is64Bit() bool {
panic("toolchainBase cannot determine datapath width.")
}
+func (toolchainBase) Bionic() bool {
+ return true
+}
+
type toolchain64Bit struct {
toolchainBase
}
diff --git a/rust/config/whitelist.go b/rust/config/whitelist.go
new file mode 100644
index 000000000..464626424
--- /dev/null
+++ b/rust/config/whitelist.go
@@ -0,0 +1,21 @@
+package config
+
+var (
+ RustAllowedPaths = []string{
+ "external/rust/crates",
+ "external/crosvm",
+ "external/adhd",
+ }
+
+ RustModuleTypes = []string{
+ "rust_binary",
+ "rust_binary_host",
+ "rust_library",
+ "rust_library_dylib",
+ "rust_library_rlib",
+ "rust_library_host",
+ "rust_library_host_dylib",
+ "rust_library_host_rlib",
+ "rust_proc_macro",
+ }
+)
diff --git a/rust/config/x86_linux_host.go b/rust/config/x86_linux_host.go
index cb6bf1a22..5376e5ba5 100644
--- a/rust/config/x86_linux_host.go
+++ b/rust/config/x86_linux_host.go
@@ -61,6 +61,10 @@ func (toolchainLinuxX8664) Supported() bool {
return true
}
+func (toolchainLinuxX8664) Bionic() bool {
+ return false
+}
+
func (t *toolchainLinuxX8664) Name() string {
return "x86_64"
}
@@ -85,6 +89,10 @@ func (toolchainLinuxX86) Supported() bool {
return true
}
+func (toolchainLinuxX86) Bionic() bool {
+ return false
+}
+
func (t *toolchainLinuxX86) Name() string {
return "x86"
}
diff --git a/rust/library.go b/rust/library.go
index 5cf8ac700..c831727c5 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -191,6 +191,16 @@ func (library *libraryDecorator) compilerProps() []interface{} {
&library.MutatedProperties)
}
+func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
+ deps = library.baseCompiler.compilerDeps(ctx, deps)
+
+ if ctx.toolchain().Bionic() && library.dylib() {
+ deps = library.baseCompiler.bionicDeps(ctx, deps)
+ }
+
+ return deps
+}
+
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
var outputFile android.WritablePath
diff --git a/rust/prebuilt.go b/rust/prebuilt.go
index d4e631ba6..fa69fbb86 100644
--- a/rust/prebuilt.go
+++ b/rust/prebuilt.go
@@ -63,3 +63,8 @@ func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags
return srcPath
}
+
+func (prebuilt *prebuiltLibraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
+ deps = prebuilt.baseCompiler.compilerDeps(ctx, deps)
+ return deps
+}
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 4acb06fcd..1a247d9b3 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -45,7 +45,7 @@ type procMacroInterface interface {
var _ compiler = (*procMacroDecorator)(nil)
func ProcMacroFactory() android.Module {
- module, _ := NewProcMacro(android.HostAndDeviceSupported)
+ module, _ := NewProcMacro(android.HostSupportedNoCross)
return module.Init()
}
diff --git a/rust/rust.go b/rust/rust.go
index 7cc0b2c3b..61b51e547 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -29,28 +29,11 @@ var pctx = android.NewPackageContext("android/soong/rust")
func init() {
// Only allow rust modules to be defined for certain projects
- rustModuleTypes := []string{
- "rust_binary",
- "rust_binary_host",
- "rust_library",
- "rust_library_dylib",
- "rust_library_rlib",
- "rust_library_host",
- "rust_library_host_dylib",
- "rust_library_host_rlib",
- "rust_proc_macro",
- }
-
- rustAllowedPaths := []string{
- "external/rust/crates",
- "external/crosvm",
- "external/adhd",
- }
android.AddNeverAllowRules(
android.NeverAllow().
- NotIn(rustAllowedPaths...).
- ModuleType(rustModuleTypes...))
+ NotIn(config.RustAllowedPaths...).
+ ModuleType(config.RustModuleTypes...))
android.RegisterModuleType("rust_defaults", defaultsFactory)
android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
@@ -60,11 +43,12 @@ func init() {
}
type Flags struct {
- GlobalFlags []string // Flags that apply globally
- RustFlags []string // Flags that apply to rust
- LinkFlags []string // Flags that apply to linker
- RustFlagsDeps android.Paths // Files depended on by compiler flags
- Toolchain config.Toolchain
+ GlobalRustFlags []string // Flags that apply globally to rust
+ GlobalLinkFlags []string // Flags that apply globally to linker
+ RustFlags []string // Flags that apply to rust
+ LinkFlags []string // Flags that apply to linker
+ RustFlagsDeps android.Paths // Files depended on by compiler flags
+ Toolchain config.Toolchain
}
type BaseProperties struct {
@@ -109,6 +93,9 @@ type PathDeps struct {
linkDirs []string
depFlags []string
//ReexportedDeps android.Paths
+
+ CrtBegin android.OptionalPath
+ CrtEnd android.OptionalPath
}
type RustLibraries []RustLibrary
@@ -338,15 +325,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
if rustDep, ok := dep.(*Module); ok {
//Handle Rust Modules
- if rustDep.Target().Os != ctx.Os() {
- ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
- return
- }
- if rustDep.Target().Arch.ArchType != ctx.Arch().ArchType {
- ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName)
- return
- }
-
linkFile := rustDep.outputFile
if !linkFile.Valid() {
ctx.ModuleErrorf("Invalid output file when adding dep %q to %q", depName, ctx.ModuleName())
@@ -378,9 +356,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
if lib, ok := rustDep.compiler.(*libraryDecorator); ok {
depPaths.linkDirs = append(depPaths.linkDirs, lib.exportedDirs()...)
depPaths.depFlags = append(depPaths.depFlags, lib.exportedDepFlags()...)
- } else if procMacro, ok := rustDep.compiler.(*libraryDecorator); ok {
- depPaths.linkDirs = append(depPaths.linkDirs, procMacro.exportedDirs()...)
- depPaths.depFlags = append(depPaths.depFlags, procMacro.exportedDepFlags()...)
}
// Append this dependencies output to this mod's linkDirs so they can be exported to dependencies
@@ -427,6 +402,10 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
directSharedLibDeps = append(directSharedLibDeps, ccDep)
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, depName)
exportDep = true
+ case cc.CrtBeginDepTag():
+ depPaths.CrtBegin = linkFile
+ case cc.CrtEndDepTag():
+ depPaths.CrtEnd = linkFile
}
// Make sure these dependencies are propagated
@@ -508,7 +487,16 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
}
actx.AddVariationDependencies(append(ccDepVariations, blueprint.Variation{Mutator: "link", Variation: "shared"}), cc.SharedDepTag(), deps.SharedLibs...)
actx.AddVariationDependencies(append(ccDepVariations, blueprint.Variation{Mutator: "link", Variation: "static"}), cc.StaticDepTag(), deps.StaticLibs...)
- actx.AddDependency(mod, procMacroDepTag, deps.ProcMacros...)
+
+ if deps.CrtBegin != "" {
+ actx.AddVariationDependencies(ccDepVariations, cc.CrtBeginDepTag(), deps.CrtBegin)
+ }
+ if deps.CrtEnd != "" {
+ actx.AddVariationDependencies(ccDepVariations, cc.CrtEndDepTag(), deps.CrtEnd)
+ }
+
+ // proc_macros are compiler plugins, and so we need the host arch variant as a dependendcy.
+ actx.AddFarVariationDependencies([]blueprint.Variation{{Mutator: "arch", Variation: ctx.Config().BuildOsVariant}}, procMacroDepTag, deps.ProcMacros...)
}
func (mod *Module) Name() string {
diff --git a/rust/rust_test.go b/rust/rust_test.go
index f7c96dd6a..0c8d35586 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -18,6 +18,7 @@ import (
"io/ioutil"
"os"
"runtime"
+ "strings"
"testing"
"android/soong/android"
@@ -150,7 +151,6 @@ func TestDepsTracking(t *testing.T) {
rust_proc_macro {
name: "libpm",
srcs: ["foo.rs"],
- host_supported: true,
}
rust_binary_host {
name: "fizz-buzz",
@@ -176,3 +176,28 @@ func TestDepsTracking(t *testing.T) {
}
}
+
+// Test to make sure proc_macros use host variants when building device modules.
+func TestProcMacroDeviceDeps(t *testing.T) {
+ ctx := testRust(t, `
+ rust_library_host_rlib {
+ name: "libbar",
+ srcs: ["foo.rs"],
+ }
+ rust_proc_macro {
+ name: "libpm",
+ rlibs: ["libbar"],
+ srcs: ["foo.rs"],
+ }
+ rust_binary {
+ name: "fizz-buzz",
+ proc_macros: ["libpm"],
+ srcs: ["foo.rs"],
+ }
+ `)
+ rustc := ctx.ModuleForTests("libpm", "linux_glibc_x86_64").Rule("rustc")
+
+ if !strings.Contains(rustc.Args["libFlags"], "libbar/linux_glibc_x86_64") {
+ t.Errorf("Proc_macro is not using host variant of dependent modules.")
+ }
+}
diff --git a/rust/testing.go b/rust/testing.go
index a38697f88..92347f1f3 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -16,6 +16,7 @@ package rust
import (
"android/soong/android"
+ "android/soong/cc"
)
func GatherRequiredDepsForTest() string {
@@ -70,12 +71,101 @@ func GatherRequiredDepsForTest() string {
srcs: [""],
host_supported: true,
}
+
+ //////////////////////////////
+ // Device module requirements
+
+ toolchain_library {
+ name: "libgcc",
+ no_libcrt: true,
+ nocrt: true,
+ src: "",
+ system_shared_libs: [],
+ }
+ cc_library {
+ name: "libc",
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ }
+ cc_library {
+ name: "libm",
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ }
+ cc_library {
+ name: "libdl",
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ }
+ cc_object {
+ name: "crtbegin_dynamic",
+ }
+
+ cc_object {
+ name: "crtend_android",
+ }
+ cc_library {
+ name: "liblog",
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ }
+
+ //////////////////////////////
+ // cc module requirements
+
+ toolchain_library {
+ name: "libatomic",
+ src: "",
+ }
+ toolchain_library {
+ name: "libclang_rt.builtins-aarch64-android",
+ src: "",
+ }
+ toolchain_library {
+ name: "libgcc_stripped",
+ src: "",
+ }
+ cc_library {
+ name: "libc++_static",
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ stl: "none",
+ }
+ cc_library {
+ name: "libc++demangle",
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ stl: "none",
+ host_supported: false,
+ }
+ cc_library {
+ name: "libc++",
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ stl: "none",
+ }
+ cc_library {
+ name: "libunwind_llvm",
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ stl: "none",
+ }
`
return bp
}
func CreateTestContext(bp string) *android.TestContext {
ctx := android.NewTestArchContext()
+ ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))
+ ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory))
ctx.RegisterModuleType("rust_binary", android.ModuleFactoryAdaptor(RustBinaryFactory))
ctx.RegisterModuleType("rust_binary_host", android.ModuleFactoryAdaptor(RustBinaryHostFactory))
ctx.RegisterModuleType("rust_library", android.ModuleFactoryAdaptor(RustLibraryFactory))
@@ -86,9 +176,16 @@ func CreateTestContext(bp string) *android.TestContext {
ctx.RegisterModuleType("rust_library_dylib", android.ModuleFactoryAdaptor(RustLibraryDylibFactory))
ctx.RegisterModuleType("rust_proc_macro", android.ModuleFactoryAdaptor(ProcMacroFactory))
ctx.RegisterModuleType("rust_prebuilt_dylib", android.ModuleFactoryAdaptor(PrebuiltDylibFactory))
+ ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("rust_libraries", LibraryMutator).Parallel()
+
+ ctx.BottomUp("image", cc.ImageMutator).Parallel()
+ ctx.BottomUp("link", cc.LinkageMutator).Parallel()
+ ctx.BottomUp("version", cc.VersionMutator).Parallel()
+ ctx.BottomUp("begin", cc.BeginMutator).Parallel()
})
+
bp = bp + GatherRequiredDepsForTest()
mockFS := map[string][]byte{