blob: 6c603df8ce5d1461f30922dfbeb3149b7b12dd83 [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
97 path android.OutputPath
98}
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...)
Ivan Lozanof1c84332019-09-20 11:00:37 -0700123 flags.GlobalRustFlags = append(flags.GlobalRustFlags, ctx.toolchain().ToolchainRustFlags())
124 flags.GlobalLinkFlags = append(flags.GlobalLinkFlags, ctx.toolchain().ToolchainLinkFlags())
Ivan Lozanoffee3342019-08-27 12:03:00 -0700125
126 if ctx.Host() && !ctx.Windows() {
127 rpath_prefix := `\$$ORIGIN/`
128 if ctx.Darwin() {
129 rpath_prefix = "@loader_path/"
130 }
131
132 var rpath string
133 if ctx.toolchain().Is64Bit() {
134 rpath = "lib64"
135 } else {
136 rpath = "lib"
137 }
138 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
139 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
140 }
141
142 return flags
143}
144
145func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
146 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
147}
148
149func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
150 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
151 deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
152 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
153 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
154 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
155
156 return deps
157}
158
Ivan Lozanof1c84332019-09-20 11:00:37 -0700159func (compiler *baseCompiler) bionicDeps(ctx DepsContext, deps Deps) Deps {
160 deps.SharedLibs = append(deps.SharedLibs, "liblog")
161 deps.SharedLibs = append(deps.SharedLibs, "libc")
162 deps.SharedLibs = append(deps.SharedLibs, "libm")
163 deps.SharedLibs = append(deps.SharedLibs, "libdl")
164
165 //TODO(b/141331117) libstd requires libgcc on Android
166 deps.StaticLibs = append(deps.StaticLibs, "libgcc")
167
168 return deps
169}
170
Ivan Lozanoffee3342019-08-27 12:03:00 -0700171func (compiler *baseCompiler) crateName() string {
172 return compiler.Properties.Crate_name
173}
174
175func (compiler *baseCompiler) installDir(ctx ModuleContext) android.OutputPath {
176 dir := compiler.dir
177 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
178 dir = compiler.dir64
179 }
Colin Cross402be412019-09-18 21:12:18 +0000180 if (!ctx.Host() && !ctx.Arch().Native) || ctx.Target().NativeBridge == android.NativeBridgeEnabled {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700181 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
182 }
183 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
184 compiler.relativeInstallPath(), compiler.relative)
185}
186
187func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
188 compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
189}
190
191func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
192 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
193}
194
195func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
196 stem := ctx.baseModuleName()
197 if String(compiler.Properties.Stem) != "" {
198 stem = String(compiler.Properties.Stem)
199 }
200
201 return stem
202}
203func (compiler *baseCompiler) relativeInstallPath() string {
204 return String(compiler.Properties.Relative_install_path)
205}
206
207func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path {
208 srcPaths := android.PathsForModuleSrc(ctx, srcs)
209 if len(srcPaths) != 1 {
210 ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules")
211 }
212 return srcPaths[0]
213}