blob: 09933d3f14a7b9b4030633d4243a10217b8d961c [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 (
Sam Delmericoa588d152023-06-16 10:28:04 -040018 "fmt"
Ivan Lozano1776a2a2020-11-11 10:59:52 -050019 "path/filepath"
Ivan Lozanoffee3342019-08-27 12:03:00 -070020 "strings"
21
22 "github.com/google/blueprint"
23
24 "android/soong/android"
Sam Delmerico476e8762023-09-21 06:21:21 +000025 cc_config "android/soong/cc/config"
ThiƩbaud Weksteen71512f32020-11-03 15:17:51 +010026 "android/soong/rust/config"
Ivan Lozanoffee3342019-08-27 12:03:00 -070027)
28
29var (
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -040030 zip = pctx.AndroidStaticRule("zip",
31 blueprint.RuleParams{
32 Command: "cat $out.rsp | tr ' ' '\\n' | tr -d \\' | sort -u > ${out}.tmp && ${SoongZipCmd} -o ${out} -C $$OUT_DIR -l ${out}.tmp",
33 CommandDeps: []string{"${SoongZipCmd}"},
34 Rspfile: "$out.rsp",
35 RspfileContent: "$in",
36 })
Ivan Lozano43845682020-07-09 21:03:28 -040037
Sam Delmericoa588d152023-06-16 10:28:04 -040038 cpDir = pctx.AndroidStaticRule("cpDir",
Ivan Lozano43845682020-07-09 21:03:28 -040039 blueprint.RuleParams{
40 Command: "cp `cat $outDir.rsp` $outDir",
41 Rspfile: "${outDir}.rsp",
42 RspfileContent: "$in",
43 },
44 "outDir")
Sasha Smundaka76acba2022-04-18 20:12:56 -070045
Sam Delmericoa588d152023-06-16 10:28:04 -040046 cp = pctx.AndroidStaticRule("cp",
47 blueprint.RuleParams{
48 Command: "rm -f $out && cp $in $out",
49 Description: "cp $out",
50 })
51
Sasha Smundaka76acba2022-04-18 20:12:56 -070052 // Cross-referencing:
53 _ = pctx.SourcePathVariable("rustExtractor",
54 "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/rust_extractor")
55 _ = pctx.VariableFunc("kytheCorpus",
56 func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
57 _ = pctx.VariableFunc("kytheCuEncoding",
58 func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
Ivan Lozanoffee3342019-08-27 12:03:00 -070059)
60
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -040061type buildOutput struct {
Joel Galensonfa049382021-01-14 16:03:18 -080062 outputFile android.Path
Sasha Smundaka76acba2022-04-18 20:12:56 -070063 kytheFile android.Path
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -040064}
Ivan Lozanoffee3342019-08-27 12:03:00 -070065
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -040066func init() {
67 pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
Ivan Lozanoffee3342019-08-27 12:03:00 -070068}
69
Sam Delmericoa588d152023-06-16 10:28:04 -040070func TransformSrcToBinary(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -070071 outputFile android.WritablePath) buildOutput {
Pirama Arumuga Nainarf77913f2021-10-25 15:37:43 -070072 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
Ivan Lozano31b095d2019-11-20 10:14:33 -080073
Sam Delmericoa588d152023-06-16 10:28:04 -040074 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "bin")
Ivan Lozanoffee3342019-08-27 12:03:00 -070075}
76
Sam Delmericoa588d152023-06-16 10:28:04 -040077func TransformSrctoRlib(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -070078 outputFile android.WritablePath) buildOutput {
Sam Delmericoa588d152023-06-16 10:28:04 -040079 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "rlib")
Ivan Lozanoffee3342019-08-27 12:03:00 -070080}
81
Sam Delmericoa588d152023-06-16 10:28:04 -040082func TransformSrctoDylib(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -070083 outputFile android.WritablePath) buildOutput {
Chris Wailes5f788402023-03-02 16:06:01 -080084 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
85
Sam Delmericoa588d152023-06-16 10:28:04 -040086 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "dylib")
Ivan Lozanoffee3342019-08-27 12:03:00 -070087}
88
Sam Delmericoa588d152023-06-16 10:28:04 -040089func TransformSrctoStatic(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -070090 outputFile android.WritablePath) buildOutput {
Pirama Arumuga Nainarf77913f2021-10-25 15:37:43 -070091 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
Sam Delmericoa588d152023-06-16 10:28:04 -040092 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "staticlib")
Ivan Lozano52767be2019-10-18 14:49:46 -070093}
94
Sam Delmericoa588d152023-06-16 10:28:04 -040095func TransformSrctoShared(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -070096 outputFile android.WritablePath) buildOutput {
Pirama Arumuga Nainarf77913f2021-10-25 15:37:43 -070097 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
Sam Delmericoa588d152023-06-16 10:28:04 -040098 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "cdylib")
Ivan Lozano52767be2019-10-18 14:49:46 -070099}
100
Sam Delmericoa588d152023-06-16 10:28:04 -0400101func TransformSrctoProcMacro(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps,
Dan Albert06feee92021-03-19 15:06:02 -0700102 flags Flags, outputFile android.WritablePath) buildOutput {
Sam Delmericoa588d152023-06-16 10:28:04 -0400103 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "proc-macro")
Ivan Lozanoffee3342019-08-27 12:03:00 -0700104}
105
106func rustLibsToPaths(libs RustLibraries) android.Paths {
107 var paths android.Paths
108 for _, lib := range libs {
109 paths = append(paths, lib.Path)
110 }
111 return paths
112}
113
Sam Delmericoa588d152023-06-16 10:28:04 -0400114func makeLibFlags(deps PathDeps, ruleCmd *android.RuleBuilderCommand) []string {
Dan Albert06feee92021-03-19 15:06:02 -0700115 var libFlags []string
116
117 // Collect library/crate flags
Sam Delmericoa588d152023-06-16 10:28:04 -0400118 for _, lib := range deps.Rlibs.ToListDirect() {
119 libPath := ruleCmd.PathForInput(lib.Path)
120 libFlags = append(libFlags, "--extern "+lib.CrateName+"="+libPath)
Dan Albert06feee92021-03-19 15:06:02 -0700121 }
Sam Delmericoa588d152023-06-16 10:28:04 -0400122 for _, lib := range deps.Dylibs.ToListDirect() {
123 libPath := ruleCmd.PathForInput(lib.Path)
124 libFlags = append(libFlags, "--extern "+lib.CrateName+"="+libPath)
Dan Albert06feee92021-03-19 15:06:02 -0700125 }
Sam Delmericoa588d152023-06-16 10:28:04 -0400126 for _, procMacro := range deps.ProcMacros.ToListDirect() {
127 procMacroPath := ruleCmd.PathForInput(procMacro.Path)
128 libFlags = append(libFlags, "--extern "+procMacro.CrateName+"="+procMacroPath)
Dan Albert06feee92021-03-19 15:06:02 -0700129 }
130
131 for _, path := range deps.linkDirs {
Sam Delmericoa588d152023-06-16 10:28:04 -0400132 libFlags = append(libFlags, "-L "+ruleCmd.PathForInput(path))
Dan Albert06feee92021-03-19 15:06:02 -0700133 }
134
135 return libFlags
136}
137
Sam Delmericoa588d152023-06-16 10:28:04 -0400138func collectImplicits(deps PathDeps) android.Paths {
139 depPaths := android.Paths{}
140 depPaths = append(depPaths, rustLibsToPaths(deps.Rlibs.ToList())...)
141 depPaths = append(depPaths, rustLibsToPaths(deps.Dylibs.ToList())...)
142 depPaths = append(depPaths, rustLibsToPaths(deps.ProcMacros.ToList())...)
143 depPaths = append(depPaths, deps.AfdoProfiles...)
144 depPaths = append(depPaths, deps.WholeStaticLibs...)
145 depPaths = append(depPaths, deps.SrcDeps...)
146 depPaths = append(depPaths, deps.srcProviderFiles...)
147 depPaths = append(depPaths, deps.LibDeps...)
148 depPaths = append(depPaths, deps.linkObjects...)
149 depPaths = append(depPaths, deps.BuildToolSrcDeps...)
150 return depPaths
151}
152
153func rustEnvVars(ctx ModuleContext, deps PathDeps, cmd *android.RuleBuilderCommand) []string {
Dan Albert06feee92021-03-19 15:06:02 -0700154 var envVars []string
155
156 // libstd requires a specific environment variable to be set. This is
157 // not officially documented and may be removed in the future. See
158 // https://github.com/rust-lang/rust/blob/master/library/std/src/env.rs#L866.
159 if ctx.RustModule().CrateName() == "std" {
160 envVars = append(envVars, "STD_ENV_ARCH="+config.StdEnvArch[ctx.RustModule().Arch().ArchType])
161 }
162
163 if len(deps.SrcDeps) > 0 {
164 moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
165 // We must calculate an absolute path for OUT_DIR since Rust's include! macro (which normally consumes this)
166 // assumes that paths are relative to the source file.
Sam Delmericoa588d152023-06-16 10:28:04 -0400167 var outDir string
168 if filepath.IsAbs(moduleGenDir.String()) {
Dan Albert06feee92021-03-19 15:06:02 -0700169 // If OUT_DIR is absolute, then moduleGenDir will be an absolute path, so we don't need to set this to anything.
Sam Delmericoa588d152023-06-16 10:28:04 -0400170 outDir = moduleGenDir.String()
171 } else if moduleGenDir.Valid() {
172 // If OUT_DIR is not absolute, we use $$PWD to generate an absolute path (os.Getwd() returns '/')
173 outDir = filepath.Join("$$PWD/", cmd.PathForInput(moduleGenDir.Path()))
174 } else {
175 outDir = "$$PWD/"
Dan Albert06feee92021-03-19 15:06:02 -0700176 }
Sam Delmericoa588d152023-06-16 10:28:04 -0400177 envVars = append(envVars, "OUT_DIR="+outDir)
Peter Collingbourne0dcd62e2023-03-31 23:05:16 -0700178 } else {
179 // TODO(pcc): Change this to "OUT_DIR=" after fixing crates to not rely on this value.
180 envVars = append(envVars, "OUT_DIR=out")
Dan Albert06feee92021-03-19 15:06:02 -0700181 }
182
Matthew Maurer34609fa2023-06-26 21:10:13 +0000183 envVars = append(envVars, "ANDROID_RUST_VERSION="+config.GetRustVersion(ctx))
184
185 if ctx.RustModule().compiler.CargoEnvCompat() {
186 if bin, ok := ctx.RustModule().compiler.(*binaryDecorator); ok {
187 envVars = append(envVars, "CARGO_BIN_NAME="+bin.getStem(ctx))
188 }
189 envVars = append(envVars, "CARGO_CRATE_NAME="+ctx.RustModule().CrateName())
190 envVars = append(envVars, "CARGO_PKG_NAME="+ctx.RustModule().CrateName())
191 pkgVersion := ctx.RustModule().compiler.CargoPkgVersion()
192 if pkgVersion != "" {
193 envVars = append(envVars, "CARGO_PKG_VERSION="+pkgVersion)
Ivan Lozanof4455622023-07-28 12:42:20 -0400194
195 // Ensure the version is in the form of "x.y.z" (approximately semver compliant).
196 //
197 // For our purposes, we don't care to enforce that these are integers since they may
198 // include other characters at times (e.g. sometimes the patch version is more than an integer).
199 if strings.Count(pkgVersion, ".") == 2 {
200 var semver_parts = strings.Split(pkgVersion, ".")
201 envVars = append(envVars, "CARGO_PKG_VERSION_MAJOR="+semver_parts[0])
202 envVars = append(envVars, "CARGO_PKG_VERSION_MINOR="+semver_parts[1])
203 envVars = append(envVars, "CARGO_PKG_VERSION_PATCH="+semver_parts[2])
204 }
Matthew Maurer34609fa2023-06-26 21:10:13 +0000205 }
206 }
207
Sam Delmerico476e8762023-09-21 06:21:21 +0000208 envVars = append(envVars, "AR="+cmd.PathForInput(
209 cc_config.ClangPath(ctx, "bin/llvm-ar")),
210 )
Matthew Maurer34609fa2023-06-26 21:10:13 +0000211
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700212 if ctx.Darwin() {
213 envVars = append(envVars, "ANDROID_RUST_DARWIN=true")
214 }
215
Dan Albert06feee92021-03-19 15:06:02 -0700216 return envVars
217}
218
Sam Delmericoa588d152023-06-16 10:28:04 -0400219func transformSrctoCrate(ctx ModuleContext, comp compiler, main android.Path, deps PathDeps, flags Flags,
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400220 outputFile android.WritablePath, crateType string) buildOutput {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700221
222 var inputs android.Paths
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400223 var output buildOutput
Dan Albert06feee92021-03-19 15:06:02 -0700224 var rustcFlags, linkFlags []string
Sam Delmericoa588d152023-06-16 10:28:04 -0400225 var earlyLinkFlags []string
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400226
227 output.outputFile = outputFile
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800228 crateName := ctx.RustModule().CrateName()
ThiƩbaud Weksteen1f7f70f2020-06-24 11:32:48 +0200229 targetTriple := ctx.toolchain().RustTriple()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700230
231 inputs = append(inputs, main)
232
233 // Collect rustc flags
Ivan Lozanof1c84332019-09-20 11:00:37 -0700234 rustcFlags = append(rustcFlags, flags.GlobalRustFlags...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700235 rustcFlags = append(rustcFlags, flags.RustFlags...)
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400236 rustcFlags = append(rustcFlags, "--crate-type="+crateType)
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800237 if crateName != "" {
238 rustcFlags = append(rustcFlags, "--crate-name="+crateName)
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700239 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700240 if targetTriple != "" {
241 rustcFlags = append(rustcFlags, "--target="+targetTriple)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700242 linkFlags = append(linkFlags, "-target "+targetTriple)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700243 }
Matthew Maurerbb3add12020-06-25 09:34:12 -0700244
245 // Suppress an implicit sysroot
246 rustcFlags = append(rustcFlags, "--sysroot=/dev/null")
247
Chris Wailesd9781fd2021-12-03 17:17:28 -0800248 // Enable incremental compilation if requested by user
249 if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
250 incrementalPath := android.PathForOutput(ctx, "rustc").String()
Chris Wailes6d12db42023-02-24 16:58:18 -0800251 rustcFlags = append(rustcFlags, "-Cincremental="+incrementalPath)
252 }
253
254 // Disallow experimental features
255 modulePath := android.PathForModuleSrc(ctx).String()
256 if !(android.IsThirdPartyPath(modulePath) || strings.HasPrefix(modulePath, "prebuilts")) {
Chris Wailes547bfdd2023-05-31 11:53:44 -0700257 rustcFlags = append(rustcFlags, "-Zallow-features=\"\"")
Chris Wailesd9781fd2021-12-03 17:17:28 -0800258 }
259
Ivan Lozanof1c84332019-09-20 11:00:37 -0700260 // Collect linker flags
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700261 if !ctx.Darwin() {
Sam Delmericoa588d152023-06-16 10:28:04 -0400262 earlyLinkFlags = append(earlyLinkFlags, "-Wl,--as-needed")
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700263 }
264
Ivan Lozanoffee3342019-08-27 12:03:00 -0700265 // Collect dependencies
Sam Delmericoa588d152023-06-16 10:28:04 -0400266 var linkImplicits android.Paths
267 implicits := collectImplicits(deps)
268 toolImplicits := android.Concat(deps.BuildToolDeps)
Peter Collingbournee7c71c32023-03-31 20:21:19 -0700269 linkImplicits = append(linkImplicits, deps.CrtBegin...)
270 linkImplicits = append(linkImplicits, deps.CrtEnd...)
Sam Delmericoa588d152023-06-16 10:28:04 -0400271 implicits = append(implicits, comp.compilationSourcesAndData(ctx)...)
Sam Delmerico51d6d1c2023-03-28 16:54:00 -0400272
Ivan Lozano43845682020-07-09 21:03:28 -0400273 if len(deps.SrcDeps) > 0 {
ThiƩbaud Weksteenee6a89b2021-02-25 16:30:57 +0100274 moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
Ivan Lozano43845682020-07-09 21:03:28 -0400275 var outputs android.WritablePaths
276
277 for _, genSrc := range deps.SrcDeps {
Ivan Lozano10735d92020-07-22 09:14:47 -0400278 if android.SuffixInList(outputs.Strings(), genSubDir+genSrc.Base()) {
Ivan Lozano43845682020-07-09 21:03:28 -0400279 ctx.PropertyErrorf("srcs",
280 "multiple source providers generate the same filename output: "+genSrc.Base())
281 }
Ivan Lozano10735d92020-07-22 09:14:47 -0400282 outputs = append(outputs, android.PathForModuleOut(ctx, genSubDir+genSrc.Base()))
Ivan Lozano43845682020-07-09 21:03:28 -0400283 }
284
285 ctx.Build(pctx, android.BuildParams{
Sam Delmericoa588d152023-06-16 10:28:04 -0400286 Rule: cpDir,
ThiƩbaud Weksteenee6a89b2021-02-25 16:30:57 +0100287 Description: "cp " + moduleGenDir.Path().Rel(),
Ivan Lozano43845682020-07-09 21:03:28 -0400288 Outputs: outputs,
289 Inputs: deps.SrcDeps,
290 Args: map[string]string{
291 "outDir": moduleGenDir.String(),
292 },
293 })
294 implicits = append(implicits, outputs.Paths()...)
Ivan Lozano43845682020-07-09 21:03:28 -0400295 }
296
Ivan Lozanobae62be2020-07-21 13:28:27 -0400297 if flags.Clippy {
Sam Delmericoa588d152023-06-16 10:28:04 -0400298 clippyRule := getRuleBuilder(ctx, pctx, false, "clippy")
299 clippyCmd := clippyRule.Command()
Ivan Lozanobae62be2020-07-21 13:28:27 -0400300 clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
Sam Delmericoa588d152023-06-16 10:28:04 -0400301 clippyDepInfoFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy.d.raw")
302 clippyDepFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy.d")
303
304 clippyCmd.
305 Flags(rustEnvVars(ctx, deps, clippyCmd)).
Sam Delmerico476e8762023-09-21 06:21:21 +0000306 Tool(config.RustPath(ctx, "bin/clippy-driver")).
Sam Delmericoa588d152023-06-16 10:28:04 -0400307 Flag("--emit metadata").
308 FlagWithOutput("-o ", clippyFile).
309 FlagWithOutput("--emit dep-info=", clippyDepInfoFile).
310 Inputs(inputs).
311 Flags(makeLibFlags(deps, clippyCmd)).
312 Flags(rustcFlags).
313 Flags(flags.ClippyFlags).
314 ImplicitTools(toolImplicits).
315 Implicits(implicits)
316
317 depfileCreationCmd := clippyRule.Command()
318 depfileCreationCmd.
319 Flag(fmt.Sprintf(
320 `grep "^%s:" %s >`,
321 depfileCreationCmd.PathForOutput(clippyFile),
322 depfileCreationCmd.PathForOutput(clippyDepInfoFile),
323 )).
324 DepFile(clippyDepFile)
325
326 clippyRule.BuildWithUnescapedNinjaVars("clippy", "clippy "+main.Rel())
327
Ivan Lozanobae62be2020-07-21 13:28:27 -0400328 // Declare the clippy build as an implicit dependency of the original crate.
329 implicits = append(implicits, clippyFile)
330 }
331
Sam Delmericoa588d152023-06-16 10:28:04 -0400332 sboxDirectory := "rustc"
333 rustSboxOutputFile := android.PathForModuleOut(ctx, sboxDirectory, outputFile.Base())
334 depFile := android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".d")
335 depInfoFile := android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".d.raw")
336 var rustcImplicitOutputs android.WritablePaths
337
338 sandboxedCompilation := comp.crateRoot(ctx) != nil
339 rustcRule := getRuleBuilder(ctx, pctx, sandboxedCompilation, sboxDirectory)
340 rustcCmd := rustcRule.Command()
341
342 linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
343 linkFlags = append(linkFlags, flags.LinkFlags...)
344 linkFlags = append(linkFlags, rustcCmd.PathsForInputs(deps.linkObjects)...)
345
346 // Check if this module needs to use the bootstrap linker
347 if ctx.RustModule().Bootstrap() && !ctx.RustModule().InRecovery() && !ctx.RustModule().InRamdisk() && !ctx.RustModule().InVendorRamdisk() {
348 dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
349 if ctx.toolchain().Is64Bit() {
350 dynamicLinker += "64"
351 }
352 linkFlags = append(linkFlags, dynamicLinker)
353 }
354
355 libFlags := makeLibFlags(deps, rustcCmd)
356
Peter Collingbournee7c71c32023-03-31 20:21:19 -0700357 usesLinker := crateType == "bin" || crateType == "dylib" || crateType == "cdylib" || crateType == "proc-macro"
358 if usesLinker {
Sam Delmericoa588d152023-06-16 10:28:04 -0400359 rustSboxOutputFile = android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".rsp")
360 rustcImplicitOutputs = android.WritablePaths{
361 android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".whole.a"),
362 android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".a"),
363 }
Peter Collingbournee7c71c32023-03-31 20:21:19 -0700364 }
365
Sam Delmerico476e8762023-09-21 06:21:21 +0000366 clangTools := android.Paths{
367 cc_config.ClangPath(ctx, "bin/llvm-ar"),
368 }
369 if ctx.Config().BuildOS != android.Darwin {
370 clangTools = append(clangTools,
371 cc_config.ClangPath(ctx, "lib/libc++.so"),
372 )
Sam Delmericoa588d152023-06-16 10:28:04 -0400373 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700374
Sam Delmericoa588d152023-06-16 10:28:04 -0400375 rustcCmd.
376 Flags(rustEnvVars(ctx, deps, rustcCmd)).
Sam Delmerico476e8762023-09-21 06:21:21 +0000377 Tool(config.RustPath(ctx, "bin/rustc")).
Sam Delmericoa588d152023-06-16 10:28:04 -0400378 FlagWithInput("-C linker=", android.PathForSource(ctx, "build", "soong", "scripts", "mkcratersp.py")).
379 Flag("--emit link").
380 Flag("-o").
381 Output(rustSboxOutputFile).
382 FlagWithOutput("--emit dep-info=", depInfoFile).
383 Inputs(inputs).
384 Flags(libFlags).
Sam Delmerico476e8762023-09-21 06:21:21 +0000385 Implicits(clangTools).
Sam Delmericoa588d152023-06-16 10:28:04 -0400386 ImplicitTools(toolImplicits).
387 Implicits(implicits).
388 Flags(rustcFlags).
389 ImplicitOutputs(rustcImplicitOutputs)
390
391 depfileCreationCmd := rustcRule.Command()
392 depfileCreationCmd.
393 Flag(fmt.Sprintf(
394 `grep "^%s:" %s >`,
395 depfileCreationCmd.PathForOutput(rustSboxOutputFile),
396 depfileCreationCmd.PathForOutput(depInfoFile),
397 )).
398 DepFile(depFile)
399
400 if !usesLinker {
Peter Collingbournee7c71c32023-03-31 20:21:19 -0700401 ctx.Build(pctx, android.BuildParams{
Sam Delmericoa588d152023-06-16 10:28:04 -0400402 Rule: cp,
403 Input: rustSboxOutputFile,
404 Output: outputFile,
405 })
406 } else {
407 // TODO: delmerico - separate rustLink into its own rule
408 // mkcratersp.py hardcodes paths to files within the sandbox, so
409 // those need to be renamed/symlinked to something in the rustLink sandbox
410 // if we want to separate the rules
411 linkerSboxOutputFile := android.PathForModuleOut(ctx, sboxDirectory, outputFile.Base())
Sam Delmerico476e8762023-09-21 06:21:21 +0000412 clangTools := android.Paths{
413 cc_config.ClangPath(ctx, "bin/clang++"),
414 cc_config.ClangPath(ctx, "bin/lld"),
415 cc_config.ClangPath(ctx, "bin/ld.lld"),
416 }
417 if ctx.Config().BuildOS != android.Darwin {
418 clangTools = append(clangTools,
419 cc_config.ClangPath(ctx, "bin/clang++.real"),
420 cc_config.ClangPath(ctx, "lib/libc++.so"),
421 )
422 }
Sam Delmericoa588d152023-06-16 10:28:04 -0400423 rustLinkCmd := rustcRule.Command()
424 rustLinkCmd.
Sam Delmerico476e8762023-09-21 06:21:21 +0000425 Tool(cc_config.ClangPath(ctx, "bin/clang++")).
Sam Delmericoa588d152023-06-16 10:28:04 -0400426 Flag("-o").
427 Output(linkerSboxOutputFile).
428 Inputs(deps.CrtBegin).
429 Flags(earlyLinkFlags).
430 FlagWithInput("@", rustSboxOutputFile).
431 Flags(linkFlags).
432 Inputs(deps.CrtEnd).
Sam Delmerico476e8762023-09-21 06:21:21 +0000433 ImplicitTools(clangTools).
Sam Delmericoa588d152023-06-16 10:28:04 -0400434 ImplicitTools(toolImplicits).
435 Implicits(rustcImplicitOutputs.Paths()).
436 Implicits(implicits).
437 Implicits(linkImplicits)
438 ctx.Build(pctx, android.BuildParams{
439 Rule: cp,
440 Input: linkerSboxOutputFile,
441 Output: outputFile,
Peter Collingbournee7c71c32023-03-31 20:21:19 -0700442 })
443 }
444
Sam Delmericoa588d152023-06-16 10:28:04 -0400445 rustcRule.BuildWithUnescapedNinjaVars("rustc", "rustc "+main.Rel())
446
Sasha Smundaka76acba2022-04-18 20:12:56 -0700447 if flags.EmitXrefs {
Sam Delmericoa588d152023-06-16 10:28:04 -0400448 kytheRule := getRuleBuilder(ctx, pctx, false, "kythe")
449 kytheCmd := kytheRule.Command()
Sasha Smundaka76acba2022-04-18 20:12:56 -0700450 kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip")
Sam Delmericoa588d152023-06-16 10:28:04 -0400451 kytheCmd.
452 Flag("KYTHE_CORPUS=${kytheCorpus}").
453 FlagWithOutput("KYTHE_OUTPUT_FILE=", kytheFile).
454 FlagWithInput("KYTHE_VNAMES=", android.PathForSource(ctx, "build", "soong", "vnames.json")).
455 Flag("KYTHE_KZIP_ENCODING=${kytheCuEncoding}").
456 Flag("KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative").
457 Tool(ctx.Config().PrebuiltBuildTool(ctx, "rust_extractor")).
458 Flags(rustEnvVars(ctx, deps, kytheCmd)).
Sam Delmerico476e8762023-09-21 06:21:21 +0000459 Tool(config.RustPath(ctx, "bin/rustc")).
Sam Delmericoa588d152023-06-16 10:28:04 -0400460 Flag("-C linker=true").
461 Inputs(inputs).
462 Flags(makeLibFlags(deps, kytheCmd)).
463 Flags(rustcFlags).
464 ImplicitTools(toolImplicits).
465 Implicits(implicits)
466 kytheRule.BuildWithUnescapedNinjaVars("kythe", "Xref Rust extractor "+main.Rel())
Sasha Smundaka76acba2022-04-18 20:12:56 -0700467 output.kytheFile = kytheFile
468 }
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400469 return output
470}
Dan Albert06feee92021-03-19 15:06:02 -0700471
Sam Delmericoa588d152023-06-16 10:28:04 -0400472func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags) android.ModuleOutPath {
Sam Delmericoa588d152023-06-16 10:28:04 -0400473 rustdocRule := getRuleBuilder(ctx, pctx, false, "rustdoc")
474 rustdocCmd := rustdocRule.Command()
Dan Albert06feee92021-03-19 15:06:02 -0700475
476 rustdocFlags := append([]string{}, flags.RustdocFlags...)
477 rustdocFlags = append(rustdocFlags, "--sysroot=/dev/null")
478
Dan Albertb433bf72021-04-27 17:12:02 -0700479 // Build an index for all our crates. -Z unstable options is required to use
480 // this flag.
481 rustdocFlags = append(rustdocFlags, "-Z", "unstable-options", "--enable-index-page")
482
Dan Albert06feee92021-03-19 15:06:02 -0700483 targetTriple := ctx.toolchain().RustTriple()
484
485 // Collect rustc flags
486 if targetTriple != "" {
487 rustdocFlags = append(rustdocFlags, "--target="+targetTriple)
488 }
489
490 crateName := ctx.RustModule().CrateName()
Dan Albertb433bf72021-04-27 17:12:02 -0700491 rustdocFlags = append(rustdocFlags, "--crate-name "+crateName)
Dan Albert06feee92021-03-19 15:06:02 -0700492
Sam Delmericoa588d152023-06-16 10:28:04 -0400493 rustdocFlags = append(rustdocFlags, makeLibFlags(deps, rustdocCmd)...)
Dan Albert06feee92021-03-19 15:06:02 -0700494 docTimestampFile := android.PathForModuleOut(ctx, "rustdoc.timestamp")
Dan Albertb433bf72021-04-27 17:12:02 -0700495
Chris Wailesb2703ad2021-07-30 13:25:42 -0700496 // Silence warnings about renamed lints for third-party crates
497 modulePath := android.PathForModuleSrc(ctx).String()
498 if android.IsThirdPartyPath(modulePath) {
Chris Wailes7b3eb242023-02-14 16:09:49 -0800499 rustdocFlags = append(rustdocFlags, " -A warnings")
Chris Wailesb2703ad2021-07-30 13:25:42 -0700500 }
Chris Wailes9953a192021-07-28 12:07:16 -0700501
Dan Albertb433bf72021-04-27 17:12:02 -0700502 // Yes, the same out directory is used simultaneously by all rustdoc builds.
503 // This is what cargo does. The docs for individual crates get generated to
504 // a subdirectory named for the crate, and rustdoc synchronizes writes to
505 // shared pieces like the index and search data itself.
506 // https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/render/write_shared.rs#L144-L146
507 docDir := android.PathForOutput(ctx, "rustdoc")
Dan Albert06feee92021-03-19 15:06:02 -0700508
Sam Delmericoa588d152023-06-16 10:28:04 -0400509 rustdocCmd.
510 Flags(rustEnvVars(ctx, deps, rustdocCmd)).
Sam Delmerico476e8762023-09-21 06:21:21 +0000511 Tool(config.RustPath(ctx, "bin/rustdoc")).
Sam Delmericoa588d152023-06-16 10:28:04 -0400512 Flags(rustdocFlags).
513 Input(main).
514 Flag("-o "+docDir.String()).
515 FlagWithOutput("&& touch ", docTimestampFile).
516 Implicit(ctx.RustModule().UnstrippedOutputFile())
Dan Albert06feee92021-03-19 15:06:02 -0700517
Sam Delmericoa588d152023-06-16 10:28:04 -0400518 rustdocRule.BuildWithUnescapedNinjaVars("rustdoc", "rustdoc "+main.Rel())
Dan Albert06feee92021-03-19 15:06:02 -0700519 return docTimestampFile
520}
Sam Delmericoa588d152023-06-16 10:28:04 -0400521
522func getRuleBuilder(ctx android.ModuleContext, pctx android.PackageContext, sbox bool, sboxDirectory string) *android.RuleBuilder {
523 r := android.NewRuleBuilder(pctx, ctx)
524 if sbox {
525 r = r.Sbox(
526 android.PathForModuleOut(ctx, sboxDirectory),
527 android.PathForModuleOut(ctx, sboxDirectory+".sbox.textproto"),
528 ).SandboxInputs()
529 }
530 return r
531}