Add AArch64 device Rust toolchain.

Bug: 141207434
Test: build example rust device module.
Change-Id: I0932a614942bf4a4d4b6c153fcc4fc79c7f202bd
This commit is contained in:
Ivan Lozano 2019-09-20 11:00:37 -07:00
parent 5ca5ef6788
commit f1c8433b40
12 changed files with 221 additions and 16 deletions

View File

@ -333,6 +333,7 @@ bootstrap_go_package {
"soong-cc-config",
],
srcs: [
"rust/config/arm64_device.go",
"rust/config/global.go",
"rust/config/toolchain.go",
"rust/config/whitelist.go",

View File

@ -401,6 +401,14 @@ func StaticDepTag() dependencyTag {
return staticDepTag
}
func CrtBeginDepTag() dependencyTag {
return crtBeginDepTag
}
func CrtEndDepTag() dependencyTag {
return crtEndDepTag
}
// Module contains the properties and members used by all C/C++ module types, and implements
// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
// to construct the output file. Behavior can be customized with a Customizer interface

View File

@ -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
}

View File

@ -28,14 +28,14 @@ var (
blueprint.RuleParams{
Command: "$rustcCmd " +
"-C linker=${config.RustLinker} " +
"-C link-args=\"${config.RustLinkerArgs} ${linkFlags}\" " +
"-C link-args=\"${crtBegin} ${config.RustLinkerArgs} ${linkFlags} ${crtEnd}\" " +
"-o $out $in ${libFlags} $rustcFlags " +
"&& $rustcCmd --emit=dep-info -o $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,19 +43,19 @@ func init() {
}
func TransformSrcToBinary(ctx android.ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags, outputFile android.WritablePath, includeDirs []string) {
transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, flags, outputFile, "bin", includeDirs)
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) {
transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, flags, outputFile, "rlib", includeDirs)
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) {
transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, flags, outputFile, "dylib", includeDirs)
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) {
transformSrctoCrate(ctx, mainSrc, deps.RLibs, deps.DyLibs, deps.ProcMacros, deps.StaticLibs, deps.SharedLibs, flags, outputFile, "proc-macro", includeDirs)
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 {
@ -67,24 +67,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) {
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 {
@ -107,6 +111,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,
@ -116,8 +123,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(),
},
})

View File

@ -113,7 +113,8 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flag
flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
flags.RustFlags = append(flags.RustFlags, "--edition="+*compiler.Properties.Edition)
flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
flags.GlobalFlags = append(flags.GlobalFlags, ctx.toolchain().ToolchainRustFlags())
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,6 +149,18 @@ 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
}

View File

@ -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, " "),
}
}

View File

@ -15,6 +15,8 @@
package config
import (
"strings"
"android/soong/android"
_ "android/soong/cc/config"
)
@ -30,6 +32,24 @@ var (
"libterm",
"libtest",
}
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",
}
)
func init() {
@ -56,4 +76,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, " "))
}

View File

@ -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
}

View File

@ -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"
}

View File

@ -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

View File

@ -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
}

View File

@ -43,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 {
@ -92,6 +93,9 @@ type PathDeps struct {
linkDirs []string
depFlags []string
//ReexportedDeps android.Paths
CrtBegin android.OptionalPath
CrtEnd android.OptionalPath
}
type RustLibraries []RustLibrary
@ -398,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
@ -480,6 +488,13 @@ 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...)
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...)
}