blob: f186ef38f7069d4b6d8e9a372a058b4cdeb8c07f [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 (
Colin Cross225a37a2023-01-11 14:17:39 -080018 "android/soong/cc"
Matthew Maurera28404a2023-11-20 23:33:28 +000019 "errors"
Ivan Lozanoffee3342019-08-27 12:03:00 -070020 "fmt"
21 "path/filepath"
Ivan Lozano45a9e312021-07-27 12:29:12 -040022 "strings"
Ivan Lozanoffee3342019-08-27 12:03:00 -070023
Ivan Lozanoad8b18b2019-10-31 19:38:29 -070024 "github.com/google/blueprint/proptools"
25
Ivan Lozanoffee3342019-08-27 12:03:00 -070026 "android/soong/android"
27 "android/soong/rust/config"
28)
29
Ivan Lozanodd055472020-09-28 13:22:45 -040030type RustLinkage int
31
32const (
Ivan Lozano806efd32024-12-11 21:38:53 +000033 DylibLinkage RustLinkage = iota
Ivan Lozanodd055472020-09-28 13:22:45 -040034 RlibLinkage
Ivan Lozanodd055472020-09-28 13:22:45 -040035)
36
Matthew Maurer689d6f62023-11-20 17:49:25 +000037type compiler interface {
38 initialize(ctx ModuleContext)
39 compilerFlags(ctx ModuleContext, flags Flags) Flags
40 cfgFlags(ctx ModuleContext, flags Flags) Flags
Jihoon Kang091ffd82024-10-03 01:13:24 +000041 featureFlags(ctx ModuleContext, module *Module, flags Flags) Flags
Ivan Lozano9587f452025-01-08 03:17:19 +000042 baseCompilerProps() BaseCompilerProperties
Matthew Maurer689d6f62023-11-20 17:49:25 +000043 compilerProps() []interface{}
44 compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput
45 compilerDeps(ctx DepsContext, deps Deps) Deps
46 crateName() string
Matthew Maurerdb72f7e2023-11-21 00:20:02 +000047 edition() string
Jihoon Kang091ffd82024-10-03 01:13:24 +000048 features(ctx android.ConfigurableEvaluatorContext, module *Module) []string
Matthew Maurer689d6f62023-11-20 17:49:25 +000049 rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath
Ivan Lozanoab586472024-05-15 10:59:47 -040050 Thinlto() bool
Matthew Maurer689d6f62023-11-20 17:49:25 +000051
52 // Output directory in which source-generated code from dependencies is
53 // copied. This is equivalent to Cargo's OUT_DIR variable.
Matthew Maurercd416532023-11-20 17:52:01 +000054 cargoOutDir() android.OptionalPath
Matthew Maurer689d6f62023-11-20 17:49:25 +000055
Matthew Maurercd416532023-11-20 17:52:01 +000056 // cargoPkgVersion returns the value of the Cargo_pkg_version property.
57 cargoPkgVersion() string
Matthew Maurer689d6f62023-11-20 17:49:25 +000058
Matthew Maurercd416532023-11-20 17:52:01 +000059 // cargoEnvCompat returns whether Cargo environment variables should be used.
60 cargoEnvCompat() bool
Matthew Maurer689d6f62023-11-20 17:49:25 +000061
62 inData() bool
63 install(ctx ModuleContext)
64 relativeInstallPath() string
65 everInstallable() bool
66
67 nativeCoverage() bool
68
69 Disabled() bool
70 SetDisabled()
71
Ivan Lozano806efd32024-12-11 21:38:53 +000072 stdLinkage(device bool) RustLinkage
Matthew Maurer689d6f62023-11-20 17:49:25 +000073 noStdlibs() bool
74
75 unstrippedOutputFilePath() android.Path
76 strippedOutputFilePath() android.OptionalPath
Matthew Maurerd221d312023-11-20 21:02:40 +000077
Matthew Maurera28404a2023-11-20 23:33:28 +000078 checkedCrateRootPath() (android.Path, error)
Andrew Walbran52533232024-03-19 11:36:04 +000079
80 Aliases() map[string]string
Cole Faust58eef4f2025-01-29 15:14:17 -080081
82 moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON)
Matthew Maurer689d6f62023-11-20 17:49:25 +000083}
84
Thiébaud Weksteene81c9242020-08-03 10:46:28 +020085func (compiler *baseCompiler) edition() string {
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -070086 return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition)
87}
88
Matthew Maurer99020b02019-10-31 10:44:40 -070089func (compiler *baseCompiler) setNoStdlibs() {
90 compiler.Properties.No_stdlibs = proptools.BoolPtr(true)
91}
92
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +020093func (compiler *baseCompiler) disableLints() {
94 compiler.Properties.Lints = proptools.StringPtr("none")
Stephen Craneda931d42020-08-04 13:02:28 -070095}
96
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080097func NewBaseCompiler(dir, dir64 string, location installLocation) *baseCompiler {
Ivan Lozanoffee3342019-08-27 12:03:00 -070098 return &baseCompiler{
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -070099 Properties: BaseCompilerProperties{},
100 dir: dir,
101 dir64: dir64,
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800102 location: location,
Ivan Lozanoffee3342019-08-27 12:03:00 -0700103 }
104}
105
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800106type installLocation int
107
108const (
109 InstallInSystem installLocation = 0
110 InstallInData = iota
Ivan Lozano43845682020-07-09 21:03:28 -0400111
112 incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\""
Thiébaud Weksteenee6a89b2021-02-25 16:30:57 +0100113 genSubDir = "out/"
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800114)
115
Ivan Lozanoffee3342019-08-27 12:03:00 -0700116type BaseCompilerProperties struct {
Ivan Lozanoe4db0032021-08-11 13:39:33 -0400117 // path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs).
118 // Only a single source file can be defined. Modules which generate source can be included by prefixing
119 // the module name with ":", for example ":libfoo_bindgen"
120 //
121 // If no source file is defined, a single generated source module can be defined to be used as the main source.
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400122 Srcs []string `android:"path,arch_variant"`
123
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000124 // Entry point that is passed to rustc to begin the compilation. E.g. main.rs or lib.rs.
125 // When this property is set,
126 // * sandboxing is enabled for this module, and
127 // * the srcs attribute is interpreted as a list of all source files potentially
128 // used in compilation, including the entrypoint, and
129 // * compile_data can be used to add additional files used in compilation that
130 // not directly used as source files.
131 Crate_root *string `android:"path,arch_variant"`
132
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200133 // name of the lint set that should be used to validate this module.
134 //
135 // Possible values are "default" (for using a sensible set of lints
136 // depending on the module's location), "android" (for the strictest
137 // lint set that applies to all Android platform code), "vendor" (for
138 // a relaxed set) and "none" (for ignoring all lint warnings and
139 // errors). The default value is "default".
140 Lints *string
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -0700141
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +0200142 // flags to pass to rustc. To enable configuration options or features, use the "cfgs" or "features" properties.
Liz Kammereda93982021-04-20 10:15:41 -0400143 Flags []string `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700144
145 // flags to pass to the linker
Liz Kammereda93982021-04-20 10:15:41 -0400146 Ld_flags []string `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700147
Andrew Walbran52533232024-03-19 11:36:04 +0000148 // Rust crate dependencies to rename. Each entry should be a string of the form "dependencyname:alias".
149 //
150 // "dependencyname" here should be the name of the crate, not the Android module. This is
151 // equivalent to writing `alias = { package = "dependencyname" }` in a `Cargo.toml`.
152 Aliases []string
153
Ivan Lozanoffee3342019-08-27 12:03:00 -0700154 // list of rust rlib crate dependencies
Ivan Lozano9587f452025-01-08 03:17:19 +0000155 Rlibs proptools.Configurable[[]string] `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700156
Vinh Tran4eeb2a92023-08-14 13:29:30 -0400157 // list of rust automatic crate dependencies.
158 // Rustlibs linkage is rlib for host targets and dylib for device targets.
Jihoon Kang127f95c2024-10-07 22:19:59 +0000159 Rustlibs proptools.Configurable[[]string] `android:"arch_variant"`
Matthew Maurer0f003b12020-06-29 14:34:06 -0700160
Ivan Lozanoffee3342019-08-27 12:03:00 -0700161 // list of rust proc_macro crate dependencies
Ivan Lozano9587f452025-01-08 03:17:19 +0000162 Proc_macros proptools.Configurable[[]string] `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700163
164 // list of C shared library dependencies
Ivan Lozano9587f452025-01-08 03:17:19 +0000165 Shared_libs proptools.Configurable[[]string] `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700166
Ivan Lozano63bb7682021-03-23 15:53:44 -0400167 // list of C static library dependencies. These dependencies do not normally propagate to dependents
168 // and may need to be redeclared. See whole_static_libs for bundling static dependencies into a library.
Ivan Lozano9587f452025-01-08 03:17:19 +0000169 Static_libs proptools.Configurable[[]string] `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700170
Ivan Lozano63bb7682021-03-23 15:53:44 -0400171 // Similar to static_libs, but will bundle the static library dependency into a library. This is helpful
172 // to avoid having to redeclare the dependency for dependents of this library, but in some cases may also
173 // result in bloat if multiple dependencies all include the same static library whole.
174 //
175 // The common use case for this is when the static library is unlikely to be a dependency of other modules to avoid
176 // having to redeclare the static library dependency for every dependent module.
177 // If you are not sure what to, for rust_library modules most static dependencies should go in static_libraries,
178 // and for rust_ffi modules most static dependencies should go into whole_static_libraries.
179 //
180 // For rust_ffi static variants, these libraries will be included in the resulting static library archive.
181 //
182 // For rust_library rlib variants, these libraries will be bundled into the resulting rlib library. This will
183 // include all of the static libraries symbols in any dylibs or binaries which use this rlib as well.
Ivan Lozano9587f452025-01-08 03:17:19 +0000184 Whole_static_libs proptools.Configurable[[]string] `android:"arch_variant"`
Ivan Lozano63bb7682021-03-23 15:53:44 -0400185
Andrew Walbran797e4be2022-03-07 15:41:53 +0000186 // list of Rust system library dependencies.
187 //
188 // This is usually only needed when `no_stdlibs` is true, in which case it can be used to depend on system crates
189 // like `core` and `alloc`.
Ivan Lozano9587f452025-01-08 03:17:19 +0000190 Stdlibs proptools.Configurable[[]string] `android:"arch_variant"`
Andrew Walbran797e4be2022-03-07 15:41:53 +0000191
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400192 // crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
193 // modules which create library variants (rust_bindgen). This must be the expected extern crate name used in
194 // source, and is required to conform to an enforced format matching library output files (if the output file is
195 // lib<someName><suffix>, the crate_name property must be <someName>).
Ivan Lozanoffee3342019-08-27 12:03:00 -0700196 Crate_name string `android:"arch_variant"`
197
198 // list of features to enable for this crate
Jihoon Kang091ffd82024-10-03 01:13:24 +0000199 Features proptools.Configurable[[]string] `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700200
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +0200201 // list of configuration options to enable for this crate. To enable features, use the "features" property.
Cole Faustfdec8722024-05-22 11:38:29 -0700202 Cfgs proptools.Configurable[[]string] `android:"arch_variant"`
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +0200203
Ivan Lozanoffee3342019-08-27 12:03:00 -0700204 // specific rust edition that should be used if the default version is not desired
205 Edition *string `android:"arch_variant"`
206
207 // sets name of the output
208 Stem *string `android:"arch_variant"`
209
210 // append to name of output
211 Suffix *string `android:"arch_variant"`
212
213 // install to a subdirectory of the default install path for the module
214 Relative_install_path *string `android:"arch_variant"`
Matthew Maurer99020b02019-10-31 10:44:40 -0700215
216 // whether to suppress inclusion of standard crates - defaults to false
Ivan Lozanoc5182022023-11-14 10:23:31 -0500217 No_stdlibs *bool `android:"arch_variant"`
Ivan Lozanoea086132020-12-08 14:43:00 -0500218
219 // Change the rustlibs linkage to select rlib linkage by default for device targets.
220 // Also link libstd as an rlib as well on device targets.
221 // Note: This is the default behavior for host targets.
222 //
223 // This is primarily meant for rust_binary and rust_ffi modules where the default
224 // linkage of libstd might need to be overridden in some use cases. This should
225 // generally be avoided with other module types since it may cause collisions at
Martin Geisler46329e92022-09-29 13:12:23 +0000226 // linkage if all dependencies of the root binary module do not link against libstd
Ivan Lozanoea086132020-12-08 14:43:00 -0500227 // the same way.
228 Prefer_rlib *bool `android:"arch_variant"`
Ivan Lozanoa9a1fc02021-08-11 15:13:43 -0400229
230 // Enables emitting certain Cargo environment variables. Only intended to be used for compatibility purposes.
231 // Will set CARGO_CRATE_NAME to the crate_name property's value.
232 // Will set CARGO_BIN_NAME to the output filename value without the extension.
233 Cargo_env_compat *bool
234
235 // If cargo_env_compat is true, sets the CARGO_PKG_VERSION env var to this value.
236 Cargo_pkg_version *string
Ivan Lozanoab586472024-05-15 10:59:47 -0400237
238 // Control whether LTO is used for the final (Rust) linkage. This does not impact
239 // cross-language LTO.
240 Lto struct {
241 // Whether thin LTO should be enabled. By default this is true.
242 // LTO provides such a large code size benefit for Rust, this should always
243 // be enabled for production builds unless there's a clear need to disable it.
244 Thin *bool `android:"arch_variant"`
245 } `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -0700246}
247
248type baseCompiler struct {
Joel Galensonfa049382021-01-14 16:03:18 -0800249 Properties BaseCompilerProperties
Ivan Lozanoffee3342019-08-27 12:03:00 -0700250
251 // Install related
252 dir string
253 dir64 string
254 subDir string
255 relative string
Colin Cross70dda7e2019-10-01 22:05:35 -0700256 path android.InstallPath
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800257 location installLocation
Ivan Lozano6cd99e62020-02-11 08:24:25 -0500258 sanitize *sanitize
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400259
Joel Galensonfa049382021-01-14 16:03:18 -0800260 distFile android.OptionalPath
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400261
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800262 installDeps android.InstallPaths
263
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400264 // unstripped output file.
265 unstrippedOutputFile android.Path
266
267 // stripped output file.
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200268 strippedOutputFile android.OptionalPath
Thiébaud Weksteenee6a89b2021-02-25 16:30:57 +0100269
270 // If a crate has a source-generated dependency, a copy of the source file
271 // will be available in cargoOutDir (equivalent to Cargo OUT_DIR).
Matthew Maurercd416532023-11-20 17:52:01 +0000272 // This is stored internally because it may not be available during
273 // singleton-generation passes like rustdoc/rust_project.json, but should
274 // be stashed during initial generation.
275 cachedCargoOutDir android.ModuleOutPath
Matthew Maurera28404a2023-11-20 23:33:28 +0000276 // Calculated crate root cached internally because ModuleContext is not
277 // available to singleton targets like rustdoc/rust_project.json
278 cachedCrateRootPath android.Path
279 // If cachedCrateRootPath is nil after initialization, this will contain
280 // an explanation of why
281 cachedCrateRootError error
Ivan Lozanoffee3342019-08-27 12:03:00 -0700282}
283
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400284func (compiler *baseCompiler) Disabled() bool {
285 return false
286}
287
Ivan Lozanoab586472024-05-15 10:59:47 -0400288// Thin LTO is enabled by default.
289func (compiler *baseCompiler) Thinlto() bool {
290 return BoolDefault(compiler.Properties.Lto.Thin, true)
291}
292
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400293func (compiler *baseCompiler) SetDisabled() {
294 panic("baseCompiler does not implement SetDisabled()")
295}
296
Ivan Lozano9ef9cb82023-02-14 10:56:14 -0500297func (compiler *baseCompiler) noStdlibs() bool {
298 return Bool(compiler.Properties.No_stdlibs)
299}
300
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400301func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath {
302 panic("baseCompiler does not implement coverageOutputZipPath()")
303}
304
Ivan Lozanoea086132020-12-08 14:43:00 -0500305func (compiler *baseCompiler) preferRlib() bool {
306 return Bool(compiler.Properties.Prefer_rlib)
307}
308
Andrew Walbran52533232024-03-19 11:36:04 +0000309func (compiler *baseCompiler) Aliases() map[string]string {
310 aliases := map[string]string{}
311 for _, entry := range compiler.Properties.Aliases {
312 dep, alias, found := strings.Cut(entry, ":")
313 if !found {
314 panic(fmt.Errorf("invalid aliases entry %q missing ':'", entry))
315 }
316 aliases[dep] = alias
317 }
318 return aliases
319}
320
Ivan Lozano806efd32024-12-11 21:38:53 +0000321func (compiler *baseCompiler) stdLinkage(device bool) RustLinkage {
Ivan Lozano2b081132020-09-08 12:46:52 -0400322 // For devices, we always link stdlibs in as dylibs by default.
Ivan Lozanoea086132020-12-08 14:43:00 -0500323 if compiler.preferRlib() {
324 return RlibLinkage
Ivan Lozano806efd32024-12-11 21:38:53 +0000325 } else if device {
Ivan Lozanodd055472020-09-28 13:22:45 -0400326 return DylibLinkage
Ivan Lozano2b081132020-09-08 12:46:52 -0400327 } else {
Ivan Lozanodd055472020-09-28 13:22:45 -0400328 return RlibLinkage
Ivan Lozano2b081132020-09-08 12:46:52 -0400329 }
Ivan Lozano042504f2020-08-18 14:31:23 -0400330}
331
Cole Faust58eef4f2025-01-29 15:14:17 -0800332func (compiler *baseCompiler) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
333 moduleInfoJSON.Class = []string{"ETC"}
334
335 mod := ctx.Module().(*Module)
336
337 moduleInfoJSON.SharedLibs = mod.transitiveAndroidMkSharedLibs.ToList()
338 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.transitiveAndroidMkSharedLibs.ToList()...)
339 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkDylibs...)
340 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkHeaderLibs...)
341 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkProcMacroLibs...)
342 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkRlibs...)
343 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkStaticLibs...)
344 moduleInfoJSON.SystemSharedLibs = []string{"none"}
345 moduleInfoJSON.StaticLibs = mod.Properties.AndroidMkStaticLibs
346
347 if mod.sourceProvider != nil {
348 moduleInfoJSON.SubName += mod.sourceProvider.getSubName()
349 }
350 moduleInfoJSON.SubName += mod.AndroidMkSuffix()
351
352 if mod.Properties.IsSdkVariant {
353 moduleInfoJSON.Uninstallable = true
354 }
355}
356
Ivan Lozanoffee3342019-08-27 12:03:00 -0700357var _ compiler = (*baseCompiler)(nil)
358
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800359func (compiler *baseCompiler) inData() bool {
360 return compiler.location == InstallInData
361}
362
Ivan Lozanoffee3342019-08-27 12:03:00 -0700363func (compiler *baseCompiler) compilerProps() []interface{} {
364 return []interface{}{&compiler.Properties}
365}
366
Ivan Lozano9587f452025-01-08 03:17:19 +0000367func (compiler *baseCompiler) baseCompilerProps() BaseCompilerProperties {
368 return compiler.Properties
369}
370
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400371func cfgsToFlags(cfgs []string) []string {
Cole Faustfdec8722024-05-22 11:38:29 -0700372 flags := make([]string, 0, len(cfgs))
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400373 for _, cfg := range cfgs {
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +0200374 flags = append(flags, "--cfg '"+cfg+"'")
375 }
Ivan Lozano67eada32021-09-23 11:50:33 -0400376
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +0200377 return flags
378}
379
Jihoon Kang091ffd82024-10-03 01:13:24 +0000380func (compiler *baseCompiler) features(ctx android.ConfigurableEvaluatorContext, module *Module) []string {
381 eval := module.ConfigurableEvaluator(ctx)
382 return compiler.Properties.Features.GetOrDefault(eval, nil)
Matthew Maurerdb72f7e2023-11-21 00:20:02 +0000383}
384
Jihoon Kang091ffd82024-10-03 01:13:24 +0000385func (compiler *baseCompiler) featuresToFlags(ctx android.ConfigurableEvaluatorContext, module *Module) []string {
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +0200386 flags := []string{}
Jihoon Kang091ffd82024-10-03 01:13:24 +0000387 for _, feature := range compiler.features(ctx, module) {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700388 flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
389 }
Ivan Lozano67eada32021-09-23 11:50:33 -0400390
391 return flags
392}
393
Jihoon Kang091ffd82024-10-03 01:13:24 +0000394func (compiler *baseCompiler) featureFlags(ctx ModuleContext, module *Module, flags Flags) Flags {
395 flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(ctx, module)...)
396 flags.RustdocFlags = append(flags.RustdocFlags, compiler.featuresToFlags(ctx, module)...)
Ivan Lozano67eada32021-09-23 11:50:33 -0400397
398 return flags
399}
400
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400401func CommonDefaultCfgFlags(flags Flags, vendor bool, product bool) Flags {
402 var cfgs []string
403 if vendor || product {
404 cfgs = append(cfgs, "android_vndk")
405 if vendor {
406 cfgs = append(cfgs, "android_vendor")
407 } else if product {
408 cfgs = append(cfgs, "android_product")
Matthew Maurer65a54a82023-02-24 19:19:22 +0000409 }
Ivan Lozano67eada32021-09-23 11:50:33 -0400410 }
411
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400412 flags.RustFlags = append(flags.RustFlags, cfgsToFlags(cfgs)...)
413 flags.RustdocFlags = append(flags.RustdocFlags, cfgsToFlags(cfgs)...)
414 return flags
415}
416
417func (compiler *baseCompiler) cfgFlags(ctx ModuleContext, flags Flags) Flags {
418 flags = CommonDefaultCfgFlags(flags, ctx.RustModule().InVendor(), ctx.RustModule().InProduct())
419
Cole Faustfdec8722024-05-22 11:38:29 -0700420 cfgFlags := cfgsToFlags(compiler.Properties.Cfgs.GetOrDefault(ctx, nil))
421 flags.RustFlags = append(flags.RustFlags, cfgFlags...)
422 flags.RustdocFlags = append(flags.RustdocFlags, cfgFlags...)
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400423
424 return flags
425}
426
427func CommonDefaultFlags(ctx android.ModuleContext, toolchain config.Toolchain, flags Flags) Flags {
428 flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
429 flags.GlobalRustFlags = append(flags.GlobalRustFlags, toolchain.ToolchainRustFlags())
430 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, toolchain.ToolchainLinkFlags())
431 flags.EmitXrefs = ctx.Config().EmitXrefRules()
432
433 if ctx.Host() && !ctx.Windows() {
434 flags.LinkFlags = append(flags.LinkFlags, cc.RpathFlags(ctx)...)
435 }
436
437 if ctx.Os() == android.Linux {
438 // Add -lc, -lrt, -ldl, -lpthread, -lm and -lgcc_s to glibc builds to match
439 // the default behavior of device builds.
440 flags.LinkFlags = append(flags.LinkFlags, config.LinuxHostGlobalLinkFlags...)
441 } else if ctx.Os() == android.Darwin {
442 // Add -lc, -ldl, -lpthread and -lm to glibc darwin builds to match the default
443 // behavior of device builds.
444 flags.LinkFlags = append(flags.LinkFlags,
445 "-lc",
446 "-ldl",
447 "-lpthread",
448 "-lm",
449 )
450 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700451 return flags
452}
453
454func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
455
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400456 flags = CommonDefaultFlags(ctx, ctx.toolchain(), flags)
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200457 lintFlags, err := config.RustcLintsForDir(ctx.ModuleDir(), compiler.Properties.Lints)
458 if err != nil {
459 ctx.PropertyErrorf("lints", err.Error())
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -0700460 }
Ivan Lozano45a9e312021-07-27 12:29:12 -0400461
462 // linkage-related flags are disallowed.
463 for _, s := range compiler.Properties.Ld_flags {
464 if strings.HasPrefix(s, "-Wl,-l") || strings.HasPrefix(s, "-Wl,-L") {
465 ctx.PropertyErrorf("ld_flags", "'-Wl,-l' and '-Wl,-L' flags cannot be manually specified")
466 }
467 }
468 for _, s := range compiler.Properties.Flags {
469 if strings.HasPrefix(s, "-l") || strings.HasPrefix(s, "-L") {
470 ctx.PropertyErrorf("flags", "'-l' and '-L' flags cannot be manually specified")
471 }
472 if strings.HasPrefix(s, "--extern") {
473 ctx.PropertyErrorf("flags", "'--extern' flag cannot be manually specified")
474 }
475 if strings.HasPrefix(s, "-Clink-args=") || strings.HasPrefix(s, "-C link-args=") {
476 ctx.PropertyErrorf("flags", "'-C link-args' flag cannot be manually specified")
477 }
478 }
479
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200480 flags.RustFlags = append(flags.RustFlags, lintFlags)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700481 flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
Thiébaud Weksteene81c9242020-08-03 10:46:28 +0200482 flags.RustFlags = append(flags.RustFlags, "--edition="+compiler.edition())
Dan Albert06feee92021-03-19 15:06:02 -0700483 flags.RustdocFlags = append(flags.RustdocFlags, "--edition="+compiler.edition())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700484 flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700485
Ivan Lozanoffee3342019-08-27 12:03:00 -0700486 return flags
487}
488
Sasha Smundaka76acba2022-04-18 20:12:56 -0700489func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700490 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
491}
492
Dan Albert06feee92021-03-19 15:06:02 -0700493func (compiler *baseCompiler) rustdoc(ctx ModuleContext, flags Flags,
494 deps PathDeps) android.OptionalPath {
495
496 return android.OptionalPath{}
497}
498
Thiébaud Weksteenee6a89b2021-02-25 16:30:57 +0100499func (compiler *baseCompiler) initialize(ctx ModuleContext) {
Matthew Maurercd416532023-11-20 17:52:01 +0000500 compiler.cachedCargoOutDir = android.PathForModuleOut(ctx, genSubDir)
Matthew Maurera28404a2023-11-20 23:33:28 +0000501 if compiler.Properties.Crate_root == nil {
502 compiler.cachedCrateRootPath, compiler.cachedCrateRootError = srcPathFromModuleSrcs(ctx, compiler.Properties.Srcs)
503 } else {
504 compiler.cachedCrateRootPath = android.PathForModuleSrc(ctx, *compiler.Properties.Crate_root)
505 compiler.cachedCrateRootError = nil
506 }
Thiébaud Weksteenee6a89b2021-02-25 16:30:57 +0100507}
508
Matthew Maurercd416532023-11-20 17:52:01 +0000509func (compiler *baseCompiler) cargoOutDir() android.OptionalPath {
510 return android.OptionalPathForPath(compiler.cachedCargoOutDir)
Thiébaud Weksteenee6a89b2021-02-25 16:30:57 +0100511}
512
Matthew Maurercd416532023-11-20 17:52:01 +0000513func (compiler *baseCompiler) cargoEnvCompat() bool {
Ivan Lozanoa9a1fc02021-08-11 15:13:43 -0400514 return Bool(compiler.Properties.Cargo_env_compat)
515}
516
Matthew Maurercd416532023-11-20 17:52:01 +0000517func (compiler *baseCompiler) cargoPkgVersion() string {
Ivan Lozanoa9a1fc02021-08-11 15:13:43 -0400518 return String(compiler.Properties.Cargo_pkg_version)
519}
520
Ivan Lozano8d10fc32021-11-05 16:36:47 -0400521func (compiler *baseCompiler) unstrippedOutputFilePath() android.Path {
522 return compiler.unstrippedOutputFile
523}
524
Jiyong Parke54f07e2021-04-07 15:08:04 +0900525func (compiler *baseCompiler) strippedOutputFilePath() android.OptionalPath {
526 return compiler.strippedOutputFile
527}
528
Ivan Lozanoffee3342019-08-27 12:03:00 -0700529func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
Ivan Lozano9587f452025-01-08 03:17:19 +0000530 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs.GetOrDefault(ctx, nil)...)
Jihoon Kang127f95c2024-10-07 22:19:59 +0000531 deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs.GetOrDefault(ctx, nil)...)
Ivan Lozano9587f452025-01-08 03:17:19 +0000532 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros.GetOrDefault(ctx, nil)...)
533 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs.GetOrDefault(ctx, nil)...)
534 deps.WholeStaticLibs = append(deps.WholeStaticLibs, compiler.Properties.Whole_static_libs.GetOrDefault(ctx, nil)...)
535 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs.GetOrDefault(ctx, nil)...)
536 deps.Stdlibs = append(deps.Stdlibs, compiler.Properties.Stdlibs.GetOrDefault(ctx, nil)...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700537
Matthew Maurer99020b02019-10-31 10:44:40 -0700538 if !Bool(compiler.Properties.No_stdlibs) {
539 for _, stdlib := range config.Stdlibs {
Colin Crossa8941ec2022-07-01 11:17:22 -0700540 // If we're building for the build host, use the prebuilt stdlibs, unless the host
541 // is linux_bionic which doesn't have prebuilts.
542 if ctx.Host() && !ctx.Target().HostCross && ctx.Target().Os != android.LinuxBionic {
Ivan Lozanofba2aa22021-11-11 09:29:07 -0500543 stdlib = "prebuilt_" + stdlib
Matthew Maurer99020b02019-10-31 10:44:40 -0700544 }
Ivan Lozano2b081132020-09-08 12:46:52 -0400545 deps.Stdlibs = append(deps.Stdlibs, stdlib)
Matthew Maurer99020b02019-10-31 10:44:40 -0700546 }
547 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700548 return deps
549}
550
Thiébaud Weksteenf1ff54a2021-03-22 14:24:54 +0100551func bionicDeps(ctx DepsContext, deps Deps, static bool) Deps {
Ivan Lozanobf63d002020-10-02 10:03:23 -0400552 bionicLibs := []string{}
553 bionicLibs = append(bionicLibs, "liblog")
554 bionicLibs = append(bionicLibs, "libc")
555 bionicLibs = append(bionicLibs, "libm")
556 bionicLibs = append(bionicLibs, "libdl")
557
558 if static {
559 deps.StaticLibs = append(deps.StaticLibs, bionicLibs...)
560 } else {
561 deps.SharedLibs = append(deps.SharedLibs, bionicLibs...)
562 }
Ivan Lozano8711c5c2021-08-13 13:14:06 -0400563 if ctx.RustModule().StaticExecutable() {
564 deps.StaticLibs = append(deps.StaticLibs, "libunwind")
565 }
Thiébaud Weksteenf1ff54a2021-03-22 14:24:54 +0100566 if libRuntimeBuiltins := config.BuiltinsRuntimeLibrary(ctx.toolchain()); libRuntimeBuiltins != "" {
567 deps.StaticLibs = append(deps.StaticLibs, libRuntimeBuiltins)
568 }
Ivan Lozanof1c84332019-09-20 11:00:37 -0700569 return deps
570}
571
Colin Crosse32f0932022-01-23 20:48:36 -0800572func muslDeps(ctx DepsContext, deps Deps, static bool) Deps {
573 muslLibs := []string{"libc_musl"}
574 if static {
575 deps.StaticLibs = append(deps.StaticLibs, muslLibs...)
576 } else {
577 deps.SharedLibs = append(deps.SharedLibs, muslLibs...)
578 }
579 if libRuntimeBuiltins := config.BuiltinsRuntimeLibrary(ctx.toolchain()); libRuntimeBuiltins != "" {
580 deps.StaticLibs = append(deps.StaticLibs, libRuntimeBuiltins)
581 }
582
583 return deps
584}
585
Ivan Lozanoffee3342019-08-27 12:03:00 -0700586func (compiler *baseCompiler) crateName() string {
587 return compiler.Properties.Crate_name
588}
589
Ivan Lozanod7586b62021-04-01 09:49:36 -0400590func (compiler *baseCompiler) everInstallable() bool {
591 // Most modules are installable, so return true by default.
592 return true
593}
594
Colin Cross70dda7e2019-10-01 22:05:35 -0700595func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700596 dir := compiler.dir
597 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
598 dir = compiler.dir64
599 }
Ivan Lozanod6fdca82020-04-07 12:30:33 -0400600 if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
601 dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
602 }
603 if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700604 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
605 }
Ivan Lozanoc08897c2021-04-02 12:41:32 -0400606
Kiyoung Kimaa394802024-01-08 12:55:45 +0900607 if compiler.location == InstallInData && ctx.RustModule().InVendorOrProduct() {
Matthew Maurer9f59e8d2021-08-19 13:10:05 -0700608 if ctx.RustModule().InProduct() {
609 dir = filepath.Join(dir, "product")
610 } else if ctx.RustModule().InVendor() {
611 dir = filepath.Join(dir, "vendor")
612 } else {
613 ctx.ModuleErrorf("Unknown data+VNDK installation kind")
614 }
Ivan Lozanoc08897c2021-04-02 12:41:32 -0400615 }
Matthew Maurer9f59e8d2021-08-19 13:10:05 -0700616
Ivan Lozanoffee3342019-08-27 12:03:00 -0700617 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
618 compiler.relativeInstallPath(), compiler.relative)
619}
620
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400621func (compiler *baseCompiler) nativeCoverage() bool {
622 return false
623}
624
Thiébaud Weksteenfabaff62020-08-27 13:48:36 +0200625func (compiler *baseCompiler) install(ctx ModuleContext) {
Jiyong Parke54f07e2021-04-07 15:08:04 +0900626 path := ctx.RustModule().OutputFile()
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800627 compiler.path = ctx.InstallFile(compiler.installDir(ctx), path.Path().Base(), path.Path(), compiler.installDeps...)
628}
629
630func (compiler *baseCompiler) installTestData(ctx ModuleContext, data []android.DataPath) {
631 installedData := ctx.InstallTestData(compiler.installDir(ctx), data)
632 compiler.installDeps = append(compiler.installDeps, installedData...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700633}
634
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400635func (compiler *baseCompiler) getStem(ctx android.ModuleContext) string {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700636 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
637}
638
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400639func (compiler *baseCompiler) getStemWithoutSuffix(ctx android.BaseModuleContext) string {
Thiébaud Weksteen1f7f70f2020-06-24 11:32:48 +0200640 stem := ctx.ModuleName()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700641 if String(compiler.Properties.Stem) != "" {
642 stem = String(compiler.Properties.Stem)
643 }
644
645 return stem
646}
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700647
Ivan Lozanoffee3342019-08-27 12:03:00 -0700648func (compiler *baseCompiler) relativeInstallPath() string {
649 return String(compiler.Properties.Relative_install_path)
650}
651
Matthew Maurera28404a2023-11-20 23:33:28 +0000652func (compiler *baseCompiler) checkedCrateRootPath() (android.Path, error) {
653 return compiler.cachedCrateRootPath, compiler.cachedCrateRootError
654}
Seth Moore3afac0b2021-10-13 15:32:18 -0700655
Matthew Maurera28404a2023-11-20 23:33:28 +0000656func crateRootPath(ctx ModuleContext, compiler compiler) android.Path {
657 root, err := compiler.checkedCrateRootPath()
658 if err != nil {
659 ctx.PropertyErrorf("srcs", err.Error())
Matthew Maurerd221d312023-11-20 21:02:40 +0000660 }
Matthew Maurera28404a2023-11-20 23:33:28 +0000661 return root
Matthew Maurerd221d312023-11-20 21:02:40 +0000662}
663
Ivan Lozano43845682020-07-09 21:03:28 -0400664// Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs.
Matthew Maurera28404a2023-11-20 23:33:28 +0000665func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, error) {
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700666 // The srcs can contain strings with prefix ":".
667 // They are dependent modules of this module, with android.SourceDepTag.
668 // They are not the main source file compiled by rustc.
669 numSrcs := 0
670 srcIndex := 0
671 for i, s := range srcs {
672 if android.SrcIsModule(s) == "" {
673 numSrcs++
674 srcIndex = i
675 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700676 }
Ivan Lozanoe4db0032021-08-11 13:39:33 -0400677 if numSrcs > 1 {
Matthew Maurera28404a2023-11-20 23:33:28 +0000678 return nil, errors.New(incorrectSourcesError)
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700679 }
Ivan Lozanoe4db0032021-08-11 13:39:33 -0400680
681 // If a main source file is not provided we expect only a single SourceProvider module to be defined
682 // within srcs, with the expectation that the first source it provides is the entry point.
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700683 if srcIndex != 0 {
Matthew Maurera28404a2023-11-20 23:33:28 +0000684 return nil, errors.New("main source file must be the first in srcs")
Ivan Lozanoe4db0032021-08-11 13:39:33 -0400685 } else if numSrcs > 1 {
Matthew Maurera28404a2023-11-20 23:33:28 +0000686 return nil, errors.New("only a single generated source module can be defined without a main source file.")
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700687 }
Ivan Lozanoe4db0032021-08-11 13:39:33 -0400688
Sam Delmerico63ca14e2023-09-25 12:13:17 +0000689 // TODO: b/297264540 - once all modules are sandboxed, we need to select the proper
690 // entry point file from Srcs rather than taking the first one
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700691 paths := android.PathsForModuleSrc(ctx, srcs)
Matthew Maurera28404a2023-11-20 23:33:28 +0000692 if len(paths) == 0 {
693 return nil, errors.New("srcs must not be empty")
694 }
695 return paths[srcIndex], nil
Ivan Lozanoffee3342019-08-27 12:03:00 -0700696}