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