compiler.go 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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. package rust
  15. import (
  16. "fmt"
  17. "path/filepath"
  18. "github.com/google/blueprint/proptools"
  19. "android/soong/android"
  20. "android/soong/rust/config"
  21. )
  22. func (compiler *baseCompiler) edition() string {
  23. return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition)
  24. }
  25. func (compiler *baseCompiler) setNoStdlibs() {
  26. compiler.Properties.No_stdlibs = proptools.BoolPtr(true)
  27. }
  28. func (compiler *baseCompiler) disableLints() {
  29. compiler.Properties.Lints = proptools.StringPtr("none")
  30. }
  31. func NewBaseCompiler(dir, dir64 string, location installLocation) *baseCompiler {
  32. return &baseCompiler{
  33. Properties: BaseCompilerProperties{},
  34. dir: dir,
  35. dir64: dir64,
  36. location: location,
  37. }
  38. }
  39. type installLocation int
  40. const (
  41. InstallInSystem installLocation = 0
  42. InstallInData = iota
  43. incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\""
  44. )
  45. type BaseCompilerProperties struct {
  46. // path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs)
  47. Srcs []string `android:"path,arch_variant"`
  48. // name of the lint set that should be used to validate this module.
  49. //
  50. // Possible values are "default" (for using a sensible set of lints
  51. // depending on the module's location), "android" (for the strictest
  52. // lint set that applies to all Android platform code), "vendor" (for
  53. // a relaxed set) and "none" (for ignoring all lint warnings and
  54. // errors). The default value is "default".
  55. Lints *string
  56. // flags to pass to rustc
  57. Flags []string `android:"path,arch_variant"`
  58. // flags to pass to the linker
  59. Ld_flags []string `android:"path,arch_variant"`
  60. // list of rust rlib crate dependencies
  61. Rlibs []string `android:"arch_variant"`
  62. // list of rust dylib crate dependencies
  63. Dylibs []string `android:"arch_variant"`
  64. // list of rust automatic crate dependencies
  65. Rustlibs []string `android:"arch_variant"`
  66. // list of rust proc_macro crate dependencies
  67. Proc_macros []string `android:"arch_variant"`
  68. // list of C shared library dependencies
  69. Shared_libs []string `android:"arch_variant"`
  70. // list of C static library dependencies
  71. Static_libs []string `android:"arch_variant"`
  72. // crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
  73. // modules which create library variants (rust_bindgen). This must be the expected extern crate name used in
  74. // source, and is required to conform to an enforced format matching library output files (if the output file is
  75. // lib<someName><suffix>, the crate_name property must be <someName>).
  76. Crate_name string `android:"arch_variant"`
  77. // list of features to enable for this crate
  78. Features []string `android:"arch_variant"`
  79. // specific rust edition that should be used if the default version is not desired
  80. Edition *string `android:"arch_variant"`
  81. // sets name of the output
  82. Stem *string `android:"arch_variant"`
  83. // append to name of output
  84. Suffix *string `android:"arch_variant"`
  85. // install to a subdirectory of the default install path for the module
  86. Relative_install_path *string `android:"arch_variant"`
  87. // whether to suppress inclusion of standard crates - defaults to false
  88. No_stdlibs *bool
  89. }
  90. type baseCompiler struct {
  91. Properties BaseCompilerProperties
  92. coverageFile android.Path //rustc generates a single gcno file
  93. // Install related
  94. dir string
  95. dir64 string
  96. subDir string
  97. relative string
  98. path android.InstallPath
  99. location installLocation
  100. coverageOutputZipFile android.OptionalPath
  101. unstrippedOutputFile android.Path
  102. distFile android.OptionalPath
  103. }
  104. func (compiler *baseCompiler) Disabled() bool {
  105. return false
  106. }
  107. func (compiler *baseCompiler) SetDisabled() {
  108. panic("baseCompiler does not implement SetDisabled()")
  109. }
  110. func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath {
  111. panic("baseCompiler does not implement coverageOutputZipPath()")
  112. }
  113. var _ compiler = (*baseCompiler)(nil)
  114. func (compiler *baseCompiler) inData() bool {
  115. return compiler.location == InstallInData
  116. }
  117. func (compiler *baseCompiler) compilerProps() []interface{} {
  118. return []interface{}{&compiler.Properties}
  119. }
  120. func (compiler *baseCompiler) featuresToFlags(features []string) []string {
  121. flags := []string{}
  122. for _, feature := range features {
  123. flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
  124. }
  125. return flags
  126. }
  127. func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
  128. lintFlags, err := config.RustcLintsForDir(ctx.ModuleDir(), compiler.Properties.Lints)
  129. if err != nil {
  130. ctx.PropertyErrorf("lints", err.Error())
  131. }
  132. flags.RustFlags = append(flags.RustFlags, lintFlags)
  133. flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
  134. flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
  135. flags.RustFlags = append(flags.RustFlags, "--edition="+compiler.edition())
  136. flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
  137. flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
  138. flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
  139. flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
  140. if ctx.Host() && !ctx.Windows() {
  141. rpath_prefix := `\$$ORIGIN/`
  142. if ctx.Darwin() {
  143. rpath_prefix = "@loader_path/"
  144. }
  145. var rpath string
  146. if ctx.toolchain().Is64Bit() {
  147. rpath = "lib64"
  148. } else {
  149. rpath = "lib"
  150. }
  151. flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
  152. flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
  153. }
  154. return flags
  155. }
  156. func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
  157. panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
  158. }
  159. func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
  160. deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
  161. deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
  162. deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs...)
  163. deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
  164. deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
  165. deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
  166. if !Bool(compiler.Properties.No_stdlibs) {
  167. for _, stdlib := range config.Stdlibs {
  168. // If we're building for the primary host target, use the compiler's stdlibs
  169. if ctx.Host() && ctx.TargetPrimary() {
  170. stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
  171. }
  172. deps.Rustlibs = append(deps.Rustlibs, stdlib)
  173. }
  174. }
  175. return deps
  176. }
  177. func bionicDeps(deps Deps) Deps {
  178. deps.SharedLibs = append(deps.SharedLibs, "liblog")
  179. deps.SharedLibs = append(deps.SharedLibs, "libc")
  180. deps.SharedLibs = append(deps.SharedLibs, "libm")
  181. deps.SharedLibs = append(deps.SharedLibs, "libdl")
  182. //TODO(b/141331117) libstd requires libgcc on Android
  183. deps.StaticLibs = append(deps.StaticLibs, "libgcc")
  184. return deps
  185. }
  186. func (compiler *baseCompiler) crateName() string {
  187. return compiler.Properties.Crate_name
  188. }
  189. func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
  190. dir := compiler.dir
  191. if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
  192. dir = compiler.dir64
  193. }
  194. if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
  195. dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
  196. }
  197. if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
  198. dir = filepath.Join(dir, ctx.Arch().ArchType.String())
  199. }
  200. return android.PathForModuleInstall(ctx, dir, compiler.subDir,
  201. compiler.relativeInstallPath(), compiler.relative)
  202. }
  203. func (compiler *baseCompiler) nativeCoverage() bool {
  204. return false
  205. }
  206. func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
  207. compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
  208. }
  209. func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
  210. return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
  211. }
  212. func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
  213. stem := ctx.ModuleName()
  214. if String(compiler.Properties.Stem) != "" {
  215. stem = String(compiler.Properties.Stem)
  216. }
  217. return stem
  218. }
  219. func (compiler *baseCompiler) relativeInstallPath() string {
  220. return String(compiler.Properties.Relative_install_path)
  221. }
  222. // Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs.
  223. func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
  224. // The srcs can contain strings with prefix ":".
  225. // They are dependent modules of this module, with android.SourceDepTag.
  226. // They are not the main source file compiled by rustc.
  227. numSrcs := 0
  228. srcIndex := 0
  229. for i, s := range srcs {
  230. if android.SrcIsModule(s) == "" {
  231. numSrcs++
  232. srcIndex = i
  233. }
  234. }
  235. if numSrcs != 1 {
  236. ctx.PropertyErrorf("srcs", incorrectSourcesError)
  237. }
  238. if srcIndex != 0 {
  239. ctx.PropertyErrorf("srcs", "main source file must be the first in srcs")
  240. }
  241. paths := android.PathsForModuleSrc(ctx, srcs)
  242. return paths[srcIndex], paths[1:]
  243. }