| Ivan Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 1 | // 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 |  | 
|  | 15 | package rust | 
|  | 16 |  | 
|  | 17 | import ( | 
|  | 18 | "strings" | 
|  | 19 | "testing" | 
| Ivan Lozano | 1dbfa14 | 2024-03-29 14:48:11 +0000 | [diff] [blame] | 20 |  | 
|  | 21 | "android/soong/android" | 
| Ivan Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 22 | ) | 
|  | 23 |  | 
|  | 24 | func TestRustBindgen(t *testing.T) { | 
|  | 25 | ctx := testRust(t, ` | 
|  | 26 | rust_bindgen { | 
|  | 27 | name: "libbindgen", | 
| Ivan Lozano | bc9e421 | 2020-09-25 16:08:34 -0400 | [diff] [blame] | 28 | defaults: ["cc_defaults_flags"], | 
| Ivan Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 29 | wrapper_src: "src/any.h", | 
| Ivan Lozano | 26ecd6c | 2020-07-31 13:40:31 -0400 | [diff] [blame] | 30 | crate_name: "bindgen", | 
|  | 31 | stem: "libbindgen", | 
|  | 32 | source_stem: "bindings", | 
| Stephen Crane | 12e2cb7 | 2020-08-04 12:26:10 -0700 | [diff] [blame] | 33 | bindgen_flags: ["--bindgen-flag.*"], | 
|  | 34 | cflags: ["--clang-flag()"], | 
| Ivan Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 35 | shared_libs: ["libfoo_shared"], | 
| Ivan Lozano | 1dbfa14 | 2024-03-29 14:48:11 +0000 | [diff] [blame] | 36 | } | 
|  | 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 Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 43 | static_libs: ["libfoo_static"], | 
| Ivan Lozano | 1dbfa14 | 2024-03-29 14:48:11 +0000 | [diff] [blame] | 44 | } | 
|  | 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 Lozano | 9b44383 | 2020-11-17 13:39:30 -0500 | [diff] [blame] | 51 | header_libs: ["libfoo_header"], | 
| Ivan Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 52 | } | 
|  | 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 Lozano | 9b44383 | 2020-11-17 13:39:30 -0500 | [diff] [blame] | 61 | cc_library_headers { | 
|  | 62 | name: "libfoo_header", | 
|  | 63 | export_include_dirs: ["header_include"], | 
|  | 64 | } | 
| Ivan Lozano | bc9e421 | 2020-09-25 16:08:34 -0400 | [diff] [blame] | 65 | cc_defaults { | 
|  | 66 | name: "cc_defaults_flags", | 
|  | 67 | cflags: ["--default-flag"], | 
|  | 68 | } | 
| Ivan Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 69 | `) | 
| Thiébaud Weksteen | 295c72b | 2020-09-23 18:10:17 +0200 | [diff] [blame] | 70 | libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs") | 
| Ivan Lozano | 1dbfa14 | 2024-03-29 14:48:11 +0000 | [diff] [blame] | 71 | 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 Crane | 12e2cb7 | 2020-08-04 12:26:10 -0700 | [diff] [blame] | 74 | // Ensure that the flags are present and escaped | 
|  | 75 | if !strings.Contains(libbindgen.Args["flags"], "'--bindgen-flag.*'") { | 
| Ivan Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 76 | t.Errorf("missing bindgen flags in rust_bindgen rule: flags %#v", libbindgen.Args["flags"]) | 
|  | 77 | } | 
| Stephen Crane | 12e2cb7 | 2020-08-04 12:26:10 -0700 | [diff] [blame] | 78 | if !strings.Contains(libbindgen.Args["cflags"], "'--clang-flag()'") { | 
| Ivan Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 79 | 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 Lozano | 45901ed | 2020-07-24 16:05:01 -0400 | [diff] [blame] | 82 | t.Errorf("missing shared_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"]) | 
| Ivan Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 83 | } | 
| Ivan Lozano | 1dbfa14 | 2024-03-29 14:48:11 +0000 | [diff] [blame] | 84 | 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 Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 86 | } | 
| Ivan Lozano | 1dbfa14 | 2024-03-29 14:48:11 +0000 | [diff] [blame] | 87 | 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 Lozano | 9b44383 | 2020-11-17 13:39:30 -0500 | [diff] [blame] | 89 | } | 
| Ivan Lozano | 1dbfa14 | 2024-03-29 14:48:11 +0000 | [diff] [blame] | 90 |  | 
|  | 91 | if android.InList("libfoo_static", libbindgenHeaderModule.Properties.AndroidMkHeaderLibs) { | 
|  | 92 | t.Errorf("Static library dependency should not be in HeaderLibs list") | 
|  | 93 | } | 
|  | 94 |  | 
| Ivan Lozano | bc9e421 | 2020-09-25 16:08:34 -0400 | [diff] [blame] | 95 | 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 Lozano | 4fef93c | 2020-07-08 08:39:44 -0400 | [diff] [blame] | 98 | } | 
| Ivan Lozano | c564d2d | 2020-08-04 15:43:37 -0400 | [diff] [blame] | 99 |  | 
|  | 100 | func 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 Weksteen | 295c72b | 2020-09-23 18:10:17 +0200 | [diff] [blame] | 116 | libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs") | 
| Ivan Lozano | c564d2d | 2020-08-04 15:43:37 -0400 | [diff] [blame] | 117 |  | 
|  | 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 Lozano | 3d94752 | 2020-09-23 13:26:25 -0400 | [diff] [blame] | 125 |  | 
|  | 126 | func 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 Lozano | 829e1e9 | 2023-10-09 11:30:09 -0400 | [diff] [blame] | 142 | wrapper_src: "src/any.hpp", | 
| Ivan Lozano | 3d94752 | 2020-09-23 13:26:25 -0400 | [diff] [blame] | 143 | 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 Weksteen | e0510d7 | 2020-09-25 15:50:09 +0200 | [diff] [blame] | 158 | 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 Lozano | 3d94752 | 2020-09-23 13:26:25 -0400 | [diff] [blame] | 160 |  | 
|  | 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 Lozano | 829e1e9 | 2023-10-09 11:30:09 -0400 | [diff] [blame] | 168 |  | 
|  | 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 Lozano | 3d94752 | 2020-09-23 13:26:25 -0400 | [diff] [blame] | 178 | } | 
| Ivan Lozano | 0a2a115 | 2020-10-16 10:49:08 -0400 | [diff] [blame] | 179 |  | 
|  | 180 | func 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 Homescu | 78a1f8d | 2023-07-08 00:35:15 +0000 | [diff] [blame] | 205 |  | 
|  | 206 | func 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 Arteca | 810c37e | 2024-04-23 00:17:47 +0000 | [diff] [blame] | 230 |  | 
| Ellen Arteca | 810c37e | 2024-04-23 00:17:47 +0000 | [diff] [blame] | 231 | func 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 Lozano | 3b591c7 | 2024-05-02 10:07:04 -0400 | [diff] [blame] | 239 | 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 |  | 
|  | 261 | func 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 Arteca | 810c37e | 2024-04-23 00:17:47 +0000 | [diff] [blame] | 270 | handle_static_inline: true | 
|  | 271 | } | 
|  | 272 | `) | 
| Ivan Lozano | 3b591c7 | 2024-05-02 10:07:04 -0400 | [diff] [blame] | 273 | 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 Arteca | 810c37e | 2024-04-23 00:17:47 +0000 | [diff] [blame] | 289 | } |