diff options
Diffstat (limited to 'rust')
-rw-r--r-- | rust/androidmk.go | 5 | ||||
-rw-r--r-- | rust/binary.go | 15 | ||||
-rw-r--r-- | rust/builder.go | 42 | ||||
-rw-r--r-- | rust/compiler.go | 45 | ||||
-rw-r--r-- | rust/compiler_test.go | 1 | ||||
-rw-r--r-- | rust/config/arm64_device.go | 92 | ||||
-rw-r--r-- | rust/config/arm_device.go | 92 | ||||
-rw-r--r-- | rust/config/global.go | 37 | ||||
-rw-r--r-- | rust/config/toolchain.go | 6 | ||||
-rw-r--r-- | rust/config/whitelist.go | 21 | ||||
-rw-r--r-- | rust/config/x86_linux_host.go | 8 | ||||
-rw-r--r-- | rust/library.go | 10 | ||||
-rw-r--r-- | rust/prebuilt.go | 5 | ||||
-rw-r--r-- | rust/proc_macro.go | 2 | ||||
-rw-r--r-- | rust/rust.go | 62 | ||||
-rw-r--r-- | rust/rust_test.go | 27 | ||||
-rw-r--r-- | rust/testing.go | 97 |
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{ |