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 15package rust 16 17import ( 18 "strings" 19 "testing" 20) 21 22func TestRustBindgen(t *testing.T) { 23 ctx := testRust(t, ` 24 rust_bindgen { 25 name: "libbindgen", 26 defaults: ["cc_defaults_flags"], 27 wrapper_src: "src/any.h", 28 crate_name: "bindgen", 29 stem: "libbindgen", 30 source_stem: "bindings", 31 bindgen_flags: ["--bindgen-flag.*"], 32 cflags: ["--clang-flag()"], 33 shared_libs: ["libfoo_shared"], 34 static_libs: ["libfoo_static"], 35 header_libs: ["libfoo_header"], 36 } 37 cc_library_shared { 38 name: "libfoo_shared", 39 export_include_dirs: ["shared_include"], 40 } 41 cc_library_static { 42 name: "libfoo_static", 43 export_include_dirs: ["static_include"], 44 } 45 cc_library_headers { 46 name: "libfoo_header", 47 export_include_dirs: ["header_include"], 48 } 49 cc_defaults { 50 name: "cc_defaults_flags", 51 cflags: ["--default-flag"], 52 } 53 `) 54 libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs") 55 // Ensure that the flags are present and escaped 56 if !strings.Contains(libbindgen.Args["flags"], "'--bindgen-flag.*'") { 57 t.Errorf("missing bindgen flags in rust_bindgen rule: flags %#v", libbindgen.Args["flags"]) 58 } 59 if !strings.Contains(libbindgen.Args["cflags"], "'--clang-flag()'") { 60 t.Errorf("missing clang cflags in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"]) 61 } 62 if !strings.Contains(libbindgen.Args["cflags"], "-Ishared_include") { 63 t.Errorf("missing shared_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"]) 64 } 65 if !strings.Contains(libbindgen.Args["cflags"], "-Istatic_include") { 66 t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"]) 67 } 68 if !strings.Contains(libbindgen.Args["cflags"], "-Iheader_include") { 69 t.Errorf("missing static_libs exported includes in rust_bindgen rule: cflags %#v", libbindgen.Args["cflags"]) 70 } 71 if !strings.Contains(libbindgen.Args["cflags"], "--default-flag") { 72 t.Errorf("rust_bindgen missing cflags defined in cc_defaults: cflags %#v", libbindgen.Args["cflags"]) 73 } 74} 75 76func TestRustBindgenCustomBindgen(t *testing.T) { 77 ctx := testRust(t, ` 78 rust_bindgen { 79 name: "libbindgen", 80 wrapper_src: "src/any.h", 81 crate_name: "bindgen", 82 stem: "libbindgen", 83 source_stem: "bindings", 84 custom_bindgen: "my_bindgen" 85 } 86 rust_binary_host { 87 name: "my_bindgen", 88 srcs: ["foo.rs"], 89 } 90 `) 91 92 libbindgen := ctx.ModuleForTests("libbindgen", "android_arm64_armv8-a_source").Output("bindings.rs") 93 94 // The rule description should contain the custom binary name rather than bindgen, so checking the description 95 // should be sufficient. 96 if !strings.Contains(libbindgen.Description, "my_bindgen") { 97 t.Errorf("Custom bindgen binary %s not used for libbindgen: rule description %#v", "my_bindgen", 98 libbindgen.Description) 99 } 100} 101 102func TestRustBindgenStdVersions(t *testing.T) { 103 testRustError(t, "c_std and cpp_std cannot both be defined at the same time.", ` 104 rust_bindgen { 105 name: "libbindgen", 106 wrapper_src: "src/any.h", 107 crate_name: "bindgen", 108 stem: "libbindgen", 109 source_stem: "bindings", 110 c_std: "somevalue", 111 cpp_std: "somevalue", 112 } 113 `) 114 115 ctx := testRust(t, ` 116 rust_bindgen { 117 name: "libbindgen_cstd", 118 wrapper_src: "src/any.h", 119 crate_name: "bindgen", 120 stem: "libbindgen", 121 source_stem: "bindings", 122 c_std: "foo" 123 } 124 rust_bindgen { 125 name: "libbindgen_cppstd", 126 wrapper_src: "src/any.h", 127 crate_name: "bindgen", 128 stem: "libbindgen", 129 source_stem: "bindings", 130 cpp_std: "foo" 131 } 132 `) 133 134 libbindgen_cstd := ctx.ModuleForTests("libbindgen_cstd", "android_arm64_armv8-a_source").Output("bindings.rs") 135 libbindgen_cppstd := ctx.ModuleForTests("libbindgen_cppstd", "android_arm64_armv8-a_source").Output("bindings.rs") 136 137 if !strings.Contains(libbindgen_cstd.Args["cflags"], "-std=foo") { 138 t.Errorf("c_std value not passed in to rust_bindgen as a clang flag") 139 } 140 141 if !strings.Contains(libbindgen_cppstd.Args["cflags"], "-std=foo") { 142 t.Errorf("cpp_std value not passed in to rust_bindgen as a clang flag") 143 } 144} 145 146func TestBindgenDisallowedFlags(t *testing.T) { 147 // Make sure passing '-x c++' to cflags generates an error 148 testRustError(t, "cflags: -x c\\+\\+ should not be specified in cflags.*", ` 149 rust_bindgen { 150 name: "libbad_flag", 151 wrapper_src: "src/any.h", 152 crate_name: "bindgen", 153 stem: "libbindgen", 154 source_stem: "bindings", 155 cflags: ["-x c++"] 156 } 157 `) 158 159 // Make sure passing '-std=' to cflags generates an error 160 testRustError(t, "cflags: -std should not be specified in cflags.*", ` 161 rust_bindgen { 162 name: "libbad_flag", 163 wrapper_src: "src/any.h", 164 crate_name: "bindgen", 165 stem: "libbindgen", 166 source_stem: "bindings", 167 cflags: ["-std=foo"] 168 } 169 `) 170} 171