summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
Diffstat (limited to 'rust')
-rw-r--r--rust/Android.bp1
-rw-r--r--rust/binary_test.go17
-rw-r--r--rust/builder.go15
-rw-r--r--rust/compiler.go22
-rw-r--r--rust/compiler_test.go70
-rw-r--r--rust/config/allowed_list.go2
-rw-r--r--rust/config/global.go2
-rw-r--r--rust/config/x86_linux_host.go4
-rw-r--r--rust/coverage.go2
-rw-r--r--rust/coverage_test.go2
-rw-r--r--rust/library.go3
-rw-r--r--rust/project_json.go4
-rw-r--r--rust/project_json_test.go6
-rw-r--r--rust/rust.go8
-rw-r--r--rust/sanitize.go3
-rw-r--r--rust/snapshot_prebuilt.go1
16 files changed, 152 insertions, 10 deletions
diff --git a/rust/Android.bp b/rust/Android.bp
index 11069d143..221014e5c 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -11,6 +11,7 @@ bootstrap_go_package {
"soong-bloaty",
"soong-cc",
"soong-rust-config",
+ "soong-snapshot",
],
srcs: [
"androidmk.go",
diff --git a/rust/binary_test.go b/rust/binary_test.go
index 86f50d3e4..968c0c1ff 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -114,6 +114,23 @@ func TestBinaryFlags(t *testing.T) {
}
}
+// Test that the bootstrap property sets the appropriate linker
+func TestBootstrap(t *testing.T) {
+ ctx := testRust(t, `
+ rust_binary {
+ name: "foo",
+ srcs: ["foo.rs"],
+ bootstrap: true,
+ }`)
+
+ foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+
+ flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64"
+ if !strings.Contains(foo.Args["linkFlags"], flag) {
+ t.Errorf("missing link flag to use bootstrap linker, expecting %#v, linkFlags: %#v", flag, foo.Args["linkFlags"])
+ }
+}
+
func TestStaticBinaryFlags(t *testing.T) {
ctx := testRust(t, `
rust_binary {
diff --git a/rust/builder.go b/rust/builder.go
index 6db508d64..a5b3ab9de 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -220,6 +220,15 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl
linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
linkFlags = append(linkFlags, flags.LinkFlags...)
+ // Check if this module needs to use the bootstrap linker
+ if ctx.RustModule().Bootstrap() && !ctx.RustModule().InRecovery() && !ctx.RustModule().InRamdisk() && !ctx.RustModule().InVendorRamdisk() {
+ dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
+ if ctx.toolchain().Is64Bit() {
+ dynamicLinker += "64"
+ }
+ linkFlags = append(linkFlags, dynamicLinker)
+ }
+
libFlags := makeLibFlags(deps)
// Collect dependencies
@@ -323,6 +332,12 @@ func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps,
rustdocFlags = append(rustdocFlags, makeLibFlags(deps)...)
docTimestampFile := android.PathForModuleOut(ctx, "rustdoc.timestamp")
+ // Silence warnings about renamed lints for third-party crates
+ modulePath := android.PathForModuleSrc(ctx).String()
+ if android.IsThirdPartyPath(modulePath) {
+ rustdocFlags = append(rustdocFlags, " -A renamed_and_removed_lints")
+ }
+
// Yes, the same out directory is used simultaneously by all rustdoc builds.
// This is what cargo does. The docs for individual crates get generated to
// a subdirectory named for the crate, and rustdoc synchronizes writes to
diff --git a/rust/compiler.go b/rust/compiler.go
index 0b28135ae..de59f39ac 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -17,6 +17,7 @@ package rust
import (
"fmt"
"path/filepath"
+ "strings"
"github.com/google/blueprint/proptools"
@@ -235,6 +236,25 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flag
if err != nil {
ctx.PropertyErrorf("lints", err.Error())
}
+
+ // linkage-related flags are disallowed.
+ for _, s := range compiler.Properties.Ld_flags {
+ if strings.HasPrefix(s, "-Wl,-l") || strings.HasPrefix(s, "-Wl,-L") {
+ ctx.PropertyErrorf("ld_flags", "'-Wl,-l' and '-Wl,-L' flags cannot be manually specified")
+ }
+ }
+ for _, s := range compiler.Properties.Flags {
+ if strings.HasPrefix(s, "-l") || strings.HasPrefix(s, "-L") {
+ ctx.PropertyErrorf("flags", "'-l' and '-L' flags cannot be manually specified")
+ }
+ if strings.HasPrefix(s, "--extern") {
+ ctx.PropertyErrorf("flags", "'--extern' flag cannot be manually specified")
+ }
+ if strings.HasPrefix(s, "-Clink-args=") || strings.HasPrefix(s, "-C link-args=") {
+ ctx.PropertyErrorf("flags", "'-C link-args' flag cannot be manually specified")
+ }
+ }
+
flags.RustFlags = append(flags.RustFlags, lintFlags)
flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
flags.RustFlags = append(flags.RustFlags, compiler.cfgsToFlags()...)
@@ -305,7 +325,7 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
if !Bool(compiler.Properties.No_stdlibs) {
for _, stdlib := range config.Stdlibs {
// If we're building for the primary arch of the build host, use the compiler's stdlibs
- if ctx.Target().Os == android.BuildOs {
+ if ctx.Target().Os == ctx.Config().BuildOS {
stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
}
deps.Stdlibs = append(deps.Stdlibs, stdlib)
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index 5ca9e7f35..c331b4caa 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -208,3 +208,73 @@ func TestStdDeviceLinkage(t *testing.T) {
t.Errorf("libstd is not linked dynamically for dylibs")
}
}
+
+// Ensure that manual link flags are disallowed.
+func TestManualLinkageRejection(t *testing.T) {
+ // rustc flags
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ flags: ["-lbar"],
+ }
+ `)
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ flags: ["--extern=foo"],
+ }
+ `)
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ flags: ["-Clink-args=foo"],
+ }
+ `)
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ flags: ["-C link-args=foo"],
+ }
+ `)
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ flags: ["-L foo/"],
+ }
+ `)
+
+ // lld flags
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ ld_flags: ["-Wl,-L bar/"],
+ }
+ `)
+ testRustError(t, ".* cannot be manually specified", `
+ rust_binary {
+ name: "foo",
+ srcs: [
+ "foo.rs",
+ ],
+ ld_flags: ["-Wl,-lbar"],
+ }
+ `)
+}
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
index 31ec3f12c..e527aea7b 100644
--- a/rust/config/allowed_list.go
+++ b/rust/config/allowed_list.go
@@ -23,10 +23,12 @@ var (
"system/extras/profcollectd",
"system/extras/simpleperf",
"system/hardware/interfaces/keystore2",
+ "system/librustutils",
"system/logging/rust",
"system/security",
"system/tools/aidl",
"tools/security/fuzzing/example_rust_fuzzer",
+ "vendor/",
}
DownstreamRustAllowedPaths = []string{
diff --git a/rust/config/global.go b/rust/config/global.go
index 1b56237b3..e5b334deb 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@ import (
var pctx = android.NewPackageContext("android/soong/rust/config")
var (
- RustDefaultVersion = "1.51.0"
+ RustDefaultVersion = "1.54.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2018"
Stdlibs = []string{
diff --git a/rust/config/x86_linux_host.go b/rust/config/x86_linux_host.go
index a9fdaed45..0aa534f87 100644
--- a/rust/config/x86_linux_host.go
+++ b/rust/config/x86_linux_host.go
@@ -37,6 +37,10 @@ func init() {
registerToolchainFactory(android.Linux, android.X86_64, linuxX8664ToolchainFactory)
registerToolchainFactory(android.Linux, android.X86, linuxX86ToolchainFactory)
+ // TODO: musl rust support
+ registerToolchainFactory(android.LinuxMusl, android.X86_64, linuxX8664ToolchainFactory)
+ registerToolchainFactory(android.LinuxMusl, android.X86, linuxX86ToolchainFactory)
+
pctx.StaticVariable("LinuxToolchainRustFlags", strings.Join(LinuxRustFlags, " "))
pctx.StaticVariable("LinuxToolchainLinkFlags", strings.Join(LinuxRustLinkFlags, " "))
pctx.StaticVariable("LinuxToolchainX86RustFlags", strings.Join(linuxX86Rustflags, " "))
diff --git a/rust/coverage.go b/rust/coverage.go
index dac526a36..050b811c7 100644
--- a/rust/coverage.go
+++ b/rust/coverage.go
@@ -55,7 +55,7 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags
flags.Coverage = true
coverage := ctx.GetDirectDepWithTag(CovLibraryName, cc.CoverageDepTag).(cc.LinkableInterface)
flags.RustFlags = append(flags.RustFlags,
- "-Z instrument-coverage", "-g", "-C link-dead-code")
+ "-Z instrument-coverage", "-g")
flags.LinkFlags = append(flags.LinkFlags,
profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open")
deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path())
diff --git a/rust/coverage_test.go b/rust/coverage_test.go
index 4b6c9d4b7..f3cd3758c 100644
--- a/rust/coverage_test.go
+++ b/rust/coverage_test.go
@@ -56,7 +56,7 @@ func TestCoverageFlags(t *testing.T) {
fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
- rustcCoverageFlags := []string{"-Z instrument-coverage", " -g ", "-C link-dead-code"}
+ rustcCoverageFlags := []string{"-Z instrument-coverage", " -g "}
for _, flag := range rustcCoverageFlags {
missingErrorStr := "missing rustc flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
containsErrorStr := "contains rustc flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
diff --git a/rust/library.go b/rust/library.go
index 5a36bd13f..8c10e298b 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -21,6 +21,7 @@ import (
"android/soong/android"
"android/soong/cc"
+ "android/soong/snapshot"
)
var (
@@ -645,7 +646,7 @@ func LibraryMutator(mctx android.BottomUpMutatorContext) {
variation := v.(*Module).ModuleBase.ImageVariation().Variation
if strings.HasPrefix(variation, cc.VendorVariationPrefix) &&
m.HasVendorVariant() &&
- !cc.IsVendorProprietaryModule(mctx) &&
+ !snapshot.IsVendorProprietaryModule(mctx) &&
strings.TrimPrefix(variation, cc.VendorVariationPrefix) == mctx.DeviceConfig().VndkVersion() {
// cc.MutateImage runs before LibraryMutator, so vendor variations which are meant for rlibs only are
diff --git a/rust/project_json.go b/rust/project_json.go
index c28bc7b76..e15ec0f22 100644
--- a/rust/project_json.go
+++ b/rust/project_json.go
@@ -54,7 +54,7 @@ type rustProjectCrate struct {
}
type rustProjectJson struct {
- Roots []string `json:"roots"`
+ // Roots []string `json:"roots"`
Crates []rustProjectCrate `json:"crates"`
}
@@ -250,7 +250,7 @@ func (singleton *projectGeneratorSingleton) addCrate(ctx android.SingletonContex
singleton.project.Crates = append(singleton.project.Crates, crate)
// rust-analyzer requires that all crates belong to at least one root:
// https://github.com/rust-analyzer/rust-analyzer/issues/4735.
- singleton.project.Roots = append(singleton.project.Roots, path.Dir(crate.RootModule))
+ // singleton.project.Roots = append(singleton.project.Roots, path.Dir(crate.RootModule))
return idx, true
}
diff --git a/rust/project_json_test.go b/rust/project_json_test.go
index 09d30dbde..bdd54c59b 100644
--- a/rust/project_json_test.go
+++ b/rust/project_json_test.go
@@ -176,6 +176,8 @@ func TestProjectJsonBinary(t *testing.T) {
}
func TestProjectJsonBindGen(t *testing.T) {
+ buildOS := android.TestConfig(t.TempDir(), nil, "", nil).BuildOS
+
bp := `
rust_library {
name: "libd",
@@ -214,9 +216,9 @@ func TestProjectJsonBindGen(t *testing.T) {
if strings.Contains(rootModule, "libbindings1") && !strings.Contains(rootModule, "android_arm64") {
t.Errorf("The source path for libbindings1 does not contain android_arm64, got %v", rootModule)
}
- if strings.Contains(rootModule, "libbindings2") && !strings.Contains(rootModule, android.BuildOs.String()) {
+ if strings.Contains(rootModule, "libbindings2") && !strings.Contains(rootModule, buildOS.String()) {
t.Errorf("The source path for libbindings2 does not contain the BuildOs, got %v; want %v",
- rootModule, android.BuildOs.String())
+ rootModule, buildOS.String())
}
// Check that libbindings1 does not depend on itself.
if strings.Contains(rootModule, "libbindings1") {
diff --git a/rust/rust.go b/rust/rust.go
index 52b409435..80be49638 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -85,6 +85,10 @@ type BaseProperties struct {
VendorRamdiskVariantNeeded bool `blueprint:"mutated"`
ExtraVariants []string `blueprint:"mutated"`
+ // Allows this module to use non-APEX version of libraries. Useful
+ // for building binaries that are started before APEXes are activated.
+ Bootstrap *bool
+
// Used by vendor snapshot to record dependencies from snapshot modules.
SnapshotSharedLibs []string `blueprint:"mutated"`
SnapshotStaticLibs []string `blueprint:"mutated"`
@@ -288,7 +292,7 @@ func (mod *Module) UseVndk() bool {
}
func (mod *Module) Bootstrap() bool {
- return false
+ return Bool(mod.Properties.Bootstrap)
}
func (mod *Module) MustUseVendorVariant() bool {
@@ -857,6 +861,8 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
if mod.installable(apexInfo) {
mod.compiler.install(ctx)
}
+
+ ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
}
}
diff --git a/rust/sanitize.go b/rust/sanitize.go
index 3d14d512f..a4ba4bd33 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -47,6 +47,9 @@ var fuzzerFlags = []string{
"-C llvm-args=-sanitizer-coverage-trace-geps",
"-C llvm-args=-sanitizer-coverage-prune-blocks=0",
+ // See https://github.com/rust-fuzz/cargo-fuzz/pull/193
+ "-C link-dead-code",
+
// Sancov breaks with lto
// TODO: Remove when https://bugs.llvm.org/show_bug.cgi?id=41734 is resolved and sancov works with LTO
"-C lto=no",
diff --git a/rust/snapshot_prebuilt.go b/rust/snapshot_prebuilt.go
index 2f549738c..79eaab382 100644
--- a/rust/snapshot_prebuilt.go
+++ b/rust/snapshot_prebuilt.go
@@ -17,6 +17,7 @@ package rust
import (
"android/soong/android"
"android/soong/cc"
+
"github.com/google/blueprint/proptools"
)