xref: /aosp_15_r20/build/soong/rust/binary.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2019 The Android Open Source Project
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage rust
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
19*333d2b36SAndroid Build Coastguard Worker)
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Workerfunc init() {
22*333d2b36SAndroid Build Coastguard Worker	android.RegisterModuleType("rust_binary", RustBinaryFactory)
23*333d2b36SAndroid Build Coastguard Worker	android.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
24*333d2b36SAndroid Build Coastguard Worker}
25*333d2b36SAndroid Build Coastguard Worker
26*333d2b36SAndroid Build Coastguard Workertype BinaryCompilerProperties struct {
27*333d2b36SAndroid Build Coastguard Worker	// Builds this binary as a static binary. Implies prefer_rlib true.
28*333d2b36SAndroid Build Coastguard Worker	//
29*333d2b36SAndroid Build Coastguard Worker	// Static executables currently only support for bionic targets. Non-bionic targets will not produce a fully static
30*333d2b36SAndroid Build Coastguard Worker	// binary, but will still implicitly imply prefer_rlib true.
31*333d2b36SAndroid Build Coastguard Worker	Static_executable *bool `android:"arch_variant"`
32*333d2b36SAndroid Build Coastguard Worker}
33*333d2b36SAndroid Build Coastguard Worker
34*333d2b36SAndroid Build Coastguard Workertype binaryInterface interface {
35*333d2b36SAndroid Build Coastguard Worker	binary() bool
36*333d2b36SAndroid Build Coastguard Worker	staticallyLinked() bool
37*333d2b36SAndroid Build Coastguard Worker	testBinary() bool
38*333d2b36SAndroid Build Coastguard Worker}
39*333d2b36SAndroid Build Coastguard Worker
40*333d2b36SAndroid Build Coastguard Workertype binaryDecorator struct {
41*333d2b36SAndroid Build Coastguard Worker	*baseCompiler
42*333d2b36SAndroid Build Coastguard Worker	stripper Stripper
43*333d2b36SAndroid Build Coastguard Worker
44*333d2b36SAndroid Build Coastguard Worker	Properties BinaryCompilerProperties
45*333d2b36SAndroid Build Coastguard Worker}
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Workervar _ compiler = (*binaryDecorator)(nil)
48*333d2b36SAndroid Build Coastguard Worker
49*333d2b36SAndroid Build Coastguard Worker// rust_binary produces a binary that is runnable on a device.
50*333d2b36SAndroid Build Coastguard Workerfunc RustBinaryFactory() android.Module {
51*333d2b36SAndroid Build Coastguard Worker	module, _ := NewRustBinary(android.HostAndDeviceSupported)
52*333d2b36SAndroid Build Coastguard Worker	return module.Init()
53*333d2b36SAndroid Build Coastguard Worker}
54*333d2b36SAndroid Build Coastguard Worker
55*333d2b36SAndroid Build Coastguard Workerfunc RustBinaryHostFactory() android.Module {
56*333d2b36SAndroid Build Coastguard Worker	module, _ := NewRustBinary(android.HostSupported)
57*333d2b36SAndroid Build Coastguard Worker	return module.Init()
58*333d2b36SAndroid Build Coastguard Worker}
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard Workerfunc NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
61*333d2b36SAndroid Build Coastguard Worker	module := newModule(hod, android.MultilibFirst)
62*333d2b36SAndroid Build Coastguard Worker
63*333d2b36SAndroid Build Coastguard Worker	binary := &binaryDecorator{
64*333d2b36SAndroid Build Coastguard Worker		baseCompiler: NewBaseCompiler("bin", "", InstallInSystem),
65*333d2b36SAndroid Build Coastguard Worker	}
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Worker	module.compiler = binary
68*333d2b36SAndroid Build Coastguard Worker
69*333d2b36SAndroid Build Coastguard Worker	return module, binary
70*333d2b36SAndroid Build Coastguard Worker}
71*333d2b36SAndroid Build Coastguard Worker
72*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
73*333d2b36SAndroid Build Coastguard Worker	flags = binary.baseCompiler.compilerFlags(ctx, flags)
74*333d2b36SAndroid Build Coastguard Worker
75*333d2b36SAndroid Build Coastguard Worker	if ctx.toolchain().Bionic() {
76*333d2b36SAndroid Build Coastguard Worker		// no-undefined-version breaks dylib compilation since __rust_*alloc* functions aren't defined,
77*333d2b36SAndroid Build Coastguard Worker		// but we can apply this to binaries.
78*333d2b36SAndroid Build Coastguard Worker		flags.LinkFlags = append(flags.LinkFlags,
79*333d2b36SAndroid Build Coastguard Worker			"-Wl,--gc-sections",
80*333d2b36SAndroid Build Coastguard Worker			"-Wl,-z,nocopyreloc",
81*333d2b36SAndroid Build Coastguard Worker			"-Wl,--no-undefined-version")
82*333d2b36SAndroid Build Coastguard Worker
83*333d2b36SAndroid Build Coastguard Worker		if Bool(binary.Properties.Static_executable) {
84*333d2b36SAndroid Build Coastguard Worker			flags.LinkFlags = append(flags.LinkFlags, "-static")
85*333d2b36SAndroid Build Coastguard Worker			flags.RustFlags = append(flags.RustFlags, "-C relocation-model=static")
86*333d2b36SAndroid Build Coastguard Worker		}
87*333d2b36SAndroid Build Coastguard Worker	}
88*333d2b36SAndroid Build Coastguard Worker
89*333d2b36SAndroid Build Coastguard Worker	return flags
90*333d2b36SAndroid Build Coastguard Worker}
91*333d2b36SAndroid Build Coastguard Worker
92*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
93*333d2b36SAndroid Build Coastguard Worker	deps = binary.baseCompiler.compilerDeps(ctx, deps)
94*333d2b36SAndroid Build Coastguard Worker
95*333d2b36SAndroid Build Coastguard Worker	static := Bool(binary.Properties.Static_executable)
96*333d2b36SAndroid Build Coastguard Worker	if ctx.toolchain().Bionic() {
97*333d2b36SAndroid Build Coastguard Worker		deps = bionicDeps(ctx, deps, static)
98*333d2b36SAndroid Build Coastguard Worker		if static {
99*333d2b36SAndroid Build Coastguard Worker			deps.CrtBegin = []string{"crtbegin_static"}
100*333d2b36SAndroid Build Coastguard Worker		} else {
101*333d2b36SAndroid Build Coastguard Worker			deps.CrtBegin = []string{"crtbegin_dynamic"}
102*333d2b36SAndroid Build Coastguard Worker		}
103*333d2b36SAndroid Build Coastguard Worker		deps.CrtEnd = []string{"crtend_android"}
104*333d2b36SAndroid Build Coastguard Worker	} else if ctx.Os() == android.LinuxMusl {
105*333d2b36SAndroid Build Coastguard Worker		deps = muslDeps(ctx, deps, static)
106*333d2b36SAndroid Build Coastguard Worker		if static {
107*333d2b36SAndroid Build Coastguard Worker			deps.CrtBegin = []string{"libc_musl_crtbegin_static"}
108*333d2b36SAndroid Build Coastguard Worker		} else {
109*333d2b36SAndroid Build Coastguard Worker			deps.CrtBegin = []string{"libc_musl_crtbegin_dynamic"}
110*333d2b36SAndroid Build Coastguard Worker		}
111*333d2b36SAndroid Build Coastguard Worker		deps.CrtEnd = []string{"libc_musl_crtend"}
112*333d2b36SAndroid Build Coastguard Worker	}
113*333d2b36SAndroid Build Coastguard Worker
114*333d2b36SAndroid Build Coastguard Worker	return deps
115*333d2b36SAndroid Build Coastguard Worker}
116*333d2b36SAndroid Build Coastguard Worker
117*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) compilerProps() []interface{} {
118*333d2b36SAndroid Build Coastguard Worker	return append(binary.baseCompiler.compilerProps(),
119*333d2b36SAndroid Build Coastguard Worker		&binary.Properties,
120*333d2b36SAndroid Build Coastguard Worker		&binary.stripper.StripProperties)
121*333d2b36SAndroid Build Coastguard Worker}
122*333d2b36SAndroid Build Coastguard Worker
123*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) nativeCoverage() bool {
124*333d2b36SAndroid Build Coastguard Worker	return true
125*333d2b36SAndroid Build Coastguard Worker}
126*333d2b36SAndroid Build Coastguard Worker
127*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) preferRlib() bool {
128*333d2b36SAndroid Build Coastguard Worker	return Bool(binary.baseCompiler.Properties.Prefer_rlib) || Bool(binary.Properties.Static_executable)
129*333d2b36SAndroid Build Coastguard Worker}
130*333d2b36SAndroid Build Coastguard Worker
131*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
132*333d2b36SAndroid Build Coastguard Worker	fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
133*333d2b36SAndroid Build Coastguard Worker	outputFile := android.PathForModuleOut(ctx, fileName)
134*333d2b36SAndroid Build Coastguard Worker	ret := buildOutput{outputFile: outputFile}
135*333d2b36SAndroid Build Coastguard Worker	crateRootPath := crateRootPath(ctx, binary)
136*333d2b36SAndroid Build Coastguard Worker
137*333d2b36SAndroid Build Coastguard Worker	// Ensure link dirs are not duplicated
138*333d2b36SAndroid Build Coastguard Worker	deps.linkDirs = android.FirstUniqueStrings(deps.linkDirs)
139*333d2b36SAndroid Build Coastguard Worker
140*333d2b36SAndroid Build Coastguard Worker	flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
141*333d2b36SAndroid Build Coastguard Worker	flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
142*333d2b36SAndroid Build Coastguard Worker	flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
143*333d2b36SAndroid Build Coastguard Worker
144*333d2b36SAndroid Build Coastguard Worker	if binary.stripper.NeedsStrip(ctx) {
145*333d2b36SAndroid Build Coastguard Worker		strippedOutputFile := outputFile
146*333d2b36SAndroid Build Coastguard Worker		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
147*333d2b36SAndroid Build Coastguard Worker		binary.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
148*333d2b36SAndroid Build Coastguard Worker
149*333d2b36SAndroid Build Coastguard Worker		binary.baseCompiler.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
150*333d2b36SAndroid Build Coastguard Worker	}
151*333d2b36SAndroid Build Coastguard Worker	binary.baseCompiler.unstrippedOutputFile = outputFile
152*333d2b36SAndroid Build Coastguard Worker
153*333d2b36SAndroid Build Coastguard Worker	ret.kytheFile = TransformSrcToBinary(ctx, crateRootPath, deps, flags, outputFile).kytheFile
154*333d2b36SAndroid Build Coastguard Worker	return ret
155*333d2b36SAndroid Build Coastguard Worker}
156*333d2b36SAndroid Build Coastguard Worker
157*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
158*333d2b36SAndroid Build Coastguard Worker	// Binaries default to dylib dependencies for device, rlib for host.
159*333d2b36SAndroid Build Coastguard Worker	if binary.preferRlib() {
160*333d2b36SAndroid Build Coastguard Worker		return rlibAutoDep
161*333d2b36SAndroid Build Coastguard Worker	} else if ctx.Device() {
162*333d2b36SAndroid Build Coastguard Worker		return dylibAutoDep
163*333d2b36SAndroid Build Coastguard Worker	} else {
164*333d2b36SAndroid Build Coastguard Worker		return rlibAutoDep
165*333d2b36SAndroid Build Coastguard Worker	}
166*333d2b36SAndroid Build Coastguard Worker}
167*333d2b36SAndroid Build Coastguard Worker
168*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) stdLinkage(ctx *depsContext) RustLinkage {
169*333d2b36SAndroid Build Coastguard Worker	if binary.preferRlib() {
170*333d2b36SAndroid Build Coastguard Worker		return RlibLinkage
171*333d2b36SAndroid Build Coastguard Worker	}
172*333d2b36SAndroid Build Coastguard Worker	return binary.baseCompiler.stdLinkage(ctx)
173*333d2b36SAndroid Build Coastguard Worker}
174*333d2b36SAndroid Build Coastguard Worker
175*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) binary() bool {
176*333d2b36SAndroid Build Coastguard Worker	return true
177*333d2b36SAndroid Build Coastguard Worker}
178*333d2b36SAndroid Build Coastguard Worker
179*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) staticallyLinked() bool {
180*333d2b36SAndroid Build Coastguard Worker	return Bool(binary.Properties.Static_executable)
181*333d2b36SAndroid Build Coastguard Worker}
182*333d2b36SAndroid Build Coastguard Worker
183*333d2b36SAndroid Build Coastguard Workerfunc (binary *binaryDecorator) testBinary() bool {
184*333d2b36SAndroid Build Coastguard Worker	return false
185*333d2b36SAndroid Build Coastguard Worker}
186