blob: 273a3ce16fc840ec5b20f01b2868639a15018e80 [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 "android/soong/android"
19)
20
21func init() {
22 android.RegisterModuleType("rust_library", RustLibraryFactory)
23 android.RegisterModuleType("rust_library_dylib", RustLibraryDylibFactory)
24 android.RegisterModuleType("rust_library_rlib", RustLibraryRlibFactory)
25 android.RegisterModuleType("rust_library_host", RustLibraryHostFactory)
26 android.RegisterModuleType("rust_library_host_dylib", RustLibraryDylibHostFactory)
27 android.RegisterModuleType("rust_library_host_rlib", RustLibraryRlibHostFactory)
Ivan Lozano52767be2019-10-18 14:49:46 -070028 android.RegisterModuleType("rust_library_shared", RustLibrarySharedFactory)
29 android.RegisterModuleType("rust_library_static", RustLibraryStaticFactory)
30 android.RegisterModuleType("rust_library_host_shared", RustLibrarySharedHostFactory)
31 android.RegisterModuleType("rust_library_host_static", RustLibraryStaticHostFactory)
Ivan Lozanoffee3342019-08-27 12:03:00 -070032}
33
34type VariantLibraryProperties struct {
35 Enabled *bool `android:"arch_variant"`
36}
37
38type LibraryCompilerProperties struct {
Ivan Lozano52767be2019-10-18 14:49:46 -070039 Rlib VariantLibraryProperties `android:"arch_variant"`
40 Dylib VariantLibraryProperties `android:"arch_variant"`
41 Shared VariantLibraryProperties `android:"arch_variant"`
42 Static VariantLibraryProperties `android:"arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -070043
44 // path to the source file that is the main entry point of the program (e.g. src/lib.rs)
45 Srcs []string `android:"path,arch_variant"`
Ivan Lozano52767be2019-10-18 14:49:46 -070046
47 // path to include directories to pass to cc_* modules, only relevant for static/shared variants.
48 Include_dirs []string `android:"path,arch_variant"`
Ivan Lozanoffee3342019-08-27 12:03:00 -070049}
50
51type LibraryMutatedProperties struct {
Ivan Lozanoffee3342019-08-27 12:03:00 -070052 // Build a dylib variant
53 BuildDylib bool `blueprint:"mutated"`
54 // Build an rlib variant
55 BuildRlib bool `blueprint:"mutated"`
Ivan Lozano52767be2019-10-18 14:49:46 -070056 // Build a shared library variant
57 BuildShared bool `blueprint:"mutated"`
58 // Build a static library variant
59 BuildStatic bool `blueprint:"mutated"`
Ivan Lozanoffee3342019-08-27 12:03:00 -070060
61 // This variant is a dylib
62 VariantIsDylib bool `blueprint:"mutated"`
63 // This variant is an rlib
64 VariantIsRlib bool `blueprint:"mutated"`
Ivan Lozano52767be2019-10-18 14:49:46 -070065 // This variant is a shared library
66 VariantIsShared bool `blueprint:"mutated"`
67 // This variant is a static library
68 VariantIsStatic bool `blueprint:"mutated"`
Ivan Lozanoffee3342019-08-27 12:03:00 -070069}
70
71type libraryDecorator struct {
72 *baseCompiler
73
74 Properties LibraryCompilerProperties
75 MutatedProperties LibraryMutatedProperties
76 distFile android.OptionalPath
77 unstrippedOutputFile android.Path
78}
79
80type libraryInterface interface {
81 rlib() bool
82 dylib() bool
Ivan Lozano52767be2019-10-18 14:49:46 -070083 static() bool
84 shared() bool
Ivan Lozanoffee3342019-08-27 12:03:00 -070085
86 // Returns true if the build options for the module have selected a particular build type
87 buildRlib() bool
88 buildDylib() bool
Ivan Lozano52767be2019-10-18 14:49:46 -070089 buildShared() bool
90 buildStatic() bool
Ivan Lozanoffee3342019-08-27 12:03:00 -070091
92 // Sets a particular variant type
93 setRlib()
94 setDylib()
Ivan Lozano52767be2019-10-18 14:49:46 -070095 setShared()
96 setStatic()
97
98 // Build a specific library variant
99 BuildOnlyRlib()
100 BuildOnlyDylib()
101 BuildOnlyStatic()
102 BuildOnlyShared()
Ivan Lozanoffee3342019-08-27 12:03:00 -0700103}
104
105func (library *libraryDecorator) exportedDirs() []string {
106 return library.linkDirs
107}
108
109func (library *libraryDecorator) exportedDepFlags() []string {
110 return library.depFlags
111}
112
113func (library *libraryDecorator) reexportDirs(dirs ...string) {
114 library.linkDirs = android.FirstUniqueStrings(append(library.linkDirs, dirs...))
115}
116
117func (library *libraryDecorator) reexportDepFlags(flags ...string) {
118 library.depFlags = android.FirstUniqueStrings(append(library.depFlags, flags...))
119}
120
121func (library *libraryDecorator) rlib() bool {
122 return library.MutatedProperties.VariantIsRlib
123}
124
125func (library *libraryDecorator) dylib() bool {
126 return library.MutatedProperties.VariantIsDylib
127}
128
Ivan Lozano52767be2019-10-18 14:49:46 -0700129func (library *libraryDecorator) shared() bool {
130 return library.MutatedProperties.VariantIsShared
131}
132
133func (library *libraryDecorator) static() bool {
134 return library.MutatedProperties.VariantIsStatic
135}
136
Ivan Lozanoffee3342019-08-27 12:03:00 -0700137func (library *libraryDecorator) buildRlib() bool {
138 return library.MutatedProperties.BuildRlib && BoolDefault(library.Properties.Rlib.Enabled, true)
139}
140
141func (library *libraryDecorator) buildDylib() bool {
142 return library.MutatedProperties.BuildDylib && BoolDefault(library.Properties.Dylib.Enabled, true)
143}
144
Ivan Lozano52767be2019-10-18 14:49:46 -0700145func (library *libraryDecorator) buildShared() bool {
146 return library.MutatedProperties.BuildShared && BoolDefault(library.Properties.Shared.Enabled, true)
147}
148
149func (library *libraryDecorator) buildStatic() bool {
150 return library.MutatedProperties.BuildStatic && BoolDefault(library.Properties.Static.Enabled, true)
151}
152
Ivan Lozanoffee3342019-08-27 12:03:00 -0700153func (library *libraryDecorator) setRlib() {
154 library.MutatedProperties.VariantIsRlib = true
155 library.MutatedProperties.VariantIsDylib = false
Ivan Lozano52767be2019-10-18 14:49:46 -0700156 library.MutatedProperties.VariantIsStatic = false
157 library.MutatedProperties.VariantIsShared = false
Ivan Lozanoffee3342019-08-27 12:03:00 -0700158}
159
160func (library *libraryDecorator) setDylib() {
161 library.MutatedProperties.VariantIsRlib = false
162 library.MutatedProperties.VariantIsDylib = true
Ivan Lozano52767be2019-10-18 14:49:46 -0700163 library.MutatedProperties.VariantIsStatic = false
164 library.MutatedProperties.VariantIsShared = false
165}
166
167func (library *libraryDecorator) setShared() {
168 library.MutatedProperties.VariantIsStatic = false
169 library.MutatedProperties.VariantIsShared = true
170 library.MutatedProperties.VariantIsRlib = false
171 library.MutatedProperties.VariantIsDylib = false
172}
173
174func (library *libraryDecorator) setStatic() {
175 library.MutatedProperties.VariantIsStatic = true
176 library.MutatedProperties.VariantIsShared = false
177 library.MutatedProperties.VariantIsRlib = false
178 library.MutatedProperties.VariantIsDylib = false
Ivan Lozanoffee3342019-08-27 12:03:00 -0700179}
180
181var _ compiler = (*libraryDecorator)(nil)
Ivan Lozano52767be2019-10-18 14:49:46 -0700182var _ libraryInterface = (*libraryDecorator)(nil)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700183
184// rust_library produces all variants.
185func RustLibraryFactory() android.Module {
186 module, _ := NewRustLibrary(android.HostAndDeviceSupported)
187 return module.Init()
188}
189
190// rust_library_dylib produces a dylib.
191func RustLibraryDylibFactory() android.Module {
192 module, library := NewRustLibrary(android.HostAndDeviceSupported)
193 library.BuildOnlyDylib()
194 return module.Init()
195}
196
197// rust_library_rlib produces an rlib.
198func RustLibraryRlibFactory() android.Module {
199 module, library := NewRustLibrary(android.HostAndDeviceSupported)
200 library.BuildOnlyRlib()
201 return module.Init()
202}
203
Ivan Lozano52767be2019-10-18 14:49:46 -0700204// rust_library_shared produces a shared library.
205func RustLibrarySharedFactory() android.Module {
206 module, library := NewRustLibrary(android.HostAndDeviceSupported)
207 library.BuildOnlyShared()
208 return module.Init()
209}
210
211// rust_library_static produces a static library.
212func RustLibraryStaticFactory() android.Module {
213 module, library := NewRustLibrary(android.HostAndDeviceSupported)
214 library.BuildOnlyStatic()
215 return module.Init()
216}
217
Ivan Lozanoffee3342019-08-27 12:03:00 -0700218// rust_library_host produces all variants.
219func RustLibraryHostFactory() android.Module {
220 module, _ := NewRustLibrary(android.HostSupported)
221 return module.Init()
222}
223
224// rust_library_dylib_host produces a dylib.
225func RustLibraryDylibHostFactory() android.Module {
226 module, library := NewRustLibrary(android.HostSupported)
227 library.BuildOnlyDylib()
228 return module.Init()
229}
230
231// rust_library_rlib_host produces an rlib.
232func RustLibraryRlibHostFactory() android.Module {
233 module, library := NewRustLibrary(android.HostSupported)
234 library.BuildOnlyRlib()
235 return module.Init()
236}
237
Ivan Lozano52767be2019-10-18 14:49:46 -0700238// rust_library_static_host produces a static library.
239func RustLibraryStaticHostFactory() android.Module {
240 module, library := NewRustLibrary(android.HostSupported)
241 library.BuildOnlyStatic()
242 return module.Init()
243}
244
245// rust_library_shared_host produces an shared library.
246func RustLibrarySharedHostFactory() android.Module {
247 module, library := NewRustLibrary(android.HostSupported)
248 library.BuildOnlyShared()
249 return module.Init()
250}
251
Ivan Lozanoffee3342019-08-27 12:03:00 -0700252func (library *libraryDecorator) BuildOnlyDylib() {
253 library.MutatedProperties.BuildRlib = false
Ivan Lozano52767be2019-10-18 14:49:46 -0700254 library.MutatedProperties.BuildShared = false
255 library.MutatedProperties.BuildStatic = false
256
Ivan Lozanoffee3342019-08-27 12:03:00 -0700257}
258
259func (library *libraryDecorator) BuildOnlyRlib() {
260 library.MutatedProperties.BuildDylib = false
Ivan Lozano52767be2019-10-18 14:49:46 -0700261 library.MutatedProperties.BuildShared = false
262 library.MutatedProperties.BuildStatic = false
263}
264
265func (library *libraryDecorator) BuildOnlyStatic() {
266 library.MutatedProperties.BuildShared = false
267 library.MutatedProperties.BuildRlib = false
268 library.MutatedProperties.BuildDylib = false
269
270}
271
272func (library *libraryDecorator) BuildOnlyShared() {
273 library.MutatedProperties.BuildStatic = false
274 library.MutatedProperties.BuildRlib = false
275 library.MutatedProperties.BuildDylib = false
Ivan Lozanoffee3342019-08-27 12:03:00 -0700276}
277
278func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
279 module := newModule(hod, android.MultilibFirst)
280
281 library := &libraryDecorator{
282 MutatedProperties: LibraryMutatedProperties{
Ivan Lozano52767be2019-10-18 14:49:46 -0700283 BuildDylib: true,
284 BuildRlib: true,
285 BuildShared: true,
286 BuildStatic: true,
Ivan Lozanoffee3342019-08-27 12:03:00 -0700287 },
288 baseCompiler: NewBaseCompiler("lib", "lib64"),
289 }
290
291 module.compiler = library
292
293 return module, library
294}
295
296func (library *libraryDecorator) compilerProps() []interface{} {
297 return append(library.baseCompiler.compilerProps(),
298 &library.Properties,
299 &library.MutatedProperties)
300}
301
Ivan Lozanof1c84332019-09-20 11:00:37 -0700302func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
303 deps = library.baseCompiler.compilerDeps(ctx, deps)
304
Ivan Lozano52767be2019-10-18 14:49:46 -0700305 if ctx.toolchain().Bionic() && (library.dylib() || library.shared()) {
Ivan Lozanof1c84332019-09-20 11:00:37 -0700306 deps = library.baseCompiler.bionicDeps(ctx, deps)
307 }
308
309 return deps
310}
311
Ivan Lozanoffee3342019-08-27 12:03:00 -0700312func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
313 var outputFile android.WritablePath
314
315 srcPath := srcPathFromModuleSrcs(ctx, library.Properties.Srcs)
316
317 flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
318
Ivan Lozano52767be2019-10-18 14:49:46 -0700319 if library.dylib() || library.shared() {
320 // We need prefer-dynamic for now to avoid linking in the static stdlib. See:
321 // https://github.com/rust-lang/rust/issues/19680
322 // https://github.com/rust-lang/rust/issues/34909
323 flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
324 }
325
Ivan Lozanoffee3342019-08-27 12:03:00 -0700326 if library.rlib() {
327 fileName := library.getStem(ctx) + ctx.toolchain().RlibSuffix()
328 outputFile = android.PathForModuleOut(ctx, fileName)
329
330 TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
331 } else if library.dylib() {
332 fileName := library.getStem(ctx) + ctx.toolchain().DylibSuffix()
333 outputFile = android.PathForModuleOut(ctx, fileName)
334
Ivan Lozanoffee3342019-08-27 12:03:00 -0700335 TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
Ivan Lozano52767be2019-10-18 14:49:46 -0700336 } else if library.static() {
337 fileName := library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
338 outputFile = android.PathForModuleOut(ctx, fileName)
339
340 TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
341 } else if library.shared() {
342 fileName := library.getStem(ctx) + ctx.toolchain().SharedLibSuffix()
343 outputFile = android.PathForModuleOut(ctx, fileName)
344
345 TransformSrctoShared(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
Ivan Lozanoffee3342019-08-27 12:03:00 -0700346 }
347
Ivan Lozano52767be2019-10-18 14:49:46 -0700348 if library.rlib() || library.dylib() {
349 library.reexportDirs(deps.linkDirs...)
350 library.reexportDepFlags(deps.depFlags...)
351 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700352 library.unstrippedOutputFile = outputFile
353
354 return outputFile
355}
356
357func LibraryMutator(mctx android.BottomUpMutatorContext) {
358 if m, ok := mctx.Module().(*Module); ok && m.compiler != nil {
359 switch library := m.compiler.(type) {
360 case libraryInterface:
Ivan Lozanoffee3342019-08-27 12:03:00 -0700361
Ivan Lozano52767be2019-10-18 14:49:46 -0700362 // We only build the rust library variants here. This assumes that
363 // LinkageMutator runs first and there's an empty variant
364 // if rust variants are required.
365 if !library.static() && !library.shared() {
366 if library.buildRlib() && library.buildDylib() {
367 modules := mctx.CreateLocalVariations("rlib", "dylib")
368 rlib := modules[0].(*Module)
369 dylib := modules[1].(*Module)
370
371 rlib.compiler.(libraryInterface).setRlib()
372 dylib.compiler.(libraryInterface).setDylib()
373 } else if library.buildRlib() {
374 modules := mctx.CreateLocalVariations("rlib")
375 modules[0].(*Module).compiler.(libraryInterface).setRlib()
376 } else if library.buildDylib() {
377 modules := mctx.CreateLocalVariations("dylib")
378 modules[0].(*Module).compiler.(libraryInterface).setDylib()
379 }
Ivan Lozanoffee3342019-08-27 12:03:00 -0700380 }
381 }
382 }
383}