blob: 4e011832543b195c21d6af1a647430bd565db980 [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...)
116 flags.GlobalFlags = append(flags.GlobalFlags, ctx.toolchain().ToolchainRustFlags())
117
118 if ctx.Host() && !ctx.Windows() {
119 rpath_prefix := `\$$ORIGIN/`
120 if ctx.Darwin() {
121 rpath_prefix = "@loader_path/"
122 }
123
124 var rpath string
125 if ctx.toolchain().Is64Bit() {
126 rpath = "lib64"
127 } else {
128 rpath = "lib"
129 }
130 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+rpath)
131 flags.LinkFlags = append(flags.LinkFlags, "-Wl,-rpath,"+rpath_prefix+"../"+rpath)
132 }
133
134 return flags
135}
136
137func (compiler *baseCompiler) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
138 panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
139}
140
141func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
142 deps.Rlibs = append(deps.Rlibs, compiler.Properties.Rlibs...)
143 deps.Dylibs = append(deps.Dylibs, compiler.Properties.Dylibs...)
144 deps.ProcMacros = append(deps.ProcMacros, compiler.Properties.Proc_macros...)
145 deps.StaticLibs = append(deps.StaticLibs, compiler.Properties.Static_libs...)
146 deps.SharedLibs = append(deps.SharedLibs, compiler.Properties.Shared_libs...)
147
148 return deps
149}
150
151func (compiler *baseCompiler) crateName() string {
152 return compiler.Properties.Crate_name
153}
154
155func (compiler *baseCompiler) installDir(ctx ModuleContext) android.OutputPath {
156 dir := compiler.dir
157 if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
158 dir = compiler.dir64
159 }
Colin Cross3b19f5d2019-09-17 14:45:31 -0700160 if !ctx.Host() || ctx.Target().NativeBridge == android.NativeBridgeEnabled {
Ivan Lozanoffee3342019-08-27 12:03:00 -0700161 dir = filepath.Join(dir, ctx.Arch().ArchType.String())
162 }
163 return android.PathForModuleInstall(ctx, dir, compiler.subDir,
164 compiler.relativeInstallPath(), compiler.relative)
165}
166
167func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
168 compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
169}
170
171func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
172 return compiler.getStemWithoutSuffix(ctx) + String(compiler.Properties.Suffix)
173}
174
175func (compiler *baseCompiler) getStemWithoutSuffix(ctx BaseModuleContext) string {
176 stem := ctx.baseModuleName()
177 if String(compiler.Properties.Stem) != "" {
178 stem = String(compiler.Properties.Stem)
179 }
180
181 return stem
182}
183func (compiler *baseCompiler) relativeInstallPath() string {
184 return String(compiler.Properties.Relative_install_path)
185}
186
187func srcPathFromModuleSrcs(ctx ModuleContext, srcs []string) android.Path {
188 srcPaths := android.PathsForModuleSrc(ctx, srcs)
189 if len(srcPaths) != 1 {
190 ctx.PropertyErrorf("srcs", "srcs can only contain one path for rust modules")
191 }
192 return srcPaths[0]
193}