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