diff options
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/Android.bp | 1 | ||||
| -rw-r--r-- | rust/binary_test.go | 17 | ||||
| -rw-r--r-- | rust/builder.go | 15 | ||||
| -rw-r--r-- | rust/compiler.go | 22 | ||||
| -rw-r--r-- | rust/compiler_test.go | 70 | ||||
| -rw-r--r-- | rust/config/allowed_list.go | 2 | ||||
| -rw-r--r-- | rust/config/global.go | 2 | ||||
| -rw-r--r-- | rust/config/x86_linux_host.go | 4 | ||||
| -rw-r--r-- | rust/coverage.go | 2 | ||||
| -rw-r--r-- | rust/coverage_test.go | 2 | ||||
| -rw-r--r-- | rust/library.go | 3 | ||||
| -rw-r--r-- | rust/project_json.go | 4 | ||||
| -rw-r--r-- | rust/project_json_test.go | 6 | ||||
| -rw-r--r-- | rust/rust.go | 8 | ||||
| -rw-r--r-- | rust/sanitize.go | 3 | ||||
| -rw-r--r-- | rust/snapshot_prebuilt.go | 1 |
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" ) |