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 15package rust 16 17import ( 18 "android/soong/cc" 19 "errors" 20 "fmt" 21 "path/filepath" 22 "strings" 23 24 "github.com/google/blueprint/proptools" 25 26 "android/soong/android" 27 "android/soong/rust/config" 28) 29 30type RustLinkage int 31 32const ( 33 DylibLinkage RustLinkage = iota 34 RlibLinkage 35) 36 37type compiler interface { 38 initialize(ctx ModuleContext) 39 compilerFlags(ctx ModuleContext, flags Flags) Flags 40 cfgFlags(ctx ModuleContext, flags Flags) Flags 41 featureFlags(ctx ModuleContext, module *Module, flags Flags) Flags 42 baseCompilerProps() BaseCompilerProperties 43 compilerProps() []interface{} 44 compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput 45 compilerDeps(ctx DepsContext, deps Deps) Deps 46 crateName() string 47 edition() string 48 features(ctx android.ConfigurableEvaluatorContext, module *Module) []string 49 rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath 50 Thinlto() bool 51 52 // Output directory in which source-generated code from dependencies is 53 // copied. This is equivalent to Cargo's OUT_DIR variable. 54 cargoOutDir() android.OptionalPath 55 56 // cargoPkgVersion returns the value of the Cargo_pkg_version property. 57 cargoPkgVersion() string 58 59 // cargoEnvCompat returns whether Cargo environment variables should be used. 60 cargoEnvCompat() bool 61 62 inData() bool 63 install(ctx ModuleContext) 64 relativeInstallPath() string 65 everInstallable() bool 66 67 nativeCoverage() bool 68 69 Disabled() bool 70 SetDisabled() 71 72 stdLinkage(device bool) RustLinkage 73 noStdlibs() bool 74 75 unstrippedOutputFilePath() android.Path 76 strippedOutputFilePath() android.OptionalPath 77 78 checkedCrateRootPath() (android.Path, error) 79 80 Aliases() map[string]string 81 82 moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) 83} 84 85func (compiler *baseCompiler) edition() string { 86 return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition) 87} 88 89func (compiler *baseCompiler) setNoStdlibs() { 90 compiler.Properties.No_stdlibs = proptools.BoolPtr(true) 91} 92 93func (compiler *baseCompiler) disableLints() { 94 compiler.Properties.Lints = proptools.StringPtr("none") 95} 96 97func NewBaseCompiler(dir, dir64 string, location installLocation) *baseCompiler { 98 return &baseCompiler{ 99 Properties: BaseCompilerProperties{}, 100 dir: dir, 101 dir64: dir64, 102 location: location, 103 } 104} 105 106type installLocation int 107 108const ( 109 InstallInSystem installLocation = 0 110 InstallInData = iota 111 112 incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\"" 113 genSubDir = "out/" 114) 115 116type BaseCompilerProperties struct { 117 // 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. 122 Srcs []string `android:"path,arch_variant"` 123 124 // 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 133 // 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 141 142 // flags to pass to rustc. To enable configuration options or features, use the "cfgs" or "features" properties. 143 Flags []string `android:"arch_variant"` 144 145 // flags to pass to the linker 146 Ld_flags []string `android:"arch_variant"` 147 148 // 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 154 // list of rust rlib crate dependencies 155 Rlibs proptools.Configurable[[]string] `android:"arch_variant"` 156 157 // list of rust automatic crate dependencies. 158 // Rustlibs linkage is rlib for host targets and dylib for device targets. 159 Rustlibs proptools.Configurable[[]string] `android:"arch_variant"` 160 161 // list of rust proc_macro crate dependencies 162 Proc_macros proptools.Configurable[[]string] `android:"arch_variant"` 163 164 // list of C shared library dependencies 165 Shared_libs proptools.Configurable[[]string] `android:"arch_variant"` 166 167 // 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. 169 Static_libs proptools.Configurable[[]string] `android:"arch_variant"` 170 171 // 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. 184 Whole_static_libs proptools.Configurable[[]string] `android:"arch_variant"` 185 186 // 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`. 190 Stdlibs proptools.Configurable[[]string] `android:"arch_variant"` 191 192 // 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>). 196 Crate_name string `android:"arch_variant"` 197 198 // list of features to enable for this crate 199 Features proptools.Configurable[[]string] `android:"arch_variant"` 200 201 // list of configuration options to enable for this crate. To enable features, use the "features" property. 202 Cfgs proptools.Configurable[[]string] `android:"arch_variant"` 203 204 // 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"` 215 216 // whether to suppress inclusion of standard crates - defaults to false 217 No_stdlibs *bool `android:"arch_variant"` 218 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 226 // linkage if all dependencies of the root binary module do not link against libstd 227 // the same way. 228 Prefer_rlib *bool `android:"arch_variant"` 229 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 237 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"` 246} 247 248type baseCompiler struct { 249 Properties BaseCompilerProperties 250 251 // Install related 252 dir string 253 dir64 string 254 subDir string 255 relative string 256 path android.InstallPath 257 location installLocation 258 sanitize *sanitize 259 260 installDeps android.InstallPaths 261 262 // unstripped output file. 263 unstrippedOutputFile android.Path 264 265 // stripped output file. 266 strippedOutputFile android.OptionalPath 267 268 // If a crate has a source-generated dependency, a copy of the source file 269 // will be available in cargoOutDir (equivalent to Cargo OUT_DIR). 270 // This is stored internally because it may not be available during 271 // singleton-generation passes like rustdoc/rust_project.json, but should 272 // be stashed during initial generation. 273 cachedCargoOutDir android.ModuleOutPath 274 // Calculated crate root cached internally because ModuleContext is not 275 // available to singleton targets like rustdoc/rust_project.json 276 cachedCrateRootPath android.Path 277 // If cachedCrateRootPath is nil after initialization, this will contain 278 // an explanation of why 279 cachedCrateRootError error 280} 281 282func (compiler *baseCompiler) Disabled() bool { 283 return false 284} 285 286// Thin LTO is enabled by default. 287func (compiler *baseCompiler) Thinlto() bool { 288 return BoolDefault(compiler.Properties.Lto.Thin, true) 289} 290 291func (compiler *baseCompiler) SetDisabled() { 292 panic("baseCompiler does not implement SetDisabled()") 293} 294 295func (compiler *baseCompiler) noStdlibs() bool { 296 return Bool(compiler.Properties.No_stdlibs) 297} 298 299func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath { 300 panic("baseCompiler does not implement coverageOutputZipPath()") 301} 302 303func (compiler *baseCompiler) preferRlib() bool { 304 return Bool(compiler.Properties.Prefer_rlib) 305} 306 307func (compiler *baseCompiler) Aliases() map[string]string { 308 aliases := map[string]string{} 309 for _, entry := range compiler.Properties.Aliases { 310 dep, alias, found := strings.Cut(entry, ":") 311 if !found { 312 panic(fmt.Errorf("invalid aliases entry %q missing ':'", entry)) 313 } 314 aliases[dep] = alias 315 } 316 return aliases 317} 318 319func (compiler *baseCompiler) stdLinkage(device bool) RustLinkage { 320 // For devices, we always link stdlibs in as dylibs by default. 321 if compiler.preferRlib() { 322 return RlibLinkage 323 } else if device { 324 return DylibLinkage 325 } else { 326 return RlibLinkage 327 } 328} 329 330func (compiler *baseCompiler) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) { 331 moduleInfoJSON.Class = []string{"ETC"} 332 333 mod := ctx.Module().(*Module) 334 335 moduleInfoJSON.SharedLibs = mod.transitiveAndroidMkSharedLibs.ToList() 336 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.transitiveAndroidMkSharedLibs.ToList()...) 337 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkDylibs...) 338 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkHeaderLibs...) 339 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkProcMacroLibs...) 340 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkRlibs...) 341 moduleInfoJSON.Dependencies = append(moduleInfoJSON.Dependencies, mod.Properties.AndroidMkStaticLibs...) 342 moduleInfoJSON.SystemSharedLibs = []string{"none"} 343 moduleInfoJSON.StaticLibs = mod.Properties.AndroidMkStaticLibs 344 345 if mod.sourceProvider != nil { 346 moduleInfoJSON.SubName += mod.sourceProvider.getSubName() 347 } 348 moduleInfoJSON.SubName += mod.AndroidMkSuffix() 349 350 if mod.Properties.IsSdkVariant { 351 moduleInfoJSON.Uninstallable = true 352 } 353} 354 355var _ compiler = (*baseCompiler)(nil) 356 357func (compiler *baseCompiler) inData() bool { 358 return compiler.location == InstallInData 359} 360 361func (compiler *baseCompiler) compilerProps() []interface{} { 362 return []interface{}{&compiler.Properties} 363} 364 365func (compiler *baseCompiler) baseCompilerProps() BaseCompilerProperties { 366 return compiler.Properties 367} 368 369func cfgsToFlags(cfgs []string) []string { 370 flags := make([]string, 0, len(cfgs)) 371 for _, cfg := range cfgs { 372 flags = append(flags, "--cfg '"+cfg+"'") 373 } 374 375 return flags 376} 377 378func (compiler *baseCompiler) features(ctx android.ConfigurableEvaluatorContext, module *Module) []string { 379 eval := module.ConfigurableEvaluator(ctx) 380 return compiler.Properties.Features.GetOrDefault(eval, nil) 381} 382 383func (compiler *baseCompiler) featuresToFlags(ctx android.ConfigurableEvaluatorContext, module *Module) []string { 384 flags := []string{} 385 for _, feature := range compiler.features(ctx, module) { 386 flags = append(flags, "--cfg 'feature=\""+feature+"\"'") 387 } 388 389 return flags 390} 391 392func (compiler *baseCompiler) featureFlags(ctx ModuleContext, module *Module, flags Flags) Flags { 393 flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(ctx, module)...) 394 flags.RustdocFlags = append(flags.RustdocFlags, compiler.featuresToFlags(ctx, module)...) 395 396 return flags 397} 398 399func CommonDefaultCfgFlags(flags Flags, vendor bool, product bool) Flags { 400 var cfgs []string 401 if vendor || product { 402 cfgs = append(cfgs, "android_vndk") 403 if vendor { 404 cfgs = append(cfgs, "android_vendor") 405 } else if product { 406 cfgs = append(cfgs, "android_product") 407 } 408 } 409 410 flags.RustFlags = append(flags.RustFlags, cfgsToFlags(cfgs)...) 411 flags.RustdocFlags = append(flags.RustdocFlags, cfgsToFlags(cfgs)...) 412 return flags 413} 414 415func (compiler *baseCompiler) cfgFlags(ctx ModuleContext, flags Flags) Flags { 416 flags = CommonDefaultCfgFlags(flags, ctx.RustModule().InVendor(), ctx.RustModule().InProduct()) 417 418 cfgFlags := cfgsToFlags(compiler.Properties.Cfgs.GetOrDefault(ctx, nil)) 419 flags.RustFlags = append(flags.RustFlags, cfgFlags...) 420 flags.RustdocFlags = append(flags.RustdocFlags, cfgFlags...) 421 422 return flags 423} 424 425func CommonDefaultFlags(ctx android.ModuleContext, toolchain config.Toolchain, flags Flags) Flags { 426 flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...) 427 flags.GlobalRustFlags = append(flags.GlobalRustFlags, toolchain.ToolchainRustFlags()) 428 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, toolchain.ToolchainLinkFlags()) 429 flags.EmitXrefs = ctx.Config().EmitXrefRules() 430 431 if ctx.Host() && !ctx.Windows() { 432 flags.LinkFlags = append(flags.LinkFlags, cc.RpathFlags(ctx)...) 433 } 434 435 if ctx.Os() == android.Linux { 436 // Add -lc, -lrt, -ldl, -lpthread, -lm and -lgcc_s to glibc builds to match 437 // the default behavior of device builds. 438 flags.LinkFlags = append(flags.LinkFlags, config.LinuxHostGlobalLinkFlags...) 439 } else if ctx.Os() == android.Darwin { 440 // Add -lc, -ldl, -lpthread and -lm to glibc darwin builds to match the default 441 // behavior of device builds. 442 flags.LinkFlags = append(flags.LinkFlags, 443 "-lc", 444 "-ldl", 445 "-lpthread", 446 "-lm", 447 ) 448 } 449 return flags 450} 451 452func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags { 453 454 flags = CommonDefaultFlags(ctx, ctx.toolchain(), flags) 455 lintFlags, err := config.RustcLintsForDir(ctx.ModuleDir(), compiler.Properties.Lints) 456 if err != nil { 457 ctx.PropertyErrorf("lints", err.Error()) 458 } 459 460 // linkage-related flags are disallowed. 461 for _, s := range compiler.Properties.Ld_flags { 462 if strings.HasPrefix(s, "-Wl,-l") || strings.HasPrefix(s, "-Wl,-L") { 463 ctx.PropertyErrorf("ld_flags", "'-Wl,-l' and '-Wl,-L' flags cannot be manually specified") 464 } 465 } 466 for _, s := range compiler.Properties.Flags { 467 if strings.HasPrefix(s, "-l") || strings.HasPrefix(s, "-L") { 468 ctx.PropertyErrorf("flags", "'-l' and '-L' flags cannot be manually specified") 469 } 470 if strings.HasPrefix(s, "--extern") { 471 ctx.PropertyErrorf("flags", "'--extern' flag cannot be manually specified") 472 } 473 if strings.HasPrefix(s, "-Clink-args=") || strings.HasPrefix(s, "-C link-args=") { 474 ctx.PropertyErrorf("flags", "'-C link-args' flag cannot be manually specified") 475 } 476 } 477 478 flags.RustFlags = append(flags.RustFlags, lintFlags) 479 flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...) 480 flags.RustFlags = append(flags.RustFlags, "--edition="+compiler.edition()) 481 flags.RustdocFlags = append(flags.RustdocFlags, "--edition="+compiler.edition()) 482 flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...) 483 484 return flags 485} 486 487func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput { 488 panic(fmt.Errorf("baseCrater doesn't know how to crate things!")) 489} 490 491func (compiler *baseCompiler) rustdoc(ctx ModuleContext, flags Flags, 492 deps PathDeps) android.OptionalPath { 493 494 return android.OptionalPath{} 495} 496 497func (compiler *baseCompiler) initialize(ctx ModuleContext) { 498 compiler.cachedCargoOutDir = android.PathForModuleOut(ctx, genSubDir) 499 if compiler.Properties.Crate_root == nil { 500 compiler.cachedCrateRootPath, compiler.cachedCrateRootError = srcPathFromModuleSrcs(ctx, compiler.Properties.Srcs) 501 } else { 502 compiler.cachedCrateRootPath = android.PathForModuleSrc(ctx, *compiler.Properties.Crate_root) 503 compiler.cachedCrateRootError = nil 504 } 505} 506 507func (compiler *baseCompiler) cargoOutDir() android.OptionalPath { 508 return android.OptionalPathForPath(compiler.cachedCargoOutDir) 509} 510 511func (compiler *baseCompiler) cargoEnvCompat() bool { 512 return Bool(compiler.Properties.Cargo_env_compat) 513} 514 515func (compiler *baseCompiler) cargoPkgVersion() string { 516 return String(compiler.Properties.Cargo_pkg_version) 517} 518 519func (compiler *baseCompiler) unstrippedOutputFilePath() android.Path { 520 return compiler.unstrippedOutputFile 521} 522 523func (compiler *baseCompiler) strippedOutputFilePath() android.OptionalPath { 524 return compiler.strippedOutputFile 525} 526 527func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps { 528 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs.GetOrDefault(ctx, nil)...) 529 deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs.GetOrDefault(ctx, nil)...) 530 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros.GetOrDefault(ctx, nil)...) 531 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs.GetOrDefault(ctx, nil)...) 532 deps.WholeStaticLibs = append(deps.WholeStaticLibs, compiler.Properties.Whole_static_libs.GetOrDefault(ctx, nil)...) 533 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs.GetOrDefault(ctx, nil)...) 534 deps.Stdlibs = append(deps.Stdlibs, compiler.Properties.Stdlibs.GetOrDefault(ctx, nil)...) 535 536 if !Bool(compiler.Properties.No_stdlibs) { 537 for _, stdlib := range config.Stdlibs { 538 // If we're building for the build host, use the prebuilt stdlibs, unless the host 539 // is linux_bionic which doesn't have prebuilts. 540 if ctx.Host() && !ctx.Target().HostCross && ctx.Target().Os != android.LinuxBionic { 541 stdlib = "prebuilt_" + stdlib 542 } 543 deps.Stdlibs = append(deps.Stdlibs, stdlib) 544 } 545 } 546 return deps 547} 548 549func bionicDeps(ctx DepsContext, deps Deps, static bool) Deps { 550 bionicLibs := []string{} 551 bionicLibs = append(bionicLibs, "liblog") 552 bionicLibs = append(bionicLibs, "libc") 553 bionicLibs = append(bionicLibs, "libm") 554 bionicLibs = append(bionicLibs, "libdl") 555 556 if static { 557 deps.StaticLibs = append(deps.StaticLibs, bionicLibs...) 558 } else { 559 deps.SharedLibs = append(deps.SharedLibs, bionicLibs...) 560 } 561 if ctx.RustModule().StaticExecutable() { 562 deps.StaticLibs = append(deps.StaticLibs, "libunwind") 563 } 564 if libRuntimeBuiltins := config.BuiltinsRuntimeLibrary(ctx.toolchain()); libRuntimeBuiltins != "" { 565 deps.StaticLibs = append(deps.StaticLibs, libRuntimeBuiltins) 566 } 567 return deps 568} 569 570func muslDeps(ctx DepsContext, deps Deps, static bool) Deps { 571 muslLibs := []string{"libc_musl"} 572 if static { 573 deps.StaticLibs = append(deps.StaticLibs, muslLibs...) 574 } else { 575 deps.SharedLibs = append(deps.SharedLibs, muslLibs...) 576 } 577 if libRuntimeBuiltins := config.BuiltinsRuntimeLibrary(ctx.toolchain()); libRuntimeBuiltins != "" { 578 deps.StaticLibs = append(deps.StaticLibs, libRuntimeBuiltins) 579 } 580 581 return deps 582} 583 584func (compiler *baseCompiler) crateName() string { 585 return compiler.Properties.Crate_name 586} 587 588func (compiler *baseCompiler) everInstallable() bool { 589 // Most modules are installable, so return true by default. 590 return true 591} 592 593func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath { 594 dir := compiler.dir 595 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" { 596 dir = compiler.dir64 597 } 598 if ctx.Target().NativeBridge == android.NativeBridgeEnabled { 599 dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath) 600 } 601 if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) { 602 dir = filepath.Join(dir, ctx.Arch().ArchType.String()) 603 } 604 605 if compiler.location == InstallInData && ctx.RustModule().InVendorOrProduct() { 606 if ctx.RustModule().InProduct() { 607 dir = filepath.Join(dir, "product") 608 } else if ctx.RustModule().InVendor() { 609 dir = filepath.Join(dir, "vendor") 610 } else { 611 ctx.ModuleErrorf("Unknown data+VNDK installation kind") 612 } 613 } 614 615 return android.PathForModuleInstall(ctx, dir, compiler.subDir, 616 compiler.relativeInstallPath(), compiler.relative) 617} 618 619func (compiler *baseCompiler) nativeCoverage() bool { 620 return false 621} 622 623func (compiler *baseCompiler) install(ctx ModuleContext) { 624 path := ctx.RustModule().OutputFile() 625 compiler.path = ctx.InstallFile(compiler.installDir(ctx), path.Path().Base(), path.Path(), compiler.installDeps...) 626} 627 628func (compiler *baseCompiler) installTestData(ctx ModuleContext, data []android.DataPath) { 629 installedData := ctx.InstallTestData(compiler.installDir(ctx), data) 630 compiler.installDeps = append(compiler.installDeps, installedData...) 631} 632 633func (compiler *baseCompiler) getStem(ctx android.ModuleContext) string { 634 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix) 635} 636 637func (compiler *baseCompiler) getStemWithoutSuffix(ctx android.BaseModuleContext) string { 638 stem := ctx.ModuleName() 639 if String(compiler.Properties.Stem) != "" { 640 stem = String(compiler.Properties.Stem) 641 } 642 643 return stem 644} 645 646func (compiler *baseCompiler) relativeInstallPath() string { 647 return String(compiler.Properties.Relative_install_path) 648} 649 650func (compiler *baseCompiler) checkedCrateRootPath() (android.Path, error) { 651 return compiler.cachedCrateRootPath, compiler.cachedCrateRootError 652} 653 654func crateRootPath(ctx ModuleContext, compiler compiler) android.Path { 655 root, err := compiler.checkedCrateRootPath() 656 if err != nil { 657 ctx.PropertyErrorf("srcs", err.Error()) 658 } 659 return root 660} 661 662// Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs. 663func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, error) { 664 // The srcs can contain strings with prefix ":". 665 // They are dependent modules of this module, with android.SourceDepTag. 666 // They are not the main source file compiled by rustc. 667 numSrcs := 0 668 srcIndex := 0 669 for i, s := range srcs { 670 if android.SrcIsModule(s) == "" { 671 numSrcs++ 672 srcIndex = i 673 } 674 } 675 if numSrcs > 1 { 676 return nil, errors.New(incorrectSourcesError) 677 } 678 679 // If a main source file is not provided we expect only a single SourceProvider module to be defined 680 // within srcs, with the expectation that the first source it provides is the entry point. 681 if srcIndex != 0 { 682 return nil, errors.New("main source file must be the first in srcs") 683 } else if numSrcs > 1 { 684 return nil, errors.New("only a single generated source module can be defined without a main source file.") 685 } 686 687 // TODO: b/297264540 - once all modules are sandboxed, we need to select the proper 688 // entry point file from Srcs rather than taking the first one 689 paths := android.PathsForModuleSrc(ctx, srcs) 690 if len(paths) == 0 { 691 return nil, errors.New("srcs must not be empty") 692 } 693 return paths[srcIndex], nil 694} 695