blob: 1281db523833a74813dc63c70ecd4c4a13ebe926 [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"
ThiƩbaud Weksteen71512f32020-11-03 15:17:51 +010024 "android/soong/rust/config"
Ivan Lozanoffee3342019-08-27 12:03:00 -070025)
26
27var (
Wen-yi Chu41326c12023-09-22 03:58:59 +000028 _ = pctx.SourcePathVariable("rustcCmd", "${config.RustBin}/rustc")
Wen-yi Chu41326c12023-09-22 03:58:59 +000029 rustc = pctx.AndroidStaticRule("rustc",
30 blueprint.RuleParams{
31 Command: "$envVars $rustcCmd " +
Colin Cross004bd3f2023-10-02 11:39:17 -070032 "-C linker=${config.RustLinker} " +
33 "-C link-args=\"${crtBegin} ${earlyLinkFlags} ${linkFlags} ${crtEnd}\" " +
Wen-yi Chu41326c12023-09-22 03:58:59 +000034 "--emit link -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" +
Ivan Lozanocfeec1c2024-03-28 19:27:24 +000035 " && grep ^$out: $out.d.raw > $out.d",
Colin Cross004bd3f2023-10-02 11:39:17 -070036 CommandDeps: []string{"$rustcCmd"},
Wen-yi Chu41326c12023-09-22 03:58:59 +000037 // Rustc deps-info writes out make compatible dep files: https://github.com/rust-lang/rust/issues/7633
38 // Rustc emits unneeded dependency lines for the .d and input .rs files.
39 // Those extra lines cause ninja warning:
40 // "warning: depfile has multiple output paths"
41 // For ninja, we keep/grep only the dependency rule for the rust $out file.
42 Deps: blueprint.DepsGCC,
43 Depfile: "$out.d",
44 },
Colin Cross004bd3f2023-10-02 11:39:17 -070045 "rustcFlags", "earlyLinkFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars")
Wen-yi Chu41326c12023-09-22 03:58:59 +000046
47 _ = pctx.SourcePathVariable("rustdocCmd", "${config.RustBin}/rustdoc")
48 rustdoc = pctx.AndroidStaticRule("rustdoc",
49 blueprint.RuleParams{
50 Command: "$envVars $rustdocCmd $rustdocFlags $in -o $outDir && " +
51 "touch $out",
52 CommandDeps: []string{"$rustdocCmd"},
53 },
54 "rustdocFlags", "outDir", "envVars")
55
56 _ = pctx.SourcePathVariable("clippyCmd", "${config.RustBin}/clippy-driver")
57 clippyDriver = pctx.AndroidStaticRule("clippy",
58 blueprint.RuleParams{
59 Command: "$envVars $clippyCmd " +
60 // Because clippy-driver uses rustc as backend, we need to have some output even during the linting.
61 // Use the metadata output as it has the smallest footprint.
62 "--emit metadata -o $out --emit dep-info=$out.d.raw $in ${libFlags} " +
63 "$rustcFlags $clippyFlags" +
Alex91c74762024-04-11 17:30:27 +020064 " && grep ^$out: $out.d.raw > $out.d",
Wen-yi Chu41326c12023-09-22 03:58:59 +000065 CommandDeps: []string{"$clippyCmd"},
66 Deps: blueprint.DepsGCC,
67 Depfile: "$out.d",
68 },
69 "rustcFlags", "libFlags", "clippyFlags", "envVars")
70
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -040071 zip = pctx.AndroidStaticRule("zip",
72 blueprint.RuleParams{
73 Command: "cat $out.rsp | tr ' ' '\\n' | tr -d \\' | sort -u > ${out}.tmp && ${SoongZipCmd} -o ${out} -C $$OUT_DIR -l ${out}.tmp",
74 CommandDeps: []string{"${SoongZipCmd}"},
75 Rspfile: "$out.rsp",
76 RspfileContent: "$in",
77 })
Ivan Lozano43845682020-07-09 21:03:28 -040078
Wen-yi Chu41326c12023-09-22 03:58:59 +000079 cp = pctx.AndroidStaticRule("cp",
Ivan Lozano43845682020-07-09 21:03:28 -040080 blueprint.RuleParams{
81 Command: "cp `cat $outDir.rsp` $outDir",
82 Rspfile: "${outDir}.rsp",
83 RspfileContent: "$in",
84 },
85 "outDir")
Sasha Smundaka76acba2022-04-18 20:12:56 -070086
87 // Cross-referencing:
88 _ = pctx.SourcePathVariable("rustExtractor",
89 "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/rust_extractor")
90 _ = pctx.VariableFunc("kytheCorpus",
91 func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
92 _ = pctx.VariableFunc("kytheCuEncoding",
93 func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
Wen-yi Chu41326c12023-09-22 03:58:59 +000094 _ = pctx.SourcePathVariable("kytheVnames", "build/soong/vnames.json")
95 kytheExtract = pctx.AndroidStaticRule("kythe",
96 blueprint.RuleParams{
97 Command: `KYTHE_CORPUS=${kytheCorpus} ` +
98 `KYTHE_OUTPUT_FILE=$out ` +
99 `KYTHE_VNAMES=$kytheVnames ` +
100 `KYTHE_KZIP_ENCODING=${kytheCuEncoding} ` +
101 `KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative ` +
102 `$rustExtractor $envVars ` +
103 `$rustcCmd ` +
Colin Cross004bd3f2023-10-02 11:39:17 -0700104 `-C linker=${config.RustLinker} ` +
105 `-C link-args="${crtBegin} ${linkFlags} ${crtEnd}" ` +
Wen-yi Chu41326c12023-09-22 03:58:59 +0000106 `$in ${libFlags} $rustcFlags`,
107 CommandDeps: []string{"$rustExtractor", "$kytheVnames"},
108 Rspfile: "${out}.rsp",
109 RspfileContent: "$in",
110 },
Colin Cross004bd3f2023-10-02 11:39:17 -0700111 "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars")
Ivan Lozanoffee3342019-08-27 12:03:00 -0700112)
113
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400114type buildOutput struct {
Joel Galensonfa049382021-01-14 16:03:18 -0800115 outputFile android.Path
Sasha Smundaka76acba2022-04-18 20:12:56 -0700116 kytheFile android.Path
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400117}
Ivan Lozanoffee3342019-08-27 12:03:00 -0700118
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400119func init() {
120 pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
Ivan Lozanoffee3342019-08-27 12:03:00 -0700121}
122
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400123type transformProperties struct {
124 crateName string
125 targetTriple string
126 is64Bit bool
127 bootstrap bool
128 inRecovery bool
129 inRamdisk bool
130 inVendorRamdisk bool
131 cargoOutDir android.OptionalPath
132 synthetic bool
133 crateType string
134}
135
136// Populates a standard transformProperties struct for Rust modules
137func getTransformProperties(ctx ModuleContext, crateType string) transformProperties {
138 module := ctx.RustModule()
139 return transformProperties{
140 crateName: module.CrateName(),
141 is64Bit: ctx.toolchain().Is64Bit(),
142 targetTriple: ctx.toolchain().RustTriple(),
143 bootstrap: module.Bootstrap(),
144 inRecovery: module.InRecovery(),
145 inRamdisk: module.InRamdisk(),
146 inVendorRamdisk: module.InVendorRamdisk(),
147 cargoOutDir: module.compiler.cargoOutDir(),
148
149 // crateType indicates what type of crate to build
150 crateType: crateType,
151
152 // synthetic indicates whether this is an actual Rust module or not
153 synthetic: false,
154 }
155}
156
Wen-yi Chu41326c12023-09-22 03:58:59 +0000157func TransformSrcToBinary(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700158 outputFile android.WritablePath) buildOutput {
Chris Wailes99180c22024-02-20 21:39:40 +0000159 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
160
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400161 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "bin"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700162}
163
Wen-yi Chu41326c12023-09-22 03:58:59 +0000164func TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700165 outputFile android.WritablePath) buildOutput {
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400166 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "rlib"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700167}
168
Wen-yi Chu41326c12023-09-22 03:58:59 +0000169func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700170 outputFile android.WritablePath) buildOutput {
Chris Wailes99180c22024-02-20 21:39:40 +0000171 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
172
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400173 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "dylib"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700174}
175
Wen-yi Chu41326c12023-09-22 03:58:59 +0000176func TransformSrctoStatic(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700177 outputFile android.WritablePath) buildOutput {
Chris Wailes99180c22024-02-20 21:39:40 +0000178 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400179 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "staticlib"))
Ivan Lozano52767be2019-10-18 14:49:46 -0700180}
181
Wen-yi Chu41326c12023-09-22 03:58:59 +0000182func TransformSrctoShared(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700183 outputFile android.WritablePath) buildOutput {
Chris Wailes99180c22024-02-20 21:39:40 +0000184 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400185 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "cdylib"))
Ivan Lozano52767be2019-10-18 14:49:46 -0700186}
187
Wen-yi Chu41326c12023-09-22 03:58:59 +0000188func TransformSrctoProcMacro(ctx ModuleContext, mainSrc android.Path, deps PathDeps,
Dan Albert06feee92021-03-19 15:06:02 -0700189 flags Flags, outputFile android.WritablePath) buildOutput {
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400190 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "proc-macro"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700191}
192
193func rustLibsToPaths(libs RustLibraries) android.Paths {
194 var paths android.Paths
195 for _, lib := range libs {
196 paths = append(paths, lib.Path)
197 }
198 return paths
199}
200
Wen-yi Chu41326c12023-09-22 03:58:59 +0000201func makeLibFlags(deps PathDeps) []string {
Dan Albert06feee92021-03-19 15:06:02 -0700202 var libFlags []string
203
204 // Collect library/crate flags
Wen-yi Chu41326c12023-09-22 03:58:59 +0000205 for _, lib := range deps.RLibs {
206 libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
Dan Albert06feee92021-03-19 15:06:02 -0700207 }
Wen-yi Chu41326c12023-09-22 03:58:59 +0000208 for _, lib := range deps.DyLibs {
209 libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
Dan Albert06feee92021-03-19 15:06:02 -0700210 }
Wen-yi Chu41326c12023-09-22 03:58:59 +0000211 for _, proc_macro := range deps.ProcMacros {
212 libFlags = append(libFlags, "--extern "+proc_macro.CrateName+"="+proc_macro.Path.String())
Dan Albert06feee92021-03-19 15:06:02 -0700213 }
214
215 for _, path := range deps.linkDirs {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000216 libFlags = append(libFlags, "-L "+path)
Dan Albert06feee92021-03-19 15:06:02 -0700217 }
218
219 return libFlags
220}
221
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400222func rustEnvVars(ctx android.ModuleContext, deps PathDeps, crateName string, cargoOutDir android.OptionalPath) []string {
Dan Albert06feee92021-03-19 15:06:02 -0700223 var envVars []string
224
225 // libstd requires a specific environment variable to be set. This is
226 // not officially documented and may be removed in the future. See
227 // https://github.com/rust-lang/rust/blob/master/library/std/src/env.rs#L866.
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400228 if crateName == "std" {
229 envVars = append(envVars, "STD_ENV_ARCH="+config.StdEnvArch[ctx.Arch().ArchType])
Dan Albert06feee92021-03-19 15:06:02 -0700230 }
231
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400232 if len(deps.SrcDeps) > 0 && cargoOutDir.Valid() {
233 moduleGenDir := cargoOutDir
Dan Albert06feee92021-03-19 15:06:02 -0700234 // We must calculate an absolute path for OUT_DIR since Rust's include! macro (which normally consumes this)
235 // assumes that paths are relative to the source file.
Wen-yi Chu41326c12023-09-22 03:58:59 +0000236 var outDirPrefix string
237 if !filepath.IsAbs(moduleGenDir.String()) {
Sam Delmericoa588d152023-06-16 10:28:04 -0400238 // 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 +0000239 outDirPrefix = "$$PWD/"
Sam Delmericoa588d152023-06-16 10:28:04 -0400240 } else {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000241 // If OUT_DIR is absolute, then moduleGenDir will be an absolute path, so we don't need to set this to anything.
242 outDirPrefix = ""
Dan Albert06feee92021-03-19 15:06:02 -0700243 }
Wen-yi Chu41326c12023-09-22 03:58:59 +0000244 envVars = append(envVars, "OUT_DIR="+filepath.Join(outDirPrefix, moduleGenDir.String()))
Peter Collingbourne0dcd62e2023-03-31 23:05:16 -0700245 } else {
246 // TODO(pcc): Change this to "OUT_DIR=" after fixing crates to not rely on this value.
247 envVars = append(envVars, "OUT_DIR=out")
Dan Albert06feee92021-03-19 15:06:02 -0700248 }
249
Matthew Maurer34609fa2023-06-26 21:10:13 +0000250 envVars = append(envVars, "ANDROID_RUST_VERSION="+config.GetRustVersion(ctx))
251
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400252 if rustMod, ok := ctx.Module().(*Module); ok && rustMod.compiler.cargoEnvCompat() {
253 // We only emulate cargo environment variables for 3p code, which is only ever built
254 // by defining a Rust module, so we only need to set these for true Rust modules.
255 if bin, ok := rustMod.compiler.(*binaryDecorator); ok {
Matthew Maurer34609fa2023-06-26 21:10:13 +0000256 envVars = append(envVars, "CARGO_BIN_NAME="+bin.getStem(ctx))
257 }
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400258 envVars = append(envVars, "CARGO_CRATE_NAME="+crateName)
259 envVars = append(envVars, "CARGO_PKG_NAME="+crateName)
260 pkgVersion := rustMod.compiler.cargoPkgVersion()
Matthew Maurer34609fa2023-06-26 21:10:13 +0000261 if pkgVersion != "" {
262 envVars = append(envVars, "CARGO_PKG_VERSION="+pkgVersion)
Ivan Lozanof4455622023-07-28 12:42:20 -0400263
264 // Ensure the version is in the form of "x.y.z" (approximately semver compliant).
265 //
266 // For our purposes, we don't care to enforce that these are integers since they may
267 // include other characters at times (e.g. sometimes the patch version is more than an integer).
268 if strings.Count(pkgVersion, ".") == 2 {
269 var semver_parts = strings.Split(pkgVersion, ".")
270 envVars = append(envVars, "CARGO_PKG_VERSION_MAJOR="+semver_parts[0])
271 envVars = append(envVars, "CARGO_PKG_VERSION_MINOR="+semver_parts[1])
272 envVars = append(envVars, "CARGO_PKG_VERSION_PATCH="+semver_parts[2])
273 }
Matthew Maurer34609fa2023-06-26 21:10:13 +0000274 }
275 }
276
Sam Delmericoc5cf9902023-10-23 21:40:13 +0000277 if ctx.Darwin() {
278 envVars = append(envVars, "ANDROID_RUST_DARWIN=true")
279 }
280
Dan Albert06feee92021-03-19 15:06:02 -0700281 return envVars
282}
283
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400284func transformSrctoCrate(ctx android.ModuleContext, main android.Path, deps PathDeps, flags Flags,
285 outputFile android.WritablePath, t transformProperties) buildOutput {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700286
287 var inputs android.Paths
Colin Cross004bd3f2023-10-02 11:39:17 -0700288 var implicits android.Paths
289 var orderOnly android.Paths
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400290 var output buildOutput
Dan Albert06feee92021-03-19 15:06:02 -0700291 var rustcFlags, linkFlags []string
Wen-yi Chu41326c12023-09-22 03:58:59 +0000292 var earlyLinkFlags string
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400293
294 output.outputFile = outputFile
Ivan Lozanoffee3342019-08-27 12:03:00 -0700295
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400296 envVars := rustEnvVars(ctx, deps, t.crateName, t.cargoOutDir)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000297
Ivan Lozanoffee3342019-08-27 12:03:00 -0700298 inputs = append(inputs, main)
299
300 // Collect rustc flags
Ivan Lozanof1c84332019-09-20 11:00:37 -0700301 rustcFlags = append(rustcFlags, flags.GlobalRustFlags...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700302 rustcFlags = append(rustcFlags, flags.RustFlags...)
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400303 rustcFlags = append(rustcFlags, "--crate-type="+t.crateType)
304 if t.crateName != "" {
305 rustcFlags = append(rustcFlags, "--crate-name="+t.crateName)
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700306 }
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400307 if t.targetTriple != "" {
308 rustcFlags = append(rustcFlags, "--target="+t.targetTriple)
309 linkFlags = append(linkFlags, "-target "+t.targetTriple)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700310 }
Matthew Maurerbb3add12020-06-25 09:34:12 -0700311
312 // Suppress an implicit sysroot
313 rustcFlags = append(rustcFlags, "--sysroot=/dev/null")
314
Chris Wailes99180c22024-02-20 21:39:40 +0000315 // Enable incremental compilation if requested by user
316 if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
317 incrementalPath := android.PathForOutput(ctx, "rustc").String()
318
319 rustcFlags = append(rustcFlags, "-C incremental="+incrementalPath)
320 } else {
321 rustcFlags = append(rustcFlags, "-C codegen-units=1")
322 }
323
Chris Wailes6d12db42023-02-24 16:58:18 -0800324 // Disallow experimental features
Colin Crossf96b0012023-10-26 14:01:51 -0700325 modulePath := ctx.ModuleDir()
Chris Wailes6d12db42023-02-24 16:58:18 -0800326 if !(android.IsThirdPartyPath(modulePath) || strings.HasPrefix(modulePath, "prebuilts")) {
Chris Wailes547bfdd2023-05-31 11:53:44 -0700327 rustcFlags = append(rustcFlags, "-Zallow-features=\"\"")
Chris Wailesd9781fd2021-12-03 17:17:28 -0800328 }
329
Ivan Lozanof1c84332019-09-20 11:00:37 -0700330 // Collect linker flags
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700331 if !ctx.Darwin() {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000332 earlyLinkFlags = "-Wl,--as-needed"
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700333 }
334
Wen-yi Chu41326c12023-09-22 03:58:59 +0000335 linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
336 linkFlags = append(linkFlags, flags.LinkFlags...)
337
338 // Check if this module needs to use the bootstrap linker
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400339 if t.bootstrap && !t.inRecovery && !t.inRamdisk && !t.inVendorRamdisk {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000340 dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400341 if t.is64Bit {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000342 dynamicLinker += "64"
343 }
344 linkFlags = append(linkFlags, dynamicLinker)
345 }
346
347 libFlags := makeLibFlags(deps)
348
Ivan Lozanoffee3342019-08-27 12:03:00 -0700349 // Collect dependencies
Wen-yi Chu41326c12023-09-22 03:58:59 +0000350 implicits = append(implicits, rustLibsToPaths(deps.RLibs)...)
351 implicits = append(implicits, rustLibsToPaths(deps.DyLibs)...)
352 implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
Colin Cross004bd3f2023-10-02 11:39:17 -0700353 implicits = append(implicits, deps.StaticLibs...)
354 implicits = append(implicits, deps.SharedLibDeps...)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000355 implicits = append(implicits, deps.srcProviderFiles...)
Colin Cross004bd3f2023-10-02 11:39:17 -0700356 implicits = append(implicits, deps.AfdoProfiles...)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000357
Colin Cross004bd3f2023-10-02 11:39:17 -0700358 implicits = append(implicits, deps.CrtBegin...)
359 implicits = append(implicits, deps.CrtEnd...)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000360
Colin Cross004bd3f2023-10-02 11:39:17 -0700361 orderOnly = append(orderOnly, deps.SharedLibs...)
Sam Delmerico51d6d1c2023-03-28 16:54:00 -0400362
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400363 if !t.synthetic {
364 // Only worry about OUT_DIR for actual Rust modules.
365 // Libraries built from cc use generated source, and do not utilize OUT_DIR.
366 if len(deps.SrcDeps) > 0 {
367 var outputs android.WritablePaths
Ivan Lozano43845682020-07-09 21:03:28 -0400368
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400369 for _, genSrc := range deps.SrcDeps {
370 if android.SuffixInList(outputs.Strings(), genSubDir+genSrc.Base()) {
371 ctx.PropertyErrorf("srcs",
372 "multiple source providers generate the same filename output: "+genSrc.Base())
373 }
374 outputs = append(outputs, android.PathForModuleOut(ctx, genSubDir+genSrc.Base()))
Ivan Lozano43845682020-07-09 21:03:28 -0400375 }
Ivan Lozano43845682020-07-09 21:03:28 -0400376
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400377 ctx.Build(pctx, android.BuildParams{
378 Rule: cp,
379 Description: "cp " + t.cargoOutDir.Path().Rel(),
380 Outputs: outputs,
381 Inputs: deps.SrcDeps,
382 Args: map[string]string{
383 "outDir": t.cargoOutDir.String(),
384 },
385 })
386 implicits = append(implicits, outputs.Paths()...)
387 }
Ivan Lozano43845682020-07-09 21:03:28 -0400388 }
389
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400390 if !t.synthetic {
391 // Only worry about clippy for actual Rust modules.
392 // Libraries built from cc use generated source, and don't need to run clippy.
393 if flags.Clippy {
394 clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
395 ctx.Build(pctx, android.BuildParams{
396 Rule: clippyDriver,
397 Description: "clippy " + main.Rel(),
398 Output: clippyFile,
399 ImplicitOutputs: nil,
400 Inputs: inputs,
401 Implicits: implicits,
402 OrderOnly: orderOnly,
403 Args: map[string]string{
404 "rustcFlags": strings.Join(rustcFlags, " "),
405 "libFlags": strings.Join(libFlags, " "),
406 "clippyFlags": strings.Join(flags.ClippyFlags, " "),
407 "envVars": strings.Join(envVars, " "),
408 },
409 })
410 // Declare the clippy build as an implicit dependency of the original crate.
411 implicits = append(implicits, clippyFile)
412 }
Ivan Lozanobae62be2020-07-21 13:28:27 -0400413 }
414
Wen-yi Chu41326c12023-09-22 03:58:59 +0000415 ctx.Build(pctx, android.BuildParams{
Colin Cross004bd3f2023-10-02 11:39:17 -0700416 Rule: rustc,
417 Description: "rustc " + main.Rel(),
418 Output: outputFile,
419 Inputs: inputs,
420 Implicits: implicits,
421 OrderOnly: orderOnly,
Wen-yi Chu41326c12023-09-22 03:58:59 +0000422 Args: map[string]string{
Colin Cross004bd3f2023-10-02 11:39:17 -0700423 "rustcFlags": strings.Join(rustcFlags, " "),
424 "earlyLinkFlags": earlyLinkFlags,
425 "linkFlags": strings.Join(linkFlags, " "),
426 "libFlags": strings.Join(libFlags, " "),
427 "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
428 "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
429 "envVars": strings.Join(envVars, " "),
Wen-yi Chu41326c12023-09-22 03:58:59 +0000430 },
431 })
Ivan Lozanoffee3342019-08-27 12:03:00 -0700432
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400433 if !t.synthetic {
434 // Only emit xrefs for true Rust modules.
435 if flags.EmitXrefs {
436 kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip")
437 ctx.Build(pctx, android.BuildParams{
438 Rule: kytheExtract,
439 Description: "Xref Rust extractor " + main.Rel(),
440 Output: kytheFile,
441 Inputs: inputs,
442 Implicits: implicits,
443 OrderOnly: orderOnly,
444 Args: map[string]string{
445 "rustcFlags": strings.Join(rustcFlags, " "),
446 "linkFlags": strings.Join(linkFlags, " "),
447 "libFlags": strings.Join(libFlags, " "),
448 "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
449 "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
450 "envVars": strings.Join(envVars, " "),
451 },
452 })
453 output.kytheFile = kytheFile
454 }
Sasha Smundaka76acba2022-04-18 20:12:56 -0700455 }
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400456 return output
457}
Dan Albert06feee92021-03-19 15:06:02 -0700458
Wen-yi Chu41326c12023-09-22 03:58:59 +0000459func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps,
460 flags Flags) android.ModuleOutPath {
Dan Albert06feee92021-03-19 15:06:02 -0700461
462 rustdocFlags := append([]string{}, flags.RustdocFlags...)
463 rustdocFlags = append(rustdocFlags, "--sysroot=/dev/null")
464
Dan Albertb433bf72021-04-27 17:12:02 -0700465 // Build an index for all our crates. -Z unstable options is required to use
466 // this flag.
467 rustdocFlags = append(rustdocFlags, "-Z", "unstable-options", "--enable-index-page")
468
Dan Albert06feee92021-03-19 15:06:02 -0700469 targetTriple := ctx.toolchain().RustTriple()
470
471 // Collect rustc flags
472 if targetTriple != "" {
473 rustdocFlags = append(rustdocFlags, "--target="+targetTriple)
474 }
475
476 crateName := ctx.RustModule().CrateName()
Dan Albertb433bf72021-04-27 17:12:02 -0700477 rustdocFlags = append(rustdocFlags, "--crate-name "+crateName)
Dan Albert06feee92021-03-19 15:06:02 -0700478
Wen-yi Chu41326c12023-09-22 03:58:59 +0000479 rustdocFlags = append(rustdocFlags, makeLibFlags(deps)...)
Dan Albert06feee92021-03-19 15:06:02 -0700480 docTimestampFile := android.PathForModuleOut(ctx, "rustdoc.timestamp")
Dan Albertb433bf72021-04-27 17:12:02 -0700481
Chris Wailesb2703ad2021-07-30 13:25:42 -0700482 // Silence warnings about renamed lints for third-party crates
Colin Crossf96b0012023-10-26 14:01:51 -0700483 modulePath := ctx.ModuleDir()
Chris Wailesb2703ad2021-07-30 13:25:42 -0700484 if android.IsThirdPartyPath(modulePath) {
Chris Wailes7b3eb242023-02-14 16:09:49 -0800485 rustdocFlags = append(rustdocFlags, " -A warnings")
Chris Wailesb2703ad2021-07-30 13:25:42 -0700486 }
Chris Wailes9953a192021-07-28 12:07:16 -0700487
Dan Albertb433bf72021-04-27 17:12:02 -0700488 // Yes, the same out directory is used simultaneously by all rustdoc builds.
489 // This is what cargo does. The docs for individual crates get generated to
490 // a subdirectory named for the crate, and rustdoc synchronizes writes to
491 // shared pieces like the index and search data itself.
492 // https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/render/write_shared.rs#L144-L146
493 docDir := android.PathForOutput(ctx, "rustdoc")
Dan Albert06feee92021-03-19 15:06:02 -0700494
Wen-yi Chu41326c12023-09-22 03:58:59 +0000495 ctx.Build(pctx, android.BuildParams{
496 Rule: rustdoc,
497 Description: "rustdoc " + main.Rel(),
498 Output: docTimestampFile,
499 Input: main,
500 Implicit: ctx.RustModule().UnstrippedOutputFile(),
501 Args: map[string]string{
502 "rustdocFlags": strings.Join(rustdocFlags, " "),
503 "outDir": docDir.String(),
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400504 "envVars": strings.Join(rustEnvVars(ctx, deps, crateName, ctx.RustModule().compiler.cargoOutDir()), " "),
Wen-yi Chu41326c12023-09-22 03:58:59 +0000505 },
506 })
Dan Albert06feee92021-03-19 15:06:02 -0700507
508 return docTimestampFile
509}