blob: ec059c37cd01ace81a0db26b6d2afa172fc3a783 [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 (
18 "fmt"
19 "path/filepath"
20
Ivan Lozanoad8b18b2019-10-31 19:38:29 -070021 "github.com/google/blueprint/proptools"
22
Ivan Lozanoffee3342019-08-27 12:03:00 -070023 "android/soong/android"
24 "android/soong/rust/config"
25)
26
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -070027func getEdition(compiler *baseCompiler) string {
28 return proptools.StringDefault(compiler.Properties.Edition, config.DefaultEdition)
29}
30
Matthew Maurer99020b02019-10-31 10:44:40 -070031func (compiler *baseCompiler) setNoStdlibs() {
32 compiler.Properties.No_stdlibs = proptools.BoolPtr(true)
33}
34
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080035func NewBaseCompiler(dir, dir64 string, location installLocation) *baseCompiler {
Ivan Lozanoffee3342019-08-27 12:03:00 -070036 return &baseCompiler{
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -070037 Properties: BaseCompilerProperties{},
38 dir: dir,
39 dir64: dir64,
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080040 location: location,
Ivan Lozanoffee3342019-08-27 12:03:00 -070041 }
42}
43
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080044type installLocation int
45
46const (
47 InstallInSystem installLocation = 0
48 InstallInData = iota
Ivan Lozano43845682020-07-09 21:03:28 -040049
50 incorrectSourcesError = "srcs can only contain one path for a rust file and source providers prefixed by \":\""
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080051)
52
Ivan Lozanoffee3342019-08-27 12:03:00 -070053type BaseCompilerProperties struct {
Ivan Lozano8a23fa42020-06-16 10:26:57 -040054 // path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs)
55 Srcs []string `android:"path,arch_variant"`
56
Thiébaud Weksteen8e46efa2020-06-30 21:43:35 +020057 // whether to suppress the standard lint flags - default to false
58 No_lint *bool
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -070059
Ivan Lozanoffee3342019-08-27 12:03:00 -070060 // flags to pass to rustc
61 Flags []string `android:"path,arch_variant"`
62
63 // flags to pass to the linker
64 Ld_flags []string `android:"path,arch_variant"`
65
66 // list of rust rlib crate dependencies
67 Rlibs []string `android:"arch_variant"`
68
69 // list of rust dylib crate dependencies
70 Dylibs []string `android:"arch_variant"`
71
Matthew Maurer0f003b12020-06-29 14:34:06 -070072 // list of rust automatic crate dependencies
73 Rustlibs []string `android:"arch_variant"`
74
Ivan Lozanoffee3342019-08-27 12:03:00 -070075 // list of rust proc_macro crate dependencies
76 Proc_macros []string `android:"arch_variant"`
77
78 // list of C shared library dependencies
79 Shared_libs []string `android:"arch_variant"`
80
81 // list of C static library dependencies
82 Static_libs []string `android:"arch_variant"`
83
Ivan Lozano26ecd6c2020-07-31 13:40:31 -040084 // crate name, required for modules which produce Rust libraries: rust_library, rust_ffi and SourceProvider
85 // modules which create library variants (rust_bindgen). This must be the expected extern crate name used in
86 // source, and is required to conform to an enforced format matching library output files (if the output file is
87 // lib<someName><suffix>, the crate_name property must be <someName>).
Ivan Lozanoffee3342019-08-27 12:03:00 -070088 Crate_name string `android:"arch_variant"`
89
90 // list of features to enable for this crate
91 Features []string `android:"arch_variant"`
92
93 // specific rust edition that should be used if the default version is not desired
94 Edition *string `android:"arch_variant"`
95
96 // sets name of the output
97 Stem *string `android:"arch_variant"`
98
99 // append to name of output
100 Suffix *string `android:"arch_variant"`
101
102 // install to a subdirectory of the default install path for the module
103 Relative_install_path *string `android:"arch_variant"`
Matthew Maurer99020b02019-10-31 10:44:40 -0700104
105 // whether to suppress inclusion of standard crates - defaults to false
106 No_stdlibs *bool
Ivan Lozanoffee3342019-08-27 12:03:00 -0700107}
108
109type baseCompiler struct {
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400110 Properties BaseCompilerProperties
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400111 coverageFile android.Path //rustc generates a single gcno file
Ivan Lozanoffee3342019-08-27 12:03:00 -0700112
113 // Install related
114 dir string
115 dir64 string
116 subDir string
117 relative string
Colin Cross70dda7e2019-10-01 22:05:35 -0700118 path android.InstallPath
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800119 location installLocation
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400120
121 coverageOutputZipFile android.OptionalPath
122 unstrippedOutputFile android.Path
123 distFile android.OptionalPath
Ivan Lozanoffee3342019-08-27 12:03:00 -0700124}
125
Ivan Lozano26ecd6c2020-07-31 13:40:31 -0400126func (compiler *baseCompiler) Disabled() bool {
127 return false
128}
129
130func (compiler *baseCompiler) SetDisabled() {
131 panic("baseCompiler does not implement SetDisabled()")
132}
133
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400134func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath {
135 panic("baseCompiler does not implement coverageOutputZipPath()")
136}
137
Ivan Lozanoffee3342019-08-27 12:03:00 -0700138var _ compiler = (*baseCompiler)(nil)
139
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800140func (compiler *baseCompiler) inData() bool {
141 return compiler.location == InstallInData
142}
143
Ivan Lozanoffee3342019-08-27 12:03:00 -0700144func (compiler *baseCompiler) compilerProps() []interface{} {
145 return []interface{}{&compiler.Properties}
146}
147
148func (compiler *baseCompiler) featuresToFlags(features []string) []string {
149 flags := []string{}
150 for _, feature := range features {
151 flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
152 }
153 return flags
154}
155
156func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
157
Thiébaud Weksteen8e46efa2020-06-30 21:43:35 +0200158 if !Bool(compiler.Properties.No_lint) {
159 flags.RustFlags = append(flags.RustFlags, config.RustcLintsForDir(ctx.ModuleDir()))
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -0700160 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700161 flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
162 flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -0700163 flags.RustFlags = append(flags.RustFlags, "--edition="+getEdition(compiler))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700164 flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
Joel Galenson724286c2019-09-30 13:01:37 -0700165 flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700166 flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
167 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700168
169 if ctx.Host() && !ctx.Windows() {
170 rpath_prefix := `\$$ORIGIN/`
171 if ctx.Darwin() {
172 rpath_prefix = "@loader_path/"
173 }
174
175 var rpath string
176 if ctx.toolchain().Is64Bit() {
177 rpath = "lib64"
178 } else {
179 rpath = "lib"
180 }
181 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
182 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
183 }
184
185 return flags
186}
187
188func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
189 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
190}
191
192func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
193 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
194 deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
Matthew Maurer0f003b12020-06-29 14:34:06 -0700195 deps.Rustlibs = append(deps.Rustlibs, compiler.Properties.Rustlibs...)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700196 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
197 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
198 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
199
Matthew Maurer99020b02019-10-31 10:44:40 -0700200 if !Bool(compiler.Properties.No_stdlibs) {
201 for _, stdlib := range config.Stdlibs {
Ivan Lozano9d1df102020-04-28 10:10:23 -0400202 // If we're building for the primary host target, use the compiler's stdlibs
203 if ctx.Host() && ctx.TargetPrimary() {
Matthew Maurer99020b02019-10-31 10:44:40 -0700204 stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
205 }
206
Matthew Maurerc761eec2020-06-25 00:47:46 -0700207 deps.Rustlibs = append(deps.Rustlibs, stdlib)
Matthew Maurer99020b02019-10-31 10:44:40 -0700208 }
209 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700210 return deps
211}
212
Ivan Lozano45901ed2020-07-24 16:05:01 -0400213func bionicDeps(deps Deps) Deps {
Ivan Lozanof1c84332019-09-20 11:00:37 -0700214 deps.SharedLibs = append(deps.SharedLibs, "liblog")
215 deps.SharedLibs = append(deps.SharedLibs, "libc")
216 deps.SharedLibs = append(deps.SharedLibs, "libm")
217 deps.SharedLibs = append(deps.SharedLibs, "libdl")
218
219 //TODO(b/141331117) libstd requires libgcc on Android
220 deps.StaticLibs = append(deps.StaticLibs, "libgcc")
221
222 return deps
223}
224
Ivan Lozanoffee3342019-08-27 12:03:00 -0700225func (compiler *baseCompiler) crateName() string {
226 return compiler.Properties.Crate_name
227}
228
Colin Cross70dda7e2019-10-01 22:05:35 -0700229func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700230 dir := compiler.dir
231 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
232 dir = compiler.dir64
233 }
Ivan Lozanod6fdca82020-04-07 12:30:33 -0400234 if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
235 dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
236 }
237 if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700238 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
239 }
240 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
241 compiler.relativeInstallPath(), compiler.relative)
242}
243
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400244func (compiler *baseCompiler) nativeCoverage() bool {
245 return false
246}
247
Ivan Lozanoffee3342019-08-27 12:03:00 -0700248func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
249 compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
250}
251
252func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
253 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
254}
255
256func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
Thiébaud Weksteen1f7f70f2020-06-24 11:32:48 +0200257 stem := ctx.ModuleName()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700258 if String(compiler.Properties.Stem) != "" {
259 stem = String(compiler.Properties.Stem)
260 }
261
262 return stem
263}
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700264
Ivan Lozanoffee3342019-08-27 12:03:00 -0700265func (compiler *baseCompiler) relativeInstallPath() string {
266 return String(compiler.Properties.Relative_install_path)
267}
268
Ivan Lozano43845682020-07-09 21:03:28 -0400269// Returns the Path for the main source file along with Paths for generated source files from modules listed in srcs.
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700270func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) (android.Path, android.Paths) {
271 // The srcs can contain strings with prefix ":".
272 // They are dependent modules of this module, with android.SourceDepTag.
273 // They are not the main source file compiled by rustc.
274 numSrcs := 0
275 srcIndex := 0
276 for i, s := range srcs {
277 if android.SrcIsModule(s) == "" {
278 numSrcs++
279 srcIndex = i
280 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700281 }
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700282 if numSrcs != 1 {
Ivan Lozano43845682020-07-09 21:03:28 -0400283 ctx.PropertyErrorf("srcs", incorrectSourcesError)
Chih-Hung Hsiehbbd25ae2020-05-15 17:36:30 -0700284 }
285 if srcIndex != 0 {
286 ctx.PropertyErrorf("srcs", "main source file must be the first in srcs")
287 }
288 paths := android.PathsForModuleSrc(ctx, srcs)
Ivan Lozano43845682020-07-09 21:03:28 -0400289 return paths[srcIndex], paths[1:]
Ivan Lozanoffee3342019-08-27 12:03:00 -0700290}