blob: abbf90d8360062e66e4756f5531886f9a9e9be77 [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 (
Ivan Lozano1776a2a2020-11-11 10:59:52 -050018 "path/filepath"
Ivan Lozanoffee3342019-08-27 12:03:00 -070019 "strings"
20
21 "github.com/google/blueprint"
22
23 "android/soong/android"
Ivan Lozano0a468a42024-05-13 21:03:34 -040024 "android/soong/cc"
ThiƩbaud Weksteen71512f32020-11-03 15:17:51 +010025 "android/soong/rust/config"
Ivan Lozanoffee3342019-08-27 12:03:00 -070026)
27
28var (
Wen-yi Chu41326c12023-09-22 03:58:59 +000029 _ = pctx.SourcePathVariable("rustcCmd", "${config.RustBin}/rustc")
Wen-yi Chu41326c12023-09-22 03:58:59 +000030 rustc = pctx.AndroidStaticRule("rustc",
31 blueprint.RuleParams{
32 Command: "$envVars $rustcCmd " +
Colin Cross004bd3f2023-10-02 11:39:17 -070033 "-C linker=${config.RustLinker} " +
34 "-C link-args=\"${crtBegin} ${earlyLinkFlags} ${linkFlags} ${crtEnd}\" " +
Wen-yi Chu41326c12023-09-22 03:58:59 +000035 "--emit link -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" +
Ivan Lozanocfeec1c2024-03-28 19:27:24 +000036 " && grep ^$out: $out.d.raw > $out.d",
Colin Cross004bd3f2023-10-02 11:39:17 -070037 CommandDeps: []string{"$rustcCmd"},
Wen-yi Chu41326c12023-09-22 03:58:59 +000038 // Rustc deps-info writes out make compatible dep files: https://github.com/rust-lang/rust/issues/7633
39 // Rustc emits unneeded dependency lines for the .d and input .rs files.
40 // Those extra lines cause ninja warning:
41 // "warning: depfile has multiple output paths"
42 // For ninja, we keep/grep only the dependency rule for the rust $out file.
43 Deps: blueprint.DepsGCC,
44 Depfile: "$out.d",
45 },
Colin Cross004bd3f2023-10-02 11:39:17 -070046 "rustcFlags", "earlyLinkFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars")
Wen-yi Chu41326c12023-09-22 03:58:59 +000047
48 _ = pctx.SourcePathVariable("rustdocCmd", "${config.RustBin}/rustdoc")
49 rustdoc = pctx.AndroidStaticRule("rustdoc",
50 blueprint.RuleParams{
51 Command: "$envVars $rustdocCmd $rustdocFlags $in -o $outDir && " +
52 "touch $out",
53 CommandDeps: []string{"$rustdocCmd"},
54 },
55 "rustdocFlags", "outDir", "envVars")
56
57 _ = pctx.SourcePathVariable("clippyCmd", "${config.RustBin}/clippy-driver")
58 clippyDriver = pctx.AndroidStaticRule("clippy",
59 blueprint.RuleParams{
60 Command: "$envVars $clippyCmd " +
61 // Because clippy-driver uses rustc as backend, we need to have some output even during the linting.
62 // Use the metadata output as it has the smallest footprint.
63 "--emit metadata -o $out --emit dep-info=$out.d.raw $in ${libFlags} " +
64 "$rustcFlags $clippyFlags" +
Alex91c74762024-04-11 17:30:27 +020065 " && grep ^$out: $out.d.raw > $out.d",
Wen-yi Chu41326c12023-09-22 03:58:59 +000066 CommandDeps: []string{"$clippyCmd"},
67 Deps: blueprint.DepsGCC,
68 Depfile: "$out.d",
69 },
70 "rustcFlags", "libFlags", "clippyFlags", "envVars")
71
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -040072 zip = pctx.AndroidStaticRule("zip",
73 blueprint.RuleParams{
74 Command: "cat $out.rsp | tr ' ' '\\n' | tr -d \\' | sort -u > ${out}.tmp && ${SoongZipCmd} -o ${out} -C $$OUT_DIR -l ${out}.tmp",
75 CommandDeps: []string{"${SoongZipCmd}"},
76 Rspfile: "$out.rsp",
77 RspfileContent: "$in",
78 })
Ivan Lozano43845682020-07-09 21:03:28 -040079
Wen-yi Chu41326c12023-09-22 03:58:59 +000080 cp = pctx.AndroidStaticRule("cp",
Ivan Lozano43845682020-07-09 21:03:28 -040081 blueprint.RuleParams{
82 Command: "cp `cat $outDir.rsp` $outDir",
83 Rspfile: "${outDir}.rsp",
84 RspfileContent: "$in",
85 },
86 "outDir")
Sasha Smundaka76acba2022-04-18 20:12:56 -070087
88 // Cross-referencing:
89 _ = pctx.SourcePathVariable("rustExtractor",
90 "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/rust_extractor")
91 _ = pctx.VariableFunc("kytheCorpus",
92 func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
93 _ = pctx.VariableFunc("kytheCuEncoding",
94 func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
Wen-yi Chu41326c12023-09-22 03:58:59 +000095 _ = pctx.SourcePathVariable("kytheVnames", "build/soong/vnames.json")
96 kytheExtract = pctx.AndroidStaticRule("kythe",
97 blueprint.RuleParams{
98 Command: `KYTHE_CORPUS=${kytheCorpus} ` +
99 `KYTHE_OUTPUT_FILE=$out ` +
100 `KYTHE_VNAMES=$kytheVnames ` +
101 `KYTHE_KZIP_ENCODING=${kytheCuEncoding} ` +
102 `KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative ` +
103 `$rustExtractor $envVars ` +
104 `$rustcCmd ` +
Colin Cross004bd3f2023-10-02 11:39:17 -0700105 `-C linker=${config.RustLinker} ` +
106 `-C link-args="${crtBegin} ${linkFlags} ${crtEnd}" ` +
Wen-yi Chu41326c12023-09-22 03:58:59 +0000107 `$in ${libFlags} $rustcFlags`,
108 CommandDeps: []string{"$rustExtractor", "$kytheVnames"},
109 Rspfile: "${out}.rsp",
110 RspfileContent: "$in",
111 },
Colin Cross004bd3f2023-10-02 11:39:17 -0700112 "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars")
Ivan Lozanoffee3342019-08-27 12:03:00 -0700113)
114
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400115type buildOutput struct {
Joel Galensonfa049382021-01-14 16:03:18 -0800116 outputFile android.Path
Sasha Smundaka76acba2022-04-18 20:12:56 -0700117 kytheFile android.Path
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400118}
Ivan Lozanoffee3342019-08-27 12:03:00 -0700119
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400120func init() {
121 pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
Ivan Lozano0a468a42024-05-13 21:03:34 -0400122 cc.TransformRlibstoStaticlib = TransformRlibstoStaticlib
Ivan Lozanoffee3342019-08-27 12:03:00 -0700123}
124
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400125type transformProperties struct {
126 crateName string
127 targetTriple string
128 is64Bit bool
129 bootstrap bool
130 inRecovery bool
131 inRamdisk bool
132 inVendorRamdisk bool
133 cargoOutDir android.OptionalPath
134 synthetic bool
135 crateType string
136}
137
138// Populates a standard transformProperties struct for Rust modules
139func getTransformProperties(ctx ModuleContext, crateType string) transformProperties {
140 module := ctx.RustModule()
141 return transformProperties{
142 crateName: module.CrateName(),
143 is64Bit: ctx.toolchain().Is64Bit(),
144 targetTriple: ctx.toolchain().RustTriple(),
145 bootstrap: module.Bootstrap(),
146 inRecovery: module.InRecovery(),
147 inRamdisk: module.InRamdisk(),
148 inVendorRamdisk: module.InVendorRamdisk(),
149 cargoOutDir: module.compiler.cargoOutDir(),
150
151 // crateType indicates what type of crate to build
152 crateType: crateType,
153
154 // synthetic indicates whether this is an actual Rust module or not
155 synthetic: false,
156 }
157}
158
Wen-yi Chu41326c12023-09-22 03:58:59 +0000159func TransformSrcToBinary(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700160 outputFile android.WritablePath) buildOutput {
Chris Wailes99180c22024-02-20 21:39:40 +0000161 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
162
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400163 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "bin"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700164}
165
Wen-yi Chu41326c12023-09-22 03:58:59 +0000166func TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700167 outputFile android.WritablePath) buildOutput {
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400168 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "rlib"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700169}
170
Ivan Lozano0a468a42024-05-13 21:03:34 -0400171func TransformRlibstoStaticlib(ctx android.ModuleContext, mainSrc android.Path, deps []cc.RustRlibDep,
172 outputFile android.WritablePath) android.Path {
173
174 var rustPathDeps PathDeps
175 var rustFlags Flags
176
177 for _, rlibDep := range deps {
178 rustPathDeps.RLibs = append(rustPathDeps.RLibs, RustLibrary{Path: rlibDep.LibPath, CrateName: rlibDep.CrateName})
179 rustPathDeps.linkDirs = append(rustPathDeps.linkDirs, rlibDep.LinkDirs...)
180 }
181
182 ccModule := ctx.(cc.ModuleContext).Module().(*cc.Module)
183 toolchain := config.FindToolchain(ctx.Os(), ctx.Arch())
184 t := transformProperties{
185 // Crate name can be a predefined value as this is a staticlib and
186 // it does not need to be unique. The crate name is used for name
187 // mangling, but it is mixed with the metadata for that purpose, which we
188 // already set to the module name.
189 crateName: "generated_rust_staticlib",
190 is64Bit: toolchain.Is64Bit(),
191 targetTriple: toolchain.RustTriple(),
192 bootstrap: ccModule.Bootstrap(),
193 inRecovery: ccModule.InRecovery(),
194 inRamdisk: ccModule.InRamdisk(),
195 inVendorRamdisk: ccModule.InVendorRamdisk(),
196
197 // crateType indicates what type of crate to build
198 crateType: "staticlib",
199
200 // synthetic indicates whether this is an actual Rust module or not
201 synthetic: true,
202 }
203
204 rustFlags = CommonDefaultFlags(ctx, toolchain, rustFlags)
205 rustFlags = CommonLibraryCompilerFlags(ctx, rustFlags)
206 rustFlags.GlobalRustFlags = append(rustFlags.GlobalRustFlags, "-C lto=thin")
207
208 rustFlags.EmitXrefs = false
209
210 return transformSrctoCrate(ctx, mainSrc, rustPathDeps, rustFlags, outputFile, t).outputFile
211}
212
Wen-yi Chu41326c12023-09-22 03:58:59 +0000213func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700214 outputFile android.WritablePath) buildOutput {
Chris Wailes99180c22024-02-20 21:39:40 +0000215 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
216
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400217 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "dylib"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700218}
219
Wen-yi Chu41326c12023-09-22 03:58:59 +0000220func TransformSrctoStatic(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700221 outputFile android.WritablePath) buildOutput {
Chris Wailes99180c22024-02-20 21:39:40 +0000222 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400223 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "staticlib"))
Ivan Lozano52767be2019-10-18 14:49:46 -0700224}
225
Wen-yi Chu41326c12023-09-22 03:58:59 +0000226func TransformSrctoShared(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700227 outputFile android.WritablePath) buildOutput {
Chris Wailes99180c22024-02-20 21:39:40 +0000228 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400229 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "cdylib"))
Ivan Lozano52767be2019-10-18 14:49:46 -0700230}
231
Wen-yi Chu41326c12023-09-22 03:58:59 +0000232func TransformSrctoProcMacro(ctx ModuleContext, mainSrc android.Path, deps PathDeps,
Dan Albert06feee92021-03-19 15:06:02 -0700233 flags Flags, outputFile android.WritablePath) buildOutput {
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400234 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "proc-macro"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700235}
236
237func rustLibsToPaths(libs RustLibraries) android.Paths {
238 var paths android.Paths
239 for _, lib := range libs {
240 paths = append(paths, lib.Path)
241 }
242 return paths
243}
244
Wen-yi Chu41326c12023-09-22 03:58:59 +0000245func makeLibFlags(deps PathDeps) []string {
Dan Albert06feee92021-03-19 15:06:02 -0700246 var libFlags []string
247
248 // Collect library/crate flags
Wen-yi Chu41326c12023-09-22 03:58:59 +0000249 for _, lib := range deps.RLibs {
250 libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
Dan Albert06feee92021-03-19 15:06:02 -0700251 }
Wen-yi Chu41326c12023-09-22 03:58:59 +0000252 for _, lib := range deps.DyLibs {
253 libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
Dan Albert06feee92021-03-19 15:06:02 -0700254 }
Wen-yi Chu41326c12023-09-22 03:58:59 +0000255 for _, proc_macro := range deps.ProcMacros {
256 libFlags = append(libFlags, "--extern "+proc_macro.CrateName+"="+proc_macro.Path.String())
Dan Albert06feee92021-03-19 15:06:02 -0700257 }
258
259 for _, path := range deps.linkDirs {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000260 libFlags = append(libFlags, "-L "+path)
Dan Albert06feee92021-03-19 15:06:02 -0700261 }
262
263 return libFlags
264}
265
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400266func rustEnvVars(ctx android.ModuleContext, deps PathDeps, crateName string, cargoOutDir android.OptionalPath) []string {
Dan Albert06feee92021-03-19 15:06:02 -0700267 var envVars []string
268
269 // libstd requires a specific environment variable to be set. This is
270 // not officially documented and may be removed in the future. See
271 // https://github.com/rust-lang/rust/blob/master/library/std/src/env.rs#L866.
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400272 if crateName == "std" {
273 envVars = append(envVars, "STD_ENV_ARCH="+config.StdEnvArch[ctx.Arch().ArchType])
Dan Albert06feee92021-03-19 15:06:02 -0700274 }
275
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400276 if len(deps.SrcDeps) > 0 && cargoOutDir.Valid() {
277 moduleGenDir := cargoOutDir
Dan Albert06feee92021-03-19 15:06:02 -0700278 // We must calculate an absolute path for OUT_DIR since Rust's include! macro (which normally consumes this)
279 // assumes that paths are relative to the source file.
Wen-yi Chu41326c12023-09-22 03:58:59 +0000280 var outDirPrefix string
281 if !filepath.IsAbs(moduleGenDir.String()) {
Sam Delmericoa588d152023-06-16 10:28:04 -0400282 // If OUT_DIR is not absolute, we use $$PWD to generate an absolute path (os.Getwd() returns '/')
Wen-yi Chu41326c12023-09-22 03:58:59 +0000283 outDirPrefix = "$$PWD/"
Sam Delmericoa588d152023-06-16 10:28:04 -0400284 } else {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000285 // If OUT_DIR is absolute, then moduleGenDir will be an absolute path, so we don't need to set this to anything.
286 outDirPrefix = ""
Dan Albert06feee92021-03-19 15:06:02 -0700287 }
Wen-yi Chu41326c12023-09-22 03:58:59 +0000288 envVars = append(envVars, "OUT_DIR="+filepath.Join(outDirPrefix, moduleGenDir.String()))
Peter Collingbourne0dcd62e2023-03-31 23:05:16 -0700289 } else {
290 // TODO(pcc): Change this to "OUT_DIR=" after fixing crates to not rely on this value.
291 envVars = append(envVars, "OUT_DIR=out")
Dan Albert06feee92021-03-19 15:06:02 -0700292 }
293
Matthew Maurer34609fa2023-06-26 21:10:13 +0000294 envVars = append(envVars, "ANDROID_RUST_VERSION="+config.GetRustVersion(ctx))
295
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400296 if rustMod, ok := ctx.Module().(*Module); ok && rustMod.compiler.cargoEnvCompat() {
297 // We only emulate cargo environment variables for 3p code, which is only ever built
298 // by defining a Rust module, so we only need to set these for true Rust modules.
299 if bin, ok := rustMod.compiler.(*binaryDecorator); ok {
Matthew Maurer34609fa2023-06-26 21:10:13 +0000300 envVars = append(envVars, "CARGO_BIN_NAME="+bin.getStem(ctx))
301 }
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400302 envVars = append(envVars, "CARGO_CRATE_NAME="+crateName)
303 envVars = append(envVars, "CARGO_PKG_NAME="+crateName)
304 pkgVersion := rustMod.compiler.cargoPkgVersion()
Matthew Maurer34609fa2023-06-26 21:10:13 +0000305 if pkgVersion != "" {
306 envVars = append(envVars, "CARGO_PKG_VERSION="+pkgVersion)
Ivan Lozanof4455622023-07-28 12:42:20 -0400307
308 // Ensure the version is in the form of "x.y.z" (approximately semver compliant).
309 //
310 // For our purposes, we don't care to enforce that these are integers since they may
311 // include other characters at times (e.g. sometimes the patch version is more than an integer).
312 if strings.Count(pkgVersion, ".") == 2 {
313 var semver_parts = strings.Split(pkgVersion, ".")
314 envVars = append(envVars, "CARGO_PKG_VERSION_MAJOR="+semver_parts[0])
315 envVars = append(envVars, "CARGO_PKG_VERSION_MINOR="+semver_parts[1])
316 envVars = append(envVars, "CARGO_PKG_VERSION_PATCH="+semver_parts[2])
317 }
Matthew Maurer34609fa2023-06-26 21:10:13 +0000318 }
319 }
320
Sam Delmericoc5cf9902023-10-23 21:40:13 +0000321 if ctx.Darwin() {
322 envVars = append(envVars, "ANDROID_RUST_DARWIN=true")
323 }
324
Dan Albert06feee92021-03-19 15:06:02 -0700325 return envVars
326}
327
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400328func transformSrctoCrate(ctx android.ModuleContext, main android.Path, deps PathDeps, flags Flags,
329 outputFile android.WritablePath, t transformProperties) buildOutput {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700330
331 var inputs android.Paths
Colin Cross004bd3f2023-10-02 11:39:17 -0700332 var implicits android.Paths
333 var orderOnly android.Paths
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400334 var output buildOutput
Dan Albert06feee92021-03-19 15:06:02 -0700335 var rustcFlags, linkFlags []string
Wen-yi Chu41326c12023-09-22 03:58:59 +0000336 var earlyLinkFlags string
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400337
338 output.outputFile = outputFile
Ivan Lozanoffee3342019-08-27 12:03:00 -0700339
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400340 envVars := rustEnvVars(ctx, deps, t.crateName, t.cargoOutDir)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000341
Ivan Lozanoffee3342019-08-27 12:03:00 -0700342 inputs = append(inputs, main)
343
344 // Collect rustc flags
Ivan Lozanof1c84332019-09-20 11:00:37 -0700345 rustcFlags = append(rustcFlags, flags.GlobalRustFlags...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700346 rustcFlags = append(rustcFlags, flags.RustFlags...)
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400347 rustcFlags = append(rustcFlags, "--crate-type="+t.crateType)
348 if t.crateName != "" {
349 rustcFlags = append(rustcFlags, "--crate-name="+t.crateName)
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700350 }
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400351 if t.targetTriple != "" {
352 rustcFlags = append(rustcFlags, "--target="+t.targetTriple)
353 linkFlags = append(linkFlags, "-target "+t.targetTriple)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700354 }
Matthew Maurerbb3add12020-06-25 09:34:12 -0700355
356 // Suppress an implicit sysroot
357 rustcFlags = append(rustcFlags, "--sysroot=/dev/null")
358
Chris Wailes99180c22024-02-20 21:39:40 +0000359 // Enable incremental compilation if requested by user
360 if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
361 incrementalPath := android.PathForOutput(ctx, "rustc").String()
362
363 rustcFlags = append(rustcFlags, "-C incremental="+incrementalPath)
364 } else {
365 rustcFlags = append(rustcFlags, "-C codegen-units=1")
366 }
367
Chris Wailes6d12db42023-02-24 16:58:18 -0800368 // Disallow experimental features
Colin Crossf96b0012023-10-26 14:01:51 -0700369 modulePath := ctx.ModuleDir()
Chris Wailes6d12db42023-02-24 16:58:18 -0800370 if !(android.IsThirdPartyPath(modulePath) || strings.HasPrefix(modulePath, "prebuilts")) {
Chris Wailes547bfdd2023-05-31 11:53:44 -0700371 rustcFlags = append(rustcFlags, "-Zallow-features=\"\"")
Chris Wailesd9781fd2021-12-03 17:17:28 -0800372 }
373
Ivan Lozanof1c84332019-09-20 11:00:37 -0700374 // Collect linker flags
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700375 if !ctx.Darwin() {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000376 earlyLinkFlags = "-Wl,--as-needed"
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700377 }
378
Wen-yi Chu41326c12023-09-22 03:58:59 +0000379 linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
380 linkFlags = append(linkFlags, flags.LinkFlags...)
381
382 // Check if this module needs to use the bootstrap linker
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400383 if t.bootstrap && !t.inRecovery && !t.inRamdisk && !t.inVendorRamdisk {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000384 dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400385 if t.is64Bit {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000386 dynamicLinker += "64"
387 }
388 linkFlags = append(linkFlags, dynamicLinker)
389 }
390
391 libFlags := makeLibFlags(deps)
392
Ivan Lozanoffee3342019-08-27 12:03:00 -0700393 // Collect dependencies
Wen-yi Chu41326c12023-09-22 03:58:59 +0000394 implicits = append(implicits, rustLibsToPaths(deps.RLibs)...)
395 implicits = append(implicits, rustLibsToPaths(deps.DyLibs)...)
396 implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
Colin Cross004bd3f2023-10-02 11:39:17 -0700397 implicits = append(implicits, deps.StaticLibs...)
398 implicits = append(implicits, deps.SharedLibDeps...)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000399 implicits = append(implicits, deps.srcProviderFiles...)
Colin Cross004bd3f2023-10-02 11:39:17 -0700400 implicits = append(implicits, deps.AfdoProfiles...)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000401
Colin Cross004bd3f2023-10-02 11:39:17 -0700402 implicits = append(implicits, deps.CrtBegin...)
403 implicits = append(implicits, deps.CrtEnd...)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000404
Colin Cross004bd3f2023-10-02 11:39:17 -0700405 orderOnly = append(orderOnly, deps.SharedLibs...)
Sam Delmerico51d6d1c2023-03-28 16:54:00 -0400406
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400407 if !t.synthetic {
408 // Only worry about OUT_DIR for actual Rust modules.
409 // Libraries built from cc use generated source, and do not utilize OUT_DIR.
410 if len(deps.SrcDeps) > 0 {
411 var outputs android.WritablePaths
Ivan Lozano43845682020-07-09 21:03:28 -0400412
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400413 for _, genSrc := range deps.SrcDeps {
414 if android.SuffixInList(outputs.Strings(), genSubDir+genSrc.Base()) {
415 ctx.PropertyErrorf("srcs",
416 "multiple source providers generate the same filename output: "+genSrc.Base())
417 }
418 outputs = append(outputs, android.PathForModuleOut(ctx, genSubDir+genSrc.Base()))
Ivan Lozano43845682020-07-09 21:03:28 -0400419 }
Ivan Lozano43845682020-07-09 21:03:28 -0400420
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400421 ctx.Build(pctx, android.BuildParams{
422 Rule: cp,
423 Description: "cp " + t.cargoOutDir.Path().Rel(),
424 Outputs: outputs,
425 Inputs: deps.SrcDeps,
426 Args: map[string]string{
427 "outDir": t.cargoOutDir.String(),
428 },
429 })
430 implicits = append(implicits, outputs.Paths()...)
431 }
Ivan Lozano43845682020-07-09 21:03:28 -0400432 }
433
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400434 if !t.synthetic {
435 // Only worry about clippy for actual Rust modules.
436 // Libraries built from cc use generated source, and don't need to run clippy.
437 if flags.Clippy {
438 clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
439 ctx.Build(pctx, android.BuildParams{
440 Rule: clippyDriver,
441 Description: "clippy " + main.Rel(),
442 Output: clippyFile,
443 ImplicitOutputs: nil,
444 Inputs: inputs,
445 Implicits: implicits,
446 OrderOnly: orderOnly,
447 Args: map[string]string{
448 "rustcFlags": strings.Join(rustcFlags, " "),
449 "libFlags": strings.Join(libFlags, " "),
450 "clippyFlags": strings.Join(flags.ClippyFlags, " "),
451 "envVars": strings.Join(envVars, " "),
452 },
453 })
454 // Declare the clippy build as an implicit dependency of the original crate.
455 implicits = append(implicits, clippyFile)
456 }
Ivan Lozanobae62be2020-07-21 13:28:27 -0400457 }
458
Wen-yi Chu41326c12023-09-22 03:58:59 +0000459 ctx.Build(pctx, android.BuildParams{
Colin Cross004bd3f2023-10-02 11:39:17 -0700460 Rule: rustc,
461 Description: "rustc " + main.Rel(),
462 Output: outputFile,
463 Inputs: inputs,
464 Implicits: implicits,
465 OrderOnly: orderOnly,
Wen-yi Chu41326c12023-09-22 03:58:59 +0000466 Args: map[string]string{
Colin Cross004bd3f2023-10-02 11:39:17 -0700467 "rustcFlags": strings.Join(rustcFlags, " "),
468 "earlyLinkFlags": earlyLinkFlags,
469 "linkFlags": strings.Join(linkFlags, " "),
470 "libFlags": strings.Join(libFlags, " "),
471 "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
472 "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
473 "envVars": strings.Join(envVars, " "),
Wen-yi Chu41326c12023-09-22 03:58:59 +0000474 },
475 })
Ivan Lozanoffee3342019-08-27 12:03:00 -0700476
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400477 if !t.synthetic {
478 // Only emit xrefs for true Rust modules.
479 if flags.EmitXrefs {
480 kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip")
481 ctx.Build(pctx, android.BuildParams{
482 Rule: kytheExtract,
483 Description: "Xref Rust extractor " + main.Rel(),
484 Output: kytheFile,
485 Inputs: inputs,
486 Implicits: implicits,
487 OrderOnly: orderOnly,
488 Args: map[string]string{
489 "rustcFlags": strings.Join(rustcFlags, " "),
490 "linkFlags": strings.Join(linkFlags, " "),
491 "libFlags": strings.Join(libFlags, " "),
492 "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
493 "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
494 "envVars": strings.Join(envVars, " "),
495 },
496 })
497 output.kytheFile = kytheFile
498 }
Sasha Smundaka76acba2022-04-18 20:12:56 -0700499 }
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400500 return output
501}
Dan Albert06feee92021-03-19 15:06:02 -0700502
Wen-yi Chu41326c12023-09-22 03:58:59 +0000503func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps,
504 flags Flags) android.ModuleOutPath {
Dan Albert06feee92021-03-19 15:06:02 -0700505
506 rustdocFlags := append([]string{}, flags.RustdocFlags...)
507 rustdocFlags = append(rustdocFlags, "--sysroot=/dev/null")
508
Dan Albertb433bf72021-04-27 17:12:02 -0700509 // Build an index for all our crates. -Z unstable options is required to use
510 // this flag.
511 rustdocFlags = append(rustdocFlags, "-Z", "unstable-options", "--enable-index-page")
512
Dan Albert06feee92021-03-19 15:06:02 -0700513 targetTriple := ctx.toolchain().RustTriple()
514
515 // Collect rustc flags
516 if targetTriple != "" {
517 rustdocFlags = append(rustdocFlags, "--target="+targetTriple)
518 }
519
520 crateName := ctx.RustModule().CrateName()
Dan Albertb433bf72021-04-27 17:12:02 -0700521 rustdocFlags = append(rustdocFlags, "--crate-name "+crateName)
Dan Albert06feee92021-03-19 15:06:02 -0700522
Wen-yi Chu41326c12023-09-22 03:58:59 +0000523 rustdocFlags = append(rustdocFlags, makeLibFlags(deps)...)
Dan Albert06feee92021-03-19 15:06:02 -0700524 docTimestampFile := android.PathForModuleOut(ctx, "rustdoc.timestamp")
Dan Albertb433bf72021-04-27 17:12:02 -0700525
Chris Wailesb2703ad2021-07-30 13:25:42 -0700526 // Silence warnings about renamed lints for third-party crates
Colin Crossf96b0012023-10-26 14:01:51 -0700527 modulePath := ctx.ModuleDir()
Chris Wailesb2703ad2021-07-30 13:25:42 -0700528 if android.IsThirdPartyPath(modulePath) {
Chris Wailes7b3eb242023-02-14 16:09:49 -0800529 rustdocFlags = append(rustdocFlags, " -A warnings")
Chris Wailesb2703ad2021-07-30 13:25:42 -0700530 }
Chris Wailes9953a192021-07-28 12:07:16 -0700531
Dan Albertb433bf72021-04-27 17:12:02 -0700532 // Yes, the same out directory is used simultaneously by all rustdoc builds.
533 // This is what cargo does. The docs for individual crates get generated to
534 // a subdirectory named for the crate, and rustdoc synchronizes writes to
535 // shared pieces like the index and search data itself.
536 // https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/render/write_shared.rs#L144-L146
537 docDir := android.PathForOutput(ctx, "rustdoc")
Dan Albert06feee92021-03-19 15:06:02 -0700538
Wen-yi Chu41326c12023-09-22 03:58:59 +0000539 ctx.Build(pctx, android.BuildParams{
540 Rule: rustdoc,
541 Description: "rustdoc " + main.Rel(),
542 Output: docTimestampFile,
543 Input: main,
544 Implicit: ctx.RustModule().UnstrippedOutputFile(),
545 Args: map[string]string{
546 "rustdocFlags": strings.Join(rustdocFlags, " "),
547 "outDir": docDir.String(),
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400548 "envVars": strings.Join(rustEnvVars(ctx, deps, crateName, ctx.RustModule().compiler.cargoOutDir()), " "),
Wen-yi Chu41326c12023-09-22 03:58:59 +0000549 },
550 })
Dan Albert06feee92021-03-19 15:06:02 -0700551
552 return docTimestampFile
553}