1// Copyright 2019 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package rust 16 17import ( 18 "android/soong/android" 19) 20 21func init() { 22 android.RegisterModuleType("rust_binary", RustBinaryFactory) 23 android.RegisterModuleType("rust_binary_host", RustBinaryHostFactory) 24} 25 26type BinaryCompilerProperties struct { 27 // passes -C prefer-dynamic to rustc, which tells it to dynamically link the stdlib 28 // (assuming it has no dylib dependencies already) 29 Prefer_dynamic *bool 30} 31 32type binaryDecorator struct { 33 *baseCompiler 34 35 Properties BinaryCompilerProperties 36} 37 38var _ compiler = (*binaryDecorator)(nil) 39 40// rust_binary produces a binary that is runnable on a device. 41func RustBinaryFactory() android.Module { 42 module, _ := NewRustBinary(android.HostAndDeviceSupported) 43 return module.Init() 44} 45 46func RustBinaryHostFactory() android.Module { 47 module, _ := NewRustBinary(android.HostSupported) 48 return module.Init() 49} 50 51func NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) { 52 module := newModule(hod, android.MultilibFirst) 53 54 binary := &binaryDecorator{ 55 baseCompiler: NewBaseCompiler("bin", "", InstallInSystem), 56 } 57 58 module.compiler = binary 59 60 return module, binary 61} 62 63func (binary *binaryDecorator) preferDynamic() bool { 64 return Bool(binary.Properties.Prefer_dynamic) 65} 66 67func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { 68 flags = binary.baseCompiler.compilerFlags(ctx, flags) 69 70 if ctx.toolchain().Bionic() { 71 // no-undefined-version breaks dylib compilation since __rust_*alloc* functions aren't defined, 72 // but we can apply this to binaries. 73 flags.LinkFlags = append(flags.LinkFlags, 74 "-Wl,--gc-sections", 75 "-Wl,-z,nocopyreloc", 76 "-Wl,--no-undefined-version") 77 } 78 79 if binary.preferDynamic() { 80 flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic") 81 } 82 return flags 83} 84 85func (binary *binaryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { 86 deps = binary.baseCompiler.compilerDeps(ctx, deps) 87 88 if ctx.toolchain().Bionic() { 89 deps = bionicDeps(deps) 90 deps.CrtBegin = "crtbegin_dynamic" 91 deps.CrtEnd = "crtend_android" 92 } 93 94 return deps 95} 96 97func (binary *binaryDecorator) compilerProps() []interface{} { 98 return append(binary.baseCompiler.compilerProps(), 99 &binary.Properties) 100} 101 102func (binary *binaryDecorator) nativeCoverage() bool { 103 return true 104} 105 106func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path { 107 fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix() 108 109 srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs) 110 111 outputFile := android.PathForModuleOut(ctx, fileName) 112 binary.unstrippedOutputFile = outputFile 113 114 flags.RustFlags = append(flags.RustFlags, deps.depFlags...) 115 116 outputs := TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile, deps.linkDirs) 117 binary.coverageFile = outputs.coverageFile 118 119 var coverageFiles android.Paths 120 if outputs.coverageFile != nil { 121 coverageFiles = append(coverageFiles, binary.coverageFile) 122 } 123 if len(deps.coverageFiles) > 0 { 124 coverageFiles = append(coverageFiles, deps.coverageFiles...) 125 } 126 binary.coverageOutputZipFile = TransformCoverageFilesToZip(ctx, coverageFiles, binary.getStem(ctx)) 127 128 return outputFile 129} 130 131func (binary *binaryDecorator) coverageOutputZipPath() android.OptionalPath { 132 return binary.coverageOutputZipFile 133} 134 135func (binary *binaryDecorator) autoDep() autoDep { 136 if binary.preferDynamic() { 137 return dylibAutoDep 138 } else { 139 return rlibAutoDep 140 } 141} 142