blob: 363fe5e3966a7e0fe8c781736b01ebb71c034bd4 [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
49)
50
Ivan Lozanoffee3342019-08-27 12:03:00 -070051type BaseCompilerProperties struct {
Ivan Lozano8a23fa42020-06-16 10:26:57 -040052 // path to the source file that is the main entry point of the program (e.g. main.rs or lib.rs)
53 Srcs []string `android:"path,arch_variant"`
54
ThiƩbaud Weksteen8e46efa2020-06-30 21:43:35 +020055 // whether to suppress the standard lint flags - default to false
56 No_lint *bool
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -070057
Ivan Lozanoffee3342019-08-27 12:03:00 -070058 // flags to pass to rustc
59 Flags []string `android:"path,arch_variant"`
60
61 // flags to pass to the linker
62 Ld_flags []string `android:"path,arch_variant"`
63
64 // list of rust rlib crate dependencies
65 Rlibs []string `android:"arch_variant"`
66
67 // list of rust dylib crate dependencies
68 Dylibs []string `android:"arch_variant"`
69
70 // list of rust proc_macro crate dependencies
71 Proc_macros []string `android:"arch_variant"`
72
73 // list of C shared library dependencies
74 Shared_libs []string `android:"arch_variant"`
75
76 // list of C static library dependencies
77 Static_libs []string `android:"arch_variant"`
78
Ivan Lozanoad8b18b2019-10-31 19:38:29 -070079 // crate name, required for libraries. This must be the expected extern crate name used in source
Ivan Lozanoffee3342019-08-27 12:03:00 -070080 Crate_name string `android:"arch_variant"`
81
82 // list of features to enable for this crate
83 Features []string `android:"arch_variant"`
84
85 // specific rust edition that should be used if the default version is not desired
86 Edition *string `android:"arch_variant"`
87
88 // sets name of the output
89 Stem *string `android:"arch_variant"`
90
91 // append to name of output
92 Suffix *string `android:"arch_variant"`
93
94 // install to a subdirectory of the default install path for the module
95 Relative_install_path *string `android:"arch_variant"`
Matthew Maurer99020b02019-10-31 10:44:40 -070096
97 // whether to suppress inclusion of standard crates - defaults to false
98 No_stdlibs *bool
Ivan Lozanoffee3342019-08-27 12:03:00 -070099}
100
101type baseCompiler struct {
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400102 Properties BaseCompilerProperties
103 depFlags []string
104 linkDirs []string
105 coverageFile android.Path //rustc generates a single gcno file
Ivan Lozanoffee3342019-08-27 12:03:00 -0700106
107 // Install related
108 dir string
109 dir64 string
110 subDir string
111 relative string
Colin Cross70dda7e2019-10-01 22:05:35 -0700112 path android.InstallPath
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800113 location installLocation
Ivan Lozano8a23fa42020-06-16 10:26:57 -0400114
115 coverageOutputZipFile android.OptionalPath
116 unstrippedOutputFile android.Path
117 distFile android.OptionalPath
Ivan Lozanoffee3342019-08-27 12:03:00 -0700118}
119
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400120func (compiler *baseCompiler) coverageOutputZipPath() android.OptionalPath {
121 panic("baseCompiler does not implement coverageOutputZipPath()")
122}
123
Ivan Lozanoffee3342019-08-27 12:03:00 -0700124var _ compiler = (*baseCompiler)(nil)
125
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800126func (compiler *baseCompiler) inData() bool {
127 return compiler.location == InstallInData
128}
129
Ivan Lozanoffee3342019-08-27 12:03:00 -0700130func (compiler *baseCompiler) compilerProps() []interface{} {
131 return []interface{}{&compiler.Properties}
132}
133
134func (compiler *baseCompiler) featuresToFlags(features []string) []string {
135 flags := []string{}
136 for _, feature := range features {
137 flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
138 }
139 return flags
140}
141
142func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
143
ThiƩbaud Weksteen8e46efa2020-06-30 21:43:35 +0200144 if !Bool(compiler.Properties.No_lint) {
145 flags.RustFlags = append(flags.RustFlags, config.RustcLintsForDir(ctx.ModuleDir()))
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -0700146 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700147 flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
148 flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -0700149 flags.RustFlags = append(flags.RustFlags, "--edition="+getEdition(compiler))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700150 flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
Joel Galenson724286c2019-09-30 13:01:37 -0700151 flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700152 flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
153 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700154
155 if ctx.Host() && !ctx.Windows() {
156 rpath_prefix := `\$$ORIGIN/`
157 if ctx.Darwin() {
158 rpath_prefix = "@loader_path/"
159 }
160
161 var rpath string
162 if ctx.toolchain().Is64Bit() {
163 rpath = "lib64"
164 } else {
165 rpath = "lib"
166 }
167 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
168 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
169 }
170
171 return flags
172}
173
174func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
175 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
176}
177
178func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
179 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
180 deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
181 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
182 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
183 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
184
Matthew Maurer99020b02019-10-31 10:44:40 -0700185 if !Bool(compiler.Properties.No_stdlibs) {
186 for _, stdlib := range config.Stdlibs {
Ivan Lozano9d1df102020-04-28 10:10:23 -0400187 // If we're building for the primary host target, use the compiler's stdlibs
188 if ctx.Host() && ctx.TargetPrimary() {
Matthew Maurer99020b02019-10-31 10:44:40 -0700189 stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
190 }
191
192 // This check is technically insufficient - on the host, where
193 // static linking is the default, if one of our static
194 // dependencies uses a dynamic library, we need to dynamically
195 // link the stdlib as well.
Ivan Lozano9d1df102020-04-28 10:10:23 -0400196 if (len(deps.Dylibs) > 0) || ctx.Device() {
Matthew Maurer99020b02019-10-31 10:44:40 -0700197 // Dynamically linked stdlib
198 deps.Dylibs = append(deps.Dylibs, stdlib)
Ivan Lozano9d1df102020-04-28 10:10:23 -0400199 } else if ctx.Host() && !ctx.TargetPrimary() {
200 // Otherwise use the static in-tree stdlib for host secondary arch
201 deps.Rlibs = append(deps.Rlibs, stdlib+".static")
Matthew Maurer99020b02019-10-31 10:44:40 -0700202 }
203 }
204 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700205 return deps
206}
207
Ivan Lozanof1c84332019-09-20 11:00:37 -0700208func (compiler *baseCompiler) bionicDeps(ctx DepsContext, deps Deps) Deps {
209 deps.SharedLibs = append(deps.SharedLibs, "liblog")
210 deps.SharedLibs = append(deps.SharedLibs, "libc")
211 deps.SharedLibs = append(deps.SharedLibs, "libm")
212 deps.SharedLibs = append(deps.SharedLibs, "libdl")
213
214 //TODO(b/141331117) libstd requires libgcc on Android
215 deps.StaticLibs = append(deps.StaticLibs, "libgcc")
216
217 return deps
218}
219
Ivan Lozanoffee3342019-08-27 12:03:00 -0700220func (compiler *baseCompiler) crateName() string {
221 return compiler.Properties.Crate_name
222}
223
Colin Cross70dda7e2019-10-01 22:05:35 -0700224func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700225 dir := compiler.dir
226 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
227 dir = compiler.dir64
228 }
Ivan Lozanod6fdca82020-04-07 12:30:33 -0400229 if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
230 dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
231 }
232 if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700233 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
234 }
235 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
236 compiler.relativeInstallPath(), compiler.relative)
237}
238
Ivan Lozanoa0cd8f92020-04-09 09:56:02 -0400239func (compiler *baseCompiler) nativeCoverage() bool {
240 return false
241}
242
Ivan Lozanoffee3342019-08-27 12:03:00 -0700243func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
244 compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
245}
246
247func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
248 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
249}
250
251func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
252 stem := ctx.baseModuleName()
253 if String(compiler.Properties.Stem) != "" {
254 stem = String(compiler.Properties.Stem)
255 }
256
257 return stem
258}
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700259
Ivan Lozanoffee3342019-08-27 12:03:00 -0700260func (compiler *baseCompiler) relativeInstallPath() string {
261 return String(compiler.Properties.Relative_install_path)
262}
263
264func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path {
265 srcPaths := android.PathsForModuleSrc(ctx, srcs)
266 if len(srcPaths) != 1 {
267 ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules")
268 }
269 return srcPaths[0]
270}