blob: 1091585d329847563ad07a63c0b510206f53d4ad [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 \":\""
Thiébaud Weksteenee6a89b2021-02-25 16:30:57 +010063 genSubDir = "out/"
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080064)
65
Ivan Lozanoffee3342019-08-27 12:03:00 -070066type BaseCompilerProperties struct {
Ivan Lozano8a23fa42020-06-16 10:26:57 -040067 // path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs)
68 Srcs []string `android:"path,arch_variant"`
69
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +020070 // name of the lint set that should be used to validate this module.
71 //
72 // Possible values are "default" (for using a sensible set of lints
73 // depending on the module's location), "android" (for the strictest
74 // lint set that applies to all Android platform code), "vendor" (for
75 // a relaxed set) and "none" (for ignoring all lint warnings and
76 // errors). The default value is "default".
77 Lints *string
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -070078
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +020079 // flags to pass to rustc. To enable configuration options or features, use the "cfgs" or "features" properties.
Liz Kammereda93982021-04-20 10:15:41 -040080 Flags []string `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -070081
82 // flags to pass to the linker
Liz Kammereda93982021-04-20 10:15:41 -040083 Ld_flags []string `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -070084
85 // list of rust rlib crate dependencies
86 Rlibs []string `android:"arch_variant"`
87
88 // list of rust dylib crate dependencies
89 Dylibs []string `android:"arch_variant"`
90
Matthew Maurer0f003b12020-06-29 14:34:06 -070091 // list of rust automatic crate dependencies
92 Rustlibs []string `android:"arch_variant"`
93
Ivan Lozanoffee3342019-08-27 12:03:00 -070094 // list of rust proc_macro crate dependencies
95 Proc_macros []string `android:"arch_variant"`
96
97 // list of C shared library dependencies
98 Shared_libs []string `android:"arch_variant"`
99
Ivan Lozano63bb7682021-03-23 15:53:44 -0400100 // list of C static library dependencies. These dependencies do not normally propagate to dependents
101 // and may need to be redeclared. See whole_static_libs for bundling static dependencies into a library.
Ivan Lozanoffee3342019-08-27 12:03:00 -0700102 Static_libs []string `android:"arch_variant"`
103
Ivan Lozano63bb7682021-03-23 15:53:44 -0400104 // Similar to static_libs, but will bundle the static library dependency into a library. This is helpful
105 // to avoid having to redeclare the dependency for dependents of this library, but in some cases may also
106 // result in bloat if multiple dependencies all include the same static library whole.
107 //
108 // The common use case for this is when the static library is unlikely to be a dependency of other modules to avoid
109 // having to redeclare the static library dependency for every dependent module.
110 // If you are not sure what to, for rust_library modules most static dependencies should go in static_libraries,
111 // and for rust_ffi modules most static dependencies should go into whole_static_libraries.
112 //
113 // For rust_ffi static variants, these libraries will be included in the resulting static library archive.
114 //
115 // For rust_library rlib variants, these libraries will be bundled into the resulting rlib library. This will
116 // include all of the static libraries symbols in any dylibs or binaries which use this rlib as well.
117 Whole_static_libs []string `android:"arch_variant"`
118
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400119 // crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
120 // modules which create library variants (rust_bindgen). This must be the expected extern crate name used in
121 // source, and is required to conform to an enforced format matching library output files (if the output file is
122 // lib<someName><suffix>, the crate_name property must be <someName>).
Ivan Lozanoffee3342019-08-27 12:03:00 -0700123 Crate_name string `android:"arch_variant"`
124
125 // list of features to enable for this crate
126 Features []string `android:"arch_variant"`
127
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +0200128 // list of configuration options to enable for this crate. To enable features, use the "features" property.
129 Cfgs []string `android:"arch_variant"`
130
Ivan Lozanoffee3342019-08-27 12:03:00 -0700131 // specific rust edition that should be used if the default version is not desired
132 Edition *string `android:"arch_variant"`
133
134 // sets name of the output
135 Stem *string `android:"arch_variant"`
136
137 // append to name of output
138 Suffix *string `android:"arch_variant"`
139
140 // install to a subdirectory of the default install path for the module
141 Relative_install_path *string `android:"arch_variant"`
Matthew Maurer99020b02019-10-31 10:44:40 -0700142
143 // whether to suppress inclusion of standard crates - defaults to false
144 No_stdlibs *bool
Ivan Lozanoea086132020-12-08 14:43:00 -0500145
146 // Change the rustlibs linkage to select rlib linkage by default for device targets.
147 // Also link libstd as an rlib as well on device targets.
148 // Note: This is the default behavior for host targets.
149 //
150 // This is primarily meant for rust_binary and rust_ffi modules where the default
151 // linkage of libstd might need to be overridden in some use cases. This should
152 // generally be avoided with other module types since it may cause collisions at
153 // linkage if all dependencies of the root binary module do not link against libstd\
154 // the same way.
155 Prefer_rlib *bool `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700156}
157
158type baseCompiler struct {
Joel Galensonfa049382021-01-14 16:03:18 -0800159 Properties BaseCompilerProperties
Ivan Lozanoffee3342019-08-27 12:03:00 -0700160
161 // Install related
162 dir string
163 dir64 string
164 subDir string
165 relative string
Colin Cross70dda7e2019-10-01 22:05:35 -0700166 path android.InstallPath
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800167 location installLocation
Ivan Lozano6cd99e62020-02-11 08:24:25 -0500168 sanitize *sanitize
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400169
Joel Galensonfa049382021-01-14 16:03:18 -0800170 distFile android.OptionalPath
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200171 // Stripped output file. If Valid(), this file will be installed instead of outputFile.
172 strippedOutputFile android.OptionalPath
Thiébaud Weksteenee6a89b2021-02-25 16:30:57 +0100173
174 // If a crate has a source-generated dependency, a copy of the source file
175 // will be available in cargoOutDir (equivalent to Cargo OUT_DIR).
176 cargoOutDir android.ModuleOutPath
Ivan Lozanoffee3342019-08-27 12:03:00 -0700177}
178
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400179func (compiler *baseCompiler) Disabled() bool {
180 return false
181}
182
183func (compiler *baseCompiler) SetDisabled() {
184 panic("baseCompiler does not implement SetDisabled()")
185}
186
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400187func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath {
188 panic("baseCompiler does not implement coverageOutputZipPath()")
189}
190
Ivan Lozanoea086132020-12-08 14:43:00 -0500191func (compiler *baseCompiler) preferRlib() bool {
192 return Bool(compiler.Properties.Prefer_rlib)
193}
194
Ivan Lozanodd055472020-09-28 13:22:45 -0400195func (compiler *baseCompiler) stdLinkage(ctx *depsContext) RustLinkage {
Ivan Lozano2b081132020-09-08 12:46:52 -0400196 // For devices, we always link stdlibs in as dylibs by default.
Ivan Lozanoea086132020-12-08 14:43:00 -0500197 if compiler.preferRlib() {
198 return RlibLinkage
199 } else if ctx.Device() {
Ivan Lozanodd055472020-09-28 13:22:45 -0400200 return DylibLinkage
Ivan Lozano2b081132020-09-08 12:46:52 -0400201 } else {
Ivan Lozanodd055472020-09-28 13:22:45 -0400202 return RlibLinkage
Ivan Lozano2b081132020-09-08 12:46:52 -0400203 }
Ivan Lozano042504f2020-08-18 14:31:23 -0400204}
205
Ivan Lozanoffee3342019-08-27 12:03:00 -0700206var _ compiler = (*baseCompiler)(nil)
207
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800208func (compiler *baseCompiler) inData() bool {
209 return compiler.location == InstallInData
210}
211
Ivan Lozanoffee3342019-08-27 12:03:00 -0700212func (compiler *baseCompiler) compilerProps() []interface{} {
213 return []interface{}{&compiler.Properties}
214}
215
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +0200216func (compiler *baseCompiler) cfgsToFlags() []string {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700217 flags := []string{}
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +0200218 for _, cfg := range compiler.Properties.Cfgs {
219 flags = append(flags, "--cfg '"+cfg+"'")
220 }
221 return flags
222}
223
224func (compiler *baseCompiler) featuresToFlags() []string {
225 flags := []string{}
226 for _, feature := range compiler.Properties.Features {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700227 flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
228 }
229 return flags
230}
231
232func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
233
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200234 lintFlags, err := config.RustcLintsForDir(ctx.ModuleDir(), compiler.Properties.Lints)
235 if err != nil {
236 ctx.PropertyErrorf("lints", err.Error())
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -0700237 }
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200238 flags.RustFlags = append(flags.RustFlags, lintFlags)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700239 flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +0200240 flags.RustFlags = append(flags.RustFlags, compiler.cfgsToFlags()...)
241 flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags()...)
Thiébaud Weksteene81c9242020-08-03 10:46:28 +0200242 flags.RustFlags = append(flags.RustFlags, "--edition="+compiler.edition())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700243 flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
Joel Galenson724286c2019-09-30 13:01:37 -0700244 flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700245 flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
246 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700247
248 if ctx.Host() && !ctx.Windows() {
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800249 rpathPrefix := `\$$ORIGIN/`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700250 if ctx.Darwin() {
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800251 rpathPrefix = "@loader_path/"
Ivan Lozanoffee3342019-08-27 12:03:00 -0700252 }
253
254 var rpath string
255 if ctx.toolchain().Is64Bit() {
256 rpath = "lib64"
257 } else {
258 rpath = "lib"
259 }
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800260 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpathPrefix+rpath)
261 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpathPrefix+"../"+rpath)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700262 }
263
Ivan Lozanof76cdf72021-02-12 09:55:06 -0500264 if ctx.RustModule().UseVndk() {
265 flags.RustFlags = append(flags.RustFlags, "--cfg 'android_vndk'")
266 }
267
Ivan Lozanoffee3342019-08-27 12:03:00 -0700268 return flags
269}
270
271func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
272 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
273}
274
Thiébaud Weksteenee6a89b2021-02-25 16:30:57 +0100275func (compiler *baseCompiler) initialize(ctx ModuleContext) {
276 compiler.cargoOutDir = android.PathForModuleOut(ctx, genSubDir)
277}
278
279func (compiler *baseCompiler) CargoOutDir() android.OptionalPath {
280 return android.OptionalPathForPath(compiler.cargoOutDir)
281}
282
Ivan Lozano3968d8f2020-12-14 11:27:52 -0500283func (compiler *baseCompiler) isDependencyRoot() bool {
284 return false
285}
286
Jiyong Parke54f07e2021-04-07 15:08:04 +0900287func (compiler *baseCompiler) strippedOutputFilePath() android.OptionalPath {
288 return compiler.strippedOutputFile
289}
290
Ivan Lozanoffee3342019-08-27 12:03:00 -0700291func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
292 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
293 deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
Matthew Maurer0f003b12020-06-29 14:34:06 -0700294 deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700295 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
296 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
Ivan Lozano63bb7682021-03-23 15:53:44 -0400297 deps.WholeStaticLibs = append(deps.WholeStaticLibs, compiler.Properties.Whole_static_libs...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700298 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
299
Matthew Maurer99020b02019-10-31 10:44:40 -0700300 if !Bool(compiler.Properties.No_stdlibs) {
301 for _, stdlib := range config.Stdlibs {
Jiyong Parkb5d2dd22020-08-31 17:22:01 +0900302 // If we're building for the primary arch of the build host, use the compiler's stdlibs
Ivan Lozanoc5d34ec2021-02-09 14:22:00 -0500303 if ctx.Target().Os == android.BuildOs {
Matthew Maurer99020b02019-10-31 10:44:40 -0700304 stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
305 }
Ivan Lozano2b081132020-09-08 12:46:52 -0400306 deps.Stdlibs = append(deps.Stdlibs, stdlib)
Matthew Maurer99020b02019-10-31 10:44:40 -0700307 }
308 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700309 return deps
310}
311
Thiébaud Weksteenf1ff54a2021-03-22 14:24:54 +0100312func bionicDeps(ctx DepsContext, deps Deps, static bool) Deps {
Ivan Lozanobf63d002020-10-02 10:03:23 -0400313 bionicLibs := []string{}
314 bionicLibs = append(bionicLibs, "liblog")
315 bionicLibs = append(bionicLibs, "libc")
316 bionicLibs = append(bionicLibs, "libm")
317 bionicLibs = append(bionicLibs, "libdl")
318
319 if static {
320 deps.StaticLibs = append(deps.StaticLibs, bionicLibs...)
321 } else {
322 deps.SharedLibs = append(deps.SharedLibs, bionicLibs...)
323 }
Ivan Lozanof1c84332019-09-20 11:00:37 -0700324
Thiébaud Weksteenf1ff54a2021-03-22 14:24:54 +0100325 if libRuntimeBuiltins := config.BuiltinsRuntimeLibrary(ctx.toolchain()); libRuntimeBuiltins != "" {
326 deps.StaticLibs = append(deps.StaticLibs, libRuntimeBuiltins)
327 }
Ivan Lozanof1c84332019-09-20 11:00:37 -0700328 return deps
329}
330
Ivan Lozanoffee3342019-08-27 12:03:00 -0700331func (compiler *baseCompiler) crateName() string {
332 return compiler.Properties.Crate_name
333}
334
Colin Cross70dda7e2019-10-01 22:05:35 -0700335func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700336 dir := compiler.dir
337 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
338 dir = compiler.dir64
339 }
Ivan Lozanod6fdca82020-04-07 12:30:33 -0400340 if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
341 dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
342 }
343 if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700344 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
345 }
Ivan Lozanoc08897c2021-04-02 12:41:32 -0400346
347 if compiler.location == InstallInData && ctx.RustModule().UseVndk() {
348 dir = filepath.Join(dir, "vendor")
349 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700350 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
351 compiler.relativeInstallPath(), compiler.relative)
352}
353
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400354func (compiler *baseCompiler) nativeCoverage() bool {
355 return false
356}
357
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200358func (compiler *baseCompiler) install(ctx ModuleContext) {
Jiyong Parke54f07e2021-04-07 15:08:04 +0900359 path := ctx.RustModule().OutputFile()
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200360 compiler.path = ctx.InstallFile(compiler.installDir(ctx), path.Path().Base(), path.Path())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700361}
362
363func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
364 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
365}
366
367func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
Thiébaud Weksteen1f7f70f2020-06-24 11:32:48 +0200368 stem := ctx.ModuleName()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700369 if String(compiler.Properties.Stem) != "" {
370 stem = String(compiler.Properties.Stem)
371 }
372
373 return stem
374}
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700375
Ivan Lozanoffee3342019-08-27 12:03:00 -0700376func (compiler *baseCompiler) relativeInstallPath() string {
377 return String(compiler.Properties.Relative_install_path)
378}
379
Ivan Lozano43845682020-07-09 21:03:28 -0400380// 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 -0700381func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
382 // The srcs can contain strings with prefix ":".
383 // They are dependent modules of this module, with android.SourceDepTag.
384 // They are not the main source file compiled by rustc.
385 numSrcs := 0
386 srcIndex := 0
387 for i, s := range srcs {
388 if android.SrcIsModule(s) == "" {
389 numSrcs++
390 srcIndex = i
391 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700392 }
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700393 if numSrcs != 1 {
Ivan Lozano43845682020-07-09 21:03:28 -0400394 ctx.PropertyErrorf("srcs", incorrectSourcesError)
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700395 }
396 if srcIndex != 0 {
397 ctx.PropertyErrorf("srcs", "main source file must be the first in srcs")
398 }
399 paths := android.PathsForModuleSrc(ctx, srcs)
Ivan Lozano43845682020-07-09 21:03:28 -0400400 return paths[srcIndex], paths[1:]
Ivan Lozanoffee3342019-08-27 12:03:00 -0700401}