123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- // 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 (
- "android/soong/android"
- )
- func init() {
- android.RegisterModuleType("rust_binary", RustBinaryFactory)
- android.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
- }
- type BinaryCompilerProperties struct {
- // Builds this binary as a static binary. Implies prefer_rlib true.
- //
- // Static executables currently only support for bionic targets. Non-bionic targets will not produce a fully static
- // binary, but will still implicitly imply prefer_rlib true.
- Static_executable *bool `android:"arch_variant"`
- }
- type binaryInterface interface {
- binary() bool
- staticallyLinked() bool
- testBinary() bool
- }
- type binaryDecorator struct {
- *baseCompiler
- stripper Stripper
- Properties BinaryCompilerProperties
- }
- var _ compiler = (*binaryDecorator)(nil)
- // rust_binary produces a binary that is runnable on a device.
- func RustBinaryFactory() android.Module {
- module, _ := NewRustBinary(android.HostAndDeviceSupported)
- return module.Init()
- }
- func RustBinaryHostFactory() android.Module {
- module, _ := NewRustBinary(android.HostSupported)
- return module.Init()
- }
- func NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
- module := newModule(hod, android.MultilibFirst)
- binary := &binaryDecorator{
- baseCompiler: NewBaseCompiler("bin", "", InstallInSystem),
- }
- module.compiler = binary
- return module, binary
- }
- func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
- flags = binary.baseCompiler.compilerFlags(ctx, flags)
- if ctx.Os().Linux() {
- flags.LinkFlags = append(flags.LinkFlags, "-Wl,--gc-sections")
- }
- 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,-z,nocopyreloc",
- "-Wl,--no-undefined-version")
- if Bool(binary.Properties.Static_executable) {
- flags.LinkFlags = append(flags.LinkFlags, "-static")
- flags.RustFlags = append(flags.RustFlags, "-C relocation-model=static")
- }
- }
- return flags
- }
- func (binary *binaryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
- deps = binary.baseCompiler.compilerDeps(ctx, deps)
- static := Bool(binary.Properties.Static_executable)
- if ctx.toolchain().Bionic() {
- deps = bionicDeps(ctx, deps, static)
- if static {
- deps.CrtBegin = []string{"crtbegin_static"}
- } else {
- deps.CrtBegin = []string{"crtbegin_dynamic"}
- }
- deps.CrtEnd = []string{"crtend_android"}
- } else if ctx.Os() == android.LinuxMusl {
- deps = muslDeps(ctx, deps, static)
- if static {
- deps.CrtBegin = []string{"libc_musl_crtbegin_static"}
- } else {
- deps.CrtBegin = []string{"libc_musl_crtbegin_dynamic"}
- }
- deps.CrtEnd = []string{"libc_musl_crtend"}
- }
- return deps
- }
- func (binary *binaryDecorator) compilerProps() []interface{} {
- return append(binary.baseCompiler.compilerProps(),
- &binary.Properties,
- &binary.stripper.StripProperties)
- }
- func (binary *binaryDecorator) nativeCoverage() bool {
- return true
- }
- func (binary *binaryDecorator) preferRlib() bool {
- return Bool(binary.baseCompiler.Properties.Prefer_rlib) || Bool(binary.Properties.Static_executable)
- }
- func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
- fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
- srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
- outputFile := android.PathForModuleOut(ctx, fileName)
- ret := buildOutput{outputFile: outputFile}
- flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
- if binary.stripper.NeedsStrip(ctx) {
- strippedOutputFile := outputFile
- outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
- binary.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
- binary.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
- }
- binary.baseCompiler.unstrippedOutputFile = outputFile
- ret.kytheFile = TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile).kytheFile
- return ret
- }
- func (binary *binaryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
- // Binaries default to dylib dependencies for device, rlib for host.
- if binary.preferRlib() {
- return rlibAutoDep
- } else if mod, ok := ctx.Module().(*Module); ok && mod.InVendor() {
- // Vendor Rust binaries should prefer rlibs.
- return rlibAutoDep
- } else if ctx.Device() {
- return dylibAutoDep
- } else {
- return rlibAutoDep
- }
- }
- func (binary *binaryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
- if binary.preferRlib() {
- return RlibLinkage
- } else if ctx.RustModule().InVendor() {
- return RlibLinkage
- }
- return binary.baseCompiler.stdLinkage(ctx)
- }
- func (binary *binaryDecorator) binary() bool {
- return true
- }
- func (binary *binaryDecorator) staticallyLinked() bool {
- return Bool(binary.Properties.Static_executable)
- }
- func (binary *binaryDecorator) testBinary() bool {
- return false
- }
|