blob: 07405183ea90f2a8be561321d48c3439a146b326 [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"
ThiƩbaud Weksteen71512f32020-11-03 15:17:51 +010025 "android/soong/rust/config"
Ivan Lozanoffee3342019-08-27 12:03:00 -070026)
27
28var (
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -040029 zip = pctx.AndroidStaticRule("zip",
30 blueprint.RuleParams{
31 Command: "cat $out.rsp | tr ' ' '\\n' | tr -d \\' | sort -u > ${out}.tmp && ${SoongZipCmd} -o ${out} -C $$OUT_DIR -l ${out}.tmp",
32 CommandDeps: []string{"${SoongZipCmd}"},
33 Rspfile: "$out.rsp",
34 RspfileContent: "$in",
35 })
Ivan Lozano43845682020-07-09 21:03:28 -040036
Sam Delmericoa588d152023-06-16 10:28:04 -040037 cpDir = pctx.AndroidStaticRule("cpDir",
Ivan Lozano43845682020-07-09 21:03:28 -040038 blueprint.RuleParams{
39 Command: "cp `cat $outDir.rsp` $outDir",
40 Rspfile: "${outDir}.rsp",
41 RspfileContent: "$in",
42 },
43 "outDir")
Sasha Smundaka76acba2022-04-18 20:12:56 -070044
Sam Delmericoa588d152023-06-16 10:28:04 -040045 cp = pctx.AndroidStaticRule("cp",
46 blueprint.RuleParams{
47 Command: "rm -f $out && cp $in $out",
48 Description: "cp $out",
49 })
50
Sasha Smundaka76acba2022-04-18 20:12:56 -070051 // Cross-referencing:
52 _ = pctx.SourcePathVariable("rustExtractor",
53 "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/rust_extractor")
54 _ = pctx.VariableFunc("kytheCorpus",
55 func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
56 _ = pctx.VariableFunc("kytheCuEncoding",
57 func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
Ivan Lozanoffee3342019-08-27 12:03:00 -070058)
59
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -040060type buildOutput struct {
Joel Galensonfa049382021-01-14 16:03:18 -080061 outputFile android.Path
Sasha Smundaka76acba2022-04-18 20:12:56 -070062 kytheFile android.Path
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -040063}
Ivan Lozanoffee3342019-08-27 12:03:00 -070064
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -040065func init() {
66 pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
Ivan Lozanoffee3342019-08-27 12:03:00 -070067}
68
Sam Delmericoa588d152023-06-16 10:28:04 -040069func TransformSrcToBinary(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -070070 outputFile android.WritablePath) buildOutput {
Pirama Arumuga Nainarf77913f2021-10-25 15:37:43 -070071 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
Ivan Lozano31b095d2019-11-20 10:14:33 -080072
Sam Delmericoa588d152023-06-16 10:28:04 -040073 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "bin")
Ivan Lozanoffee3342019-08-27 12:03:00 -070074}
75
Sam Delmericoa588d152023-06-16 10:28:04 -040076func TransformSrctoRlib(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -070077 outputFile android.WritablePath) buildOutput {
Sam Delmericoa588d152023-06-16 10:28:04 -040078 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "rlib")
Ivan Lozanoffee3342019-08-27 12:03:00 -070079}
80
Sam Delmericoa588d152023-06-16 10:28:04 -040081func TransformSrctoDylib(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -070082 outputFile android.WritablePath) buildOutput {
Chris Wailes5f788402023-03-02 16:06:01 -080083 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
84
Sam Delmericoa588d152023-06-16 10:28:04 -040085 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "dylib")
Ivan Lozanoffee3342019-08-27 12:03:00 -070086}
87
Sam Delmericoa588d152023-06-16 10:28:04 -040088func TransformSrctoStatic(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -070089 outputFile android.WritablePath) buildOutput {
Pirama Arumuga Nainarf77913f2021-10-25 15:37:43 -070090 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
Sam Delmericoa588d152023-06-16 10:28:04 -040091 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "staticlib")
Ivan Lozano52767be2019-10-18 14:49:46 -070092}
93
Sam Delmericoa588d152023-06-16 10:28:04 -040094func TransformSrctoShared(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -070095 outputFile android.WritablePath) buildOutput {
Pirama Arumuga Nainarf77913f2021-10-25 15:37:43 -070096 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
Sam Delmericoa588d152023-06-16 10:28:04 -040097 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "cdylib")
Ivan Lozano52767be2019-10-18 14:49:46 -070098}
99
Sam Delmericoa588d152023-06-16 10:28:04 -0400100func TransformSrctoProcMacro(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps,
Dan Albert06feee92021-03-19 15:06:02 -0700101 flags Flags, outputFile android.WritablePath) buildOutput {
Sam Delmericoa588d152023-06-16 10:28:04 -0400102 return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "proc-macro")
Ivan Lozanoffee3342019-08-27 12:03:00 -0700103}
104
105func rustLibsToPaths(libs RustLibraries) android.Paths {
106 var paths android.Paths
107 for _, lib := range libs {
108 paths = append(paths, lib.Path)
109 }
110 return paths
111}
112
Sam Delmericoa588d152023-06-16 10:28:04 -0400113func makeLibFlags(deps PathDeps, ruleCmd *android.RuleBuilderCommand) []string {
Dan Albert06feee92021-03-19 15:06:02 -0700114 var libFlags []string
115
116 // Collect library/crate flags
Sam Delmericoa588d152023-06-16 10:28:04 -0400117 for _, lib := range deps.Rlibs.ToListDirect() {
118 libPath := ruleCmd.PathForInput(lib.Path)
119 libFlags = append(libFlags, "--extern "+lib.CrateName+"="+libPath)
Dan Albert06feee92021-03-19 15:06:02 -0700120 }
Sam Delmericoa588d152023-06-16 10:28:04 -0400121 for _, lib := range deps.Dylibs.ToListDirect() {
122 libPath := ruleCmd.PathForInput(lib.Path)
123 libFlags = append(libFlags, "--extern "+lib.CrateName+"="+libPath)
Dan Albert06feee92021-03-19 15:06:02 -0700124 }
Sam Delmericoa588d152023-06-16 10:28:04 -0400125 for _, procMacro := range deps.ProcMacros.ToListDirect() {
126 procMacroPath := ruleCmd.PathForInput(procMacro.Path)
127 libFlags = append(libFlags, "--extern "+procMacro.CrateName+"="+procMacroPath)
Dan Albert06feee92021-03-19 15:06:02 -0700128 }
129
130 for _, path := range deps.linkDirs {
Sam Delmericoa588d152023-06-16 10:28:04 -0400131 libFlags = append(libFlags, "-L "+ruleCmd.PathForInput(path))
Dan Albert06feee92021-03-19 15:06:02 -0700132 }
133
134 return libFlags
135}
136
Sam Delmericoa588d152023-06-16 10:28:04 -0400137func collectImplicits(deps PathDeps) android.Paths {
138 depPaths := android.Paths{}
139 depPaths = append(depPaths, rustLibsToPaths(deps.Rlibs.ToList())...)
140 depPaths = append(depPaths, rustLibsToPaths(deps.Dylibs.ToList())...)
141 depPaths = append(depPaths, rustLibsToPaths(deps.ProcMacros.ToList())...)
142 depPaths = append(depPaths, deps.AfdoProfiles...)
143 depPaths = append(depPaths, deps.WholeStaticLibs...)
144 depPaths = append(depPaths, deps.SrcDeps...)
145 depPaths = append(depPaths, deps.srcProviderFiles...)
146 depPaths = append(depPaths, deps.LibDeps...)
147 depPaths = append(depPaths, deps.linkObjects...)
148 depPaths = append(depPaths, deps.BuildToolSrcDeps...)
149 return depPaths
150}
151
152func rustEnvVars(ctx ModuleContext, deps PathDeps, cmd *android.RuleBuilderCommand) []string {
Dan Albert06feee92021-03-19 15:06:02 -0700153 var envVars []string
154
155 // libstd requires a specific environment variable to be set. This is
156 // not officially documented and may be removed in the future. See
157 // https://github.com/rust-lang/rust/blob/master/library/std/src/env.rs#L866.
158 if ctx.RustModule().CrateName() == "std" {
159 envVars = append(envVars, "STD_ENV_ARCH="+config.StdEnvArch[ctx.RustModule().Arch().ArchType])
160 }
161
162 if len(deps.SrcDeps) > 0 {
163 moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
164 // We must calculate an absolute path for OUT_DIR since Rust's include! macro (which normally consumes this)
165 // assumes that paths are relative to the source file.
Sam Delmericoa588d152023-06-16 10:28:04 -0400166 var outDir string
167 if filepath.IsAbs(moduleGenDir.String()) {
Dan Albert06feee92021-03-19 15:06:02 -0700168 // 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 -0400169 outDir = moduleGenDir.String()
170 } else if moduleGenDir.Valid() {
171 // If OUT_DIR is not absolute, we use $$PWD to generate an absolute path (os.Getwd() returns '/')
172 outDir = filepath.Join("$$PWD/", cmd.PathForInput(moduleGenDir.Path()))
173 } else {
174 outDir = "$$PWD/"
Dan Albert06feee92021-03-19 15:06:02 -0700175 }
Sam Delmericoa588d152023-06-16 10:28:04 -0400176 envVars = append(envVars, "OUT_DIR="+outDir)
Peter Collingbourne0dcd62e2023-03-31 23:05:16 -0700177 } else {
178 // TODO(pcc): Change this to "OUT_DIR=" after fixing crates to not rely on this value.
179 envVars = append(envVars, "OUT_DIR=out")
Dan Albert06feee92021-03-19 15:06:02 -0700180 }
181
Matthew Maurer34609fa2023-06-26 21:10:13 +0000182 envVars = append(envVars, "ANDROID_RUST_VERSION="+config.GetRustVersion(ctx))
183
184 if ctx.RustModule().compiler.CargoEnvCompat() {
185 if bin, ok := ctx.RustModule().compiler.(*binaryDecorator); ok {
186 envVars = append(envVars, "CARGO_BIN_NAME="+bin.getStem(ctx))
187 }
188 envVars = append(envVars, "CARGO_CRATE_NAME="+ctx.RustModule().CrateName())
189 envVars = append(envVars, "CARGO_PKG_NAME="+ctx.RustModule().CrateName())
190 pkgVersion := ctx.RustModule().compiler.CargoPkgVersion()
191 if pkgVersion != "" {
192 envVars = append(envVars, "CARGO_PKG_VERSION="+pkgVersion)
Ivan Lozanof4455622023-07-28 12:42:20 -0400193
194 // Ensure the version is in the form of "x.y.z" (approximately semver compliant).
195 //
196 // For our purposes, we don't care to enforce that these are integers since they may
197 // include other characters at times (e.g. sometimes the patch version is more than an integer).
198 if strings.Count(pkgVersion, ".") == 2 {
199 var semver_parts = strings.Split(pkgVersion, ".")
200 envVars = append(envVars, "CARGO_PKG_VERSION_MAJOR="+semver_parts[0])
201 envVars = append(envVars, "CARGO_PKG_VERSION_MINOR="+semver_parts[1])
202 envVars = append(envVars, "CARGO_PKG_VERSION_PATCH="+semver_parts[2])
203 }
Matthew Maurer34609fa2023-06-26 21:10:13 +0000204 }
205 }
206
Sam Delmericoa588d152023-06-16 10:28:04 -0400207 envVars = append(envVars, "AR="+cmd.PathForTool(deps.Llvm_ar))
Matthew Maurer34609fa2023-06-26 21:10:13 +0000208
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700209 if ctx.Darwin() {
210 envVars = append(envVars, "ANDROID_RUST_DARWIN=true")
211 }
212
Dan Albert06feee92021-03-19 15:06:02 -0700213 return envVars
214}
215
Sam Delmericoa588d152023-06-16 10:28:04 -0400216func transformSrctoCrate(ctx ModuleContext, comp compiler, main android.Path, deps PathDeps, flags Flags,
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400217 outputFile android.WritablePath, crateType string) buildOutput {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700218
219 var inputs android.Paths
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400220 var output buildOutput
Dan Albert06feee92021-03-19 15:06:02 -0700221 var rustcFlags, linkFlags []string
Sam Delmericoa588d152023-06-16 10:28:04 -0400222 var earlyLinkFlags []string
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400223
224 output.outputFile = outputFile
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800225 crateName := ctx.RustModule().CrateName()
ThiƩbaud Weksteen1f7f70f2020-06-24 11:32:48 +0200226 targetTriple := ctx.toolchain().RustTriple()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700227
228 inputs = append(inputs, main)
229
230 // Collect rustc flags
Ivan Lozanof1c84332019-09-20 11:00:37 -0700231 rustcFlags = append(rustcFlags, flags.GlobalRustFlags...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700232 rustcFlags = append(rustcFlags, flags.RustFlags...)
Ivan Lozano7b0781d2021-11-03 15:30:18 -0400233 rustcFlags = append(rustcFlags, "--crate-type="+crateType)
Jaewoong Jung18aefc12020-12-21 09:11:10 -0800234 if crateName != "" {
235 rustcFlags = append(rustcFlags, "--crate-name="+crateName)
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700236 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700237 if targetTriple != "" {
238 rustcFlags = append(rustcFlags, "--target="+targetTriple)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700239 linkFlags = append(linkFlags, "-target "+targetTriple)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700240 }
Matthew Maurerbb3add12020-06-25 09:34:12 -0700241
242 // Suppress an implicit sysroot
243 rustcFlags = append(rustcFlags, "--sysroot=/dev/null")
244
Chris Wailesd9781fd2021-12-03 17:17:28 -0800245 // Enable incremental compilation if requested by user
246 if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
247 incrementalPath := android.PathForOutput(ctx, "rustc").String()
Chris Wailes6d12db42023-02-24 16:58:18 -0800248 rustcFlags = append(rustcFlags, "-Cincremental="+incrementalPath)
249 }
250
251 // Disallow experimental features
252 modulePath := android.PathForModuleSrc(ctx).String()
253 if !(android.IsThirdPartyPath(modulePath) || strings.HasPrefix(modulePath, "prebuilts")) {
Chris Wailes547bfdd2023-05-31 11:53:44 -0700254 rustcFlags = append(rustcFlags, "-Zallow-features=\"\"")
Chris Wailesd9781fd2021-12-03 17:17:28 -0800255 }
256
Ivan Lozanof1c84332019-09-20 11:00:37 -0700257 // Collect linker flags
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700258 if !ctx.Darwin() {
Sam Delmericoa588d152023-06-16 10:28:04 -0400259 earlyLinkFlags = append(earlyLinkFlags, "-Wl,--as-needed")
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700260 }
261
Ivan Lozanoffee3342019-08-27 12:03:00 -0700262 // Collect dependencies
Sam Delmericoa588d152023-06-16 10:28:04 -0400263 var linkImplicits android.Paths
264 implicits := collectImplicits(deps)
265 toolImplicits := android.Concat(deps.BuildToolDeps)
Peter Collingbournee7c71c32023-03-31 20:21:19 -0700266 linkImplicits = append(linkImplicits, deps.CrtBegin...)
267 linkImplicits = append(linkImplicits, deps.CrtEnd...)
Sam Delmericoa588d152023-06-16 10:28:04 -0400268 implicits = append(implicits, comp.compilationSourcesAndData(ctx)...)
Sam Delmerico51d6d1c2023-03-28 16:54:00 -0400269
Ivan Lozano43845682020-07-09 21:03:28 -0400270 if len(deps.SrcDeps) > 0 {
ThiƩbaud Weksteenee6a89b2021-02-25 16:30:57 +0100271 moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
Ivan Lozano43845682020-07-09 21:03:28 -0400272 var outputs android.WritablePaths
273
274 for _, genSrc := range deps.SrcDeps {
Ivan Lozano10735d92020-07-22 09:14:47 -0400275 if android.SuffixInList(outputs.Strings(), genSubDir+genSrc.Base()) {
Ivan Lozano43845682020-07-09 21:03:28 -0400276 ctx.PropertyErrorf("srcs",
277 "multiple source providers generate the same filename output: "+genSrc.Base())
278 }
Ivan Lozano10735d92020-07-22 09:14:47 -0400279 outputs = append(outputs, android.PathForModuleOut(ctx, genSubDir+genSrc.Base()))
Ivan Lozano43845682020-07-09 21:03:28 -0400280 }
281
282 ctx.Build(pctx, android.BuildParams{
Sam Delmericoa588d152023-06-16 10:28:04 -0400283 Rule: cpDir,
ThiƩbaud Weksteenee6a89b2021-02-25 16:30:57 +0100284 Description: "cp " + moduleGenDir.Path().Rel(),
Ivan Lozano43845682020-07-09 21:03:28 -0400285 Outputs: outputs,
286 Inputs: deps.SrcDeps,
287 Args: map[string]string{
288 "outDir": moduleGenDir.String(),
289 },
290 })
291 implicits = append(implicits, outputs.Paths()...)
Ivan Lozano43845682020-07-09 21:03:28 -0400292 }
293
Ivan Lozanobae62be2020-07-21 13:28:27 -0400294 if flags.Clippy {
Sam Delmericoa588d152023-06-16 10:28:04 -0400295 // TODO(b/298461712) remove this hack to let slim manifest branches build
296 if deps.Clippy_driver == nil {
297 deps.Clippy_driver = config.RustPath(ctx, "bin/clippy-driver")
298 }
299
300 clippyRule := getRuleBuilder(ctx, pctx, false, "clippy")
301 clippyCmd := clippyRule.Command()
Ivan Lozanobae62be2020-07-21 13:28:27 -0400302 clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
Sam Delmericoa588d152023-06-16 10:28:04 -0400303 clippyDepInfoFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy.d.raw")
304 clippyDepFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy.d")
305
306 clippyCmd.
307 Flags(rustEnvVars(ctx, deps, clippyCmd)).
308 Tool(deps.Clippy_driver).
309 Flag("--emit metadata").
310 FlagWithOutput("-o ", clippyFile).
311 FlagWithOutput("--emit dep-info=", clippyDepInfoFile).
312 Inputs(inputs).
313 Flags(makeLibFlags(deps, clippyCmd)).
314 Flags(rustcFlags).
315 Flags(flags.ClippyFlags).
316 ImplicitTools(toolImplicits).
317 Implicits(implicits)
318
319 depfileCreationCmd := clippyRule.Command()
320 depfileCreationCmd.
321 Flag(fmt.Sprintf(
322 `grep "^%s:" %s >`,
323 depfileCreationCmd.PathForOutput(clippyFile),
324 depfileCreationCmd.PathForOutput(clippyDepInfoFile),
325 )).
326 DepFile(clippyDepFile)
327
328 clippyRule.BuildWithUnescapedNinjaVars("clippy", "clippy "+main.Rel())
329
Ivan Lozanobae62be2020-07-21 13:28:27 -0400330 // Declare the clippy build as an implicit dependency of the original crate.
331 implicits = append(implicits, clippyFile)
332 }
333
Sam Delmericoa588d152023-06-16 10:28:04 -0400334 sboxDirectory := "rustc"
335 rustSboxOutputFile := android.PathForModuleOut(ctx, sboxDirectory, outputFile.Base())
336 depFile := android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".d")
337 depInfoFile := android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".d.raw")
338 var rustcImplicitOutputs android.WritablePaths
339
340 sandboxedCompilation := comp.crateRoot(ctx) != nil
341 rustcRule := getRuleBuilder(ctx, pctx, sandboxedCompilation, sboxDirectory)
342 rustcCmd := rustcRule.Command()
343
344 linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
345 linkFlags = append(linkFlags, flags.LinkFlags...)
346 linkFlags = append(linkFlags, rustcCmd.PathsForInputs(deps.linkObjects)...)
347
348 // Check if this module needs to use the bootstrap linker
349 if ctx.RustModule().Bootstrap() && !ctx.RustModule().InRecovery() && !ctx.RustModule().InRamdisk() && !ctx.RustModule().InVendorRamdisk() {
350 dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
351 if ctx.toolchain().Is64Bit() {
352 dynamicLinker += "64"
353 }
354 linkFlags = append(linkFlags, dynamicLinker)
355 }
356
357 libFlags := makeLibFlags(deps, rustcCmd)
358
Peter Collingbournee7c71c32023-03-31 20:21:19 -0700359 usesLinker := crateType == "bin" || crateType == "dylib" || crateType == "cdylib" || crateType == "proc-macro"
360 if usesLinker {
Sam Delmericoa588d152023-06-16 10:28:04 -0400361 rustSboxOutputFile = android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".rsp")
362 rustcImplicitOutputs = android.WritablePaths{
363 android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".whole.a"),
364 android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".a"),
365 }
Peter Collingbournee7c71c32023-03-31 20:21:19 -0700366 }
367
Sam Delmericoa588d152023-06-16 10:28:04 -0400368 // TODO(b/298461712) remove this hack to let slim manifest branches build
369 if deps.Rustc == nil {
370 deps.Rustc = config.RustPath(ctx, "bin/rustc")
371 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700372
Sam Delmericoa588d152023-06-16 10:28:04 -0400373 rustcCmd.
374 Flags(rustEnvVars(ctx, deps, rustcCmd)).
375 Tool(deps.Rustc).
376 FlagWithInput("-C linker=", android.PathForSource(ctx, "build", "soong", "scripts", "mkcratersp.py")).
377 Flag("--emit link").
378 Flag("-o").
379 Output(rustSboxOutputFile).
380 FlagWithOutput("--emit dep-info=", depInfoFile).
381 Inputs(inputs).
382 Flags(libFlags).
383 ImplicitTools(toolImplicits).
384 Implicits(implicits).
385 Flags(rustcFlags).
386 ImplicitOutputs(rustcImplicitOutputs)
387
388 depfileCreationCmd := rustcRule.Command()
389 depfileCreationCmd.
390 Flag(fmt.Sprintf(
391 `grep "^%s:" %s >`,
392 depfileCreationCmd.PathForOutput(rustSboxOutputFile),
393 depfileCreationCmd.PathForOutput(depInfoFile),
394 )).
395 DepFile(depFile)
396
397 if !usesLinker {
Peter Collingbournee7c71c32023-03-31 20:21:19 -0700398 ctx.Build(pctx, android.BuildParams{
Sam Delmericoa588d152023-06-16 10:28:04 -0400399 Rule: cp,
400 Input: rustSboxOutputFile,
401 Output: outputFile,
402 })
403 } else {
404 // TODO: delmerico - separate rustLink into its own rule
405 // mkcratersp.py hardcodes paths to files within the sandbox, so
406 // those need to be renamed/symlinked to something in the rustLink sandbox
407 // if we want to separate the rules
408 linkerSboxOutputFile := android.PathForModuleOut(ctx, sboxDirectory, outputFile.Base())
409 rustLinkCmd := rustcRule.Command()
410 rustLinkCmd.
411 Tool(deps.Clang).
412 Flag("-o").
413 Output(linkerSboxOutputFile).
414 Inputs(deps.CrtBegin).
415 Flags(earlyLinkFlags).
416 FlagWithInput("@", rustSboxOutputFile).
417 Flags(linkFlags).
418 Inputs(deps.CrtEnd).
419 ImplicitTools(toolImplicits).
420 Implicits(rustcImplicitOutputs.Paths()).
421 Implicits(implicits).
422 Implicits(linkImplicits)
423 ctx.Build(pctx, android.BuildParams{
424 Rule: cp,
425 Input: linkerSboxOutputFile,
426 Output: outputFile,
Peter Collingbournee7c71c32023-03-31 20:21:19 -0700427 })
428 }
429
Sam Delmericoa588d152023-06-16 10:28:04 -0400430 rustcRule.BuildWithUnescapedNinjaVars("rustc", "rustc "+main.Rel())
431
Sasha Smundaka76acba2022-04-18 20:12:56 -0700432 if flags.EmitXrefs {
Sam Delmericoa588d152023-06-16 10:28:04 -0400433 kytheRule := getRuleBuilder(ctx, pctx, false, "kythe")
434 kytheCmd := kytheRule.Command()
Sasha Smundaka76acba2022-04-18 20:12:56 -0700435 kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip")
Sam Delmericoa588d152023-06-16 10:28:04 -0400436 kytheCmd.
437 Flag("KYTHE_CORPUS=${kytheCorpus}").
438 FlagWithOutput("KYTHE_OUTPUT_FILE=", kytheFile).
439 FlagWithInput("KYTHE_VNAMES=", android.PathForSource(ctx, "build", "soong", "vnames.json")).
440 Flag("KYTHE_KZIP_ENCODING=${kytheCuEncoding}").
441 Flag("KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative").
442 Tool(ctx.Config().PrebuiltBuildTool(ctx, "rust_extractor")).
443 Flags(rustEnvVars(ctx, deps, kytheCmd)).
444 Tool(deps.Rustc).
445 Flag("-C linker=true").
446 Inputs(inputs).
447 Flags(makeLibFlags(deps, kytheCmd)).
448 Flags(rustcFlags).
449 ImplicitTools(toolImplicits).
450 Implicits(implicits)
451 kytheRule.BuildWithUnescapedNinjaVars("kythe", "Xref Rust extractor "+main.Rel())
Sasha Smundaka76acba2022-04-18 20:12:56 -0700452 output.kytheFile = kytheFile
453 }
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400454 return output
455}
Dan Albert06feee92021-03-19 15:06:02 -0700456
Sam Delmericoa588d152023-06-16 10:28:04 -0400457func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags) android.ModuleOutPath {
458 // TODO(b/298461712) remove this hack to let slim manifest branches build
459 if deps.Rustdoc == nil {
460 deps.Rustdoc = config.RustPath(ctx, "bin/rustdoc")
461 }
462
463 rustdocRule := getRuleBuilder(ctx, pctx, false, "rustdoc")
464 rustdocCmd := rustdocRule.Command()
Dan Albert06feee92021-03-19 15:06:02 -0700465
466 rustdocFlags := append([]string{}, flags.RustdocFlags...)
467 rustdocFlags = append(rustdocFlags, "--sysroot=/dev/null")
468
Dan Albertb433bf72021-04-27 17:12:02 -0700469 // Build an index for all our crates. -Z unstable options is required to use
470 // this flag.
471 rustdocFlags = append(rustdocFlags, "-Z", "unstable-options", "--enable-index-page")
472
Dan Albert06feee92021-03-19 15:06:02 -0700473 targetTriple := ctx.toolchain().RustTriple()
474
475 // Collect rustc flags
476 if targetTriple != "" {
477 rustdocFlags = append(rustdocFlags, "--target="+targetTriple)
478 }
479
480 crateName := ctx.RustModule().CrateName()
Dan Albertb433bf72021-04-27 17:12:02 -0700481 rustdocFlags = append(rustdocFlags, "--crate-name "+crateName)
Dan Albert06feee92021-03-19 15:06:02 -0700482
Sam Delmericoa588d152023-06-16 10:28:04 -0400483 rustdocFlags = append(rustdocFlags, makeLibFlags(deps, rustdocCmd)...)
Dan Albert06feee92021-03-19 15:06:02 -0700484 docTimestampFile := android.PathForModuleOut(ctx, "rustdoc.timestamp")
Dan Albertb433bf72021-04-27 17:12:02 -0700485
Chris Wailesb2703ad2021-07-30 13:25:42 -0700486 // Silence warnings about renamed lints for third-party crates
487 modulePath := android.PathForModuleSrc(ctx).String()
488 if android.IsThirdPartyPath(modulePath) {
Chris Wailes7b3eb242023-02-14 16:09:49 -0800489 rustdocFlags = append(rustdocFlags, " -A warnings")
Chris Wailesb2703ad2021-07-30 13:25:42 -0700490 }
Chris Wailes9953a192021-07-28 12:07:16 -0700491
Dan Albertb433bf72021-04-27 17:12:02 -0700492 // Yes, the same out directory is used simultaneously by all rustdoc builds.
493 // This is what cargo does. The docs for individual crates get generated to
494 // a subdirectory named for the crate, and rustdoc synchronizes writes to
495 // shared pieces like the index and search data itself.
496 // https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/render/write_shared.rs#L144-L146
497 docDir := android.PathForOutput(ctx, "rustdoc")
Dan Albert06feee92021-03-19 15:06:02 -0700498
Sam Delmericoa588d152023-06-16 10:28:04 -0400499 rustdocCmd.
500 Flags(rustEnvVars(ctx, deps, rustdocCmd)).
501 Tool(deps.Rustdoc).
502 Flags(rustdocFlags).
503 Input(main).
504 Flag("-o "+docDir.String()).
505 FlagWithOutput("&& touch ", docTimestampFile).
506 Implicit(ctx.RustModule().UnstrippedOutputFile())
Dan Albert06feee92021-03-19 15:06:02 -0700507
Sam Delmericoa588d152023-06-16 10:28:04 -0400508 rustdocRule.BuildWithUnescapedNinjaVars("rustdoc", "rustdoc "+main.Rel())
Dan Albert06feee92021-03-19 15:06:02 -0700509 return docTimestampFile
510}
Sam Delmericoa588d152023-06-16 10:28:04 -0400511
512func getRuleBuilder(ctx android.ModuleContext, pctx android.PackageContext, sbox bool, sboxDirectory string) *android.RuleBuilder {
513 r := android.NewRuleBuilder(pctx, ctx)
514 if sbox {
515 r = r.Sbox(
516 android.PathForModuleOut(ctx, sboxDirectory),
517 android.PathForModuleOut(ctx, sboxDirectory+".sbox.textproto"),
518 ).SandboxInputs()
519 }
520 return r
521}