2019-08-28 03:03:00 +08:00
|
|
|
// 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"
|
|
|
|
|
2019-11-01 10:38:29 +08:00
|
|
|
"github.com/google/blueprint/proptools"
|
|
|
|
|
2019-08-28 03:03:00 +08:00
|
|
|
"android/soong/android"
|
|
|
|
"android/soong/rust/config"
|
|
|
|
)
|
|
|
|
|
2020-09-29 01:22:45 +08:00
|
|
|
type RustLinkage int
|
|
|
|
|
|
|
|
const (
|
|
|
|
DefaultLinkage RustLinkage = iota
|
|
|
|
RlibLinkage
|
|
|
|
DylibLinkage
|
|
|
|
)
|
|
|
|
|
2020-08-03 16:46:28 +08:00
|
|
|
func (compiler *baseCompiler) edition() string {
|
2019-10-04 00:47:06 +08:00
|
|
|
return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition)
|
|
|
|
}
|
|
|
|
|
2019-11-01 01:44:40 +08:00
|
|
|
func (compiler *baseCompiler) setNoStdlibs() {
|
|
|
|
compiler.Properties.No_stdlibs = proptools.BoolPtr(true)
|
|
|
|
}
|
|
|
|
|
2020-08-13 18:55:59 +08:00
|
|
|
func (compiler *baseCompiler) disableLints() {
|
|
|
|
compiler.Properties.Lints = proptools.StringPtr("none")
|
2020-08-05 04:02:28 +08:00
|
|
|
}
|
|
|
|
|
2019-12-13 11:36:05 +08:00
|
|
|
func NewBaseCompiler(dir, dir64 string, location installLocation) *baseCompiler {
|
2019-08-28 03:03:00 +08:00
|
|
|
return &baseCompiler{
|
2019-10-04 00:47:06 +08:00
|
|
|
Properties: BaseCompilerProperties{},
|
|
|
|
dir: dir,
|
|
|
|
dir64: dir64,
|
2019-12-13 11:36:05 +08:00
|
|
|
location: location,
|
2019-08-28 03:03:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-13 11:36:05 +08:00
|
|
|
type installLocation int
|
|
|
|
|
|
|
|
const (
|
|
|
|
InstallInSystem installLocation = 0
|
|
|
|
InstallInData = iota
|
2020-07-10 09:03:28 +08:00
|
|
|
|
|
|
|
incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\""
|
2019-12-13 11:36:05 +08:00
|
|
|
)
|
|
|
|
|
2019-08-28 03:03:00 +08:00
|
|
|
type BaseCompilerProperties struct {
|
2020-06-16 22:26:57 +08:00
|
|
|
// path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs)
|
|
|
|
Srcs []string `android:"path,arch_variant"`
|
|
|
|
|
2020-08-13 18:55:59 +08:00
|
|
|
// name of the lint set that should be used to validate this module.
|
|
|
|
//
|
|
|
|
// Possible values are "default" (for using a sensible set of lints
|
|
|
|
// depending on the module's location), "android" (for the strictest
|
|
|
|
// lint set that applies to all Android platform code), "vendor" (for
|
|
|
|
// a relaxed set) and "none" (for ignoring all lint warnings and
|
|
|
|
// errors). The default value is "default".
|
|
|
|
Lints *string
|
2019-09-27 09:59:27 +08:00
|
|
|
|
2019-08-28 03:03:00 +08:00
|
|
|
// 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"`
|
|
|
|
|
2020-06-30 05:34:06 +08:00
|
|
|
// list of rust automatic crate dependencies
|
|
|
|
Rustlibs []string `android:"arch_variant"`
|
|
|
|
|
2019-08-28 03:03:00 +08:00
|
|
|
// 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"`
|
|
|
|
|
2020-08-01 01:40:31 +08:00
|
|
|
// crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
|
|
|
|
// modules which create library variants (rust_bindgen). This must be the expected extern crate name used in
|
|
|
|
// source, and is required to conform to an enforced format matching library output files (if the output file is
|
|
|
|
// lib<someName><suffix>, the crate_name property must be <someName>).
|
2019-08-28 03:03:00 +08:00
|
|
|
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"`
|
2019-11-01 01:44:40 +08:00
|
|
|
|
|
|
|
// whether to suppress inclusion of standard crates - defaults to false
|
|
|
|
No_stdlibs *bool
|
2019-08-28 03:03:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
type baseCompiler struct {
|
2020-06-16 22:26:57 +08:00
|
|
|
Properties BaseCompilerProperties
|
|
|
|
coverageFile android.Path //rustc generates a single gcno file
|
2019-08-28 03:03:00 +08:00
|
|
|
|
|
|
|
// Install related
|
|
|
|
dir string
|
|
|
|
dir64 string
|
|
|
|
subDir string
|
|
|
|
relative string
|
2019-10-02 13:05:35 +08:00
|
|
|
path android.InstallPath
|
2019-12-13 11:36:05 +08:00
|
|
|
location installLocation
|
2020-06-16 22:26:57 +08:00
|
|
|
|
|
|
|
coverageOutputZipFile android.OptionalPath
|
|
|
|
distFile android.OptionalPath
|
2020-08-27 19:48:36 +08:00
|
|
|
// Stripped output file. If Valid(), this file will be installed instead of outputFile.
|
|
|
|
strippedOutputFile android.OptionalPath
|
2019-08-28 03:03:00 +08:00
|
|
|
}
|
|
|
|
|
2020-08-01 01:40:31 +08:00
|
|
|
func (compiler *baseCompiler) Disabled() bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (compiler *baseCompiler) SetDisabled() {
|
|
|
|
panic("baseCompiler does not implement SetDisabled()")
|
|
|
|
}
|
|
|
|
|
2020-04-09 21:56:02 +08:00
|
|
|
func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath {
|
|
|
|
panic("baseCompiler does not implement coverageOutputZipPath()")
|
|
|
|
}
|
|
|
|
|
2020-09-29 01:22:45 +08:00
|
|
|
func (compiler *baseCompiler) stdLinkage(ctx *depsContext) RustLinkage {
|
2020-09-09 00:46:52 +08:00
|
|
|
// For devices, we always link stdlibs in as dylibs by default.
|
|
|
|
if ctx.Device() {
|
2020-09-29 01:22:45 +08:00
|
|
|
return DylibLinkage
|
2020-09-09 00:46:52 +08:00
|
|
|
} else {
|
2020-09-29 01:22:45 +08:00
|
|
|
return RlibLinkage
|
2020-09-09 00:46:52 +08:00
|
|
|
}
|
2020-08-19 02:31:23 +08:00
|
|
|
}
|
|
|
|
|
2019-08-28 03:03:00 +08:00
|
|
|
var _ compiler = (*baseCompiler)(nil)
|
|
|
|
|
2019-12-13 11:36:05 +08:00
|
|
|
func (compiler *baseCompiler) inData() bool {
|
|
|
|
return compiler.location == InstallInData
|
|
|
|
}
|
|
|
|
|
2019-08-28 03:03:00 +08:00
|
|
|
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 {
|
|
|
|
|
2020-08-13 18:55:59 +08:00
|
|
|
lintFlags, err := config.RustcLintsForDir(ctx.ModuleDir(), compiler.Properties.Lints)
|
|
|
|
if err != nil {
|
|
|
|
ctx.PropertyErrorf("lints", err.Error())
|
2019-09-27 09:59:27 +08:00
|
|
|
}
|
2020-08-13 18:55:59 +08:00
|
|
|
flags.RustFlags = append(flags.RustFlags, lintFlags)
|
2019-08-28 03:03:00 +08:00
|
|
|
flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
|
|
|
|
flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
|
2020-08-03 16:46:28 +08:00
|
|
|
flags.RustFlags = append(flags.RustFlags, "--edition="+compiler.edition())
|
2019-08-28 03:03:00 +08:00
|
|
|
flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
|
2019-10-01 04:01:37 +08:00
|
|
|
flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
|
2019-09-21 02:00:37 +08:00
|
|
|
flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
|
|
|
|
flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
|
2019-08-28 03:03:00 +08:00
|
|
|
|
|
|
|
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...)
|
2020-06-30 05:34:06 +08:00
|
|
|
deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs...)
|
2019-08-28 03:03:00 +08:00
|
|
|
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...)
|
|
|
|
|
2019-11-01 01:44:40 +08:00
|
|
|
if !Bool(compiler.Properties.No_stdlibs) {
|
|
|
|
for _, stdlib := range config.Stdlibs {
|
2020-08-31 16:22:01 +08:00
|
|
|
// If we're building for the primary arch of the build host, use the compiler's stdlibs
|
|
|
|
if ctx.Target().Os == android.BuildOs && ctx.TargetPrimary() {
|
2019-11-01 01:44:40 +08:00
|
|
|
stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
|
|
|
|
}
|
|
|
|
|
2020-09-09 00:46:52 +08:00
|
|
|
deps.Stdlibs = append(deps.Stdlibs, stdlib)
|
2019-11-01 01:44:40 +08:00
|
|
|
}
|
|
|
|
}
|
2019-08-28 03:03:00 +08:00
|
|
|
return deps
|
|
|
|
}
|
|
|
|
|
2020-10-02 22:03:23 +08:00
|
|
|
func bionicDeps(deps Deps, static bool) Deps {
|
|
|
|
bionicLibs := []string{}
|
|
|
|
bionicLibs = append(bionicLibs, "liblog")
|
|
|
|
bionicLibs = append(bionicLibs, "libc")
|
|
|
|
bionicLibs = append(bionicLibs, "libm")
|
|
|
|
bionicLibs = append(bionicLibs, "libdl")
|
|
|
|
|
|
|
|
if static {
|
|
|
|
deps.StaticLibs = append(deps.StaticLibs, bionicLibs...)
|
|
|
|
} else {
|
|
|
|
deps.SharedLibs = append(deps.SharedLibs, bionicLibs...)
|
|
|
|
}
|
2019-09-21 02:00:37 +08:00
|
|
|
|
|
|
|
//TODO(b/141331117) libstd requires libgcc on Android
|
|
|
|
deps.StaticLibs = append(deps.StaticLibs, "libgcc")
|
|
|
|
|
|
|
|
return deps
|
|
|
|
}
|
|
|
|
|
2019-08-28 03:03:00 +08:00
|
|
|
func (compiler *baseCompiler) crateName() string {
|
|
|
|
return compiler.Properties.Crate_name
|
|
|
|
}
|
|
|
|
|
2019-10-02 13:05:35 +08:00
|
|
|
func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
|
2019-08-28 03:03:00 +08:00
|
|
|
dir := compiler.dir
|
|
|
|
if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
|
|
|
|
dir = compiler.dir64
|
|
|
|
}
|
2020-04-08 00:30:33 +08:00
|
|
|
if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
|
|
|
|
dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
|
|
|
|
}
|
|
|
|
if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
|
2019-08-28 03:03:00 +08:00
|
|
|
dir = filepath.Join(dir, ctx.Arch().ArchType.String())
|
|
|
|
}
|
|
|
|
return android.PathForModuleInstall(ctx, dir, compiler.subDir,
|
|
|
|
compiler.relativeInstallPath(), compiler.relative)
|
|
|
|
}
|
|
|
|
|
2020-04-09 21:56:02 +08:00
|
|
|
func (compiler *baseCompiler) nativeCoverage() bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2020-08-27 19:48:36 +08:00
|
|
|
func (compiler *baseCompiler) install(ctx ModuleContext) {
|
|
|
|
path := ctx.RustModule().outputFile
|
|
|
|
if compiler.strippedOutputFile.Valid() {
|
|
|
|
path = compiler.strippedOutputFile
|
|
|
|
}
|
|
|
|
compiler.path = ctx.InstallFile(compiler.installDir(ctx), path.Path().Base(), path.Path())
|
2019-08-28 03:03:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
|
|
|
|
return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
|
2020-06-24 17:32:48 +08:00
|
|
|
stem := ctx.ModuleName()
|
2019-08-28 03:03:00 +08:00
|
|
|
if String(compiler.Properties.Stem) != "" {
|
|
|
|
stem = String(compiler.Properties.Stem)
|
|
|
|
}
|
|
|
|
|
|
|
|
return stem
|
|
|
|
}
|
2019-11-01 10:38:29 +08:00
|
|
|
|
2019-08-28 03:03:00 +08:00
|
|
|
func (compiler *baseCompiler) relativeInstallPath() string {
|
|
|
|
return String(compiler.Properties.Relative_install_path)
|
|
|
|
}
|
|
|
|
|
2020-07-10 09:03:28 +08:00
|
|
|
// Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs.
|
2020-05-16 08:36:30 +08:00
|
|
|
func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
|
|
|
|
// The srcs can contain strings with prefix ":".
|
|
|
|
// They are dependent modules of this module, with android.SourceDepTag.
|
|
|
|
// They are not the main source file compiled by rustc.
|
|
|
|
numSrcs := 0
|
|
|
|
srcIndex := 0
|
|
|
|
for i, s := range srcs {
|
|
|
|
if android.SrcIsModule(s) == "" {
|
|
|
|
numSrcs++
|
|
|
|
srcIndex = i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if numSrcs != 1 {
|
2020-07-10 09:03:28 +08:00
|
|
|
ctx.PropertyErrorf("srcs", incorrectSourcesError)
|
2020-05-16 08:36:30 +08:00
|
|
|
}
|
|
|
|
if srcIndex != 0 {
|
|
|
|
ctx.PropertyErrorf("srcs", "main source file must be the first in srcs")
|
2019-08-28 03:03:00 +08:00
|
|
|
}
|
2020-05-16 08:36:30 +08:00
|
|
|
paths := android.PathsForModuleSrc(ctx, srcs)
|
2020-07-10 09:03:28 +08:00
|
|
|
return paths[srcIndex], paths[1:]
|
2019-08-28 03:03:00 +08:00
|
|
|
}
|