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 "android/soong/android" 22 "android/soong/cc" 23) 24 25// Test that cc modules can depend on vendor_available rust_ffi_rlib/rust_ffi_static libraries. 26func TestVendorLinkage(t *testing.T) { 27 ctx := testRust(t, ` 28 cc_binary { 29 name: "fizz_vendor_available", 30 static_libs: [ 31 "libfoo_vendor", 32 "libfoo_vendor_static" 33 ], 34 vendor_available: true, 35 } 36 cc_binary { 37 name: "fizz_soc_specific", 38 static_libs: ["libfoo_vendor"], 39 soc_specific: true, 40 } 41 rust_ffi_rlib { 42 name: "libfoo_vendor", 43 crate_name: "foo", 44 srcs: ["foo.rs"], 45 vendor_available: true, 46 } 47 rust_ffi_static { 48 name: "libfoo_vendor_static", 49 crate_name: "foo", 50 srcs: ["foo.rs"], 51 vendor_available: true, 52 } 53 `) 54 55 vendorBinary := ctx.ModuleForTests("fizz_vendor_available", "android_vendor_arm64_armv8-a").Module().(*cc.Module) 56 57 if android.InList("libfoo_vendor_static.vendor", vendorBinary.Properties.AndroidMkStaticLibs) { 58 t.Errorf("vendorBinary should not have a staticlib dependency on libfoo_vendor_static.vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs) 59 } 60} 61 62// Test that variants which use the vndk emit the appropriate cfg flag. 63func TestImageCfgFlag(t *testing.T) { 64 ctx := testRust(t, ` 65 rust_ffi_shared { 66 name: "libfoo", 67 crate_name: "foo", 68 srcs: ["foo.rs"], 69 vendor_available: true, 70 product_available: true, 71 } 72 `) 73 74 vendor := ctx.ModuleForTests("libfoo", "android_vendor_arm64_armv8-a_shared").Rule("rustc") 75 76 if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") { 77 t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"]) 78 } 79 if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vendor'") { 80 t.Errorf("missing \"--cfg 'android_vendor'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"]) 81 } 82 if strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_product'") { 83 t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"]) 84 } 85 86 product := ctx.ModuleForTests("libfoo", "android_product_arm64_armv8-a_shared").Rule("rustc") 87 if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") { 88 t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"]) 89 } 90 if strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vendor'") { 91 t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"]) 92 } 93 if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_product'") { 94 t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"]) 95 } 96 97 system := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("rustc") 98 if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vndk'") { 99 t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"]) 100 } 101 if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vendor'") { 102 t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"]) 103 } 104 if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_product'") { 105 t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo system variant, rustcFlags: %#v", product.Args["rustcFlags"]) 106 } 107 108} 109 110// Test that cc modules can link against vendor_ramdisk_available rust_ffi_rlib and rust_ffi_static libraries. 111func TestVendorRamdiskLinkage(t *testing.T) { 112 ctx := testRust(t, ` 113 cc_library_shared { 114 name: "libcc_vendor_ramdisk", 115 static_libs: [ 116 "libfoo_vendor_ramdisk", 117 "libfoo_static_vendor_ramdisk" 118 ], 119 system_shared_libs: [], 120 vendor_ramdisk_available: true, 121 } 122 rust_ffi_rlib { 123 name: "libfoo_vendor_ramdisk", 124 crate_name: "foo", 125 srcs: ["foo.rs"], 126 vendor_ramdisk_available: true, 127 } 128 rust_ffi_static { 129 name: "libfoo_static_vendor_ramdisk", 130 crate_name: "foo", 131 srcs: ["foo.rs"], 132 vendor_ramdisk_available: true, 133 } 134 `) 135 136 vendorRamdiskLibrary := ctx.ModuleForTests("libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_shared").Module().(*cc.Module) 137 138 if android.InList("libfoo_static_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) { 139 t.Errorf("libcc_vendor_ramdisk should not have a dependency on the libfoo_static_vendor_ramdisk static library") 140 } 141} 142 143// Test that prebuilt libraries cannot be made vendor available. 144func TestForbiddenVendorLinkage(t *testing.T) { 145 testRustError(t, "Rust prebuilt modules not supported for non-system images.", ` 146 rust_prebuilt_library { 147 name: "librust_prebuilt", 148 crate_name: "rust_prebuilt", 149 rlib: { 150 srcs: ["libtest.rlib"], 151 }, 152 dylib: { 153 srcs: ["libtest.so"], 154 }, 155 vendor: true, 156 } 157 `) 158} 159 160func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) { 161 mod := ctx.ModuleForTests(name, variant).Module().(*Module) 162 partitionDefined := false 163 checkPartition := func(specific bool, partition string) { 164 if specific { 165 if expected != partition && !partitionDefined { 166 // The variant is installed to the 'partition' 167 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition) 168 } 169 partitionDefined = true 170 } else { 171 // The variant is not installed to the 'partition' 172 if expected == partition { 173 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition) 174 } 175 } 176 } 177 socSpecific := func(m *Module) bool { 178 return m.SocSpecific() 179 } 180 deviceSpecific := func(m *Module) bool { 181 return m.DeviceSpecific() 182 } 183 productSpecific := func(m *Module) bool { 184 return m.ProductSpecific() || m.productSpecificModuleContext() 185 } 186 systemExtSpecific := func(m *Module) bool { 187 return m.SystemExtSpecific() 188 } 189 checkPartition(socSpecific(mod), "vendor") 190 checkPartition(deviceSpecific(mod), "odm") 191 checkPartition(productSpecific(mod), "product") 192 checkPartition(systemExtSpecific(mod), "system_ext") 193 if !partitionDefined && expected != "system" { 194 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+ 195 " but installed to system partition", variant, name, expected) 196 } 197} 198 199func TestInstallPartition(t *testing.T) { 200 t.Parallel() 201 t.Helper() 202 ctx := testRust(t, ` 203 rust_binary { 204 name: "sample_system", 205 crate_name: "sample", 206 srcs: ["foo.rs"], 207 } 208 rust_binary { 209 name: "sample_system_ext", 210 crate_name: "sample", 211 srcs: ["foo.rs"], 212 system_ext_specific: true, 213 } 214 rust_binary { 215 name: "sample_product", 216 crate_name: "sample", 217 srcs: ["foo.rs"], 218 product_specific: true, 219 } 220 rust_binary { 221 name: "sample_vendor", 222 crate_name: "sample", 223 srcs: ["foo.rs"], 224 vendor: true, 225 } 226 rust_binary { 227 name: "sample_odm", 228 crate_name: "sample", 229 srcs: ["foo.rs"], 230 device_specific: true, 231 } 232 rust_binary { 233 name: "sample_all_available", 234 crate_name: "sample", 235 srcs: ["foo.rs"], 236 vendor_available: true, 237 product_available: true, 238 } 239 `) 240 241 checkInstallPartition(t, ctx, "sample_system", binaryCoreVariant, "system") 242 checkInstallPartition(t, ctx, "sample_system_ext", binaryCoreVariant, "system_ext") 243 checkInstallPartition(t, ctx, "sample_product", binaryProductVariant, "product") 244 checkInstallPartition(t, ctx, "sample_vendor", binaryVendorVariant, "vendor") 245 checkInstallPartition(t, ctx, "sample_odm", binaryVendorVariant, "odm") 246 247 checkInstallPartition(t, ctx, "sample_all_available", binaryCoreVariant, "system") 248} 249