Add Rust support to Soong.
Adds support to Soong for building rust modules. This currently only supports x86_64 device and x86 linux host targets. The functionality is sufficient to build crosvm. Bug: 136189233 Test: Test module builds. Test: crosvm builds. Change-Id: I6ea04615834a6d673578ab10ea1a2eb04259fe09
This commit is contained in:
193
rust/compiler.go
Normal file
193
rust/compiler.go
Normal file
@@ -0,0 +1,193 @@
|
||||
// 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 rust
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/rust/config"
|
||||
)
|
||||
|
||||
func NewBaseCompiler(dir, dir64 string) *baseCompiler {
|
||||
return &baseCompiler{
|
||||
Properties: BaseCompilerProperties{
|
||||
Edition: &config.DefaultEdition,
|
||||
},
|
||||
dir: dir,
|
||||
dir64: dir64,
|
||||
}
|
||||
}
|
||||
|
||||
type BaseCompilerProperties struct {
|
||||
// flags to pass to rustc
|
||||
Flags []string `android:"path,arch_variant"`
|
||||
|
||||
// flags to pass to the linker
|
||||
Ld_flags []string `android:"path,arch_variant"`
|
||||
|
||||
// list of rust rlib crate dependencies
|
||||
Rlibs []string `android:"arch_variant"`
|
||||
|
||||
// list of rust dylib crate dependencies
|
||||
Dylibs []string `android:"arch_variant"`
|
||||
|
||||
// list of rust proc_macro crate dependencies
|
||||
Proc_macros []string `android:"arch_variant"`
|
||||
|
||||
// list of C shared library dependencies
|
||||
Shared_libs []string `android:"arch_variant"`
|
||||
|
||||
// list of C static library dependencies
|
||||
Static_libs []string `android:"arch_variant"`
|
||||
|
||||
// crate name (defaults to module name); if library, this must be the expected extern crate name
|
||||
Crate_name string `android:"arch_variant"`
|
||||
|
||||
// list of features to enable for this crate
|
||||
Features []string `android:"arch_variant"`
|
||||
|
||||
// specific rust edition that should be used if the default version is not desired
|
||||
Edition *string `android:"arch_variant"`
|
||||
|
||||
// sets name of the output
|
||||
Stem *string `android:"arch_variant"`
|
||||
|
||||
// append to name of output
|
||||
Suffix *string `android:"arch_variant"`
|
||||
|
||||
// install to a subdirectory of the default install path for the module
|
||||
Relative_install_path *string `android:"arch_variant"`
|
||||
}
|
||||
|
||||
type baseCompiler struct {
|
||||
Properties BaseCompilerProperties
|
||||
pathDeps android.Paths
|
||||
rustFlagsDeps android.Paths
|
||||
linkFlagsDeps android.Paths
|
||||
flags string
|
||||
linkFlags string
|
||||
depFlags []string
|
||||
linkDirs []string
|
||||
edition string
|
||||
src android.Path //rustc takes a single src file
|
||||
|
||||
// Install related
|
||||
dir string
|
||||
dir64 string
|
||||
subDir string
|
||||
relative string
|
||||
path android.OutputPath
|
||||
}
|
||||
|
||||
var _ compiler = (*baseCompiler)(nil)
|
||||
|
||||
func (compiler *baseCompiler) compilerProps() []interface{} {
|
||||
return []interface{}{&compiler.Properties}
|
||||
}
|
||||
|
||||
func (compiler *baseCompiler) featuresToFlags(features []string) []string {
|
||||
flags := []string{}
|
||||
for _, feature := range features {
|
||||
flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||
|
||||
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.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
|
||||
flags.GlobalFlags = append(flags.GlobalFlags, ctx.toolchain().ToolchainRustFlags())
|
||||
|
||||
if ctx.Host() && !ctx.Windows() {
|
||||
rpath_prefix := `\$$ORIGIN/`
|
||||
if ctx.Darwin() {
|
||||
rpath_prefix = "@loader_path/"
|
||||
}
|
||||
|
||||
var rpath string
|
||||
if ctx.toolchain().Is64Bit() {
|
||||
rpath = "lib64"
|
||||
} else {
|
||||
rpath = "lib"
|
||||
}
|
||||
flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
|
||||
flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
|
||||
}
|
||||
|
||||
return flags
|
||||
}
|
||||
|
||||
func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
|
||||
panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
|
||||
}
|
||||
|
||||
func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
|
||||
deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
|
||||
deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
|
||||
deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
|
||||
deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
|
||||
deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
|
||||
|
||||
return deps
|
||||
}
|
||||
|
||||
func (compiler *baseCompiler) crateName() string {
|
||||
return compiler.Properties.Crate_name
|
||||
}
|
||||
|
||||
func (compiler *baseCompiler) installDir(ctx ModuleContext) android.OutputPath {
|
||||
dir := compiler.dir
|
||||
if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
|
||||
dir = compiler.dir64
|
||||
}
|
||||
if (!ctx.Host() && !ctx.Arch().Native) || ctx.Target().NativeBridge == android.NativeBridgeEnabled {
|
||||
dir = filepath.Join(dir, ctx.Arch().ArchType.String())
|
||||
}
|
||||
return android.PathForModuleInstall(ctx, dir, compiler.subDir,
|
||||
compiler.relativeInstallPath(), compiler.relative)
|
||||
}
|
||||
|
||||
func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
|
||||
compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
|
||||
}
|
||||
|
||||
func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
|
||||
return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
|
||||
}
|
||||
|
||||
func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
|
||||
stem := ctx.baseModuleName()
|
||||
if String(compiler.Properties.Stem) != "" {
|
||||
stem = String(compiler.Properties.Stem)
|
||||
}
|
||||
|
||||
return stem
|
||||
}
|
||||
func (compiler *baseCompiler) relativeInstallPath() string {
|
||||
return String(compiler.Properties.Relative_install_path)
|
||||
}
|
||||
|
||||
func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path {
|
||||
srcPaths := android.PathsForModuleSrc(ctx, srcs)
|
||||
if len(srcPaths) != 1 {
|
||||
ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules")
|
||||
}
|
||||
return srcPaths[0]
|
||||
}
|
Reference in New Issue
Block a user