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