blob: 81b258c1e82953f538008df447749fe0f34b5631 [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
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080039func NewBaseCompiler(dir, dir64 string, location installLocation) *baseCompiler {
Ivan Lozanoffee3342019-08-27 12:03:00 -070040 return &baseCompiler{
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -070041 Properties: BaseCompilerProperties{},
42 dir: dir,
43 dir64: dir64,
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080044 location: location,
Ivan Lozanoffee3342019-08-27 12:03:00 -070045 }
46}
47
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -080048type installLocation int
49
50const (
51 InstallInSystem installLocation = 0
52 InstallInData = iota
53)
54
Ivan Lozanoffee3342019-08-27 12:03:00 -070055type BaseCompilerProperties struct {
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -070056 // whether to pass "-D warnings" to rustc. Defaults to true.
57 Deny_warnings *bool
58
Ivan Lozanoffee3342019-08-27 12:03:00 -070059 // flags to pass to rustc
60 Flags []string `android:"path,arch_variant"`
61
62 // flags to pass to the linker
63 Ld_flags []string `android:"path,arch_variant"`
64
65 // list of rust rlib crate dependencies
66 Rlibs []string `android:"arch_variant"`
67
68 // list of rust dylib crate dependencies
69 Dylibs []string `android:"arch_variant"`
70
71 // list of rust proc_macro crate dependencies
72 Proc_macros []string `android:"arch_variant"`
73
74 // list of C shared library dependencies
75 Shared_libs []string `android:"arch_variant"`
76
77 // list of C static library dependencies
78 Static_libs []string `android:"arch_variant"`
79
Ivan Lozanoad8b18b2019-10-31 19:38:29 -070080 // crate name, required for libraries. This must be the expected extern crate name used in source
Ivan Lozanoffee3342019-08-27 12:03:00 -070081 Crate_name string `android:"arch_variant"`
82
83 // list of features to enable for this crate
84 Features []string `android:"arch_variant"`
85
86 // specific rust edition that should be used if the default version is not desired
87 Edition *string `android:"arch_variant"`
88
89 // sets name of the output
90 Stem *string `android:"arch_variant"`
91
92 // append to name of output
93 Suffix *string `android:"arch_variant"`
94
95 // install to a subdirectory of the default install path for the module
96 Relative_install_path *string `android:"arch_variant"`
Matthew Maurer99020b02019-10-31 10:44:40 -070097
98 // whether to suppress inclusion of standard crates - defaults to false
99 No_stdlibs *bool
Ivan Lozanoffee3342019-08-27 12:03:00 -0700100}
101
102type baseCompiler struct {
103 Properties BaseCompilerProperties
104 pathDeps android.Paths
105 rustFlagsDeps android.Paths
106 linkFlagsDeps android.Paths
107 flags string
108 linkFlags string
109 depFlags []string
110 linkDirs []string
111 edition string
112 src android.Path //rustc takes a single src file
113
114 // Install related
115 dir string
116 dir64 string
117 subDir string
118 relative string
Colin Cross70dda7e2019-10-01 22:05:35 -0700119 path android.InstallPath
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800120 location installLocation
Ivan Lozanoffee3342019-08-27 12:03:00 -0700121}
122
123var _ compiler = (*baseCompiler)(nil)
124
Chih-Hung Hsieh9a4a7ba2019-12-12 19:36:05 -0800125func (compiler *baseCompiler) inData() bool {
126 return compiler.location == InstallInData
127}
128
Ivan Lozanoffee3342019-08-27 12:03:00 -0700129func (compiler *baseCompiler) compilerProps() []interface{} {
130 return []interface{}{&compiler.Properties}
131}
132
133func (compiler *baseCompiler) featuresToFlags(features []string) []string {
134 flags := []string{}
135 for _, feature := range features {
136 flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
137 }
138 return flags
139}
140
141func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
142
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -0700143 if getDenyWarnings(compiler) {
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -0700144 flags.RustFlags = append(flags.RustFlags, "-D warnings")
145 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700146 flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
147 flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
Chih-Hung Hsieh961a30c2019-10-03 09:47:06 -0700148 flags.RustFlags = append(flags.RustFlags, "--edition="+getEdition(compiler))
Ivan Lozanoffee3342019-08-27 12:03:00 -0700149 flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
Joel Galenson724286c2019-09-30 13:01:37 -0700150 flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700151 flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
152 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700153
154 if ctx.Host() && !ctx.Windows() {
155 rpath_prefix := `\$$ORIGIN/`
156 if ctx.Darwin() {
157 rpath_prefix = "@loader_path/"
158 }
159
160 var rpath string
161 if ctx.toolchain().Is64Bit() {
162 rpath = "lib64"
163 } else {
164 rpath = "lib"
165 }
166 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
167 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
168 }
169
170 return flags
171}
172
173func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
174 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
175}
176
177func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
178 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
179 deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
180 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
181 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
182 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
183
Matthew Maurer99020b02019-10-31 10:44:40 -0700184 if !Bool(compiler.Properties.No_stdlibs) {
185 for _, stdlib := range config.Stdlibs {
186 // If we're building for host, use the compiler's stdlibs
187 if ctx.Host() {
188 stdlib = stdlib + "_" + ctx.toolchain().RustTriple()
189 }
190
191 // This check is technically insufficient - on the host, where
192 // static linking is the default, if one of our static
193 // dependencies uses a dynamic library, we need to dynamically
194 // link the stdlib as well.
195 if (len(deps.Dylibs) > 0) || (!ctx.Host()) {
196 // Dynamically linked stdlib
197 deps.Dylibs = append(deps.Dylibs, stdlib)
198 }
199 }
200 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700201 return deps
202}
203
Ivan Lozanof1c84332019-09-20 11:00:37 -0700204func (compiler *baseCompiler) bionicDeps(ctx DepsContext, deps Deps) Deps {
205 deps.SharedLibs = append(deps.SharedLibs, "liblog")
206 deps.SharedLibs = append(deps.SharedLibs, "libc")
207 deps.SharedLibs = append(deps.SharedLibs, "libm")
208 deps.SharedLibs = append(deps.SharedLibs, "libdl")
209
210 //TODO(b/141331117) libstd requires libgcc on Android
211 deps.StaticLibs = append(deps.StaticLibs, "libgcc")
212
213 return deps
214}
215
Ivan Lozanoffee3342019-08-27 12:03:00 -0700216func (compiler *baseCompiler) crateName() string {
217 return compiler.Properties.Crate_name
218}
219
Colin Cross70dda7e2019-10-01 22:05:35 -0700220func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700221 dir := compiler.dir
222 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
223 dir = compiler.dir64
224 }
Ivan Lozanod6fdca82020-04-07 12:30:33 -0400225 if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
226 dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
227 }
228 if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700229 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
230 }
231 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
232 compiler.relativeInstallPath(), compiler.relative)
233}
234
235func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
236 compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
237}
238
239func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
240 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
241}
242
243func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
244 stem := ctx.baseModuleName()
245 if String(compiler.Properties.Stem) != "" {
246 stem = String(compiler.Properties.Stem)
247 }
248
249 return stem
250}
Ivan Lozanoad8b18b2019-10-31 19:38:29 -0700251
Ivan Lozanoffee3342019-08-27 12:03:00 -0700252func (compiler *baseCompiler) relativeInstallPath() string {
253 return String(compiler.Properties.Relative_install_path)
254}
255
256func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path {
257 srcPaths := android.PathsForModuleSrc(ctx, srcs)
258 if len(srcPaths) != 1 {
259 ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules")
260 }
261 return srcPaths[0]
262}