blob: 88e3fb2c7d9b5b74b9e671f0c0cf1f8ee3b01328 [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
31func getDenyWarnings(compiler *baseCompiler) bool {
32 return BoolDefault(compiler.Properties.Deny_warnings, config.DefaultDenyWarnings)
33}
34
Matthew Maurer99020b02019-10-31 10:44:40 -070035func (compiler *baseCompiler) setNoStdlibs() {
36 compiler.Properties.No_stdlibs = proptools.BoolPtr(true)
37}
38
Ivan Lozanoffee3342019-08-27 12:03:00 -070039func NewBaseCompiler(dir, dir64 string) *baseCompiler {
40 return &baseCompiler{
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -070041 Properties: BaseCompilerProperties{},
42 dir: dir,
43 dir64: dir64,
Ivan Lozanoffee3342019-08-27 12:03:00 -070044 }
45}
46
47type BaseCompilerProperties struct {
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -070048 // whether to pass "-D warnings" to rustc. Defaults to true.
49 Deny_warnings *bool
50
Ivan Lozanoffee3342019-08-27 12:03:00 -070051 // flags to pass to rustc
52 Flags []string `android:"path,arch_variant"`
53
54 // flags to pass to the linker
55 Ld_flags []string `android:"path,arch_variant"`
56
57 // list of rust rlib crate dependencies
58 Rlibs []string `android:"arch_variant"`
59
60 // list of rust dylib crate dependencies
61 Dylibs []string `android:"arch_variant"`
62
63 // list of rust proc_macro crate dependencies
64 Proc_macros []string `android:"arch_variant"`
65
66 // list of C shared library dependencies
67 Shared_libs []string `android:"arch_variant"`
68
69 // list of C static library dependencies
70 Static_libs []string `android:"arch_variant"`
71
Ivan Lozanoad8b18b2019-10-31 19:38:29 -070072 // crate name, required for libraries. This must be the expected extern crate name used in source
Ivan Lozanoffee3342019-08-27 12:03:00 -070073 Crate_name string `android:"arch_variant"`
74
75 // list of features to enable for this crate
76 Features []string `android:"arch_variant"`
77
78 // specific rust edition that should be used if the default version is not desired
79 Edition *string `android:"arch_variant"`
80
81 // sets name of the output
82 Stem *string `android:"arch_variant"`
83
84 // append to name of output
85 Suffix *string `android:"arch_variant"`
86
87 // install to a subdirectory of the default install path for the module
88 Relative_install_path *string `android:"arch_variant"`
Matthew Maurer99020b02019-10-31 10:44:40 -070089
90 // whether to suppress inclusion of standard crates - defaults to false
91 No_stdlibs *bool
Ivan Lozanoffee3342019-08-27 12:03:00 -070092}
93
94type baseCompiler struct {
95 Properties BaseCompilerProperties
96 pathDeps android.Paths
97 rustFlagsDeps android.Paths
98 linkFlagsDeps android.Paths
99 flags string
100 linkFlags string
101 depFlags []string
102 linkDirs []string
103 edition string
104 src android.Path //rustc takes a single src file
105
106 // Install related
107 dir string
108 dir64 string
109 subDir string
110 relative string
Colin Cross70dda7e2019-10-01 22:05:35 -0700111 path android.InstallPath
Ivan Lozanoffee3342019-08-27 12:03:00 -0700112}
113
114var _ compiler = (*baseCompiler)(nil)
115
116func (compiler *baseCompiler) compilerProps() []interface{} {
117 return []interface{}{&compiler.Properties}
118}
119
120func (compiler *baseCompiler) featuresToFlags(features []string) []string {
121 flags := []string{}
122 for _, feature := range features {
123 flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
124 }
125 return flags
126}
127
128func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
129
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -0700130 if getDenyWarnings(compiler) {
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -0700131 flags.RustFlags = append(flags.RustFlags, "-D warnings")
132 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700133 flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
134 flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -0700135 flags.RustFlags = append(flags.RustFlags, "--edition="+getEdition(compiler))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700136 flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
Joel Galenson724286c2019-09-30 13:01:37 -0700137 flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700138 flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
139 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700140
141 if ctx.Host() && !ctx.Windows() {
142 rpath_prefix := `\$$ORIGIN/`
143 if ctx.Darwin() {
144 rpath_prefix = "@loader_path/"
145 }
146
147 var rpath string
148 if ctx.toolchain().Is64Bit() {
149 rpath = "lib64"
150 } else {
151 rpath = "lib"
152 }
153 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
154 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
155 }
156
157 return flags
158}
159
160func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
161 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
162}
163
164func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
165 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
166 deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
167 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
168 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
169 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
170
Matthew Maurer99020b02019-10-31 10:44:40 -0700171 if !Bool(compiler.Properties.No_stdlibs) {
172 for _, stdlib := range config.Stdlibs {
173 // If we're building for host, use the compiler's stdlibs
174 if ctx.Host() {
175 stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
176 }
177
178 // This check is technically insufficient - on the host, where
179 // static linking is the default, if one of our static
180 // dependencies uses a dynamic library, we need to dynamically
181 // link the stdlib as well.
182 if (len(deps.Dylibs) > 0) || (!ctx.Host()) {
183 // Dynamically linked stdlib
184 deps.Dylibs = append(deps.Dylibs, stdlib)
185 }
186 }
187 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700188 return deps
189}
190
Ivan Lozanof1c84332019-09-20 11:00:37 -0700191func (compiler *baseCompiler) bionicDeps(ctx DepsContext, deps Deps) Deps {
192 deps.SharedLibs = append(deps.SharedLibs, "liblog")
193 deps.SharedLibs = append(deps.SharedLibs, "libc")
194 deps.SharedLibs = append(deps.SharedLibs, "libm")
195 deps.SharedLibs = append(deps.SharedLibs, "libdl")
196
197 //TODO(b/141331117) libstd requires libgcc on Android
198 deps.StaticLibs = append(deps.StaticLibs, "libgcc")
199
200 return deps
201}
202
Ivan Lozanoffee3342019-08-27 12:03:00 -0700203func (compiler *baseCompiler) crateName() string {
204 return compiler.Properties.Crate_name
205}
206
Colin Cross70dda7e2019-10-01 22:05:35 -0700207func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700208 dir := compiler.dir
209 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
210 dir = compiler.dir64
211 }
Colin Cross3b19f5d2019-09-17 14:45:31 -0700212 if !ctx.Host() || ctx.Target().NativeBridge == android.NativeBridgeEnabled {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700213 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
214 }
215 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
216 compiler.relativeInstallPath(), compiler.relative)
217}
218
219func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
220 compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
221}
222
223func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
224 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
225}
226
227func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
228 stem := ctx.baseModuleName()
229 if String(compiler.Properties.Stem) != "" {
230 stem = String(compiler.Properties.Stem)
231 }
232
233 return stem
234}
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700235
Ivan Lozanoffee3342019-08-27 12:03:00 -0700236func (compiler *baseCompiler) relativeInstallPath() string {
237 return String(compiler.Properties.Relative_install_path)
238}
239
240func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path {
241 srcPaths := android.PathsForModuleSrc(ctx, srcs)
242 if len(srcPaths) != 1 {
243 ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules")
244 }
245 return srcPaths[0]
246}