xref: /aosp_15_r20/build/soong/rust/library_test.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	"strings"
19*333d2b36SAndroid Build Coastguard Worker	"testing"
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
22*333d2b36SAndroid Build Coastguard Worker)
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker// Test that variants are being generated correctly, and that crate-types are correct.
25*333d2b36SAndroid Build Coastguard Workerfunc TestLibraryVariants(t *testing.T) {
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
28*333d2b36SAndroid Build Coastguard Worker		rust_library_host {
29*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
30*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
31*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
32*333d2b36SAndroid Build Coastguard Worker		}
33*333d2b36SAndroid Build Coastguard Worker		rust_ffi_host {
34*333d2b36SAndroid Build Coastguard Worker			name: "libfoo.ffi",
35*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
36*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo"
37*333d2b36SAndroid Build Coastguard Worker		}
38*333d2b36SAndroid Build Coastguard Worker		rust_ffi_host_static {
39*333d2b36SAndroid Build Coastguard Worker			name: "libfoo.ffi_static",
40*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
41*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo"
42*333d2b36SAndroid Build Coastguard Worker		}`)
43*333d2b36SAndroid Build Coastguard Worker
44*333d2b36SAndroid Build Coastguard Worker	// Test all variants are being built.
45*333d2b36SAndroid Build Coastguard Worker	libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
46*333d2b36SAndroid Build Coastguard Worker	libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
47*333d2b36SAndroid Build Coastguard Worker	libfooFFIRlib := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
48*333d2b36SAndroid Build Coastguard Worker	libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared").Rule("rustc")
49*333d2b36SAndroid Build Coastguard Worker
50*333d2b36SAndroid Build Coastguard Worker	rlibCrateType := "rlib"
51*333d2b36SAndroid Build Coastguard Worker	dylibCrateType := "dylib"
52*333d2b36SAndroid Build Coastguard Worker	sharedCrateType := "cdylib"
53*333d2b36SAndroid Build Coastguard Worker
54*333d2b36SAndroid Build Coastguard Worker	// Test crate type for rlib is correct.
55*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
56*333d2b36SAndroid Build Coastguard Worker		t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooRlib.Args["rustcFlags"])
57*333d2b36SAndroid Build Coastguard Worker	}
58*333d2b36SAndroid Build Coastguard Worker
59*333d2b36SAndroid Build Coastguard Worker	// Test crate type for dylib is correct.
60*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(libfooDylib.Args["rustcFlags"], "crate-type="+dylibCrateType) {
61*333d2b36SAndroid Build Coastguard Worker		t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", dylibCrateType, libfooDylib.Args["rustcFlags"])
62*333d2b36SAndroid Build Coastguard Worker	}
63*333d2b36SAndroid Build Coastguard Worker
64*333d2b36SAndroid Build Coastguard Worker	// Test crate type for FFI rlibs is correct
65*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(libfooFFIRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
66*333d2b36SAndroid Build Coastguard Worker		t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooFFIRlib.Args["rustcFlags"])
67*333d2b36SAndroid Build Coastguard Worker	}
68*333d2b36SAndroid Build Coastguard Worker
69*333d2b36SAndroid Build Coastguard Worker	// Test crate type for C shared libraries is correct.
70*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(libfooShared.Args["rustcFlags"], "crate-type="+sharedCrateType) {
71*333d2b36SAndroid Build Coastguard Worker		t.Errorf("missing crate-type for shared variant, expecting %#v, got rustcFlags: %#v", sharedCrateType, libfooShared.Args["rustcFlags"])
72*333d2b36SAndroid Build Coastguard Worker	}
73*333d2b36SAndroid Build Coastguard Worker
74*333d2b36SAndroid Build Coastguard Worker}
75*333d2b36SAndroid Build Coastguard Worker
76*333d2b36SAndroid Build Coastguard Worker// Test that dylibs are not statically linking the standard library.
77*333d2b36SAndroid Build Coastguard Workerfunc TestDylibPreferDynamic(t *testing.T) {
78*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
79*333d2b36SAndroid Build Coastguard Worker		rust_library_host_dylib {
80*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
81*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
82*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
83*333d2b36SAndroid Build Coastguard Worker		}`)
84*333d2b36SAndroid Build Coastguard Worker
85*333d2b36SAndroid Build Coastguard Worker	libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
86*333d2b36SAndroid Build Coastguard Worker
87*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(libfooDylib.Args["rustcFlags"], "prefer-dynamic") {
88*333d2b36SAndroid Build Coastguard Worker		t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
89*333d2b36SAndroid Build Coastguard Worker	}
90*333d2b36SAndroid Build Coastguard Worker}
91*333d2b36SAndroid Build Coastguard Worker
92*333d2b36SAndroid Build Coastguard Worker// Check that we are passing the android_dylib config flag
93*333d2b36SAndroid Build Coastguard Workerfunc TestAndroidDylib(t *testing.T) {
94*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
95*333d2b36SAndroid Build Coastguard Worker		rust_library_host_dylib {
96*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
97*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
98*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
99*333d2b36SAndroid Build Coastguard Worker		}`)
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Worker	libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(libfooDylib.Args["rustcFlags"], "--cfg 'android_dylib'") {
104*333d2b36SAndroid Build Coastguard Worker		t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
105*333d2b36SAndroid Build Coastguard Worker	}
106*333d2b36SAndroid Build Coastguard Worker}
107*333d2b36SAndroid Build Coastguard Worker
108*333d2b36SAndroid Build Coastguard Workerfunc TestValidateLibraryStem(t *testing.T) {
109*333d2b36SAndroid Build Coastguard Worker	testRustError(t, "crate_name must be defined.", `
110*333d2b36SAndroid Build Coastguard Worker			rust_library_host {
111*333d2b36SAndroid Build Coastguard Worker				name: "libfoo",
112*333d2b36SAndroid Build Coastguard Worker				srcs: ["foo.rs"],
113*333d2b36SAndroid Build Coastguard Worker			}`)
114*333d2b36SAndroid Build Coastguard Worker
115*333d2b36SAndroid Build Coastguard Worker	testRustError(t, "library crate_names must be alphanumeric with underscores allowed", `
116*333d2b36SAndroid Build Coastguard Worker			rust_library_host {
117*333d2b36SAndroid Build Coastguard Worker				name: "libfoo-bar",
118*333d2b36SAndroid Build Coastguard Worker				srcs: ["foo.rs"],
119*333d2b36SAndroid Build Coastguard Worker				crate_name: "foo-bar"
120*333d2b36SAndroid Build Coastguard Worker			}`)
121*333d2b36SAndroid Build Coastguard Worker
122*333d2b36SAndroid Build Coastguard Worker	testRustError(t, "Invalid name or stem property; library filenames must start with lib<crate_name>", `
123*333d2b36SAndroid Build Coastguard Worker			rust_library_host {
124*333d2b36SAndroid Build Coastguard Worker				name: "foobar",
125*333d2b36SAndroid Build Coastguard Worker				srcs: ["foo.rs"],
126*333d2b36SAndroid Build Coastguard Worker				crate_name: "foo_bar"
127*333d2b36SAndroid Build Coastguard Worker			}`)
128*333d2b36SAndroid Build Coastguard Worker	testRustError(t, "Invalid name or stem property; library filenames must start with lib<crate_name>", `
129*333d2b36SAndroid Build Coastguard Worker			rust_library_host {
130*333d2b36SAndroid Build Coastguard Worker				name: "foobar",
131*333d2b36SAndroid Build Coastguard Worker				stem: "libfoo",
132*333d2b36SAndroid Build Coastguard Worker				srcs: ["foo.rs"],
133*333d2b36SAndroid Build Coastguard Worker				crate_name: "foo_bar"
134*333d2b36SAndroid Build Coastguard Worker			}`)
135*333d2b36SAndroid Build Coastguard Worker	testRustError(t, "Invalid name or stem property; library filenames must start with lib<crate_name>", `
136*333d2b36SAndroid Build Coastguard Worker			rust_library_host {
137*333d2b36SAndroid Build Coastguard Worker				name: "foobar",
138*333d2b36SAndroid Build Coastguard Worker				stem: "foo_bar",
139*333d2b36SAndroid Build Coastguard Worker				srcs: ["foo.rs"],
140*333d2b36SAndroid Build Coastguard Worker				crate_name: "foo_bar"
141*333d2b36SAndroid Build Coastguard Worker			}`)
142*333d2b36SAndroid Build Coastguard Worker
143*333d2b36SAndroid Build Coastguard Worker}
144*333d2b36SAndroid Build Coastguard Worker
145*333d2b36SAndroid Build Coastguard Workerfunc TestSharedLibrary(t *testing.T) {
146*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
147*333d2b36SAndroid Build Coastguard Worker		rust_ffi_shared {
148*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
149*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
150*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
151*333d2b36SAndroid Build Coastguard Worker		}`)
152*333d2b36SAndroid Build Coastguard Worker
153*333d2b36SAndroid Build Coastguard Worker	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared")
154*333d2b36SAndroid Build Coastguard Worker
155*333d2b36SAndroid Build Coastguard Worker	libfooOutput := libfoo.Rule("rustc")
156*333d2b36SAndroid Build Coastguard Worker	if !strings.Contains(libfooOutput.Args["linkFlags"], "-Wl,-soname=libfoo.so") {
157*333d2b36SAndroid Build Coastguard Worker		t.Errorf("missing expected -Wl,-soname linker flag for libfoo shared lib, linkFlags: %#v",
158*333d2b36SAndroid Build Coastguard Worker			libfooOutput.Args["linkFlags"])
159*333d2b36SAndroid Build Coastguard Worker	}
160*333d2b36SAndroid Build Coastguard Worker
161*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkDylibs) {
162*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Non-static libstd dylib expected to be a dependency of Rust shared libraries. Dylib deps are: %#v",
163*333d2b36SAndroid Build Coastguard Worker			libfoo.Module().(*Module).Properties.AndroidMkDylibs)
164*333d2b36SAndroid Build Coastguard Worker	}
165*333d2b36SAndroid Build Coastguard Worker}
166*333d2b36SAndroid Build Coastguard Worker
167*333d2b36SAndroid Build Coastguard Workerfunc TestSharedLibraryToc(t *testing.T) {
168*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
169*333d2b36SAndroid Build Coastguard Worker		rust_ffi_shared {
170*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
171*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
172*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
173*333d2b36SAndroid Build Coastguard Worker		}
174*333d2b36SAndroid Build Coastguard Worker		cc_binary {
175*333d2b36SAndroid Build Coastguard Worker			name: "fizzbuzz",
176*333d2b36SAndroid Build Coastguard Worker			shared_libs: ["libfoo"],
177*333d2b36SAndroid Build Coastguard Worker		}`)
178*333d2b36SAndroid Build Coastguard Worker
179*333d2b36SAndroid Build Coastguard Worker	fizzbuzz := ctx.ModuleForTests("fizzbuzz", "android_arm64_armv8-a").Rule("ld")
180*333d2b36SAndroid Build Coastguard Worker
181*333d2b36SAndroid Build Coastguard Worker	if !android.SuffixInList(fizzbuzz.Implicits.Strings(), "libfoo.so.toc") {
182*333d2b36SAndroid Build Coastguard Worker		t.Errorf("missing expected libfoo.so.toc implicit dependency, instead found: %#v",
183*333d2b36SAndroid Build Coastguard Worker			fizzbuzz.Implicits.Strings())
184*333d2b36SAndroid Build Coastguard Worker	}
185*333d2b36SAndroid Build Coastguard Worker}
186*333d2b36SAndroid Build Coastguard Worker
187*333d2b36SAndroid Build Coastguard Workerfunc TestStaticLibraryLinkage(t *testing.T) {
188*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
189*333d2b36SAndroid Build Coastguard Worker		rust_ffi_static {
190*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
191*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
192*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
193*333d2b36SAndroid Build Coastguard Worker		}`)
194*333d2b36SAndroid Build Coastguard Worker
195*333d2b36SAndroid Build Coastguard Worker	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_rlib-std")
196*333d2b36SAndroid Build Coastguard Worker
197*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkRlibs) {
198*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Static libstd rlib expected to be a dependency of Rust rlib libraries. Rlib deps are: %#v",
199*333d2b36SAndroid Build Coastguard Worker			libfoo.Module().(*Module).Properties.AndroidMkDylibs)
200*333d2b36SAndroid Build Coastguard Worker	}
201*333d2b36SAndroid Build Coastguard Worker}
202*333d2b36SAndroid Build Coastguard Worker
203*333d2b36SAndroid Build Coastguard Workerfunc TestNativeDependencyOfRlib(t *testing.T) {
204*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
205*333d2b36SAndroid Build Coastguard Worker		rust_ffi_rlib {
206*333d2b36SAndroid Build Coastguard Worker			name: "libffi_rlib",
207*333d2b36SAndroid Build Coastguard Worker			crate_name: "ffi_rlib",
208*333d2b36SAndroid Build Coastguard Worker			rlibs: ["librust_rlib"],
209*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
210*333d2b36SAndroid Build Coastguard Worker		}
211*333d2b36SAndroid Build Coastguard Worker		rust_library_rlib {
212*333d2b36SAndroid Build Coastguard Worker			name: "librust_rlib",
213*333d2b36SAndroid Build Coastguard Worker			crate_name: "rust_rlib",
214*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
215*333d2b36SAndroid Build Coastguard Worker			shared_libs: ["libshared_cc_dep"],
216*333d2b36SAndroid Build Coastguard Worker			static_libs: ["libstatic_cc_dep"],
217*333d2b36SAndroid Build Coastguard Worker		}
218*333d2b36SAndroid Build Coastguard Worker		cc_library_shared {
219*333d2b36SAndroid Build Coastguard Worker			name: "libshared_cc_dep",
220*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.cpp"],
221*333d2b36SAndroid Build Coastguard Worker		}
222*333d2b36SAndroid Build Coastguard Worker		cc_library_static {
223*333d2b36SAndroid Build Coastguard Worker			name: "libstatic_cc_dep",
224*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.cpp"],
225*333d2b36SAndroid Build Coastguard Worker		}
226*333d2b36SAndroid Build Coastguard Worker		`)
227*333d2b36SAndroid Build Coastguard Worker
228*333d2b36SAndroid Build Coastguard Worker	rustRlibRlibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_rlib-std")
229*333d2b36SAndroid Build Coastguard Worker	rustRlibDylibStd := ctx.ModuleForTests("librust_rlib", "android_arm64_armv8-a_rlib_dylib-std")
230*333d2b36SAndroid Build Coastguard Worker	ffiRlib := ctx.ModuleForTests("libffi_rlib", "android_arm64_armv8-a_rlib_rlib-std")
231*333d2b36SAndroid Build Coastguard Worker
232*333d2b36SAndroid Build Coastguard Worker	modules := []android.TestingModule{
233*333d2b36SAndroid Build Coastguard Worker		rustRlibRlibStd,
234*333d2b36SAndroid Build Coastguard Worker		rustRlibDylibStd,
235*333d2b36SAndroid Build Coastguard Worker		ffiRlib,
236*333d2b36SAndroid Build Coastguard Worker	}
237*333d2b36SAndroid Build Coastguard Worker
238*333d2b36SAndroid Build Coastguard Worker	// librust_rlib specifies -L flag to cc deps output directory on rustc command
239*333d2b36SAndroid Build Coastguard Worker	// and re-export the cc deps to rdep libffi_static
240*333d2b36SAndroid Build Coastguard Worker	// When building rlib crate, rustc doesn't link the native libraries
241*333d2b36SAndroid Build Coastguard Worker	// The build system assumes the  cc deps will be at the final linkage (either a shared library or binary)
242*333d2b36SAndroid Build Coastguard Worker	// Hence, these flags are no-op
243*333d2b36SAndroid Build Coastguard Worker	// TODO: We could consider removing these flags
244*333d2b36SAndroid Build Coastguard Worker	for _, module := range modules {
245*333d2b36SAndroid Build Coastguard Worker		if !strings.Contains(module.Rule("rustc").Args["libFlags"],
246*333d2b36SAndroid Build Coastguard Worker			"-L out/soong/.intermediates/libshared_cc_dep/android_arm64_armv8-a_shared/") {
247*333d2b36SAndroid Build Coastguard Worker			t.Errorf(
248*333d2b36SAndroid Build Coastguard Worker				"missing -L flag for libshared_cc_dep of %s, rustcFlags: %#v",
249*333d2b36SAndroid Build Coastguard Worker				module.Module().Name(), rustRlibRlibStd.Rule("rustc").Args["libFlags"],
250*333d2b36SAndroid Build Coastguard Worker			)
251*333d2b36SAndroid Build Coastguard Worker		}
252*333d2b36SAndroid Build Coastguard Worker		if !strings.Contains(module.Rule("rustc").Args["libFlags"],
253*333d2b36SAndroid Build Coastguard Worker			"-L out/soong/.intermediates/libstatic_cc_dep/android_arm64_armv8-a_static/") {
254*333d2b36SAndroid Build Coastguard Worker			t.Errorf(
255*333d2b36SAndroid Build Coastguard Worker				"missing -L flag for libstatic_cc_dep of %s, rustcFlags: %#v",
256*333d2b36SAndroid Build Coastguard Worker				module.Module().Name(), rustRlibRlibStd.Rule("rustc").Args["libFlags"],
257*333d2b36SAndroid Build Coastguard Worker			)
258*333d2b36SAndroid Build Coastguard Worker		}
259*333d2b36SAndroid Build Coastguard Worker	}
260*333d2b36SAndroid Build Coastguard Worker}
261*333d2b36SAndroid Build Coastguard Worker
262*333d2b36SAndroid Build Coastguard Worker// Test that variants pull in the right type of rustlib autodep
263*333d2b36SAndroid Build Coastguard Workerfunc TestAutoDeps(t *testing.T) {
264*333d2b36SAndroid Build Coastguard Worker
265*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
266*333d2b36SAndroid Build Coastguard Worker		rust_library_host {
267*333d2b36SAndroid Build Coastguard Worker			name: "libbar",
268*333d2b36SAndroid Build Coastguard Worker			srcs: ["bar.rs"],
269*333d2b36SAndroid Build Coastguard Worker			crate_name: "bar",
270*333d2b36SAndroid Build Coastguard Worker		}
271*333d2b36SAndroid Build Coastguard Worker		rust_library_host_rlib {
272*333d2b36SAndroid Build Coastguard Worker			name: "librlib_only",
273*333d2b36SAndroid Build Coastguard Worker			srcs: ["bar.rs"],
274*333d2b36SAndroid Build Coastguard Worker			crate_name: "rlib_only",
275*333d2b36SAndroid Build Coastguard Worker		}
276*333d2b36SAndroid Build Coastguard Worker		rust_library_host {
277*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
278*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
279*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
280*333d2b36SAndroid Build Coastguard Worker			rustlibs: [
281*333d2b36SAndroid Build Coastguard Worker				"libbar",
282*333d2b36SAndroid Build Coastguard Worker				"librlib_only",
283*333d2b36SAndroid Build Coastguard Worker			],
284*333d2b36SAndroid Build Coastguard Worker		}
285*333d2b36SAndroid Build Coastguard Worker		rust_ffi_host {
286*333d2b36SAndroid Build Coastguard Worker			name: "libfoo.ffi",
287*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
288*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
289*333d2b36SAndroid Build Coastguard Worker			rustlibs: [
290*333d2b36SAndroid Build Coastguard Worker				"libbar",
291*333d2b36SAndroid Build Coastguard Worker				"librlib_only",
292*333d2b36SAndroid Build Coastguard Worker			],
293*333d2b36SAndroid Build Coastguard Worker		}
294*333d2b36SAndroid Build Coastguard Worker		rust_ffi_host_static {
295*333d2b36SAndroid Build Coastguard Worker			name: "libfoo.ffi.static",
296*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
297*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
298*333d2b36SAndroid Build Coastguard Worker			rustlibs: [
299*333d2b36SAndroid Build Coastguard Worker				"libbar",
300*333d2b36SAndroid Build Coastguard Worker				"librlib_only",
301*333d2b36SAndroid Build Coastguard Worker			],
302*333d2b36SAndroid Build Coastguard Worker		}`)
303*333d2b36SAndroid Build Coastguard Worker
304*333d2b36SAndroid Build Coastguard Worker	libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std")
305*333d2b36SAndroid Build Coastguard Worker	libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib")
306*333d2b36SAndroid Build Coastguard Worker	libfooFFIRlib := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_rlib_rlib-std")
307*333d2b36SAndroid Build Coastguard Worker	libfooShared := ctx.ModuleForTests("libfoo.ffi", "linux_glibc_x86_64_shared")
308*333d2b36SAndroid Build Coastguard Worker
309*333d2b36SAndroid Build Coastguard Worker	for _, static := range []android.TestingModule{libfooRlib, libfooFFIRlib} {
310*333d2b36SAndroid Build Coastguard Worker		if !android.InList("libbar.rlib-std", static.Module().(*Module).Properties.AndroidMkRlibs) {
311*333d2b36SAndroid Build Coastguard Worker			t.Errorf("libbar not present as rlib dependency in static lib: %s", static.Module().Name())
312*333d2b36SAndroid Build Coastguard Worker		}
313*333d2b36SAndroid Build Coastguard Worker		if android.InList("libbar", static.Module().(*Module).Properties.AndroidMkDylibs) {
314*333d2b36SAndroid Build Coastguard Worker			t.Errorf("libbar present as dynamic dependency in static lib: %s", static.Module().Name())
315*333d2b36SAndroid Build Coastguard Worker		}
316*333d2b36SAndroid Build Coastguard Worker	}
317*333d2b36SAndroid Build Coastguard Worker
318*333d2b36SAndroid Build Coastguard Worker	for _, dyn := range []android.TestingModule{libfooDylib, libfooShared} {
319*333d2b36SAndroid Build Coastguard Worker		if !android.InList("libbar", dyn.Module().(*Module).Properties.AndroidMkDylibs) {
320*333d2b36SAndroid Build Coastguard Worker			t.Errorf("libbar not present as dynamic dependency in dynamic lib: %s", dyn.Module().Name())
321*333d2b36SAndroid Build Coastguard Worker		}
322*333d2b36SAndroid Build Coastguard Worker		if android.InList("libbar", dyn.Module().(*Module).Properties.AndroidMkRlibs) {
323*333d2b36SAndroid Build Coastguard Worker			t.Errorf("libbar present as rlib dependency in dynamic lib: %s", dyn.Module().Name())
324*333d2b36SAndroid Build Coastguard Worker		}
325*333d2b36SAndroid Build Coastguard Worker		if !android.InList("librlib_only", dyn.Module().(*Module).Properties.AndroidMkRlibs) {
326*333d2b36SAndroid Build Coastguard Worker			t.Errorf("librlib_only should be selected by rustlibs as an rlib: %s.", dyn.Module().Name())
327*333d2b36SAndroid Build Coastguard Worker		}
328*333d2b36SAndroid Build Coastguard Worker	}
329*333d2b36SAndroid Build Coastguard Worker}
330*333d2b36SAndroid Build Coastguard Worker
331*333d2b36SAndroid Build Coastguard Worker// Test that stripped versions are correctly generated and used.
332*333d2b36SAndroid Build Coastguard Workerfunc TestStrippedLibrary(t *testing.T) {
333*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
334*333d2b36SAndroid Build Coastguard Worker		rust_library_dylib {
335*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
336*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
337*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
338*333d2b36SAndroid Build Coastguard Worker		}
339*333d2b36SAndroid Build Coastguard Worker		rust_library_dylib {
340*333d2b36SAndroid Build Coastguard Worker			name: "libbar",
341*333d2b36SAndroid Build Coastguard Worker			crate_name: "bar",
342*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
343*333d2b36SAndroid Build Coastguard Worker			strip: {
344*333d2b36SAndroid Build Coastguard Worker				none: true
345*333d2b36SAndroid Build Coastguard Worker			}
346*333d2b36SAndroid Build Coastguard Worker		}
347*333d2b36SAndroid Build Coastguard Worker	`)
348*333d2b36SAndroid Build Coastguard Worker
349*333d2b36SAndroid Build Coastguard Worker	foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib")
350*333d2b36SAndroid Build Coastguard Worker	foo.Output("libfoo.dylib.so")
351*333d2b36SAndroid Build Coastguard Worker	foo.Output("unstripped/libfoo.dylib.so")
352*333d2b36SAndroid Build Coastguard Worker	// Check that the `cp` rule is using the stripped version as input.
353*333d2b36SAndroid Build Coastguard Worker	cp := foo.Rule("android.Cp")
354*333d2b36SAndroid Build Coastguard Worker	if strings.HasSuffix(cp.Input.String(), "unstripped/libfoo.dylib.so") {
355*333d2b36SAndroid Build Coastguard Worker		t.Errorf("installed library not based on stripped version: %v", cp.Input)
356*333d2b36SAndroid Build Coastguard Worker	}
357*333d2b36SAndroid Build Coastguard Worker
358*333d2b36SAndroid Build Coastguard Worker	fizzBar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeOutput("unstripped/libbar.dylib.so")
359*333d2b36SAndroid Build Coastguard Worker	if fizzBar.Rule != nil {
360*333d2b36SAndroid Build Coastguard Worker		t.Errorf("unstripped library exists, so stripped library has incorrectly been generated")
361*333d2b36SAndroid Build Coastguard Worker	}
362*333d2b36SAndroid Build Coastguard Worker}
363*333d2b36SAndroid Build Coastguard Worker
364*333d2b36SAndroid Build Coastguard Workerfunc TestLibstdLinkage(t *testing.T) {
365*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
366*333d2b36SAndroid Build Coastguard Worker		rust_library {
367*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
368*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
369*333d2b36SAndroid Build Coastguard Worker			crate_name: "foo",
370*333d2b36SAndroid Build Coastguard Worker		}
371*333d2b36SAndroid Build Coastguard Worker		rust_ffi {
372*333d2b36SAndroid Build Coastguard Worker			name: "libbar",
373*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
374*333d2b36SAndroid Build Coastguard Worker			crate_name: "bar",
375*333d2b36SAndroid Build Coastguard Worker			rustlibs: ["libfoo"],
376*333d2b36SAndroid Build Coastguard Worker		}
377*333d2b36SAndroid Build Coastguard Worker		rust_ffi_static {
378*333d2b36SAndroid Build Coastguard Worker			name: "libbar_static",
379*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
380*333d2b36SAndroid Build Coastguard Worker			crate_name: "bar",
381*333d2b36SAndroid Build Coastguard Worker			rustlibs: ["libfoo"],
382*333d2b36SAndroid Build Coastguard Worker		}
383*333d2b36SAndroid Build Coastguard Worker		rust_ffi {
384*333d2b36SAndroid Build Coastguard Worker			name: "libbar.prefer_rlib",
385*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
386*333d2b36SAndroid Build Coastguard Worker			crate_name: "bar",
387*333d2b36SAndroid Build Coastguard Worker			rustlibs: ["libfoo"],
388*333d2b36SAndroid Build Coastguard Worker			prefer_rlib: true,
389*333d2b36SAndroid Build Coastguard Worker		}`)
390*333d2b36SAndroid Build Coastguard Worker
391*333d2b36SAndroid Build Coastguard Worker	libfooDylib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)
392*333d2b36SAndroid Build Coastguard Worker	libfooRlibStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
393*333d2b36SAndroid Build Coastguard Worker	libfooRlibDynamic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_dylib-std").Module().(*Module)
394*333d2b36SAndroid Build Coastguard Worker
395*333d2b36SAndroid Build Coastguard Worker	libbarShared := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module().(*Module)
396*333d2b36SAndroid Build Coastguard Worker	libbarFFIRlib := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_rlib_rlib-std").Module().(*Module)
397*333d2b36SAndroid Build Coastguard Worker
398*333d2b36SAndroid Build Coastguard Worker	// prefer_rlib works the same for both rust_library and rust_ffi, so a single check is sufficient here.
399*333d2b36SAndroid Build Coastguard Worker	libbarRlibStd := ctx.ModuleForTests("libbar.prefer_rlib", "android_arm64_armv8-a_shared").Module().(*Module)
400*333d2b36SAndroid Build Coastguard Worker
401*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libstd", libfooRlibStatic.Properties.AndroidMkRlibs) {
402*333d2b36SAndroid Build Coastguard Worker		t.Errorf("rlib-std variant for device rust_library_rlib does not link libstd as an rlib")
403*333d2b36SAndroid Build Coastguard Worker	}
404*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libstd", libfooRlibDynamic.Properties.AndroidMkDylibs) {
405*333d2b36SAndroid Build Coastguard Worker		t.Errorf("dylib-std variant for device rust_library_rlib does not link libstd as an dylib")
406*333d2b36SAndroid Build Coastguard Worker	}
407*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libstd", libfooDylib.Properties.AndroidMkDylibs) {
408*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Device rust_library_dylib does not link libstd as an dylib")
409*333d2b36SAndroid Build Coastguard Worker	}
410*333d2b36SAndroid Build Coastguard Worker
411*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libstd", libbarShared.Properties.AndroidMkDylibs) {
412*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Device rust_ffi_shared does not link libstd as an dylib")
413*333d2b36SAndroid Build Coastguard Worker	}
414*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libstd", libbarFFIRlib.Properties.AndroidMkRlibs) {
415*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Device rust_ffi_rlib does not link libstd as an rlib")
416*333d2b36SAndroid Build Coastguard Worker	}
417*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libfoo.rlib-std", libbarFFIRlib.Properties.AndroidMkRlibs) {
418*333d2b36SAndroid Build Coastguard Worker		t.Errorf("Device rust_ffi_rlib does not link dependent rustlib rlib-std variant")
419*333d2b36SAndroid Build Coastguard Worker	}
420*333d2b36SAndroid Build Coastguard Worker	if !android.InList("libstd", libbarRlibStd.Properties.AndroidMkRlibs) {
421*333d2b36SAndroid Build Coastguard Worker		t.Errorf("rust_ffi with prefer_rlib does not link libstd as an rlib")
422*333d2b36SAndroid Build Coastguard Worker	}
423*333d2b36SAndroid Build Coastguard Worker
424*333d2b36SAndroid Build Coastguard Worker}
425*333d2b36SAndroid Build Coastguard Worker
426*333d2b36SAndroid Build Coastguard Workerfunc TestRustFFIExportedIncludes(t *testing.T) {
427*333d2b36SAndroid Build Coastguard Worker	ctx := testRust(t, `
428*333d2b36SAndroid Build Coastguard Worker		rust_ffi {
429*333d2b36SAndroid Build Coastguard Worker			name: "libbar",
430*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.rs"],
431*333d2b36SAndroid Build Coastguard Worker			crate_name: "bar",
432*333d2b36SAndroid Build Coastguard Worker			export_include_dirs: ["rust_includes"],
433*333d2b36SAndroid Build Coastguard Worker			host_supported: true,
434*333d2b36SAndroid Build Coastguard Worker		}
435*333d2b36SAndroid Build Coastguard Worker		cc_library_static {
436*333d2b36SAndroid Build Coastguard Worker			name: "libfoo",
437*333d2b36SAndroid Build Coastguard Worker			srcs: ["foo.cpp"],
438*333d2b36SAndroid Build Coastguard Worker			shared_libs: ["libbar"],
439*333d2b36SAndroid Build Coastguard Worker			host_supported: true,
440*333d2b36SAndroid Build Coastguard Worker		}`)
441*333d2b36SAndroid Build Coastguard Worker	libfooStatic := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_static").Rule("cc")
442*333d2b36SAndroid Build Coastguard Worker	android.AssertStringDoesContain(t, "cFlags for lib module", libfooStatic.Args["cFlags"], " -Irust_includes ")
443*333d2b36SAndroid Build Coastguard Worker}
444