blob: 2b7362f08a6aa350ca3b9fcf81b46182f5b57801 [file] [log] [blame]
Ivan Lozano4fef93c2020-07-08 08:39:44 -04001// Copyright 2020 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"
Ivan Lozano1dbfa142024-03-29 14:48:11 +000020
21 "android/soong/android"
Ivan Lozano4fef93c2020-07-08 08:39:44 -040022)
23
24func TestRustBindgen(t *testing.T) {
25 ctx := testRust(t, `
26 rust_bindgen {
27 name: "libbindgen",
Ivan Lozanobc9e4212020-09-25 16:08:34 -040028 defaults: ["cc_defaults_flags"],
Ivan Lozano4fef93c2020-07-08 08:39:44 -040029 wrapper_src: "src/any.h",
Ivan Lozano26ecd6c2020-07-31 13:40:31 -040030 crate_name: "bindgen",
31 stem: "libbindgen",
32 source_stem: "bindings",
Stephen Crane12e2cb72020-08-04 12:26:10 -070033 bindgen_flags: ["--bindgen-flag.*"],
34 cflags: ["--clang-flag()"],
Ivan Lozano4fef93c2020-07-08 08:39:44 -040035 shared_libs: ["libfoo_shared"],
Ivan Lozano1dbfa142024-03-29 14:48:11 +000036 }
37 rust_bindgen {
38 name: "libbindgen_staticlib",
39 wrapper_src: "src/any.h",
40 crate_name: "bindgen_staticlib",
41 stem: "libbindgen_staticlib",
42 source_stem: "bindings",
Ivan Lozano4fef93c2020-07-08 08:39:44 -040043 static_libs: ["libfoo_static"],
Ivan Lozano1dbfa142024-03-29 14:48:11 +000044 }
45 rust_bindgen {
46 name: "libbindgen_headerlib",
47 wrapper_src: "src/any.h",
48 crate_name: "bindgen_headerlib",
49 stem: "libbindgen_headerlib",
50 source_stem: "bindings",
Ivan Lozano9b443832020-11-17 13:39:30 -050051 header_libs: ["libfoo_header"],
Ivan Lozano4fef93c2020-07-08 08:39:44 -040052 }
53 cc_library_shared {
54 name: "libfoo_shared",
55 export_include_dirs: ["shared_include"],
56 }
57 cc_library_static {
58 name: "libfoo_static",
59 export_include_dirs: ["static_include"],
60 }
Ivan Lozano9b443832020-11-17 13:39:30 -050061 cc_library_headers {
62 name: "libfoo_header",
63 export_include_dirs: ["header_include"],
64 }
Ivan Lozanobc9e4212020-09-25 16:08:34 -040065 cc_defaults {
66 name: "cc_defaults_flags",
67 cflags: ["--default-flag"],
68 }
Ivan Lozano4fef93c2020-07-08 08:39:44 -040069 `)
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +020070 libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
Ivan Lozano1dbfa142024-03-29 14:48:11 +000071 libbindgenStatic := ctx.ModuleForTests("libbindgen_staticlib", "android_arm64_armv8-a_source").Output("bindings.rs")
72 libbindgenHeader := ctx.ModuleForTests("libbindgen_headerlib", "android_arm64_armv8-a_source").Output("bindings.rs")
73 libbindgenHeaderModule := ctx.ModuleForTests("libbindgen_headerlib", "android_arm64_armv8-a_source").Module().(*Module)
Stephen Crane12e2cb72020-08-04 12:26:10 -070074 // Ensure that the flags are present and escaped
75 if !strings.Contains(libbindgen.Args["flags"], "'--bindgen-flag.*'") {
Ivan Lozano4fef93c2020-07-08 08:39:44 -040076 t.Errorf("missing bindgen flags in rust_bindgen rule: flags %#v", libbindgen.Args["flags"])
77 }
Stephen Crane12e2cb72020-08-04 12:26:10 -070078 if !strings.Contains(libbindgen.Args["cflags"], "'--clang-flag()'") {
Ivan Lozano4fef93c2020-07-08 08:39:44 -040079 t.Errorf("missing clang cflags in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
80 }
81 if !strings.Contains(libbindgen.Args["cflags"], "-Ishared_include") {
Ivan Lozano45901ed2020-07-24 16:05:01 -040082 t.Errorf("missing shared_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"])
Ivan Lozano4fef93c2020-07-08 08:39:44 -040083 }
Ivan Lozano1dbfa142024-03-29 14:48:11 +000084 if !strings.Contains(libbindgenStatic.Args["cflags"], "-Istatic_include") {
85 t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgenStatic.Args["cflags"])
Ivan Lozano4fef93c2020-07-08 08:39:44 -040086 }
Ivan Lozano1dbfa142024-03-29 14:48:11 +000087 if !strings.Contains(libbindgenHeader.Args["cflags"], "-Iheader_include") {
88 t.Errorf("missing header_libs exported includes in rust_bindgen rule: cflags %#v", libbindgenHeader.Args["cflags"])
Ivan Lozano9b443832020-11-17 13:39:30 -050089 }
Ivan Lozano1dbfa142024-03-29 14:48:11 +000090
91 if android.InList("libfoo_static", libbindgenHeaderModule.Properties.AndroidMkHeaderLibs) {
92 t.Errorf("Static library dependency should not be in HeaderLibs list")
93 }
94
Ivan Lozanobc9e4212020-09-25 16:08:34 -040095 if !strings.Contains(libbindgen.Args["cflags"], "--default-flag") {
96 t.Errorf("rust_bindgen missing cflags defined in cc_defaults: cflags %#v", libbindgen.Args["cflags"])
97 }
Ivan Lozano4fef93c2020-07-08 08:39:44 -040098}
Ivan Lozanoc564d2d2020-08-04 15:43:37 -040099
100func TestRustBindgenCustomBindgen(t *testing.T) {
101 ctx := testRust(t, `
102 rust_bindgen {
103 name: "libbindgen",
104 wrapper_src: "src/any.h",
105 crate_name: "bindgen",
106 stem: "libbindgen",
107 source_stem: "bindings",
108 custom_bindgen: "my_bindgen"
109 }
110 rust_binary_host {
111 name: "my_bindgen",
112 srcs: ["foo.rs"],
113 }
114 `)
115
Thiébaud Weksteen295c72b2020-09-23 18:10:17 +0200116 libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
Ivan Lozanoc564d2d2020-08-04 15:43:37 -0400117
118 // The rule description should contain the custom binary name rather than bindgen, so checking the description
119 // should be sufficient.
120 if !strings.Contains(libbindgen.Description, "my_bindgen") {
121 t.Errorf("Custom bindgen binary %s not used for libbindgen: rule description %#v", "my_bindgen",
122 libbindgen.Description)
123 }
124}
Ivan Lozano3d947522020-09-23 13:26:25 -0400125
126func TestRustBindgenStdVersions(t *testing.T) {
127 testRustError(t, "c_std and cpp_std cannot both be defined at the same time.", `
128 rust_bindgen {
129 name: "libbindgen",
130 wrapper_src: "src/any.h",
131 crate_name: "bindgen",
132 stem: "libbindgen",
133 source_stem: "bindings",
134 c_std: "somevalue",
135 cpp_std: "somevalue",
136 }
137 `)
138
139 ctx := testRust(t, `
140 rust_bindgen {
141 name: "libbindgen_cstd",
Ivan Lozano829e1e92023-10-09 11:30:09 -0400142 wrapper_src: "src/any.hpp",
Ivan Lozano3d947522020-09-23 13:26:25 -0400143 crate_name: "bindgen",
144 stem: "libbindgen",
145 source_stem: "bindings",
146 c_std: "foo"
147 }
148 rust_bindgen {
149 name: "libbindgen_cppstd",
150 wrapper_src: "src/any.h",
151 crate_name: "bindgen",
152 stem: "libbindgen",
153 source_stem: "bindings",
154 cpp_std: "foo"
155 }
156 `)
157
Thiébaud Weksteene0510d72020-09-25 15:50:09 +0200158 libbindgen_cstd := ctx.ModuleForTests("libbindgen_cstd", "android_arm64_armv8-a_source").Output("bindings.rs")
159 libbindgen_cppstd := ctx.ModuleForTests("libbindgen_cppstd", "android_arm64_armv8-a_source").Output("bindings.rs")
Ivan Lozano3d947522020-09-23 13:26:25 -0400160
161 if !strings.Contains(libbindgen_cstd.Args["cflags"], "-std=foo") {
162 t.Errorf("c_std value not passed in to rust_bindgen as a clang flag")
163 }
164
165 if !strings.Contains(libbindgen_cppstd.Args["cflags"], "-std=foo") {
166 t.Errorf("cpp_std value not passed in to rust_bindgen as a clang flag")
167 }
Ivan Lozano829e1e92023-10-09 11:30:09 -0400168
169 // Make sure specifying cpp_std emits the '-x c++' flag
170 if !strings.Contains(libbindgen_cppstd.Args["cflags"], "-x c++") {
171 t.Errorf("Setting cpp_std should cause the '-x c++' flag to be emitted")
172 }
173
174 // Make sure specifying c_std omits the '-x c++' flag
175 if strings.Contains(libbindgen_cstd.Args["cflags"], "-x c++") {
176 t.Errorf("Setting c_std should not cause the '-x c++' flag to be emitted")
177 }
Ivan Lozano3d947522020-09-23 13:26:25 -0400178}
Ivan Lozano0a2a1152020-10-16 10:49:08 -0400179
180func TestBindgenDisallowedFlags(t *testing.T) {
181 // Make sure passing '-x c++' to cflags generates an error
182 testRustError(t, "cflags: -x c\\+\\+ should not be specified in cflags.*", `
183 rust_bindgen {
184 name: "libbad_flag",
185 wrapper_src: "src/any.h",
186 crate_name: "bindgen",
187 stem: "libbindgen",
188 source_stem: "bindings",
189 cflags: ["-x c++"]
190 }
191 `)
192
193 // Make sure passing '-std=' to cflags generates an error
194 testRustError(t, "cflags: -std should not be specified in cflags.*", `
195 rust_bindgen {
196 name: "libbad_flag",
197 wrapper_src: "src/any.h",
198 crate_name: "bindgen",
199 stem: "libbindgen",
200 source_stem: "bindings",
201 cflags: ["-std=foo"]
202 }
203 `)
204}
Andrei Homescu78a1f8d2023-07-08 00:35:15 +0000205
206func TestBindgenFlagFile(t *testing.T) {
207 ctx := testRust(t, `
208 rust_bindgen {
209 name: "libbindgen",
210 wrapper_src: "src/any.h",
211 crate_name: "bindgen",
212 stem: "libbindgen",
213 source_stem: "bindings",
214 bindgen_flag_files: [
215 "flag_file.txt",
216 ],
217 }
218 `)
219 libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
220
221 if !strings.Contains(libbindgen.Args["flagfiles"], "/dev/null") {
222 t.Errorf("missing /dev/null in rust_bindgen rule: flags %#v", libbindgen.Args["flagfiles"])
223 }
224 if !strings.Contains(libbindgen.Args["flagfiles"], "flag_file.txt") {
225 t.Errorf("missing bindgen flags file in rust_bindgen rule: flags %#v", libbindgen.Args["flagfiles"])
226 }
227 // TODO: The best we can do right now is check $flagfiles. Once bindgen.go switches to RuleBuilder,
228 // we may be able to check libbinder.RuleParams.Command to see if it contains $(cat /dev/null flag_file.txt)
229}
Ellen Arteca810c37e2024-04-23 00:17:47 +0000230
Ellen Arteca810c37e2024-04-23 00:17:47 +0000231func TestBindgenHandleStaticInlining(t *testing.T) {
232 ctx := testRust(t, `
233 rust_bindgen {
234 name: "libbindgen",
235 wrapper_src: "src/any.h",
236 crate_name: "bindgen",
237 stem: "libbindgen",
238 source_stem: "bindings",
Ivan Lozano3b591c72024-05-02 10:07:04 -0400239 handle_static_inline: true,
240 static_inline_library: "libbindgen_staticfns"
241 }
242
243 cc_library_static {
244 name: "libbindgen_staticfns",
245 srcs: [":libbindgen"],
246 include_dirs: ["src/"],
247 }
248 `)
249 libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs")
250 // Make sure the flag to support `static inline` functions is present
251 if !strings.Contains(libbindgen.Args["flags"], "--wrap-static-fns") {
252 t.Errorf("missing flag to handle static inlining in rust_bindgen rule: flags %#v", libbindgen.Args["flags"])
253 }
254
255 if !strings.Contains(libbindgen.Args["flags"], "--wrap-static-fns-path") {
256 t.Errorf("missing flag to define path for static inlining C source from bindgen (--wrap-static-fns-path): flags %#v", libbindgen.Args["flags"])
257 }
258
259}
260
261func TestBindgenStaticInlineProperties(t *testing.T) {
262 // Make sure handle_static_inline without static_inline_library generates an error
263 testRustError(t, "requires declaring static_inline_library to the corresponding cc_library module that includes the generated C source from bindgen", `
264 rust_bindgen {
265 name: "libbindgen",
266 wrapper_src: "src/any.h",
267 crate_name: "bindgen",
268 stem: "libbindgen",
269 source_stem: "bindings",
Ellen Arteca810c37e2024-04-23 00:17:47 +0000270 handle_static_inline: true
271 }
272 `)
Ivan Lozano3b591c72024-05-02 10:07:04 -0400273 testRustError(t, "requires declaring handle_static_inline", `
274 rust_bindgen {
275 name: "libbindgen",
276 wrapper_src: "src/any.h",
277 crate_name: "bindgen",
278 stem: "libbindgen",
279 source_stem: "bindings",
280 static_inline_library: "libbindgen_staticfns"
281 }
282
283 cc_library_static {
284 name: "libbindgen_staticfns",
285 srcs: [":libbindgen"],
286 include_dirs: ["src/"],
287 }
288 `)
Ellen Arteca810c37e2024-04-23 00:17:47 +0000289}