blob: 76d5ad8440003e7611dd9549d4a63fabfbee0c20 [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
21 "android/soong/android"
22 "android/soong/rust/config"
23)
24
25func NewBaseCompiler(dir, dir64 string) *baseCompiler {
26 return &baseCompiler{
27 Properties: BaseCompilerProperties{
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -070028 Edition: &config.DefaultEdition,
29 Deny_warnings: config.DefaultDenyWarnings,
Ivan Lozanoffee3342019-08-27 12:03:00 -070030 },
31 dir: dir,
32 dir64: dir64,
33 }
34}
35
36type BaseCompilerProperties struct {
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -070037 // whether to pass "-D warnings" to rustc. Defaults to true.
38 Deny_warnings *bool
39
Ivan Lozanoffee3342019-08-27 12:03:00 -070040 // flags to pass to rustc
41 Flags []string `android:"path,arch_variant"`
42
43 // flags to pass to the linker
44 Ld_flags []string `android:"path,arch_variant"`
45
46 // list of rust rlib crate dependencies
47 Rlibs []string `android:"arch_variant"`
48
49 // list of rust dylib crate dependencies
50 Dylibs []string `android:"arch_variant"`
51
52 // list of rust proc_macro crate dependencies
53 Proc_macros []string `android:"arch_variant"`
54
55 // list of C shared library dependencies
56 Shared_libs []string `android:"arch_variant"`
57
58 // list of C static library dependencies
59 Static_libs []string `android:"arch_variant"`
60
61 // crate name (defaults to module name); if library, this must be the expected extern crate name
62 Crate_name string `android:"arch_variant"`
63
64 // list of features to enable for this crate
65 Features []string `android:"arch_variant"`
66
67 // specific rust edition that should be used if the default version is not desired
68 Edition *string `android:"arch_variant"`
69
70 // sets name of the output
71 Stem *string `android:"arch_variant"`
72
73 // append to name of output
74 Suffix *string `android:"arch_variant"`
75
76 // install to a subdirectory of the default install path for the module
77 Relative_install_path *string `android:"arch_variant"`
78}
79
80type baseCompiler struct {
81 Properties BaseCompilerProperties
82 pathDeps android.Paths
83 rustFlagsDeps android.Paths
84 linkFlagsDeps android.Paths
85 flags string
86 linkFlags string
87 depFlags []string
88 linkDirs []string
89 edition string
90 src android.Path //rustc takes a single src file
91
92 // Install related
93 dir string
94 dir64 string
95 subDir string
96 relative string
Colin Cross70dda7e2019-10-01 22:05:35 -070097 path android.InstallPath
Ivan Lozanoffee3342019-08-27 12:03:00 -070098}
99
100var _ compiler = (*baseCompiler)(nil)
101
102func (compiler *baseCompiler) compilerProps() []interface{} {
103 return []interface{}{&compiler.Properties}
104}
105
106func (compiler *baseCompiler) featuresToFlags(features []string) []string {
107 flags := []string{}
108 for _, feature := range features {
109 flags = append(flags, "--cfg 'feature=\""+feature+"\"'")
110 }
111 return flags
112}
113
114func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags) Flags {
115
Chih-Hung Hsiehefdd7ac2019-09-26 18:59:27 -0700116 if Bool(compiler.Properties.Deny_warnings) {
117 flags.RustFlags = append(flags.RustFlags, "-D warnings")
118 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700119 flags.RustFlags = append(flags.RustFlags, compiler.Properties.Flags...)
120 flags.RustFlags = append(flags.RustFlags, compiler.featuresToFlags(compiler.Properties.Features)...)
121 flags.RustFlags = append(flags.RustFlags, "--edition="+*compiler.Properties.Edition)
122 flags.LinkFlags = append(flags.LinkFlags, compiler.Properties.Ld_flags...)
Joel Galenson724286c2019-09-30 13:01:37 -0700123 flags.GlobalRustFlags = append(flags.GlobalRustFlags, config.GlobalRustFlags...)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700124 flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
125 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700126
127 if ctx.Host() && !ctx.Windows() {
128 rpath_prefix := `\$$ORIGIN/`
129 if ctx.Darwin() {
130 rpath_prefix = "@loader_path/"
131 }
132
133 var rpath string
134 if ctx.toolchain().Is64Bit() {
135 rpath = "lib64"
136 } else {
137 rpath = "lib"
138 }
139 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
140 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
141 }
142
143 return flags
144}
145
146func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
147 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
148}
149
150func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
151 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
152 deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
153 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
154 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
155 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
156
157 return deps
158}
159
Ivan Lozanof1c84332019-09-20 11:00:37 -0700160func (compiler *baseCompiler) bionicDeps(ctx DepsContext, deps Deps) Deps {
161 deps.SharedLibs = append(deps.SharedLibs, "liblog")
162 deps.SharedLibs = append(deps.SharedLibs, "libc")
163 deps.SharedLibs = append(deps.SharedLibs, "libm")
164 deps.SharedLibs = append(deps.SharedLibs, "libdl")
165
166 //TODO(b/141331117) libstd requires libgcc on Android
167 deps.StaticLibs = append(deps.StaticLibs, "libgcc")
168
169 return deps
170}
171
Ivan Lozanoffee3342019-08-27 12:03:00 -0700172func (compiler *baseCompiler) crateName() string {
173 return compiler.Properties.Crate_name
174}
175
Colin Cross70dda7e2019-10-01 22:05:35 -0700176func (compiler *baseCompiler) installDir(ctx ModuleContext) android.InstallPath {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700177 dir := compiler.dir
178 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
179 dir = compiler.dir64
180 }
Colin Cross402be412019-09-18 21:12:18 +0000181 if (!ctx.Host() && !ctx.Arch().Native) || ctx.Target().NativeBridge == android.NativeBridgeEnabled {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700182 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
183 }
184 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
185 compiler.relativeInstallPath(), compiler.relative)
186}
187
188func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
189 compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
190}
191
192func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
193 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
194}
195
196func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
197 stem := ctx.baseModuleName()
198 if String(compiler.Properties.Stem) != "" {
199 stem = String(compiler.Properties.Stem)
200 }
201
202 return stem
203}
204func (compiler *baseCompiler) relativeInstallPath() string {
205 return String(compiler.Properties.Relative_install_path)
206}
207
208func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path {
209 srcPaths := android.PathsForModuleSrc(ctx, srcs)
210 if len(srcPaths) != 1 {
211 ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules")
212 }
213 return srcPaths[0]
214}