blob: 4312452d2a668066cfea30f728c747df3bf5c18f [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
Ivan Lozanodd055472020-09-28 13:22:45 -040027type RustLinkage int
28
29const (
30 DefaultLinkage RustLinkage = iota
31 RlibLinkage
32 DylibLinkage
33)
34
Thiébaud Weksteene81c9242020-08-03 10:46:28 +020035func (compiler *baseCompiler) edition() string {
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -070036 return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition)
37}
38
Matthew Maurer99020b02019-10-31 10:44:40 -070039func (compiler *baseCompiler) setNoStdlibs() {
40 compiler.Properties.No_stdlibs = proptools.BoolPtr(true)
41}
42
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +020043func (compiler *baseCompiler) disableLints() {
44 compiler.Properties.Lints = proptools.StringPtr("none")
Stephen Craneda931d42020-08-04 13:02:28 -070045}
46
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080047func NewBaseCompiler(dir, dir64 string, location installLocation) *baseCompiler {
Ivan Lozanoffee3342019-08-27 12:03:00 -070048 return &baseCompiler{
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -070049 Properties: BaseCompilerProperties{},
50 dir: dir,
51 dir64: dir64,
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080052 location: location,
Ivan Lozanoffee3342019-08-27 12:03:00 -070053 }
54}
55
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080056type installLocation int
57
58const (
59 InstallInSystem installLocation = 0
60 InstallInData = iota
Ivan Lozano43845682020-07-09 21:03:28 -040061
62 incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\""
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080063)
64
Ivan Lozanoffee3342019-08-27 12:03:00 -070065type BaseCompilerProperties struct {
Ivan Lozano8a23fa42020-06-16 10:26:57 -040066 // path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs)
67 Srcs []string `android:"path,arch_variant"`
68
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +020069 // name of the lint set that should be used to validate this module.
70 //
71 // Possible values are "default" (for using a sensible set of lints
72 // depending on the module's location), "android" (for the strictest
73 // lint set that applies to all Android platform code), "vendor" (for
74 // a relaxed set) and "none" (for ignoring all lint warnings and
75 // errors). The default value is "default".
76 Lints *string
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -070077
Ivan Lozanoffee3342019-08-27 12:03:00 -070078 // flags to pass to rustc
79 Flags []string `android:"path,arch_variant"`
80
81 // flags to pass to the linker
82 Ld_flags []string `android:"path,arch_variant"`
83
84 // list of rust rlib crate dependencies
85 Rlibs []string `android:"arch_variant"`
86
87 // list of rust dylib crate dependencies
88 Dylibs []string `android:"arch_variant"`
89
Matthew Maurer0f003b12020-06-29 14:34:06 -070090 // list of rust automatic crate dependencies
91 Rustlibs []string `android:"arch_variant"`
92
Ivan Lozanoffee3342019-08-27 12:03:00 -070093 // list of rust proc_macro crate dependencies
94 Proc_macros []string `android:"arch_variant"`
95
96 // list of C shared library dependencies
97 Shared_libs []string `android:"arch_variant"`
98
99 // list of C static library dependencies
100 Static_libs []string `android:"arch_variant"`
101
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400102 // crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
103 // modules which create library variants (rust_bindgen). This must be the expected extern crate name used in
104 // source, and is required to conform to an enforced format matching library output files (if the output file is
105 // lib<someName><suffix>, the crate_name property must be <someName>).
Ivan Lozanoffee3342019-08-27 12:03:00 -0700106 Crate_name string `android:"arch_variant"`
107
108 // list of features to enable for this crate
109 Features []string `android:"arch_variant"`
110
111 // specific rust edition that should be used if the default version is not desired
112 Edition *string `android:"arch_variant"`
113
114 // sets name of the output
115 Stem *string `android:"arch_variant"`
116
117 // append to name of output
118 Suffix *string `android:"arch_variant"`
119
120 // install to a subdirectory of the default install path for the module
121 Relative_install_path *string `android:"arch_variant"`
Matthew Maurer99020b02019-10-31 10:44:40 -0700122
123 // whether to suppress inclusion of standard crates - defaults to false
124 No_stdlibs *bool
Ivan Lozanoea086132020-12-08 14:43:00 -0500125
126 // Change the rustlibs linkage to select rlib linkage by default for device targets.
127 // Also link libstd as an rlib as well on device targets.
128 // Note: This is the default behavior for host targets.
129 //
130 // This is primarily meant for rust_binary and rust_ffi modules where the default
131 // linkage of libstd might need to be overridden in some use cases. This should
132 // generally be avoided with other module types since it may cause collisions at
133 // linkage if all dependencies of the root binary module do not link against libstd\
134 // the same way.
135 Prefer_rlib *bool `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700136}
137
138type baseCompiler struct {
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400139 Properties BaseCompilerProperties
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400140 coverageFile android.Path //rustc generates a single gcno file
Ivan Lozanoffee3342019-08-27 12:03:00 -0700141
142 // Install related
143 dir string
144 dir64 string
145 subDir string
146 relative string
Colin Cross70dda7e2019-10-01 22:05:35 -0700147 path android.InstallPath
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800148 location installLocation
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400149
150 coverageOutputZipFile android.OptionalPath
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400151 distFile android.OptionalPath
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200152 // Stripped output file. If Valid(), this file will be installed instead of outputFile.
153 strippedOutputFile android.OptionalPath
Ivan Lozanoffee3342019-08-27 12:03:00 -0700154}
155
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400156func (compiler *baseCompiler) Disabled() bool {
157 return false
158}
159
160func (compiler *baseCompiler) SetDisabled() {
161 panic("baseCompiler does not implement SetDisabled()")
162}
163
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400164func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath {
165 panic("baseCompiler does not implement coverageOutputZipPath()")
166}
167
Ivan Lozanoea086132020-12-08 14:43:00 -0500168func (compiler *baseCompiler) preferRlib() bool {
169 return Bool(compiler.Properties.Prefer_rlib)
170}
171
Ivan Lozanodd055472020-09-28 13:22:45 -0400172func (compiler *baseCompiler) stdLinkage(ctx *depsContext) RustLinkage {
Ivan Lozano2b081132020-09-08 12:46:52 -0400173 // For devices, we always link stdlibs in as dylibs by default.
Ivan Lozanoea086132020-12-08 14:43:00 -0500174 if compiler.preferRlib() {
175 return RlibLinkage
176 } else if ctx.Device() {
Ivan Lozanodd055472020-09-28 13:22:45 -0400177 return DylibLinkage
Ivan Lozano2b081132020-09-08 12:46:52 -0400178 } else {
Ivan Lozanodd055472020-09-28 13:22:45 -0400179 return RlibLinkage
Ivan Lozano2b081132020-09-08 12:46:52 -0400180 }
Ivan Lozano042504f2020-08-18 14:31:23 -0400181}
182
Ivan Lozanoffee3342019-08-27 12:03:00 -0700183var _ compiler = (*baseCompiler)(nil)
184
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800185func (compiler *baseCompiler) inData() bool {
186 return compiler.location == InstallInData
187}
188
Ivan Lozanoffee3342019-08-27 12:03:00 -0700189func (compiler *baseCompiler) compilerProps() []interface{} {
190 return []interface{}{&compiler.Properties}
191}
192
193func (compiler *baseCompiler) featuresToFlags(features []string) []string {
194 flags := []string{}
195 for _, feature := range features {
196 flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
197 }
198 return flags
199}
200
201func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
202
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200203 lintFlags, err := config.RustcLintsForDir(ctx.ModuleDir(), compiler.Properties.Lints)
204 if err != nil {
205 ctx.PropertyErrorf("lints", err.Error())
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -0700206 }
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200207 flags.RustFlags = append(flags.RustFlags, lintFlags)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700208 flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
209 flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
Thiébaud Weksteene81c9242020-08-03 10:46:28 +0200210 flags.RustFlags = append(flags.RustFlags, "--edition="+compiler.edition())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700211 flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
Joel Galenson724286c2019-09-30 13:01:37 -0700212 flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700213 flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
214 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700215
216 if ctx.Host() && !ctx.Windows() {
217 rpath_prefix := `\$$ORIGIN/`
218 if ctx.Darwin() {
219 rpath_prefix = "@loader_path/"
220 }
221
222 var rpath string
223 if ctx.toolchain().Is64Bit() {
224 rpath = "lib64"
225 } else {
226 rpath = "lib"
227 }
228 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
229 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
230 }
231
232 return flags
233}
234
235func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
236 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
237}
238
239func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
240 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
241 deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
Matthew Maurer0f003b12020-06-29 14:34:06 -0700242 deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700243 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
244 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
245 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
246
Matthew Maurer99020b02019-10-31 10:44:40 -0700247 if !Bool(compiler.Properties.No_stdlibs) {
248 for _, stdlib := range config.Stdlibs {
Jiyong Parkb5d2dd22020-08-31 17:22:01 +0900249 // If we're building for the primary arch of the build host, use the compiler's stdlibs
250 if ctx.Target().Os == android.BuildOs && ctx.TargetPrimary() {
Matthew Maurer99020b02019-10-31 10:44:40 -0700251 stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
252 }
253
Ivan Lozano2b081132020-09-08 12:46:52 -0400254 deps.Stdlibs = append(deps.Stdlibs, stdlib)
Matthew Maurer99020b02019-10-31 10:44:40 -0700255 }
256 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700257 return deps
258}
259
Ivan Lozanobf63d002020-10-02 10:03:23 -0400260func bionicDeps(deps Deps, static bool) Deps {
261 bionicLibs := []string{}
262 bionicLibs = append(bionicLibs, "liblog")
263 bionicLibs = append(bionicLibs, "libc")
264 bionicLibs = append(bionicLibs, "libm")
265 bionicLibs = append(bionicLibs, "libdl")
266
267 if static {
268 deps.StaticLibs = append(deps.StaticLibs, bionicLibs...)
269 } else {
270 deps.SharedLibs = append(deps.SharedLibs, bionicLibs...)
271 }
Ivan Lozanof1c84332019-09-20 11:00:37 -0700272
273 //TODO(b/141331117) libstd requires libgcc on Android
274 deps.StaticLibs = append(deps.StaticLibs, "libgcc")
275
276 return deps
277}
278
Ivan Lozanoffee3342019-08-27 12:03:00 -0700279func (compiler *baseCompiler) crateName() string {
280 return compiler.Properties.Crate_name
281}
282
Colin Cross70dda7e2019-10-01 22:05:35 -0700283func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700284 dir := compiler.dir
285 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
286 dir = compiler.dir64
287 }
Ivan Lozanod6fdca82020-04-07 12:30:33 -0400288 if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
289 dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
290 }
291 if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700292 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
293 }
294 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
295 compiler.relativeInstallPath(), compiler.relative)
296}
297
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400298func (compiler *baseCompiler) nativeCoverage() bool {
299 return false
300}
301
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200302func (compiler *baseCompiler) install(ctx ModuleContext) {
303 path := ctx.RustModule().outputFile
304 if compiler.strippedOutputFile.Valid() {
305 path = compiler.strippedOutputFile
306 }
307 compiler.path = ctx.InstallFile(compiler.installDir(ctx), path.Path().Base(), path.Path())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700308}
309
310func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
311 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
312}
313
314func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
Thiébaud Weksteen1f7f70f2020-06-24 11:32:48 +0200315 stem := ctx.ModuleName()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700316 if String(compiler.Properties.Stem) != "" {
317 stem = String(compiler.Properties.Stem)
318 }
319
320 return stem
321}
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700322
Ivan Lozanoffee3342019-08-27 12:03:00 -0700323func (compiler *baseCompiler) relativeInstallPath() string {
324 return String(compiler.Properties.Relative_install_path)
325}
326
Ivan Lozano43845682020-07-09 21:03:28 -0400327// 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 -0700328func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
329 // The srcs can contain strings with prefix ":".
330 // They are dependent modules of this module, with android.SourceDepTag.
331 // They are not the main source file compiled by rustc.
332 numSrcs := 0
333 srcIndex := 0
334 for i, s := range srcs {
335 if android.SrcIsModule(s) == "" {
336 numSrcs++
337 srcIndex = i
338 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700339 }
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700340 if numSrcs != 1 {
Ivan Lozano43845682020-07-09 21:03:28 -0400341 ctx.PropertyErrorf("srcs", incorrectSourcesError)
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700342 }
343 if srcIndex != 0 {
344 ctx.PropertyErrorf("srcs", "main source file must be the first in srcs")
345 }
346 paths := android.PathsForModuleSrc(ctx, srcs)
Ivan Lozano43845682020-07-09 21:03:28 -0400347 return paths[srcIndex], paths[1:]
Ivan Lozanoffee3342019-08-27 12:03:00 -0700348}