blob: 52f840e7a16e7d0f9559a4047a353bf5cd219f39 [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 "android/soong/rust/config"
20)
21
22func init() {
23 android.RegisterModuleType("rust_binary", RustBinaryFactory)
24 android.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
25}
26
27type BinaryCompilerProperties struct {
28 // path to the main source file that contains the program entry point (e.g. src/main.rs)
29 Srcs []string `android:"path,arch_variant"`
30
31 // passes -C prefer-dynamic to rustc, which tells it to dynamically link the stdlib (assuming it has no dylib dependencies already)
32 Prefer_dynamic *bool
33}
34
35type binaryDecorator struct {
36 *baseCompiler
37
38 Properties BinaryCompilerProperties
39 distFile android.OptionalPath
40 unstrippedOutputFile android.Path
41}
42
43var _ compiler = (*binaryDecorator)(nil)
44
45// rust_binary produces a binary that is runnable on a device.
46func RustBinaryFactory() android.Module {
47 module, _ := NewRustBinary(android.HostAndDeviceSupported)
48 return module.Init()
49}
50
51func RustBinaryHostFactory() android.Module {
52 module, _ := NewRustBinary(android.HostSupported)
53 return module.Init()
54}
55
56func NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
57 module := newModule(hod, android.MultilibFirst)
58
59 binary := &binaryDecorator{
60 baseCompiler: NewBaseCompiler("bin", ""),
61 }
62
63 module.compiler = binary
64
65 return module, binary
66}
67
68func (binary *binaryDecorator) preferDynamic() bool {
69 return Bool(binary.Properties.Prefer_dynamic)
70}
71
72func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
73 flags = binary.baseCompiler.compilerFlags(ctx, flags)
Ivan Lozanof1c84332019-09-20 11:00:37 -070074
75 if ctx.toolchain().Bionic() {
76 // no-undefined-version breaks dylib compilation since __rust_*alloc* functions aren't defined, but we can apply this to binaries.
77 flags.LinkFlags = append(flags.LinkFlags,
78 "-Wl,--gc-sections",
79 "-Wl,-z,nocopyreloc",
80 "-Wl,--no-undefined-version")
81 }
82
Ivan Lozanoffee3342019-08-27 12:03:00 -070083 if binary.preferDynamic() {
84 flags.RustFlags = append(flags.RustFlags, "-C prefer-dynamic")
85 }
86 return flags
87}
88
89func (binary *binaryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
90 deps = binary.baseCompiler.compilerDeps(ctx, deps)
91
92 if binary.preferDynamic() || len(deps.Dylibs) > 0 {
93 for _, stdlib := range config.Stdlibs {
94 deps.Dylibs = append(deps.Dylibs, stdlib+"_"+ctx.toolchain().RustTriple())
95 }
96 }
97
Ivan Lozanof1c84332019-09-20 11:00:37 -070098 if ctx.toolchain().Bionic() {
99 deps = binary.baseCompiler.bionicDeps(ctx, deps)
100 deps.CrtBegin = "crtbegin_dynamic"
101 deps.CrtEnd = "crtend_android"
102 }
103
Ivan Lozanoffee3342019-08-27 12:03:00 -0700104 return deps
105}
106
107func (binary *binaryDecorator) compilerProps() []interface{} {
108 return append(binary.baseCompiler.compilerProps(),
109 &binary.Properties)
110}
111
112func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
113 fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
114
115 srcPath := srcPathFromModuleSrcs(ctx, binary.Properties.Srcs)
116
117 outputFile := android.PathForModuleOut(ctx, fileName)
118 binary.unstrippedOutputFile = outputFile
119
120 flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
121
122 TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
123
124 return outputFile
125}