blob: 1ce92f4ec45ec1947ccaff36a9110e2f808770c9 [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 {
Ivan Lozanoab586472024-05-15 10:59:47 -0400161 if ctx.RustModule().compiler.Thinlto() {
162 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
163 }
Chris Wailes99180c22024-02-20 21:39:40 +0000164
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400165 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "bin"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700166}
167
Wen-yi Chu41326c12023-09-22 03:58:59 +0000168func TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700169 outputFile android.WritablePath) buildOutput {
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400170 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "rlib"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700171}
172
Ivan Lozano0a468a42024-05-13 21:03:34 -0400173func TransformRlibstoStaticlib(ctx android.ModuleContext, mainSrc android.Path, deps []cc.RustRlibDep,
174 outputFile android.WritablePath) android.Path {
175
176 var rustPathDeps PathDeps
177 var rustFlags Flags
178
179 for _, rlibDep := range deps {
180 rustPathDeps.RLibs = append(rustPathDeps.RLibs, RustLibrary{Path: rlibDep.LibPath, CrateName: rlibDep.CrateName})
181 rustPathDeps.linkDirs = append(rustPathDeps.linkDirs, rlibDep.LinkDirs...)
182 }
183
184 ccModule := ctx.(cc.ModuleContext).Module().(*cc.Module)
185 toolchain := config.FindToolchain(ctx.Os(), ctx.Arch())
186 t := transformProperties{
187 // Crate name can be a predefined value as this is a staticlib and
188 // it does not need to be unique. The crate name is used for name
189 // mangling, but it is mixed with the metadata for that purpose, which we
190 // already set to the module name.
191 crateName: "generated_rust_staticlib",
192 is64Bit: toolchain.Is64Bit(),
193 targetTriple: toolchain.RustTriple(),
194 bootstrap: ccModule.Bootstrap(),
195 inRecovery: ccModule.InRecovery(),
196 inRamdisk: ccModule.InRamdisk(),
197 inVendorRamdisk: ccModule.InVendorRamdisk(),
198
199 // crateType indicates what type of crate to build
200 crateType: "staticlib",
201
202 // synthetic indicates whether this is an actual Rust module or not
203 synthetic: true,
204 }
205
206 rustFlags = CommonDefaultFlags(ctx, toolchain, rustFlags)
207 rustFlags = CommonLibraryCompilerFlags(ctx, rustFlags)
208 rustFlags.GlobalRustFlags = append(rustFlags.GlobalRustFlags, "-C lto=thin")
209
210 rustFlags.EmitXrefs = false
211
212 return transformSrctoCrate(ctx, mainSrc, rustPathDeps, rustFlags, outputFile, t).outputFile
213}
214
Wen-yi Chu41326c12023-09-22 03:58:59 +0000215func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700216 outputFile android.WritablePath) buildOutput {
Ivan Lozanoab586472024-05-15 10:59:47 -0400217 if ctx.RustModule().compiler.Thinlto() {
218 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
219 }
Chris Wailes99180c22024-02-20 21:39:40 +0000220
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400221 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "dylib"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700222}
223
Wen-yi Chu41326c12023-09-22 03:58:59 +0000224func TransformSrctoStatic(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700225 outputFile android.WritablePath) buildOutput {
Ivan Lozanoab586472024-05-15 10:59:47 -0400226 if ctx.RustModule().compiler.Thinlto() {
227 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
228 }
229
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400230 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "staticlib"))
Ivan Lozano52767be2019-10-18 14:49:46 -0700231}
232
Wen-yi Chu41326c12023-09-22 03:58:59 +0000233func TransformSrctoShared(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
Dan Albert06feee92021-03-19 15:06:02 -0700234 outputFile android.WritablePath) buildOutput {
Ivan Lozanoab586472024-05-15 10:59:47 -0400235 if ctx.RustModule().compiler.Thinlto() {
236 flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
237 }
238
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400239 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "cdylib"))
Ivan Lozano52767be2019-10-18 14:49:46 -0700240}
241
Wen-yi Chu41326c12023-09-22 03:58:59 +0000242func TransformSrctoProcMacro(ctx ModuleContext, mainSrc android.Path, deps PathDeps,
Dan Albert06feee92021-03-19 15:06:02 -0700243 flags Flags, outputFile android.WritablePath) buildOutput {
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400244 return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, getTransformProperties(ctx, "proc-macro"))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700245}
246
247func rustLibsToPaths(libs RustLibraries) android.Paths {
248 var paths android.Paths
249 for _, lib := range libs {
250 paths = append(paths, lib.Path)
251 }
252 return paths
253}
254
Wen-yi Chu41326c12023-09-22 03:58:59 +0000255func makeLibFlags(deps PathDeps) []string {
Dan Albert06feee92021-03-19 15:06:02 -0700256 var libFlags []string
257
258 // Collect library/crate flags
Wen-yi Chu41326c12023-09-22 03:58:59 +0000259 for _, lib := range deps.RLibs {
260 libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
Dan Albert06feee92021-03-19 15:06:02 -0700261 }
Wen-yi Chu41326c12023-09-22 03:58:59 +0000262 for _, lib := range deps.DyLibs {
263 libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
Dan Albert06feee92021-03-19 15:06:02 -0700264 }
Wen-yi Chu41326c12023-09-22 03:58:59 +0000265 for _, proc_macro := range deps.ProcMacros {
266 libFlags = append(libFlags, "--extern "+proc_macro.CrateName+"="+proc_macro.Path.String())
Dan Albert06feee92021-03-19 15:06:02 -0700267 }
268
269 for _, path := range deps.linkDirs {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000270 libFlags = append(libFlags, "-L "+path)
Dan Albert06feee92021-03-19 15:06:02 -0700271 }
272
273 return libFlags
274}
275
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400276func rustEnvVars(ctx android.ModuleContext, deps PathDeps, crateName string, cargoOutDir android.OptionalPath) []string {
Dan Albert06feee92021-03-19 15:06:02 -0700277 var envVars []string
278
279 // libstd requires a specific environment variable to be set. This is
280 // not officially documented and may be removed in the future. See
281 // https://github.com/rust-lang/rust/blob/master/library/std/src/env.rs#L866.
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400282 if crateName == "std" {
283 envVars = append(envVars, "STD_ENV_ARCH="+config.StdEnvArch[ctx.Arch().ArchType])
Dan Albert06feee92021-03-19 15:06:02 -0700284 }
285
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400286 if len(deps.SrcDeps) > 0 && cargoOutDir.Valid() {
287 moduleGenDir := cargoOutDir
Dan Albert06feee92021-03-19 15:06:02 -0700288 // We must calculate an absolute path for OUT_DIR since Rust's include! macro (which normally consumes this)
289 // assumes that paths are relative to the source file.
Wen-yi Chu41326c12023-09-22 03:58:59 +0000290 var outDirPrefix string
291 if !filepath.IsAbs(moduleGenDir.String()) {
Sam Delmericoa588d152023-06-16 10:28:04 -0400292 // 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 +0000293 outDirPrefix = "$$PWD/"
Sam Delmericoa588d152023-06-16 10:28:04 -0400294 } else {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000295 // If OUT_DIR is absolute, then moduleGenDir will be an absolute path, so we don't need to set this to anything.
296 outDirPrefix = ""
Dan Albert06feee92021-03-19 15:06:02 -0700297 }
Wen-yi Chu41326c12023-09-22 03:58:59 +0000298 envVars = append(envVars, "OUT_DIR="+filepath.Join(outDirPrefix, moduleGenDir.String()))
Peter Collingbourne0dcd62e2023-03-31 23:05:16 -0700299 } else {
300 // TODO(pcc): Change this to "OUT_DIR=" after fixing crates to not rely on this value.
301 envVars = append(envVars, "OUT_DIR=out")
Dan Albert06feee92021-03-19 15:06:02 -0700302 }
303
Matthew Maurer34609fa2023-06-26 21:10:13 +0000304 envVars = append(envVars, "ANDROID_RUST_VERSION="+config.GetRustVersion(ctx))
305
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400306 if rustMod, ok := ctx.Module().(*Module); ok && rustMod.compiler.cargoEnvCompat() {
307 // We only emulate cargo environment variables for 3p code, which is only ever built
308 // by defining a Rust module, so we only need to set these for true Rust modules.
309 if bin, ok := rustMod.compiler.(*binaryDecorator); ok {
Matthew Maurer34609fa2023-06-26 21:10:13 +0000310 envVars = append(envVars, "CARGO_BIN_NAME="+bin.getStem(ctx))
311 }
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400312 envVars = append(envVars, "CARGO_CRATE_NAME="+crateName)
313 envVars = append(envVars, "CARGO_PKG_NAME="+crateName)
314 pkgVersion := rustMod.compiler.cargoPkgVersion()
Matthew Maurer34609fa2023-06-26 21:10:13 +0000315 if pkgVersion != "" {
316 envVars = append(envVars, "CARGO_PKG_VERSION="+pkgVersion)
Ivan Lozanof4455622023-07-28 12:42:20 -0400317
318 // Ensure the version is in the form of "x.y.z" (approximately semver compliant).
319 //
320 // For our purposes, we don't care to enforce that these are integers since they may
321 // include other characters at times (e.g. sometimes the patch version is more than an integer).
322 if strings.Count(pkgVersion, ".") == 2 {
323 var semver_parts = strings.Split(pkgVersion, ".")
324 envVars = append(envVars, "CARGO_PKG_VERSION_MAJOR="+semver_parts[0])
325 envVars = append(envVars, "CARGO_PKG_VERSION_MINOR="+semver_parts[1])
326 envVars = append(envVars, "CARGO_PKG_VERSION_PATCH="+semver_parts[2])
327 }
Matthew Maurer34609fa2023-06-26 21:10:13 +0000328 }
329 }
330
Sam Delmericoc5cf9902023-10-23 21:40:13 +0000331 if ctx.Darwin() {
332 envVars = append(envVars, "ANDROID_RUST_DARWIN=true")
333 }
334
Dan Albert06feee92021-03-19 15:06:02 -0700335 return envVars
336}
337
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400338func transformSrctoCrate(ctx android.ModuleContext, main android.Path, deps PathDeps, flags Flags,
339 outputFile android.WritablePath, t transformProperties) buildOutput {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700340
341 var inputs android.Paths
Colin Cross004bd3f2023-10-02 11:39:17 -0700342 var implicits android.Paths
343 var orderOnly android.Paths
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400344 var output buildOutput
Dan Albert06feee92021-03-19 15:06:02 -0700345 var rustcFlags, linkFlags []string
Wen-yi Chu41326c12023-09-22 03:58:59 +0000346 var earlyLinkFlags string
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400347
348 output.outputFile = outputFile
Ivan Lozanoffee3342019-08-27 12:03:00 -0700349
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400350 envVars := rustEnvVars(ctx, deps, t.crateName, t.cargoOutDir)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000351
Ivan Lozanoffee3342019-08-27 12:03:00 -0700352 inputs = append(inputs, main)
353
354 // Collect rustc flags
Ivan Lozanof1c84332019-09-20 11:00:37 -0700355 rustcFlags = append(rustcFlags, flags.GlobalRustFlags...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700356 rustcFlags = append(rustcFlags, flags.RustFlags...)
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400357 rustcFlags = append(rustcFlags, "--crate-type="+t.crateType)
358 if t.crateName != "" {
359 rustcFlags = append(rustcFlags, "--crate-name="+t.crateName)
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700360 }
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400361 if t.targetTriple != "" {
362 rustcFlags = append(rustcFlags, "--target="+t.targetTriple)
363 linkFlags = append(linkFlags, "-target "+t.targetTriple)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700364 }
Matthew Maurerbb3add12020-06-25 09:34:12 -0700365
366 // Suppress an implicit sysroot
367 rustcFlags = append(rustcFlags, "--sysroot=/dev/null")
368
Chris Wailes99180c22024-02-20 21:39:40 +0000369 // Enable incremental compilation if requested by user
370 if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
371 incrementalPath := android.PathForOutput(ctx, "rustc").String()
372
373 rustcFlags = append(rustcFlags, "-C incremental="+incrementalPath)
374 } else {
375 rustcFlags = append(rustcFlags, "-C codegen-units=1")
376 }
377
Chris Wailes6d12db42023-02-24 16:58:18 -0800378 // Disallow experimental features
Colin Crossf96b0012023-10-26 14:01:51 -0700379 modulePath := ctx.ModuleDir()
Chris Wailes6d12db42023-02-24 16:58:18 -0800380 if !(android.IsThirdPartyPath(modulePath) || strings.HasPrefix(modulePath, "prebuilts")) {
Chris Wailes547bfdd2023-05-31 11:53:44 -0700381 rustcFlags = append(rustcFlags, "-Zallow-features=\"\"")
Chris Wailesd9781fd2021-12-03 17:17:28 -0800382 }
383
Ivan Lozanof1c84332019-09-20 11:00:37 -0700384 // Collect linker flags
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700385 if !ctx.Darwin() {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000386 earlyLinkFlags = "-Wl,--as-needed"
A. Cody Schuffelenf29ca582023-07-13 19:03:39 -0700387 }
388
Wen-yi Chu41326c12023-09-22 03:58:59 +0000389 linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
390 linkFlags = append(linkFlags, flags.LinkFlags...)
391
392 // Check if this module needs to use the bootstrap linker
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400393 if t.bootstrap && !t.inRecovery && !t.inRamdisk && !t.inVendorRamdisk {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000394 dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400395 if t.is64Bit {
Wen-yi Chu41326c12023-09-22 03:58:59 +0000396 dynamicLinker += "64"
397 }
398 linkFlags = append(linkFlags, dynamicLinker)
399 }
400
401 libFlags := makeLibFlags(deps)
402
Ivan Lozanoffee3342019-08-27 12:03:00 -0700403 // Collect dependencies
Wen-yi Chu41326c12023-09-22 03:58:59 +0000404 implicits = append(implicits, rustLibsToPaths(deps.RLibs)...)
405 implicits = append(implicits, rustLibsToPaths(deps.DyLibs)...)
406 implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
Colin Cross004bd3f2023-10-02 11:39:17 -0700407 implicits = append(implicits, deps.StaticLibs...)
408 implicits = append(implicits, deps.SharedLibDeps...)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000409 implicits = append(implicits, deps.srcProviderFiles...)
Colin Cross004bd3f2023-10-02 11:39:17 -0700410 implicits = append(implicits, deps.AfdoProfiles...)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000411
Colin Cross004bd3f2023-10-02 11:39:17 -0700412 implicits = append(implicits, deps.CrtBegin...)
413 implicits = append(implicits, deps.CrtEnd...)
Wen-yi Chu41326c12023-09-22 03:58:59 +0000414
Colin Cross004bd3f2023-10-02 11:39:17 -0700415 orderOnly = append(orderOnly, deps.SharedLibs...)
Sam Delmerico51d6d1c2023-03-28 16:54:00 -0400416
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400417 if !t.synthetic {
418 // Only worry about OUT_DIR for actual Rust modules.
419 // Libraries built from cc use generated source, and do not utilize OUT_DIR.
420 if len(deps.SrcDeps) > 0 {
421 var outputs android.WritablePaths
Ivan Lozano43845682020-07-09 21:03:28 -0400422
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400423 for _, genSrc := range deps.SrcDeps {
424 if android.SuffixInList(outputs.Strings(), genSubDir+genSrc.Base()) {
425 ctx.PropertyErrorf("srcs",
426 "multiple source providers generate the same filename output: "+genSrc.Base())
427 }
428 outputs = append(outputs, android.PathForModuleOut(ctx, genSubDir+genSrc.Base()))
Ivan Lozano43845682020-07-09 21:03:28 -0400429 }
Ivan Lozano43845682020-07-09 21:03:28 -0400430
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400431 ctx.Build(pctx, android.BuildParams{
432 Rule: cp,
433 Description: "cp " + t.cargoOutDir.Path().Rel(),
434 Outputs: outputs,
435 Inputs: deps.SrcDeps,
436 Args: map[string]string{
437 "outDir": t.cargoOutDir.String(),
438 },
439 })
440 implicits = append(implicits, outputs.Paths()...)
441 }
Ivan Lozano43845682020-07-09 21:03:28 -0400442 }
443
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400444 if !t.synthetic {
445 // Only worry about clippy for actual Rust modules.
446 // Libraries built from cc use generated source, and don't need to run clippy.
447 if flags.Clippy {
448 clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
449 ctx.Build(pctx, android.BuildParams{
450 Rule: clippyDriver,
451 Description: "clippy " + main.Rel(),
452 Output: clippyFile,
453 ImplicitOutputs: nil,
454 Inputs: inputs,
455 Implicits: implicits,
456 OrderOnly: orderOnly,
457 Args: map[string]string{
458 "rustcFlags": strings.Join(rustcFlags, " "),
459 "libFlags": strings.Join(libFlags, " "),
460 "clippyFlags": strings.Join(flags.ClippyFlags, " "),
461 "envVars": strings.Join(envVars, " "),
462 },
463 })
464 // Declare the clippy build as an implicit dependency of the original crate.
465 implicits = append(implicits, clippyFile)
466 }
Ivan Lozanobae62be2020-07-21 13:28:27 -0400467 }
468
Wen-yi Chu41326c12023-09-22 03:58:59 +0000469 ctx.Build(pctx, android.BuildParams{
Colin Cross004bd3f2023-10-02 11:39:17 -0700470 Rule: rustc,
471 Description: "rustc " + main.Rel(),
472 Output: outputFile,
473 Inputs: inputs,
474 Implicits: implicits,
475 OrderOnly: orderOnly,
Wen-yi Chu41326c12023-09-22 03:58:59 +0000476 Args: map[string]string{
Colin Cross004bd3f2023-10-02 11:39:17 -0700477 "rustcFlags": strings.Join(rustcFlags, " "),
478 "earlyLinkFlags": earlyLinkFlags,
479 "linkFlags": strings.Join(linkFlags, " "),
480 "libFlags": strings.Join(libFlags, " "),
481 "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
482 "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
483 "envVars": strings.Join(envVars, " "),
Wen-yi Chu41326c12023-09-22 03:58:59 +0000484 },
485 })
Ivan Lozanoffee3342019-08-27 12:03:00 -0700486
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400487 if !t.synthetic {
488 // Only emit xrefs for true Rust modules.
489 if flags.EmitXrefs {
490 kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip")
491 ctx.Build(pctx, android.BuildParams{
492 Rule: kytheExtract,
493 Description: "Xref Rust extractor " + main.Rel(),
494 Output: kytheFile,
495 Inputs: inputs,
496 Implicits: implicits,
497 OrderOnly: orderOnly,
498 Args: map[string]string{
499 "rustcFlags": strings.Join(rustcFlags, " "),
500 "linkFlags": strings.Join(linkFlags, " "),
501 "libFlags": strings.Join(libFlags, " "),
502 "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
503 "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
504 "envVars": strings.Join(envVars, " "),
505 },
506 })
507 output.kytheFile = kytheFile
508 }
Sasha Smundaka76acba2022-04-18 20:12:56 -0700509 }
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400510 return output
511}
Dan Albert06feee92021-03-19 15:06:02 -0700512
Wen-yi Chu41326c12023-09-22 03:58:59 +0000513func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps,
514 flags Flags) android.ModuleOutPath {
Dan Albert06feee92021-03-19 15:06:02 -0700515
516 rustdocFlags := append([]string{}, flags.RustdocFlags...)
517 rustdocFlags = append(rustdocFlags, "--sysroot=/dev/null")
518
Dan Albertb433bf72021-04-27 17:12:02 -0700519 // Build an index for all our crates. -Z unstable options is required to use
520 // this flag.
521 rustdocFlags = append(rustdocFlags, "-Z", "unstable-options", "--enable-index-page")
522
Dan Albert06feee92021-03-19 15:06:02 -0700523 targetTriple := ctx.toolchain().RustTriple()
524
525 // Collect rustc flags
526 if targetTriple != "" {
527 rustdocFlags = append(rustdocFlags, "--target="+targetTriple)
528 }
529
530 crateName := ctx.RustModule().CrateName()
Dan Albertb433bf72021-04-27 17:12:02 -0700531 rustdocFlags = append(rustdocFlags, "--crate-name "+crateName)
Dan Albert06feee92021-03-19 15:06:02 -0700532
Wen-yi Chu41326c12023-09-22 03:58:59 +0000533 rustdocFlags = append(rustdocFlags, makeLibFlags(deps)...)
Dan Albert06feee92021-03-19 15:06:02 -0700534 docTimestampFile := android.PathForModuleOut(ctx, "rustdoc.timestamp")
Dan Albertb433bf72021-04-27 17:12:02 -0700535
Chris Wailesb2703ad2021-07-30 13:25:42 -0700536 // Silence warnings about renamed lints for third-party crates
Colin Crossf96b0012023-10-26 14:01:51 -0700537 modulePath := ctx.ModuleDir()
Chris Wailesb2703ad2021-07-30 13:25:42 -0700538 if android.IsThirdPartyPath(modulePath) {
Chris Wailes7b3eb242023-02-14 16:09:49 -0800539 rustdocFlags = append(rustdocFlags, " -A warnings")
Chris Wailesb2703ad2021-07-30 13:25:42 -0700540 }
Chris Wailes9953a192021-07-28 12:07:16 -0700541
Dan Albertb433bf72021-04-27 17:12:02 -0700542 // Yes, the same out directory is used simultaneously by all rustdoc builds.
543 // This is what cargo does. The docs for individual crates get generated to
544 // a subdirectory named for the crate, and rustdoc synchronizes writes to
545 // shared pieces like the index and search data itself.
546 // https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/render/write_shared.rs#L144-L146
547 docDir := android.PathForOutput(ctx, "rustdoc")
Dan Albert06feee92021-03-19 15:06:02 -0700548
Wen-yi Chu41326c12023-09-22 03:58:59 +0000549 ctx.Build(pctx, android.BuildParams{
550 Rule: rustdoc,
551 Description: "rustdoc " + main.Rel(),
552 Output: docTimestampFile,
553 Input: main,
554 Implicit: ctx.RustModule().UnstrippedOutputFile(),
555 Args: map[string]string{
556 "rustdocFlags": strings.Join(rustdocFlags, " "),
557 "outDir": docDir.String(),
Ivan Lozano28ed8f42024-05-06 21:46:39 -0400558 "envVars": strings.Join(rustEnvVars(ctx, deps, crateName, ctx.RustModule().compiler.cargoOutDir()), " "),
Wen-yi Chu41326c12023-09-22 03:58:59 +0000559 },
560 })
Dan Albert06feee92021-03-19 15:06:02 -0700561
562 return docTimestampFile
563}