blob: 2600f4d0f09b15a461b8e3f3784ed331d96dfc75 [file] [log] [blame]
Ivan Lozanoffee3342019-08-27 12:03:00 -07001// 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 "fmt"
19 "path/filepath"
20
Ivan Lozanoad8b18b2019-10-31 19:38:29 -070021 "github.com/google/blueprint/proptools"
22
Ivan Lozanoffee3342019-08-27 12:03:00 -070023 "android/soong/android"
24 "android/soong/rust/config"
25)
26
Thiébaud Weksteene81c9242020-08-03 10:46:28 +020027func (compiler *baseCompiler) edition() string {
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -070028 return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition)
29}
30
Matthew Maurer99020b02019-10-31 10:44:40 -070031func (compiler *baseCompiler) setNoStdlibs() {
32 compiler.Properties.No_stdlibs = proptools.BoolPtr(true)
33}
34
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +020035func (compiler *baseCompiler) disableLints() {
36 compiler.Properties.Lints = proptools.StringPtr("none")
Stephen Craneda931d42020-08-04 13:02:28 -070037}
38
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080039func NewBaseCompiler(dir, dir64 string, location installLocation) *baseCompiler {
Ivan Lozanoffee3342019-08-27 12:03:00 -070040 return &baseCompiler{
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -070041 Properties: BaseCompilerProperties{},
42 dir: dir,
43 dir64: dir64,
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080044 location: location,
Ivan Lozanoffee3342019-08-27 12:03:00 -070045 }
46}
47
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080048type installLocation int
49
50const (
51 InstallInSystem installLocation = 0
52 InstallInData = iota
Ivan Lozano43845682020-07-09 21:03:28 -040053
54 incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\""
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080055)
56
Ivan Lozanoffee3342019-08-27 12:03:00 -070057type BaseCompilerProperties struct {
Ivan Lozano8a23fa42020-06-16 10:26:57 -040058 // path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs)
59 Srcs []string `android:"path,arch_variant"`
60
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +020061 // name of the lint set that should be used to validate this module.
62 //
63 // Possible values are "default" (for using a sensible set of lints
64 // depending on the module's location), "android" (for the strictest
65 // lint set that applies to all Android platform code), "vendor" (for
66 // a relaxed set) and "none" (for ignoring all lint warnings and
67 // errors). The default value is "default".
68 Lints *string
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -070069
Ivan Lozanoffee3342019-08-27 12:03:00 -070070 // flags to pass to rustc
71 Flags []string `android:"path,arch_variant"`
72
73 // flags to pass to the linker
74 Ld_flags []string `android:"path,arch_variant"`
75
76 // list of rust rlib crate dependencies
77 Rlibs []string `android:"arch_variant"`
78
79 // list of rust dylib crate dependencies
80 Dylibs []string `android:"arch_variant"`
81
Matthew Maurer0f003b12020-06-29 14:34:06 -070082 // list of rust automatic crate dependencies
83 Rustlibs []string `android:"arch_variant"`
84
Ivan Lozanoffee3342019-08-27 12:03:00 -070085 // list of rust proc_macro crate dependencies
86 Proc_macros []string `android:"arch_variant"`
87
88 // list of C shared library dependencies
89 Shared_libs []string `android:"arch_variant"`
90
91 // list of C static library dependencies
92 Static_libs []string `android:"arch_variant"`
93
Ivan Lozano26ecd6c2020-07-31 13:40:31 -040094 // crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
95 // modules which create library variants (rust_bindgen). This must be the expected extern crate name used in
96 // source, and is required to conform to an enforced format matching library output files (if the output file is
97 // lib<someName><suffix>, the crate_name property must be <someName>).
Ivan Lozanoffee3342019-08-27 12:03:00 -070098 Crate_name string `android:"arch_variant"`
99
100 // list of features to enable for this crate
101 Features []string `android:"arch_variant"`
102
103 // specific rust edition that should be used if the default version is not desired
104 Edition *string `android:"arch_variant"`
105
106 // sets name of the output
107 Stem *string `android:"arch_variant"`
108
109 // append to name of output
110 Suffix *string `android:"arch_variant"`
111
112 // install to a subdirectory of the default install path for the module
113 Relative_install_path *string `android:"arch_variant"`
Matthew Maurer99020b02019-10-31 10:44:40 -0700114
115 // whether to suppress inclusion of standard crates - defaults to false
116 No_stdlibs *bool
Ivan Lozanoffee3342019-08-27 12:03:00 -0700117}
118
119type baseCompiler struct {
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400120 Properties BaseCompilerProperties
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400121 coverageFile android.Path //rustc generates a single gcno file
Ivan Lozanoffee3342019-08-27 12:03:00 -0700122
123 // Install related
124 dir string
125 dir64 string
126 subDir string
127 relative string
Colin Cross70dda7e2019-10-01 22:05:35 -0700128 path android.InstallPath
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800129 location installLocation
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400130
131 coverageOutputZipFile android.OptionalPath
132 unstrippedOutputFile android.Path
133 distFile android.OptionalPath
Ivan Lozanoffee3342019-08-27 12:03:00 -0700134}
135
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400136func (compiler *baseCompiler) Disabled() bool {
137 return false
138}
139
140func (compiler *baseCompiler) SetDisabled() {
141 panic("baseCompiler does not implement SetDisabled()")
142}
143
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400144func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath {
145 panic("baseCompiler does not implement coverageOutputZipPath()")
146}
147
Ivan Lozano042504f2020-08-18 14:31:23 -0400148func (compiler *baseCompiler) static() bool {
149 return false
150}
151
Ivan Lozanoffee3342019-08-27 12:03:00 -0700152var _ compiler = (*baseCompiler)(nil)
153
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800154func (compiler *baseCompiler) inData() bool {
155 return compiler.location == InstallInData
156}
157
Ivan Lozanoffee3342019-08-27 12:03:00 -0700158func (compiler *baseCompiler) compilerProps() []interface{} {
159 return []interface{}{&compiler.Properties}
160}
161
162func (compiler *baseCompiler) featuresToFlags(features []string) []string {
163 flags := []string{}
164 for _, feature := range features {
165 flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
166 }
167 return flags
168}
169
170func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
171
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200172 lintFlags, err := config.RustcLintsForDir(ctx.ModuleDir(), compiler.Properties.Lints)
173 if err != nil {
174 ctx.PropertyErrorf("lints", err.Error())
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -0700175 }
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200176 flags.RustFlags = append(flags.RustFlags, lintFlags)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700177 flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
178 flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
Thiébaud Weksteene81c9242020-08-03 10:46:28 +0200179 flags.RustFlags = append(flags.RustFlags, "--edition="+compiler.edition())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700180 flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
Joel Galenson724286c2019-09-30 13:01:37 -0700181 flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700182 flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
183 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700184
185 if ctx.Host() && !ctx.Windows() {
186 rpath_prefix := `\$$ORIGIN/`
187 if ctx.Darwin() {
188 rpath_prefix = "@loader_path/"
189 }
190
191 var rpath string
192 if ctx.toolchain().Is64Bit() {
193 rpath = "lib64"
194 } else {
195 rpath = "lib"
196 }
197 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
198 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
199 }
200
201 return flags
202}
203
204func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
205 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
206}
207
208func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
209 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
210 deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
Matthew Maurer0f003b12020-06-29 14:34:06 -0700211 deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700212 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
213 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
214 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
215
Matthew Maurer99020b02019-10-31 10:44:40 -0700216 if !Bool(compiler.Properties.No_stdlibs) {
217 for _, stdlib := range config.Stdlibs {
Ivan Lozano9d1df102020-04-28 10:10:23 -0400218 // If we're building for the primary host target, use the compiler's stdlibs
219 if ctx.Host() && ctx.TargetPrimary() {
Matthew Maurer99020b02019-10-31 10:44:40 -0700220 stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
221 }
222
Ivan Lozano042504f2020-08-18 14:31:23 -0400223 // For devices, we always link stdlibs in as dylibs except for ffi static libraries.
224 // (rustc does not support linking libstd as a dylib for ffi static libraries)
225 if ctx.Host() {
226 deps.Rustlibs = append(deps.Rustlibs, stdlib)
227 } else if ctx.RustModule().compiler.static() {
228 deps.Rlibs = append(deps.Rlibs, stdlib)
229 } else {
230 deps.Dylibs = append(deps.Dylibs, stdlib)
231 }
Matthew Maurer99020b02019-10-31 10:44:40 -0700232 }
233 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700234 return deps
235}
236
Ivan Lozano45901ed2020-07-24 16:05:01 -0400237func bionicDeps(deps Deps) Deps {
Ivan Lozanof1c84332019-09-20 11:00:37 -0700238 deps.SharedLibs = append(deps.SharedLibs, "liblog")
239 deps.SharedLibs = append(deps.SharedLibs, "libc")
240 deps.SharedLibs = append(deps.SharedLibs, "libm")
241 deps.SharedLibs = append(deps.SharedLibs, "libdl")
242
243 //TODO(b/141331117) libstd requires libgcc on Android
244 deps.StaticLibs = append(deps.StaticLibs, "libgcc")
245
246 return deps
247}
248
Ivan Lozanoffee3342019-08-27 12:03:00 -0700249func (compiler *baseCompiler) crateName() string {
250 return compiler.Properties.Crate_name
251}
252
Colin Cross70dda7e2019-10-01 22:05:35 -0700253func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700254 dir := compiler.dir
255 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
256 dir = compiler.dir64
257 }
Ivan Lozanod6fdca82020-04-07 12:30:33 -0400258 if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
259 dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
260 }
261 if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700262 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
263 }
264 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
265 compiler.relativeInstallPath(), compiler.relative)
266}
267
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400268func (compiler *baseCompiler) nativeCoverage() bool {
269 return false
270}
271
Ivan Lozanoffee3342019-08-27 12:03:00 -0700272func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
273 compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
274}
275
276func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
277 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
278}
279
280func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
Thiébaud Weksteen1f7f70f2020-06-24 11:32:48 +0200281 stem := ctx.ModuleName()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700282 if String(compiler.Properties.Stem) != "" {
283 stem = String(compiler.Properties.Stem)
284 }
285
286 return stem
287}
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700288
Ivan Lozanoffee3342019-08-27 12:03:00 -0700289func (compiler *baseCompiler) relativeInstallPath() string {
290 return String(compiler.Properties.Relative_install_path)
291}
292
Ivan Lozano43845682020-07-09 21:03:28 -0400293// Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs.
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700294func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
295 // The srcs can contain strings with prefix ":".
296 // They are dependent modules of this module, with android.SourceDepTag.
297 // They are not the main source file compiled by rustc.
298 numSrcs := 0
299 srcIndex := 0
300 for i, s := range srcs {
301 if android.SrcIsModule(s) == "" {
302 numSrcs++
303 srcIndex = i
304 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700305 }
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700306 if numSrcs != 1 {
Ivan Lozano43845682020-07-09 21:03:28 -0400307 ctx.PropertyErrorf("srcs", incorrectSourcesError)
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700308 }
309 if srcIndex != 0 {
310 ctx.PropertyErrorf("srcs", "main source file must be the first in srcs")
311 }
312 paths := android.PathsForModuleSrc(ctx, srcs)
Ivan Lozano43845682020-07-09 21:03:28 -0400313 return paths[srcIndex], paths[1:]
Ivan Lozanoffee3342019-08-27 12:03:00 -0700314}