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