blob: ec6829a1bca264e84291ffc6f3aed3cb0de62d20 [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 "strings"
19 "testing"
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +020020
21 "android/soong/android"
Ivan Lozanoffee3342019-08-27 12:03:00 -070022)
23
24// Test that feature flags are being correctly generated.
25func TestFeaturesToFlags(t *testing.T) {
26 ctx := testRust(t, `
27 rust_library_host_dylib {
28 name: "libfoo",
29 srcs: ["foo.rs"],
30 crate_name: "foo",
31 features: [
32 "fizz",
33 "buzz"
34 ],
35 }`)
36
37 libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
38
39 if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"fizz\"'") ||
40 !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"buzz\"'") {
41 t.Fatalf("missing fizz and buzz feature flags for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
42 }
43}
44
Thiébaud Weksteenc44e7372021-04-07 14:53:06 +020045// Test that cfgs flags are being correctly generated.
46func TestCfgsToFlags(t *testing.T) {
47 ctx := testRust(t, `
48 rust_library_host {
49 name: "libfoo",
50 srcs: ["foo.rs"],
51 crate_name: "foo",
52 cfgs: [
53 "std",
54 "cfg1=\"one\""
55 ],
56 }`)
57
58 libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
59
60 if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'std'") ||
61 !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'cfg1=\"one\"'") {
62 t.Fatalf("missing std and cfg1 flags for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
63 }
64}
65
Ivan Lozanoffee3342019-08-27 12:03:00 -070066// Test that we reject multiple source files.
67func TestEnforceSingleSourceFile(t *testing.T) {
68
Ivan Lozano43845682020-07-09 21:03:28 -040069 singleSrcError := "srcs can only contain one path for a rust file and source providers prefixed by \":\""
Ivan Lozanoffee3342019-08-27 12:03:00 -070070
71 // Test libraries
72 testRustError(t, singleSrcError, `
73 rust_library_host {
74 name: "foo-bar-library",
75 srcs: ["foo.rs", "src/bar.rs"],
76 }`)
77
78 // Test binaries
79 testRustError(t, singleSrcError, `
80 rust_binary_host {
81 name: "foo-bar-binary",
82 srcs: ["foo.rs", "src/bar.rs"],
83 }`)
84
85 // Test proc_macros
86 testRustError(t, singleSrcError, `
87 rust_proc_macro {
88 name: "foo-bar-proc-macro",
89 srcs: ["foo.rs", "src/bar.rs"],
Ivan Lozanoffee3342019-08-27 12:03:00 -070090 }`)
91
92 // Test prebuilts
93 testRustError(t, singleSrcError, `
94 rust_prebuilt_dylib {
95 name: "foo-bar-prebuilt",
96 srcs: ["liby.so", "libz.so"],
97 host_supported: true,
98 }`)
99}
Ivan Lozanof900f4b2020-04-28 13:58:45 -0400100
Seth Moore3afac0b2021-10-13 15:32:18 -0700101// Test that we reject _no_ source files.
102func TestEnforceMissingSourceFiles(t *testing.T) {
103
104 singleSrcError := "srcs must not be empty"
105
106 // Test libraries
107 testRustError(t, singleSrcError, `
108 rust_library_host {
109 name: "foo-bar-library",
110 crate_name: "foo",
111 }`)
112
113 // Test binaries
114 testRustError(t, singleSrcError, `
115 rust_binary_host {
116 name: "foo-bar-binary",
117 crate_name: "foo",
118 }`)
119
120 // Test proc_macros
121 testRustError(t, singleSrcError, `
122 rust_proc_macro {
123 name: "foo-bar-proc-macro",
124 crate_name: "foo",
125 }`)
126
127 // Test prebuilts
128 testRustError(t, singleSrcError, `
129 rust_prebuilt_dylib {
130 name: "foo-bar-prebuilt",
131 crate_name: "foo",
132 host_supported: true,
133 }`)
134}
135
Ivan Lozanoa9a1fc02021-08-11 15:13:43 -0400136// Test environment vars for Cargo compat are set.
137func TestCargoCompat(t *testing.T) {
138 ctx := testRust(t, `
139 rust_binary {
140 name: "fizz",
141 srcs: ["foo.rs"],
142 crate_name: "foo",
143 cargo_env_compat: true,
144 cargo_pkg_version: "1.0.0"
145 }`)
146
147 fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc")
148
149 if !strings.Contains(fizz.Args["envVars"], "CARGO_BIN_NAME=fizz") {
150 t.Fatalf("expected 'CARGO_BIN_NAME=fizz' in envVars, actual envVars: %#v", fizz.Args["envVars"])
151 }
152 if !strings.Contains(fizz.Args["envVars"], "CARGO_CRATE_NAME=foo") {
153 t.Fatalf("expected 'CARGO_CRATE_NAME=foo' in envVars, actual envVars: %#v", fizz.Args["envVars"])
154 }
155 if !strings.Contains(fizz.Args["envVars"], "CARGO_PKG_VERSION=1.0.0") {
156 t.Fatalf("expected 'CARGO_PKG_VERSION=1.0.0' in envVars, actual envVars: %#v", fizz.Args["envVars"])
157 }
158}
159
Ivan Lozanof900f4b2020-04-28 13:58:45 -0400160func TestInstallDir(t *testing.T) {
161 ctx := testRust(t, `
162 rust_library_dylib {
163 name: "libfoo",
164 srcs: ["foo.rs"],
165 crate_name: "foo",
166 }
167 rust_binary {
168 name: "fizzbuzz",
169 srcs: ["foo.rs"],
170 }`)
171
172 install_path_lib64 := ctx.ModuleForTests("libfoo",
173 "android_arm64_armv8-a_dylib").Module().(*Module).compiler.(*libraryDecorator).path.String()
174 install_path_lib32 := ctx.ModuleForTests("libfoo",
175 "android_arm_armv7-a-neon_dylib").Module().(*Module).compiler.(*libraryDecorator).path.String()
176 install_path_bin := ctx.ModuleForTests("fizzbuzz",
177 "android_arm64_armv8-a").Module().(*Module).compiler.(*binaryDecorator).path.String()
178
179 if !strings.HasSuffix(install_path_lib64, "system/lib64/libfoo.dylib.so") {
180 t.Fatalf("unexpected install path for 64-bit library: %#v", install_path_lib64)
181 }
182 if !strings.HasSuffix(install_path_lib32, "system/lib/libfoo.dylib.so") {
183 t.Fatalf("unexpected install path for 32-bit library: %#v", install_path_lib32)
184 }
185 if !strings.HasSuffix(install_path_bin, "system/bin/fizzbuzz") {
186 t.Fatalf("unexpected install path for binary: %#v", install_path_bin)
187 }
188}
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200189
190func TestLints(t *testing.T) {
191
192 bp := `
193 // foo uses the default value of lints
194 rust_library {
195 name: "libfoo",
196 srcs: ["foo.rs"],
197 crate_name: "foo",
198 }
199 // bar forces the use of the "android" lint set
200 rust_library {
201 name: "libbar",
202 srcs: ["foo.rs"],
203 crate_name: "bar",
204 lints: "android",
205 }
206 // foobar explicitly disable all lints
207 rust_library {
208 name: "libfoobar",
209 srcs: ["foo.rs"],
210 crate_name: "foobar",
211 lints: "none",
212 }`
213
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200214 var lintTests = []struct {
215 modulePath string
216 fooFlags string
217 }{
218 {"", "${config.RustDefaultLints}"},
219 {"external/", "${config.RustAllowAllLints}"},
220 {"hardware/", "${config.RustVendorLints}"},
221 }
222
223 for _, tc := range lintTests {
224 t.Run("path="+tc.modulePath, func(t *testing.T) {
225
Paul Duffin9e0c3f92021-03-30 22:45:21 +0100226 result := android.GroupFixturePreparers(
227 prepareForRustTest,
228 // Test with the blueprint file in different directories.
229 android.FixtureAddTextFile(tc.modulePath+"Android.bp", bp),
230 ).RunTest(t)
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200231
Paul Duffin9e0c3f92021-03-30 22:45:21 +0100232 r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
233 android.AssertStringDoesContain(t, "libfoo flags", r.Args["rustcFlags"], tc.fooFlags)
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200234
Paul Duffin9e0c3f92021-03-30 22:45:21 +0100235 r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
236 android.AssertStringDoesContain(t, "libbar flags", r.Args["rustcFlags"], "${config.RustDefaultLints}")
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200237
Paul Duffin9e0c3f92021-03-30 22:45:21 +0100238 r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
239 android.AssertStringDoesContain(t, "libfoobar flags", r.Args["rustcFlags"], "${config.RustAllowAllLints}")
Thiébaud Weksteen9e8451e2020-08-13 12:55:59 +0200240 })
241 }
242}
Ivan Lozano042504f2020-08-18 14:31:23 -0400243
244// Test that devices are linking the stdlib dynamically
245func TestStdDeviceLinkage(t *testing.T) {
246 ctx := testRust(t, `
247 rust_binary {
248 name: "fizz",
249 srcs: ["foo.rs"],
250 }
251 rust_library {
252 name: "libfoo",
253 srcs: ["foo.rs"],
254 crate_name: "foo",
255 }`)
256 fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
Ivan Lozano2b081132020-09-08 12:46:52 -0400257 fooRlib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_rlib_dylib-std").Module().(*Module)
Ivan Lozano042504f2020-08-18 14:31:23 -0400258 fooDylib := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").Module().(*Module)
259
260 if !android.InList("libstd", fizz.Properties.AndroidMkDylibs) {
261 t.Errorf("libstd is not linked dynamically for device binaries")
262 }
263 if !android.InList("libstd", fooRlib.Properties.AndroidMkDylibs) {
264 t.Errorf("libstd is not linked dynamically for rlibs")
265 }
266 if !android.InList("libstd", fooDylib.Properties.AndroidMkDylibs) {
267 t.Errorf("libstd is not linked dynamically for dylibs")
268 }
269}
Ivan Lozano45a9e312021-07-27 12:29:12 -0400270
271// Ensure that manual link flags are disallowed.
272func TestManualLinkageRejection(t *testing.T) {
273 // rustc flags
274 testRustError(t, ".* cannot be manually specified", `
275 rust_binary {
276 name: "foo",
277 srcs: [
278 "foo.rs",
279 ],
280 flags: ["-lbar"],
281 }
282 `)
283 testRustError(t, ".* cannot be manually specified", `
284 rust_binary {
285 name: "foo",
286 srcs: [
287 "foo.rs",
288 ],
289 flags: ["--extern=foo"],
290 }
291 `)
292 testRustError(t, ".* cannot be manually specified", `
293 rust_binary {
294 name: "foo",
295 srcs: [
296 "foo.rs",
297 ],
298 flags: ["-Clink-args=foo"],
299 }
300 `)
301 testRustError(t, ".* cannot be manually specified", `
302 rust_binary {
303 name: "foo",
304 srcs: [
305 "foo.rs",
306 ],
307 flags: ["-C link-args=foo"],
308 }
309 `)
310 testRustError(t, ".* cannot be manually specified", `
311 rust_binary {
312 name: "foo",
313 srcs: [
314 "foo.rs",
315 ],
316 flags: ["-L foo/"],
317 }
318 `)
319
320 // lld flags
321 testRustError(t, ".* cannot be manually specified", `
322 rust_binary {
323 name: "foo",
324 srcs: [
325 "foo.rs",
326 ],
327 ld_flags: ["-Wl,-L bar/"],
328 }
329 `)
330 testRustError(t, ".* cannot be manually specified", `
331 rust_binary {
332 name: "foo",
333 srcs: [
334 "foo.rs",
335 ],
336 ld_flags: ["-Wl,-lbar"],
337 }
338 `)
339}